Compare commits

...

121 Commits

Author SHA1 Message Date
Benjamin Berg
c7cab77fc1 usb-transfer: Work around libgusb cancellation issue
We have plenty of code paths where a transfer may be cancelled before it
is submitted. Unfortunately, libgusb up to and including version 0.3.6
are not handling that case correctly (due to libusb ignoring
cancellation on transfers that are not yet submitted).

Work around this, but do so in a somewhat lazy fashion that is not
entirely race free.

Closes: #306
2020-10-01 00:19:35 +02:00
Benjamin Berg
a63dcc96d5 virtual_image: Open a window for race conditions during open/close
Delay the open/close callbacks by 100ms so that we have a window of
opportunity for race conditions. This is needed to test certain
conditiosn in fprintd.
2020-09-29 12:02:19 +00:00
Benjamin Berg
fab349f356 Remove trailing \n where they are not necessary
Adding a trailing \n to g_message, g_debug, g_warning and g_error is not
neccessary, as a newline will be added automatically by the logging
infrastructure.
2020-09-29 10:42:03 +02:00
Benjamin Berg
62edf93958 tests: Add AES3500 test case
Thanks for Federico Cupellini for providing test samples.
2020-09-29 10:35:48 +02:00
Benjamin Berg
8c4ff253cb aes3k: Fix transfer error path and cancellable lifetime
The cancellable needs to be free'ed at deactivation. Also free it if we
run into a fatal error, which then in turn indicates that the device is
deactivated already.
2020-09-29 10:35:25 +02:00
Benjamin Berg
3ce6a15547 image-device: Don't deactivate if deactivation was already started
The test only prevent deactivation after it completed. Also guard
against trying to deactivate a second time.
2020-09-28 19:12:28 +02:00
Benjamin Berg
174aa2c091 Release 1.90.3 2020-09-14 14:23:45 +02:00
Benjamin Berg
9efe25b91c ci: Disable flatpak building for forks
Also move to use a single rules set for flatpak rather than only/except
rules.
2020-09-14 14:17:25 +02:00
Benjamin Berg
bcce8876e2 aes3k: Fix cancellation logic of aes3k driver
The change_state function is called synchronously from the
image_captured callback. This means that deactivation of the device
happens during the img_cb function, causing the USB transfer to be
re-registered even though the device is already deactivating.

There are various ways to fix this, but it makes sense to directly bind
the cancellation to the deactivation. So create a cancellable that we
cancel at deactivation time, and make sure we always deactivate by going
through cancellation.

closes: #306
2020-09-14 11:23:38 +00:00
boger.wang
3962372f47 tests: add identify test for driver goodixmoc
add identify ioctl file, modify custom.py add identify test
2020-09-14 09:55:55 +00:00
boger.wang
f67f61c638 goodixmoc: Add identify function
this device support verify and identify both, actually call the same
interface.
2020-09-14 09:55:55 +00:00
boger.wang
d5f7f4dfaa goodixmoc: Prevent incorrect firmware type running
only firmware type:APP can function well, if device flash in a factory
or test firmware, report a error tips user update firmware by fwupd
2020-09-14 09:55:55 +00:00
Benjamin Berg
ce6961d165 image-device: Fix cancellation documentation
Image devices are simply deactivated suddenly. As such, the cancellation
logic of FpDevice is not really useful there, but the documentation was
apparently accidentally copied unmodified.
2020-09-07 12:12:34 +02:00
Benjamin Berg
30e1a68344 ci: Build flatpak using GNOME runner and template 2020-09-03 09:42:28 +02:00
Benjamin Berg
5b087ed848 demo: Switch to use GNOME 3.36 runtime 2020-09-03 09:41:11 +02:00
Benjamin Berg
5d0481b031 context: Lower severity of warning if USB fails to initialise
This is unlikely to happen in a real world scenario and currently breaks
running the CI test (not the umockdev based ones) while building the
flatpak. Lower the severity to avoid aborting because there is a
warning.
2020-09-03 09:41:11 +02:00
Benjamin Berg
596d22a449 context: Fix invalid accesses to GUsbContext if USB is missing
When USB cannot be initialised (inside the flatpak build environment),
then we would have invalid accesses to the NULL pointer. Fix those.
2020-09-03 09:41:11 +02:00
boger.wang
c85f385191 tests: add test for goodixmoc driver 2020-09-01 16:39:06 +08:00
boger.wang
eb2aaaaa20 drivers: add goodix moc sensor driver support 2020-09-01 16:39:06 +08:00
boger.wang
e3c009c5b3 fp-device: add new type FpDeviceError FP_DEVICE_ERROR_DATA_DUPLICATE 2020-09-01 16:39:06 +08:00
Vincent Huang
a4f7293f32 synaptics: retry get version command once when receiving non-success
status
2020-08-21 17:42:00 +08:00
Vincent Huang
8b64312f4b synaptics: support sensors pid 0xe9 & 0xdf 2020-07-31 09:47:35 +08:00
Marco Trevisan (Treviño)
b7e27bfdc6 demo: Handle the non-imaging mode also if we get a non-supported error
Image devices may return a FP_DEVICE_ERROR_NOT_SUPPORTED error once capture
is already started, in such case handle the error going in non imaging mode
2020-06-17 14:16:34 +02:00
Marco Trevisan (Treviño)
37b19674f1 verify: Use fast matching callback also for non-storage devices 2020-06-17 14:14:50 +02:00
Marco Trevisan (Treviño)
a5f4ad507a img-capture: Exit with error if the device doesn't support capture 2020-06-17 14:12:43 +02:00
Marco Trevisan (Treviño)
1f96077e36 examples: Don't try to save an image from a print without it
A device may produce both prints with image data and not, so only do it
in the case the prints contains image data
2020-06-17 14:00:19 +02:00
Marco Trevisan (Treviño)
ed26976ac5 fpi-usb-transfer: Use the same values of libusb for transfer types 2020-06-16 22:50:47 +02:00
Marco Trevisan (Treviño)
e4d292b595 fp-image-device: Properly include fp-device.h 2020-06-16 22:49:38 +02:00
Marco Trevisan (Treviño)
c6b8430c72 fpi-print: Improve debug on print score 2020-06-16 22:49:18 +02:00
Marco Trevisan (Treviño)
cbf1dcca29 fpi-image-device: Improve debugging messages 2020-06-16 22:48:51 +02:00
Marco Trevisan (Treviño)
7f7d099ba0 fpi-device: Don't double check for cancellable value
g_cancellable_is_cancelled already handles properly null values
2020-06-16 22:43:18 +02:00
Marco Trevisan (Treviño)
b6f965c1d9 fpi-device: Use the current action string instead of value 2020-06-16 22:42:34 +02:00
Vasily Khoruzhick
fd2875aa3e examples: add img-capture example
This one can be useful in scripts, e.g. for building fingerprint
dataset.
2020-06-13 09:20:28 -07:00
Benjamin Berg
4b2816db64 Update for 1.90.2 2020-06-08 11:40:02 +02:00
Benjamin Berg
4af3e59174 uru4000: Always detect whether encryption is in use
This is based on the patch and observation from Bastien that some
URU4000B devices do not use encryption by default (it is a configuration
stored within the firmware). As such, it makes sense to always detect
whether encryption is in use by inspecting the image.

The encryption option would disable flipping of the image for the
URU400B device. Retain this behaviour for backward compatibility.
2020-06-05 15:53:53 +00:00
Benjamin Berg
24b1faffde upeksonly: Add a comment that multiple URBs are needed 2020-06-05 17:44:36 +02:00
Benjamin Berg
49983c8ee7 upeksonly: Fix memory leak of register data helper struct 2020-06-05 17:44:36 +02:00
Vasily Khoruzhick
d276c3489e upeksonly: Fix register write value
The value was set after the transfer was submitting, causing the value
to always be zero.
2020-06-05 17:44:36 +02:00
Benjamin Berg
3f51e6dcb6 upeksonly: Pass required user data to write_regs_cb
The user data for write_regs_cb needs to be set to wrdata. This was
simply missing, add the appropriate argument.
2020-06-05 17:44:36 +02:00
Benjamin Berg
b4dbbd667a upeksonly: Avoid reading beyond received packet boundary
The code would just read 4096 bytes from the packet, without checking
the size and neither setting short_is_error. It is not clear whether
packets from the device are always 4096 bytes or not. But the code
assume we always get a full line, so enforce that and use the actual
packet size otherwise.
2020-06-05 17:44:36 +02:00
Benjamin Berg
7d9245505f upeksonly: Remove callback support after killing transfers
This seems to have been unused even before the v2 port.
2020-06-05 17:44:36 +02:00
Benjamin Berg
570daf2321 upeksonly: Remove ABORT_SSM constant
This was not used. The old driver used this if creating a USB transfer
failed, however, we delay any such failures (which cannot really happen)
into the callback today, where the error is handled differently.
2020-06-05 15:40:17 +00:00
Benjamin Berg
60d0f84294 upeksonly: Fix creation of image transfers
The GPtrArray needs to be created at some point. Also, reference
counting was wrong as submitting the transfer sinks the ref, but we rely
on it surviving.

Note that we really should change this to only have one in-flight
transfer and starting a new one after it finishes.

Co-authored-by: Vasily Khoruzhick <anarsoul@gmail.com>
2020-06-05 15:40:17 +00:00
Benjamin Berg
6633025437 vfs301: Allow freeing of data by copying it
When sending static data, it would not be copied. The function that
sends it assumed that it should be free'ed though.

Fix this by simply always making a copy.
2020-06-05 15:17:42 +00:00
Benjamin Berg
40ed353666 elan: Only queue state changes once
The driver would warn about the fact that a state change is queued, but
still queue it a second time. This would result in deactivation to run
twice.

See: #216
2020-06-05 15:13:18 +00:00
Benjamin Berg
32bdd8d5c4 image: Fix reporting of retry on activation timeout
The image driver may still be deactivating when a new activation request
comes in. This is because of a hack to do early reporting, which is
technically not needed anymore.

Fix the immediate issue by properly reporting the retry case. The proper
fix is to only finish the previous operation after the device has been
deactivated.
2020-06-05 15:07:05 +00:00
Benjamin Berg
ec4fc9aec5 ci: Put coverage regexp into CI description
One can set it in the project, but that doesn't get copied to forks. And
that means the coverage information isn't printed in MRs sometimes.

Just add it into .gitlab-ci.yml so that it always works.
2020-06-05 15:03:38 +00:00
Benjamin Berg
390611d5c9 tests: Improve the instructions to create new umockdev captures
Thanks to Evgeny for much of the work and suggestions from Boger Wang.

Co-authored-by: Evgeny Gagauz <evgenij.gagauz@gmail.com>
2020-06-05 15:03:38 +00:00
Benjamin Berg
685052c605 tests: Add test for vfs0050 driver
This test is based on data captured by Evgeny.

Co-authored-by: Evgeny Gagauz <evgenij.gagauz@gmail.com>
2020-06-05 15:03:38 +00:00
Benjamin Berg
4b83f8bfd9 vfs0050: Accept zero bytes read instead of timeout for emulation
This allows us to replace non-emulateable timeout conditions into zero
byte replies in the recording.
2020-06-05 15:03:38 +00:00
Benjamin Berg
b137807420 upekts: Fix error reporting during verify
We delayed the wrong error types for the early reporting mechanism.
2020-06-05 14:48:57 +00:00
Benjamin Berg
0936fc3597 upekts: Fix error handling in verify_stop_deinit_cb
The error memory management was incorrect possibly causing double free's
and critical warnings.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b7f436e8de upekts: Fix reading of fingerprint data for verification
the code tried to fetch the data from the device rather the print.
Obviously, this could never work.
2020-06-05 14:48:57 +00:00
Benjamin Berg
4f0b0fa526 tests: Ensure FpDevice checks enrolled prints for completeness
Enrolled prints need to have their type set. FpDevice should ensure that
is the case when a driver returns a print back.
2020-06-05 14:48:57 +00:00
Benjamin Berg
f0abefa9fa device: Ensure enrolled print as an appropriate type set
The driver might forget to set the type of the print. Catch that error a
bit earlier rather than failing when the API user tries to load it from
disk again.
2020-06-05 14:48:57 +00:00
Benjamin Berg
7f58556011 tests: An enrolled print needs to have a type set 2020-06-05 14:48:57 +00:00
Benjamin Berg
cecb01bcb9 upekts: Set the print type during enroll
The type of the print (RAW or NBIS) needs to be filled in by the driver.
For most drivers the image devices does this (NBIS), but the
corresponding call was missing in the upekts driver, rendering the
enrolled print unusable.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b95402bc72 upekts: Fix memory leak and remove unneeded copy
__handle_incoming_msg would copy the payload of the message into a newly
created buffer just to destroy it again immediately after calling the
callback. Just reference the correct address inside the original package
instead.

Also, in one case the extra buffer was leaked afterwards.
2020-06-05 14:48:57 +00:00
Benjamin Berg
484743f652 upekts: Assert correct packet length in __handle_incoming_msg
The surrounding code already checks this and reads the correct amount.
Add an assert to ensure we really never do an out of bounds read.
2020-06-05 14:48:57 +00:00
Benjamin Berg
a5cfc1644f upekts: Fix 9 byte buffer overflow while reading extended data
The driver would correctly calculate the amount of extra space needed to
receive the whole packet. It would also request the correct number of
bytes for this transfer.

However, the reallocated buffer to hold this data was directly derived
from the expected payload size and did not include the overhead.

Make the code more explicit and get rid of the confusing
MAX_DATA_IN_READ_BUF define that hides details on buffer allocation
calculation from the code.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b3565b83e1 upekts: Only release USB interface on exit
The device is already beeing de-initialised from the verify/enroll
commands. Trying it again will result in a timeout error as it is not
responding properly at that point.
2020-06-05 14:48:57 +00:00
Benjamin Berg
8f46de0a60 upekts: Fix reference counting in do_enroll_stop
The print passed to do_enroll_stop does not need to be ref'ed in the
function.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b3c5fe4b82 upekts: Fix ownership transfer to fpi_device_enroll_complete
fpi_device_enroll_complete takes the ownership of the pointers. As such,
they need to be stolen from EnrollStopData.
2020-06-05 14:48:57 +00:00
Vasily Khoruzhick
4cf5f92a52 lib: re-add partial image flag
And activate perimeter points removal if this flag is set

This flag should be set for aes1610, aesx660, aes2501, aes2550
and upektc_img since these sensors may produce incomplete image.

Fixes: #142
2020-06-04 09:34:31 -07:00
Vasily Khoruzhick
297236b51a nbis: re-add step to remove perimeter points
This step helps to drop false minutiae for short sensors and
it was accidentally dropped during NBIS update. Re-add this step
and add a patch to update script to ensure that it's not dropped
during next update.

Fixes: 9fb789dc78 ("nbis: Update to NBIS 5.0.0")
2020-06-03 20:44:41 -07:00
Benjamin Berg
8626c64831 ci: Output diff of uncrustify check
Not having the diff is a bit painfull when the local version of
uncrustify differs from the one on the CI runner. So uncrustify in-place
and output the diff.
2020-06-02 11:56:19 +00:00
Benjamin Berg
e4f9935706 Uncrustify with newer version 2020-06-02 11:56:19 +00:00
Benjamin Berg
8ba29606bb Add MAINTAINERS file 2020-05-22 15:00:11 +02:00
Evgeny Gagauz
1b74813adf vfs0050: Stop capture after a timeout happens
If a transfer errors out then actual_length is negative. The only error
that is not caught is a timeout error, which should also result in the
SSM to move to the next state.
2020-05-13 09:51:23 +00:00
Benjamin Berg
07ff03970f libfprint: Fix a few issues with the documentation
This must have been broken all along. Get it into a better shape. Looks
like mostly cases of bad copy/paste.
2020-05-11 20:51:29 +02:00
Benjamin Berg
25ab4849a4 doc: Move sections and fix title for internal FpImageDevice
Otherwise the public API page (which is empty) is overwritten.
2020-05-11 20:51:29 +02:00
Benjamin Berg
840bcc77a5 ci: Export HTML documentation as artifacts
We build the HTML documentation. For feature branches, it is convenient
to be able to view the documentation easily. Expose them as artifacts
and add a link to the browser underneath the pipeline in the MR.

Unfortunately, it does not seem to be possible to link directly to the
HTML.
2020-05-11 20:51:29 +02:00
Benjamin Berg
a464f602ca nbis: Apply patch to fix scan-build warnings
Apply the newly added patch to the checkout.
2020-05-07 14:22:02 +00:00
Benjamin Berg
ad17011e68 nbis: Add patch to fix warnings reported by scan-build
This patch basically only adds annotations. None of the errors can be
hit in practice.
2020-05-07 14:22:02 +00:00
Benjamin Berg
744a71ce08 vfs301: Assert hex string has 2 or more characters
Otherwise static analysis thinks we may end up allocating a 0 byte
output buffer.
2020-05-07 14:22:02 +00:00
Benjamin Berg
422fc5facf tests: Add unused annotation
The variables exist for memory management but are unused otherwise. Tag
them as such.
2020-05-07 14:22:02 +00:00
Benjamin Berg
6d542edf8a test: Remove unused initialisers
Make the static analysis happy.
2020-05-07 14:22:02 +00:00
Benjamin Berg
8d4d56b1f1 tests: Annotate a few variables as unused
These solely exist for memory management, but the static analysis
complains.
2020-05-07 14:22:02 +00:00
Benjamin Berg
6e30a1ee45 print: Fix "possible leak" warning by moving initialization
For some reason static checkers report that the auto-free is not run if
the goto exists the loop. It seems to me like that should work fine, but
we can simply make the analysers happy by moving it.
2020-05-07 14:22:02 +00:00
Benjamin Berg
87c3b9c5ba upekts: Fix possible NULL pointer access
Reported by scan-build.
2020-05-07 14:22:02 +00:00
Benjamin Berg
0a08a6a7c0 ci: Run clang scan-build test as part of CI 2020-05-07 14:22:02 +00:00
Benjamin Berg
9db89e00d0 elan: Downgrade g_message to debug severity
See: #211
2020-05-07 13:55:35 +00:00
Benjamin Berg
3ad65b9589 vfs5011: Prevent too small images
We need more than 1 line for assembling, but in general, we should
have a reasonable amount of lines. So use the width in the hope we'll
get an image that is about square at least.

Closes: #135
2020-05-07 13:55:35 +00:00
Benjamin Berg
48aa6d0252 upekts: Fix regression during initialisation
The driver has two helper functions to format a command. In one case,
the function was accidentally changed during the port to the new driver
APIs.

See https://bugzilla.redhat.com/show_bug.cgi?id=1832229
2020-05-07 09:55:13 +02:00
Michal Prívozník
eefc954f91 context: Fix order of PID/VID in a debug message
When no driver is found for an USB device a debug message is
printed. However, it has PID and VID in wrong order - usually it
is Vendor ID which goes first. This is how 'lsusb' prints it.
Matching the order helps debugging.

Signed-off-by: Michal Privoznik <michal@privoznik.com>
2020-04-27 16:16:43 +02:00
Michal Prívozník
5bcf9ac008 print: Include "fpi-compact.h"
In the fpi_print_fill_from_user_id() GDate is defined using
g_autoptr(). However, this requires new enough GLib. For older
versions there's a definition provided locally in fpi-compact.h.
Include the file to fix build with older version of GLib.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-27 16:16:39 +02:00
Benjamin Berg
d2402309ee examples: Cancel verify operation on Ctrl+C
This makes it easier to do basic testing of cancellation paths in the
drivers.
2020-04-24 18:40:48 +00:00
Benjamin Berg
a651b65401 example: Cancel enroll operation on Ctrl+C
This makes it easier to do basic testing of cancellation paths in the
drivers.
2020-04-24 18:40:48 +00:00
Marco Trevisan (Treviño)
bc3f622b2a context: Factorize duplicated code 2020-04-24 20:21:01 +02:00
Marco Trevisan (Treviño)
5de49b33e6 image-device: Terminate the current action with error on print failure
If we fail when setting the scanned image to a print, we'll have a fatal
error, in such case we can terminate the current action and deactivate the
device.
2020-04-24 20:09:56 +02:00
Marco Trevisan (Treviño)
81e198c034 image: Return an error if we got an empty or NULL minutiae array
In some cases nbim's get_minutiae returns no minutiae without providing an
error code, and if this happens we would crash in the task callback function
as we would try to deference the data->minutiae pointer.

Related to: #251
2020-04-24 20:09:56 +02:00
Marco Trevisan (Treviño)
c0895a858d etes603: Return TOO_SHORT retry error for small images
If the image height is less than the sensor horizontal resolution, then
return a retry error rather than trying to submit the image for further
processing.

Related to: #251
2020-04-24 20:03:51 +02:00
Benjamin Berg
5d5995f201 image: Check for task success rather than just cancellation
The minutiae detection might fail and we must not copy any data at that
point. So check g_task_had_error to ensure that we only do so when the
task was successful.

Fixes: #251
2020-04-24 20:03:37 +02:00
Benjamin Berg
f71045b743 synaptics: Use the FpPrint ID generation functionality
As the functionality is now part of the internal FpPrint API, it makes
sene to use it.
2020-04-20 16:43:52 +02:00
Benjamin Berg
0274d0783b print: Add helpers to generate a unique print ID containing metadata
It makes sense to include this functionality in the core library as more
than one driver will be using it soon.
2020-04-20 16:43:52 +02:00
Bastien Nocera
5c5a4f6907 upekts: Fix memory leak
Don't allocate a new finger print structure,
the fpi_device_get_enroll_data() just below will overwrite it.
2020-04-15 15:55:39 +02:00
Bastien Nocera
5b6f5c9aad synaptics: Don't pass always-NULL value
No need to pass "error" to this report function, it will always be NULL.
2020-04-15 15:55:39 +02:00
Marco Trevisan (Treviño)
41e05b1133 test-fpi-device: Don't compare error pointers that have been cleared
During verify/identify complete we replace the error pointer that the driver
returned with another error we created, after clearing that one.

However, when we initialize a new error the compiler may reuse the same
allocation of the cleared one, and this might lead to a test failure.

So, don't be so fragile and ignore the pointer check
2020-04-15 14:19:53 +02:00
Bastien Nocera
579e01359b fp-print: Fix sign-compare warnings
libfprint/fp-print.c: In function ‘fp_print_equal’:
libfprint/fp-print.c:596:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Wsign-compare]
  596 |       for (i = 0; i < self->prints->len; i++)
      |                     ^
libfprint/fp-print.c: In function ‘fp_print_serialize’:
libfprint/fp-print.c:667:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Wsign-compare]
  667 |       for (i = 0; i < print->prints->len; i++)
      |                     ^
libfprint/fp-print.c: In function ‘fp_print_deserialize’:
libfprint/fp-print.c:823:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Wsign-compare]
  823 |       for (i = 0; i < g_variant_n_children (prints); i++)
      |                     ^
2020-04-15 12:48:05 +02:00
Bastien Nocera
cc887c1a37 libfprint: Fix typos 2020-04-14 13:51:02 +02:00
Bastien Nocera
fdd2d6abf8 fprint-list: Fix typos in Copyright statements 2020-04-14 13:51:02 +02:00
Bastien Nocera
6bf29108a1 examples: Fix typo 2020-04-14 13:51:02 +02:00
Bastien Nocera
d0751ae06b tests/elan: Fix typos 2020-04-14 13:51:02 +02:00
Bastien Nocera
a218a5efdd virtual-image: Fix typo 2020-04-14 13:51:01 +02:00
Bastien Nocera
c6ae8e58a4 elan: Fix typo 2020-04-14 13:50:49 +02:00
Bastien Nocera
87c7894c28 synaptics: Fix typos 2020-04-14 13:47:48 +02:00
Marco Trevisan (Treviño)
e7ff4f705c tests: Import FPrint only during execution not when parsing
The unittest_parser script would try to import FPrint gi module, but it
would fail as per the fact that none is installed yet, so make sure that
we don't load any FPrint module until we try to actually run the tests
2020-03-27 21:19:09 +00:00
Marco Trevisan (Treviño)
c26588942a ci: Print coverage data once available so that gitlab can parse it 2020-03-27 00:00:07 +01:00
Laurent Bigonville
3d68cddfe7 Properly set the dependencies in the pkg-config file
The public API uses gio and gobject header, ensure that these are in the
list of Required pkg-config modules, otherwise they are added to
Required.private which is not OK.
2020-03-20 11:13:06 +00:00
Benjamin Berg
96fba323b9 meson: Fix linking issue of libfprint with newer gcc
It appears the order of linking is relevant in this case, change it to
fix some linking issues.

It may be that there are better solutions to this problem.
2020-03-20 12:05:14 +01:00
Benjamin Berg
bd4f118b5e ci: Update CI after the fdo template changes
The CI definition needs to be updated to work with the new fdo
templates.
2020-03-20 12:05:14 +01:00
Benjamin Berg
9d4b5ad682 Revert "ci: Fix CI syntax error"
This reverts commit bd500b2235.

The fix from the commit was not correct.

See https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/124
2020-03-20 12:05:08 +01:00
Benjamin Berg
ca788b6de2 Revert "ci: Fix unknown keys in CI"
This reverts commit ebe5cb58ba.

The fix from the commit was not correct.

See https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/124
2020-03-20 12:04:58 +01:00
Bastien Nocera
90ccf9a0af vfs0050: Fix incorrect destructor for GError 2020-03-13 10:23:52 +01:00
Bastien Nocera
2581f1aa32 aes1610: Fix memory leak
Fix small memory leak when reading some data that's not going to be
processed.
2020-03-13 10:23:52 +01:00
Bastien Nocera
ebe5cb58ba ci: Fix unknown keys in CI
Fix:
root config contains unknown keys: container_fedora_build
2020-03-13 10:14:59 +01:00
Bastien Nocera
bd500b2235 ci: Fix CI syntax error
Fix CI syntax error:
container_fedora_build: unknown keys in `extends` (.fedora@container-build)
Caused by changes in the wayland CI templates:
4a73f030d0
2020-03-13 10:08:58 +01:00
Bastien Nocera
8fa50d667c ci: s/flatpack/flatpak/
“Flatpack” is for IKEA furniture.
2020-03-13 10:08:58 +01:00
Marco Trevisan (Treviño)
2ae8b74e60 meson: Add fpi-compat.h to the private headers 2020-02-27 06:03:21 +01:00
Benjamin Berg
f4ec816a6b tests: Cast to correct pointer type rather than gpointer
This is just a small cleanup
2020-02-19 16:42:30 +01:00
Benjamin Berg
9e2a7235e3 tests: Fix reading of gboolean into pointer
Otherwise the payload will be lost later on when using GPOINTER_TO_INT
to cast it back.

See: #236
2020-02-19 16:42:30 +01:00
86 changed files with 5154 additions and 452 deletions

View File

@@ -3,12 +3,13 @@ include:
- project: 'wayland/ci-templates'
ref: master
file: '/templates/fedora.yml'
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml'
variables:
extends: .libfprint_common_variables
FEDORA_TAG: rawhide
FEDORA_VERSION: rawhide
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:$FEDORA_TAG"
FDO_DISTRIBUTION_TAG: latest
FDO_DISTRIBUTION_VERSION: rawhide
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
@@ -16,7 +17,7 @@ stages:
- check-source
- build
- test
- flatpack
- flatpak
image: "$FEDORA_IMAGE"
@@ -48,6 +49,11 @@ build:
<<: *build_one_driver
<<: *build
# <<: *check_abi
artifacts:
expose_as: "HTML Documentation"
paths:
- _build/doc/html/
expire_in: 1 week
test:
stage: test
@@ -59,10 +65,12 @@ test:
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
- ninja -C _build coverage
- cat _build/meson-logs/coverage.txt
artifacts:
paths:
- _build/meson-logs
expire_in: 1 week
coverage: '/^TOTAL.*\s+(\d+\%)$/'
test_valgrind:
stage: test
@@ -74,72 +82,63 @@ test_valgrind:
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
test_scan_build:
stage: test
except:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
allow_failure: true
script:
- meson -Ddrivers=all . _build
# This is ugly, the wrapper disables the malloc checker
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build ninja -C _build scan-build
# Check that the directory is empty
- "! ls -A _build/meson-logs/scanbuild | grep -q ."
artifacts:
paths:
- _build/meson-logs
expire_in: 1 week
test_indent:
stage: check-source
except:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
script:
- scripts/uncrustify.sh --check
- scripts/uncrustify.sh
- git diff
- "! git status -s | grep -q ."
.flatpak_script_template: &flatpak_script
script:
- flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH}
# Make sure to keep this in sync with the Flatpak manifest, all arguments
# are passed except the config-args because we build it ourselves
- flatpak build app meson --prefix=/app --libdir=lib ${MESON_ARGS} _build
- flatpak build app ninja -C _build install
- flatpak build app rm -rf /app/include/ /app/lib/pkgconfig/
- flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH}
# Generate a Flatpak bundle
- flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${DBUS_ID}
.flatpak_artifacts_template: &flatpak_artifacts
artifacts:
paths:
- ${BUNDLE}
when: always
expire_in: 30 days
.flatpak_template: &flatpak
<<: *flatpak_script
<<: *flatpak_artifacts
.flatpak_master_template: &flatpak_master
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
stage: flatpack
variables:
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
# From demo/org.freedesktop.libfprint.Demo.json
MESON_ARGS: "-Dudev_rules=false -Dx11-examples=false -Dgtk-examples=true"
FLATPAK_MODULE: "libfprint"
DBUS_ID: "org.freedesktop.libfprint.Demo"
<<: *flatpak
flatpak-auto master:
<<: *flatpak_master
when: always
only:
- tags
- master
flatpak-manual master:
<<: *flatpak_master
when: manual
except:
refs:
- tags
- master
variables:
- $CI_PIPELINE_SOURCE == "schedule"
flatpak:
stage: flatpak
extends: .flatpak
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36
variables:
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
FLATPAK_MODULE: "libfprint"
APP_ID: "org.freedesktop.libfprint.Demo"
rules:
- if: '$CI_PROJECT_PATH != "libfprint/libfprint"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
when: always
- if: '$CI_COMMIT_TAG'
when: always
# For any other (commit), allow manual run.
# This excludes MRs which would create a duplicate pipeline
- if: '$CI_COMMIT_BRANCH'
when: manual
allow_failure: true
# CONTAINERS creation stage
container_fedora_build:
extends: .fedora@container-build
extends: .fdo.container-build@fedora
only:
variables:
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
# a list of packages to install
FEDORA_RPMS: $LIBFPRINT_DEPENDENCIES
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES

View File

@@ -24,3 +24,4 @@
umockdev
uncrustify
valgrind
clang-analyzer

4
.gitlab-ci/scan-build Executable file
View File

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

13
MAINTAINERS Normal file
View File

@@ -0,0 +1,13 @@
Current maintainers of libfprint are:
* Benjamin Berg <bberg@redhat.com>
* Marco Trevisan (Treviño) <mail@3v1n0.net>
Many drivers are not actively maintained and may not be fully functional.
We are happy to receive contributions, but the support we can give is
limitted unfortunately. For many drivers we may not even have test devices.
Maintained drivers are:
* synaptics:
Contributed and maintained by Synaptics Inc.
Contact: Vincent Huang <vincent.huang@tw.synaptics.com>

29
NEWS
View File

@@ -1,6 +1,35 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
2020-06-08: v1.90.3 release
This release mostly contains support for a number of new match-on-chip
devices. Most notable is the addition of the new goodixmoc driver.
Currently the driver has the small caveat that we have no strategy to
garbage collect old prints yet (a simple strategy could be implemented
in fprintd).
Highlights:
* New goodixmoc driver supporting Goodix USB devices:
27C6:5840
27C6:6496
27C6:60A2
* Newly added support for Synaptics device:
06CB:00E9
06CB:00DF
* Fixed an issue with Synaptics devices sometimes not working at boot
* Fix issue with aes3k driver (#306)
2020-06-08: v1.90.2 release
This release contains a large amount of bug and regression fixes. These
are not listed explicitly, but affect the majority of drivers.
Highlights:
* A patch for nbis required for some sensors was accidentally dropped in
an earlier release. Users of these sensors/drivers (aes1610, aes2501,
aes2550, aes1660, aes2660, elan, upektc_img) need to re-enroll (#142).
2019-11-20: v1.90.1 release
This release fixes a lot of the regressions introduced in 1.90.0. Please note

View File

@@ -241,6 +241,8 @@ dev_capture_start_cb (FpDevice *dev,
if (error->domain == FP_DEVICE_RETRY ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
libfprint_demo_set_mode (win, RETRY_MODE);
else if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
libfprint_demo_set_mode (win, NOIMAGING_MODE);
else
libfprint_demo_set_mode (win, ERROR_MODE);
return;

View File

@@ -1,7 +1,7 @@
{
"app-id": "org.freedesktop.libfprint.Demo",
"runtime": "org.gnome.Platform",
"runtime-version": "3.32",
"runtime-version": "3.36",
"sdk": "org.gnome.Sdk",
"command": "gtk-libfprint-test",
"finish-args": [

View File

@@ -175,7 +175,7 @@ fpi_image_resize
<SECTION>
<FILE>fpi-image-device</FILE>
<TITLE>FpImageDevice</TITLE>
<TITLE>Internal FpImageDevice</TITLE>
FpiImageDeviceState
FpImageDeviceClass
fpi_image_device_session_error
@@ -207,6 +207,8 @@ fpi_print_set_type
fpi_print_set_device_stored
fpi_print_add_from_image
fpi_print_bz3_match
fpi_print_generate_user_id
fpi_print_fill_from_user_id
</SECTION>
<SECTION>

View File

@@ -1,6 +1,6 @@
/*
* Example fingerprint enrollment program
* Enrolls your choosen finger and saves the print to disk
* Enrolls your chosen finger and saves the print to disk
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
*
@@ -23,20 +23,25 @@
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _EnrollData
{
GMainLoop *loop;
FpFinger finger;
int ret_value;
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
} EnrollData;
static void
enroll_data_free (EnrollData *enroll_data)
{
g_clear_handle_id (&enroll_data->sigint_handler, g_source_remove);
g_clear_object (&enroll_data->cancellable);
g_main_loop_unref (enroll_data->loop);
g_free (enroll_data);
}
@@ -52,7 +57,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s\n", error->message);
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (enroll_data->loop);
}
@@ -84,7 +89,7 @@ on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
}
else
{
g_warning ("Enroll failed with error %s\n", error->message);
g_warning ("Enroll failed with error %s", error->message);
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
@@ -107,7 +112,7 @@ on_enroll_progress (FpDevice *device,
return;
}
if (fp_device_supports_capture (device) &&
if (print && fp_print_get_image (print) &&
print_image_save (print, "enrolled.pgm"))
printf ("Wrote scanned image to enrolled.pgm\n");
@@ -137,11 +142,22 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
printf ("Scan your finger now.\n");
print_template = print_create_template (dev, enroll_data->finger);
fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
NULL, (GAsyncReadyCallback) on_enroll_completed,
fp_device_enroll (dev, print_template, enroll_data->cancellable,
on_enroll_progress, NULL, NULL,
(GAsyncReadyCallback) on_enroll_completed,
enroll_data);
}
static gboolean
sigint_cb (void *user_data)
{
EnrollData *enroll_data = user_data;
g_cancellable_cancel (enroll_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
@@ -188,8 +204,15 @@ main (void)
enroll_data->finger = finger;
enroll_data->ret_value = EXIT_FAILURE;
enroll_data->loop = g_main_loop_new (NULL, FALSE);
enroll_data->cancellable = g_cancellable_new ();
enroll_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
enroll_data,
NULL);
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
fp_device_open (dev, enroll_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
enroll_data);
g_main_loop_run (enroll_data->loop);

192
examples/img-capture.c Normal file
View File

@@ -0,0 +1,192 @@
/*
* Example fingerprint verification program, which verifies the
* finger which has been previously enrolled to disk.
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
* Copyright (C) 2020 Vasily Khoruzhick <anarsoul@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-capture"
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct CaptureData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
int ret_value;
const char *filename;
} CaptureData;
static void
capture_data_free (CaptureData *capture_data)
{
g_clear_handle_id (&capture_data->sigint_handler, g_source_remove);
g_clear_object (&capture_data->cancellable);
g_main_loop_unref (capture_data->loop);
g_free (capture_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (CaptureData, capture_data_free)
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
CaptureData *capture_data = user_data;
g_autoptr(GError) error = NULL;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (capture_data->loop);
}
static void
capture_quit (FpDevice *dev,
CaptureData *capture_data)
{
if (!fp_device_is_open (dev))
{
g_main_loop_quit (capture_data->loop);
return;
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, capture_data);
}
static void
dev_capture_cb (FpDevice *dev,
GAsyncResult *res,
void *user_data)
{
g_autoptr(GError) error = NULL;
CaptureData *capture_data = user_data;
FpImage *image = NULL;
g_clear_object (&capture_data->cancellable);
image = fp_device_capture_finish (dev, res, &error);
if (!image)
{
g_warning ("Error capturing data: %s", error->message);
capture_quit (dev, capture_data);
return;
}
save_image_to_pgm (image, capture_data->filename);
capture_quit (dev, capture_data);
}
static void
start_capture (FpDevice *dev, CaptureData *capture_data)
{
fp_device_capture (dev, TRUE, capture_data->cancellable, (GAsyncReadyCallback) dev_capture_cb, capture_data);
}
static void
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
CaptureData *capture_data = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
capture_quit (dev, capture_data);
return;
}
g_print ("Opened device. ");
start_capture (dev, capture_data);
}
static gboolean
sigint_cb (void *user_data)
{
CaptureData *capture_data = user_data;
g_cancellable_cancel (capture_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (int argc, const char *argv[])
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(CaptureData) capture_data = NULL;
GPtrArray *devices;
FpDevice *dev;
setenv ("G_MESSAGES_DEBUG", "all", 0);
setenv ("LIBUSB_DEBUG", "3", 0);
ctx = fp_context_new ();
devices = fp_context_get_devices (ctx);
if (!devices)
{
g_warning ("Impossible to get devices");
return EXIT_FAILURE;
}
dev = discover_device (devices);
if (!dev)
{
g_warning ("No devices detected.");
return EXIT_FAILURE;
}
if (!fp_device_supports_capture (dev))
{
g_warning ("Device %s doesn't support capture",
fp_device_get_name (dev));
return EXIT_FAILURE;
}
capture_data = g_new0 (CaptureData, 1);
capture_data->ret_value = EXIT_FAILURE;
capture_data->loop = g_main_loop_new (NULL, FALSE);
capture_data->cancellable = g_cancellable_new ();
capture_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
capture_data,
NULL);
if (argc == 2)
capture_data->filename = argv[1];
else
capture_data->filename = "finger.pgm";
fp_device_open (dev, capture_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
capture_data);
g_main_loop_run (capture_data->loop);
return capture_data->ret_value;
}

View File

@@ -54,7 +54,7 @@ on_device_closed (FpDevice *dev,
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s\n", error->message);
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (list_data->loop);
}
@@ -86,7 +86,7 @@ delete_next_print (FpDevice *dev,
g_assert_nonnull (list_data->to_delete);
print = list_data->to_delete->data;
g_debug ("Deleting print %s\n", fp_print_get_description (print));
g_debug ("Deleting print %s", fp_print_get_description (print));
fp_device_delete_print (dev, print, NULL,
(GAsyncReadyCallback) on_print_deleted, list_data);
}

View File

@@ -1,5 +1,5 @@
examples = [ 'enroll', 'verify', 'manage-prints' ]
examples = [ 'enroll', 'verify', 'manage-prints', 'img-capture' ]
foreach example: examples
executable(example,
[ example + '.c', 'storage.c', 'utilities.c' ],

View File

@@ -180,7 +180,7 @@ print_create_template (FpDevice *dev, FpFinger finger)
}
static gboolean
gboolean
save_image_to_pgm (FpImage *img, const char *path)
{
FILE *fd = fopen (path, "w");

View File

@@ -28,3 +28,5 @@ FpPrint * print_create_template (FpDevice *dev,
FpFinger finger);
gboolean print_image_save (FpPrint *print,
const char *path);
gboolean save_image_to_pgm (FpImage *img,
const char *path);

View File

@@ -23,20 +23,25 @@
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _VerifyData
{
GMainLoop *loop;
FpFinger finger;
int ret_value;
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
} VerifyData;
static void
verify_data_free (VerifyData *verify_data)
{
g_clear_handle_id (&verify_data->sigint_handler, g_source_remove);
g_clear_object (&verify_data->cancellable);
g_main_loop_unref (verify_data->loop);
g_free (verify_data);
}
@@ -52,7 +57,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s\n", error->message);
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (verify_data->loop);
}
@@ -119,7 +124,7 @@ on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
return;
}
if (print && fp_device_supports_capture (dev) &&
if (print && fp_print_get_image (print) &&
print_image_save (print, "verify.pgm"))
g_print ("Print image saved as verify.pgm\n");
@@ -196,7 +201,7 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
fp_print_get_description (verify_print));
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, NULL,
fp_device_verify (dev, verify_print, verify_data->cancellable,
on_match_cb, verify_data, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
@@ -250,8 +255,8 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
}
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, NULL,
NULL, NULL, NULL,
fp_device_verify (dev, verify_print, verify_data->cancellable,
on_match_cb, verify_data, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
}
@@ -276,6 +281,16 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
start_verification (dev, verify_data);
}
static gboolean
sigint_cb (void *user_data)
{
VerifyData *verify_data = user_data;
g_cancellable_cancel (verify_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
@@ -306,8 +321,14 @@ main (void)
verify_data = g_new0 (VerifyData, 1);
verify_data->ret_value = EXIT_FAILURE;
verify_data->loop = g_main_loop_new (NULL, FALSE);
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
verify_data->cancellable = g_cancellable_new ();
verify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
verify_data,
NULL);
fp_device_open (dev, verify_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
verify_data);
g_main_loop_run (verify_data->loop);

View File

@@ -138,7 +138,7 @@ generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
unsigned char *data;
data = g_malloc (bytes);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, NULL);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, g_free);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
@@ -614,6 +614,7 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *device,
self->strips = g_slist_reverse (self->strips);
fpi_do_movement_estimation (&assembling_ctx, self->strips);
img = fpi_assemble_frames (&assembling_ctx, self->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_free_full (self->strips, g_free);
self->strips = NULL;

View File

@@ -458,6 +458,7 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
fpi_do_movement_estimation (&assembling_ctx, self->strips);
img = fpi_assemble_frames (&assembling_ctx,
self->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;

View File

@@ -197,12 +197,12 @@ process_strip_data (FpiSsm *ssm, FpImageDevice *dev,
if (data[0] != AES2550_EDATA_MAGIC)
{
fp_dbg ("Bogus magic: %.2x\n", (int) (data[0]));
fp_dbg ("Bogus magic: %.2x", (int) (data[0]));
return FALSE;
}
len = data[1] * 256 + data[2];
if (len != (AES2550_STRIP_SIZE - 3))
fp_dbg ("Bogus frame len: %.4x\n", len);
fp_dbg ("Bogus frame len: %.4x", len);
stripe = g_malloc0 (FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bits per pixel */
stripe->delta_x = (int8_t) data[6];
stripe->delta_y = -(int8_t) data[7];
@@ -230,6 +230,7 @@ capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
self->strips = g_slist_reverse (self->strips);
img = fpi_assemble_frames (&assembling_ctx, self->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;

View File

@@ -42,8 +42,7 @@
typedef struct
{
FpiUsbTransfer *img_trf;
gboolean deactivating;
GCancellable *img_trf_cancel;
} FpiDeviceAes3kPrivate;
#define CTRL_TIMEOUT 1000
@@ -84,22 +83,22 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
FpImage *img;
int i;
priv->img_trf = NULL;
if (error)
{
if (g_error_matches (error,
G_IO_ERROR,
G_IO_ERROR_CANCELLED))
{
/* Deactivation was completed. */
/* Cancellation implies we are deactivating. */
g_error_free (error);
if (priv->deactivating)
fpi_image_device_deactivate_complete (dev, NULL);
g_clear_object (&priv->img_trf_cancel);
fpi_image_device_deactivate_complete (dev, NULL);
return;
}
fpi_image_device_session_error (dev, error);
g_clear_object (&priv->img_trf_cancel);
return;
}
fpi_image_device_report_finger_status (dev, TRUE);
@@ -126,30 +125,37 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
* it really has, then restart the capture */
fpi_image_device_report_finger_status (dev, FALSE);
/* Note: We always restart the transfer, it may already be cancelled though. */
do_capture (dev);
}
static void
do_capture (FpImageDevice *dev)
{
g_autoptr(FpiUsbTransfer) img_trf = NULL;
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (priv->img_trf, EP_IN, cls->data_buflen);
priv->img_trf->short_is_error = TRUE;
fpi_usb_transfer_submit (priv->img_trf, 0,
fpi_device_get_cancellable (FP_DEVICE (dev)),
img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (img_trf, EP_IN, cls->data_buflen);
img_trf->short_is_error = TRUE;
fpi_usb_transfer_submit (g_steal_pointer (&img_trf), 0,
priv->img_trf_cancel,
img_cb, NULL);
}
static void
init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
{
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (FPI_DEVICE_AES3K (dev));
fpi_image_device_activate_complete (dev, result);
if (!result)
do_capture (dev);
{
priv->img_trf_cancel = g_cancellable_new ();
do_capture (dev);
}
}
static void
@@ -159,7 +165,7 @@ aes3k_dev_activate (FpImageDevice *dev)
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
priv->deactivating = FALSE;
g_assert (!priv->img_trf_cancel);
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
}
@@ -169,10 +175,11 @@ aes3k_dev_deactivate (FpImageDevice *dev)
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
priv->deactivating = TRUE;
if (priv->img_trf)
return;
fpi_image_device_deactivate_complete (dev, NULL);
/* Deactivation finishes from the cancellation handler */
if (priv->img_trf_cancel)
g_cancellable_cancel (priv->img_trf_cancel);
else
fpi_image_device_deactivate_complete (dev, NULL);
}
static void

View File

@@ -116,7 +116,7 @@ aesX660_read_calibrate_data_cb (FpiUsbTransfer *transfer,
/* Calibrate response was read correctly? */
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE)
{
fp_dbg ("Bogus calibrate response: %.2x\n", data[0]);
fp_dbg ("Bogus calibrate response: %.2x", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus calibrate "
@@ -155,14 +155,14 @@ finger_det_read_fd_data_cb (FpiUsbTransfer *transfer,
if (error)
{
fp_dbg ("Failed to read FD data\n");
fp_dbg ("Failed to read FD data");
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE)
{
fp_dbg ("Bogus FD response: %.2x\n", data[0]);
fp_dbg ("Bogus FD response: %.2x", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus FD response %.2x",
@@ -177,7 +177,7 @@ finger_det_read_fd_data_cb (FpiUsbTransfer *transfer,
}
else
{
fp_dbg ("Wait for finger returned %.2x as result\n",
fp_dbg ("Wait for finger returned %.2x as result",
data[AESX660_FINGER_PRESENT_OFFSET]);
fpi_ssm_jump_to_state (transfer->ssm, FINGER_DET_SEND_FD_CMD);
}
@@ -331,6 +331,7 @@ capture_set_idle_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
priv->strips = g_slist_reverse (priv->strips);
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
g_slist_free (priv->strips);
priv->strips = NULL;
@@ -404,7 +405,7 @@ capture_read_stripe_data_cb (FpiUsbTransfer *transfer,
g_byte_array_set_size (priv->stripe_packet, 0);
}
fp_dbg ("finger %s\n", finger_missing ? "missing" : "present");
fp_dbg ("finger %s", finger_missing ? "missing" : "present");
if (finger_missing)
fpi_ssm_next_state (transfer->ssm);
@@ -439,7 +440,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
break;
case CAPTURE_SET_IDLE:
fp_dbg ("Got %lu frames\n", priv->strips_len);
fp_dbg ("Got %lu frames", priv->strips_len);
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
capture_set_idle_cmd_cb);
break;
@@ -512,19 +513,19 @@ activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
if (error)
{
fp_dbg ("read_id cmd failed\n");
fp_dbg ("read_id cmd failed");
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* ID was read correctly */
if (data[0] == 0x07)
{
fp_dbg ("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n",
fp_dbg ("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x",
data[4], data[3], data[5], data[6], data[7]);
}
else
{
fp_dbg ("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
fp_dbg ("Bogus read ID response: %.2x", data[AESX660_RESPONSE_TYPE_OFFSET]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read ID response %.2x",
@@ -552,7 +553,7 @@ activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
break;
default:
fp_dbg ("Failed to init device! init status: %.2x\n", data[7]);
fp_dbg ("Failed to init device! init status: %.2x", data[7]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Failed to init device %.2x",
@@ -569,11 +570,11 @@ activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
unsigned char *data = transfer->buffer;
fp_dbg ("read_init_cb\n");
fp_dbg ("read_init_cb");
if (error)
{
fp_dbg ("read_init transfer status: %s, actual_len: %d\n", error->message,
fp_dbg ("read_init transfer status: %s, actual_len: %d", error->message,
(gint) transfer->actual_length);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
@@ -581,7 +582,7 @@ activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
/* ID was read correctly */
if (data[0] != 0x42 || data[3] != 0x01)
{
fp_dbg ("Bogus read init response: %.2x %.2x\n", data[0],
fp_dbg ("Bogus read init response: %.2x %.2x", data[0],
data[3]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
@@ -613,13 +614,13 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
{
case ACTIVATE_SET_IDLE:
priv->init_seq_idx = 0;
fp_dbg ("Activate: set idle\n");
fp_dbg ("Activate: set idle");
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_SEND_READ_ID_CMD:
fp_dbg ("Activate: read ID\n");
fp_dbg ("Activate: read ID");
aesX660_send_cmd (ssm, _dev, read_id_cmd, sizeof (read_id_cmd),
fpi_ssm_usb_transfer_cb);
break;
@@ -629,7 +630,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
break;
case ACTIVATE_SEND_INIT_CMD:
fp_dbg ("Activate: send init seq #%d cmd #%d\n",
fp_dbg ("Activate: send init seq #%d cmd #%d",
priv->init_seq_idx,
priv->init_cmd_idx);
aesX660_send_cmd (ssm, _dev,
@@ -639,7 +640,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
break;
case ACTIVATE_READ_INIT_RESPONSE:
fp_dbg ("Activate: read init response\n");
fp_dbg ("Activate: read init response");
aesX660_read_response (ssm, _dev, TRUE, FALSE, INIT_LEN, activate_read_init_cb);
break;

View File

@@ -207,6 +207,7 @@ elan_save_img_frame (FpiDeviceElan *elandev)
unsigned int frame_size = elandev->frame_width * elandev->frame_height;
unsigned short *frame = g_malloc (frame_size * sizeof (short));
elan_save_frame (elandev, frame);
unsigned int sum = 0;
@@ -244,6 +245,7 @@ elan_process_frame_linear (unsigned short *raw_frame,
G_DEBUG_HERE ();
unsigned short min = 0xffff, max = 0;
for (int i = 0; i < frame_size; i++)
{
if (raw_frame[i] < min)
@@ -255,6 +257,7 @@ elan_process_frame_linear (unsigned short *raw_frame,
g_assert (max != min);
unsigned short px;
for (int i = 0; i < frame_size; i++)
{
px = raw_frame[i];
@@ -278,6 +281,7 @@ elan_process_frame_thirds (unsigned short *raw_frame,
unsigned short lvl0, lvl1, lvl2, lvl3;
unsigned short *sorted = g_malloc (frame_size * sizeof (short));
memcpy (sorted, raw_frame, frame_size * sizeof (short));
qsort (sorted, frame_size, sizeof (short), cmp_short);
lvl0 = sorted[0];
@@ -287,6 +291,7 @@ elan_process_frame_thirds (unsigned short *raw_frame,
g_free (sorted);
unsigned short px;
for (int i = 0; i < frame_size; i++)
{
px = raw_frame[i];
@@ -320,6 +325,7 @@ elan_submit_image (FpImageDevice *dev)
g_slist_foreach (raw_frames, (GFunc) self->process_frame, &frames);
fpi_do_movement_estimation (&assembling_ctx, frames);
img = fpi_assemble_frames (&assembling_ctx, frames);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_free_full (frames, g_free);
@@ -509,6 +515,7 @@ elan_stop_capture (FpDevice *dev)
FpiSsm *ssm =
fpi_ssm_new (dev, stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
fpi_ssm_start (ssm, stop_capture_complete);
}
@@ -619,6 +626,7 @@ elan_capture (FpDevice *dev)
elan_dev_reset_state (self);
FpiSsm *ssm =
fpi_ssm_new (dev, capture_run_state, CAPTURE_NUM_STATES);
fpi_ssm_start (ssm, capture_complete);
}
@@ -733,7 +741,7 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
fp_dbg ("calibration failed");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Callibration failed!"));
"Calibration failed!"));
}
break;
@@ -797,6 +805,7 @@ elan_calibrate (FpDevice *dev)
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
CALIBRATE_NUM_STATES);
fpi_ssm_start (ssm, calibrate_complete);
}
@@ -892,6 +901,7 @@ elan_activate (FpImageDevice *dev)
FpiSsm *ssm =
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES);
fpi_ssm_start (ssm, activate_complete);
}
@@ -988,7 +998,7 @@ static void
elan_change_state_async (FpDevice *dev,
void *data)
{
g_message ("state change dev: %p", dev);
fp_dbg ("state change dev: %p", dev);
elan_change_state (FP_IMAGE_DEVICE (dev));
}
@@ -1005,7 +1015,10 @@ dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
if (self->dev_state_next == state)
fp_dbg ("change to state %d already queued", state);
{
fp_dbg ("change to state %d already queued", state);
return;
}
switch (state)
{

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/*
* Goodix Moc driver for libfprint
* Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "fpi-device.h"
#include "fpi-ssm.h"
G_DECLARE_FINAL_TYPE (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FPI, DEVICE_GOODIXMOC, FpDevice)
typedef enum {
FP_CMD_SEND = 0,
FP_CMD_GET_ACK,
FP_CMD_GET_DATA,
FP_CMD_NUM_STATES,
} FpCmdState;
typedef enum {
FP_INIT_VERSION = 0,
FP_INIT_CONFIG,
FP_INIT_NUM_STATES,
} FpInitState;
typedef enum {
FP_ENROLL_ENUM = 0,
FP_ENROLL_IDENTIFY,
FP_ENROLL_CREATE,
FP_ENROLL_CAPTURE,
FP_ENROLL_UPDATE,
FP_ENROLL_WAIT_FINGER_UP,
FP_ENROLL_CHECK_DUPLICATE,
FP_ENROLL_COMMIT,
FP_ENROLL_NUM_STATES,
} FpEnrollState;
typedef enum {
FP_VERIFY_CAPTURE = 0,
FP_VERIFY_IDENTIFY,
FP_VERIFY_NUM_STATES,
} FpVerifyState;

View File

@@ -0,0 +1,422 @@
/*
* Goodix Moc driver for libfprint
* Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <glib.h>
#include "goodix_proto.h"
/*
* Crc functions
*/
#define WIDTH (8 * sizeof (uint32_t))
#define FINAL_XOR_VALUE 0xFFFFFFFF
#define REFLECT_DATA(X) ((uint8_t) reflect ((X), 8))
#define REFLECT_REMAINDER(X) ((unsigned int) reflect ((X), WIDTH))
uint8_t
gx_proto_crc8_calc (uint8_t *lubp_date, uint32_t lui_len)
{
const uint8_t *data = lubp_date;
unsigned int crc = 0;
int i, j;
for (j = lui_len; j; j--, data++)
{
crc ^= (*data << 8);
for (i = 8; i; i--)
{
if (crc & 0x8000)
crc ^= (0x1070 << 3);
crc <<= 1;
}
}
crc >>= 8;
crc = ~crc;
return (uint8_t) crc;
}
typedef struct
{
uint32_t crc;
} gf_crc32_context;
static uint32_t s_crc_table[256] =
{ 0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
static uint32_t
reflect (uint32_t data, uint8_t n_bits)
{
unsigned long reflection = 0x00000000;
uint8_t bit;
/*
* Reflect the data about the center bit.
*/
for (bit = 0; bit < n_bits; ++bit)
{
/*
* If the LSB bit is set, set the reflection of it.
*/
if (data & 0x01)
reflection |= (1 << ((n_bits - 1) - bit));
data = (data >> 1);
}
return reflection;
}
static void
crc32_init (gf_crc32_context *ctx)
{
ctx->crc = 0xFFFFFFFF;
}
static void
crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
{
uint8_t data;
uint32_t byte;
/*
* Divide the message by the polynomial, a byte at a time.
*/
for (byte = 0; byte < n_bytes; ++byte)
{
data = REFLECT_DATA (message[byte]) ^ (ctx->crc >> (WIDTH - 8));
ctx->crc = s_crc_table[data] ^ (ctx->crc << 8);
}
}
static void
crc32_final (gf_crc32_context *ctx, uint8_t *md)
{
ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
memcpy (md, &ctx->crc, 4);
}
uint8_t
gx_proto_crc32_calc (uint8_t *pchMsg, uint32_t wDataLen, uint8_t *pchMsgDst)
{
gf_crc32_context context = { 0 };
if (!pchMsg)
return 0;
crc32_init (&context);
crc32_update (&context, pchMsg, wDataLen);
crc32_final (&context, pchMsgDst);
return 1;
}
/*
* protocol
*
*/
static uint8_t dump_seq = 0;
static void
init_pack_header (
ppack_header pheader,
uint16_t len,
uint16_t cmd,
uint8_t packagenum
)
{
g_assert (pheader);
memset (pheader, 0, sizeof (*pheader));
pheader->cmd0 = HIBYTE (cmd);
pheader->cmd1 = LOBYTE (cmd);
pheader->packagenum = packagenum;
pheader->reserved = dump_seq++;
pheader->len = len + PACKAGE_CRC_SIZE;
pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
pheader->rev_crc8 = ~pheader->crc8;
}
int
gx_proto_build_package (uint8_t *ppackage,
uint32_t *package_len,
uint16_t cmd,
const uint8_t *payload,
uint32_t payload_size)
{
pack_header header;
if (!ppackage || !package_len)
return -1;
if(*package_len < (payload_size + PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE))
return -1;
init_pack_header (&header, payload_size, cmd, 0);
memcpy (ppackage, &header, PACKAGE_HEADER_SIZE);
memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size);
return 0;
}
int
gx_proto_parse_header (
uint8_t *buffer,
uint32_t buffer_len,
pack_header *pheader)
{
if (!buffer || !pheader)
return -1;
if (buffer_len < PACKAGE_HEADER_SIZE)
return -1;
memcpy (pheader, buffer, sizeof (pack_header));
pheader->len = GUINT16_FROM_LE (*(buffer + 4));
pheader->len -= PACKAGE_CRC_SIZE;
return 0;
}
static int
gx_proto_parse_fingerid (
uint8_t * fid_buffer,
uint16_t fid_buffer_size,
ptemplate_format_t template
)
{
uint8_t * buffer = NULL;
uint16_t Offset = 0;
if (!template || !fid_buffer)
return -1;
if (fid_buffer_size < 70)
return -1;
buffer = fid_buffer;
Offset = 0;
if (buffer[Offset++] != 67)
return -1;
template->type = buffer[Offset++];
template->finger_index = buffer[Offset++];
Offset++;
memcpy (template->accountid, &buffer[Offset], 32);
Offset += 32;
memcpy (template->tid, &buffer[Offset], 32);
Offset += 32; // Offset == 68
template->payload.size = buffer[Offset++];
memset (template->payload.data, 0, 56);
memcpy (template->payload.data, &buffer[Offset], template->payload.size);
return 0;
}
int
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_cmd_response_t presp)
{
uint32_t offset = 0;
uint8_t *fingerlist = NULL;
if (!buffer || !presp)
return -1;
if (buffer_len < 1)
return -1;
presp->result = buffer[0];
switch (HIBYTE (cmd))
{
case RESPONSE_PACKAGE_CMD:
{
presp->parse_msg.ack_cmd = buffer[1];
}
break;
case MOC_CMD0_UPDATE_CONFIG:
case MOC_CMD0_COMMITENROLLMENT:
case MOC_CMD0_DELETETEMPLATE:
break;
case MOC_CMD0_GET_VERSION:
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
break;
case MOC_CMD0_CAPTURE_DATA:
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
{
presp->capture_data_resp.img_quality = buffer[1];
presp->capture_data_resp.img_coverage = buffer[2];
}
break;
case MOC_CMD0_ENROLL_INIT:
if (presp->result == GX_SUCCESS)
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
break;
case MOC_CMD0_ENROLL:
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
presp->enroll_update.img_overlay = buffer[1];
presp->enroll_update.img_preoverlay = buffer[2];
break;
case MOC_CMD0_CHECK4DUPLICATE:
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
if (presp->check_duplicate_resp.duplicate)
{
uint16_t tid_size = GUINT16_FROM_LE (*(buffer + 1));
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
}
break;
case MOC_CMD0_GETFINGERLIST:
if (presp->result != GX_SUCCESS)
break;
presp->finger_list_resp.finger_num = buffer[1];
if (presp->finger_list_resp.finger_num > FP_MAX_FINGERNUM)
{
presp->finger_list_resp.finger_num = 0;
presp->result = GX_ERROR_NO_AVAILABLE_SPACE;
break;
}
fingerlist = buffer + 2;
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
{
uint16_t fingerid_length = GUINT16_FROM_LE (*(fingerlist + offset));
offset += 2;
if (gx_proto_parse_fingerid (fingerlist + offset,
fingerid_length,
&presp->finger_list_resp.finger_list[num]) != 0)
{
g_error ("parse fingerlist error");
presp->finger_list_resp.finger_num = 0;
presp->result = GX_FAILED;
break;
}
offset += fingerid_length;
}
break;
case MOC_CMD0_IDENTIFY:
{
uint32_t score = 0;
uint8_t study = 0;
uint16_t fingerid_size = 0;
presp->verify.match = (buffer[0] == 0) ? true : false;
if (presp->verify.match)
{
offset += 1;
presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset));
offset += 2;
score = GUINT32_FROM_LE (*(buffer + offset));
offset += 4;
study = GUINT16_FROM_LE (*(buffer + offset));
offset += 1;
fingerid_size = GUINT16_FROM_LE (*(buffer + offset));
offset += 2;
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
{
presp->result = GX_FAILED;
break;
}
g_debug ("match, score: %d, study: %d", score, study);
}
}
break;
case MOC_CMD0_FINGER_MODE:
presp->finger_status.status = buffer[0];
break;
default:
break;
}
return 0;
}
static uint8_t sensor_config[26] = {
0x00, 0x00, 0x64, 0x50, 0x0f, 0x41, 0x08, 0x0a, 0x18, 0x00, 0x00, 0x23, 0x00,
0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x05, 0x05
};
int
gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig)
{
uint32_t crc32_calc = 0;
if (!pconfig)
return -1;
memset (pconfig, 0, sizeof (*pconfig));
//NOTICE: Do not change any value!
memcpy (&pconfig->config, sensor_config, 26);
pconfig->reserved[0] = 1;
gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);
memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE);
return 0;
}

View File

@@ -0,0 +1,232 @@
/*
* Goodix Moc driver for libfprint
* Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define PACKAGE_CRC_SIZE (4)
#define PACKAGE_HEADER_SIZE (8)
#define FP_MAX_FINGERNUM (10)
#define TEMPLATE_ID_SIZE (32)
#define GX_VERSION_LEN (8)
/* Type covert */
#define MAKE_CMD_EX(cmd0, cmd1) ((uint16_t) (((cmd0) << 8) | (cmd1)))
#define LOBYTE(value) ((uint8_t) (value))
#define HIBYTE(value) ((uint8_t) (((uint16_t) (value) >> 8) & 0xFF))
/* Error code */
#define GX_SUCCESS 0x00
#define GX_FAILED 0x80
#define GX_ERROR_FINGER_ID_NOEXIST 0x9C
#define GX_ERROR_TEMPLATE_INCOMPLETE 0xB8
#define GX_ERROR_WAIT_FINGER_UP_TIMEOUT 0xC7
#define GX_ERROR_NO_AVAILABLE_SPACE 0x8F
/* Command Type Define */
#define RESPONSE_PACKAGE_CMD 0xAA
#define MOC_CMD0_ENROLL 0xA0
#define MOC_CMD0_ENROLL_INIT 0xA1
#define MOC_CMD0_CAPTURE_DATA 0xA2
#define MOC_CMD0_CHECK4DUPLICATE 0xA3
#define MOC_CMD0_COMMITENROLLMENT 0xA4
#define MOC_CMD0_IDENTIFY 0xA5
#define MOC_CMD0_GETFINGERLIST 0xA6
#define MOC_CMD0_DELETETEMPLATE 0xA7
#define MOC_CMD1_DEFAULT 0x00
#define MOC_CMD1_UNTIL_DOWN 0x00
#define MOC_CMD1_WHEN_DOWN 0x01
#define MOC_CMD1_DELETE_TEMPLATE 0x04
#define MOC_CMD1_DELETE_ALL 0x01
#define MOC_CMD0_GET_VERSION 0xD0
#define MOC_CMD0_UPDATE_CONFIG 0xC0
#define MOC_CMD1_NWRITE_CFG_TO_FLASH 0x00
#define MOC_CMD1_WRITE_CFG_TO_FLASH 0x01
#define MOC_CMD0_FINGER_MODE 0xB0
#define MOC_CMD1_GET_FINGER_MODE 0x00
#define MOC_CMD1_SET_FINGER_DOWN 0x01
#define MOC_CMD1_SET_FINGER_UP 0x02
/* */
typedef struct _gxfp_version_info
{
uint8_t format[2];
uint8_t fwtype[GX_VERSION_LEN];
uint8_t fwversion[GX_VERSION_LEN];
uint8_t customer[GX_VERSION_LEN];
uint8_t mcu[GX_VERSION_LEN];
uint8_t sensor[GX_VERSION_LEN];
uint8_t algversion[GX_VERSION_LEN];
uint8_t interface[GX_VERSION_LEN];
uint8_t protocol[GX_VERSION_LEN];
uint8_t flashVersion[GX_VERSION_LEN];
uint8_t reserved[62];
} gxfp_version_info_t, *pgxfp_version_info_t;
typedef struct _gxfp_parse_msg
{
uint8_t ack_cmd;
bool has_no_config;
} gxfp_parse_msg_t, *pgxfp_parse_msg_t;
typedef struct _gxfp_enroll_init
{
uint8_t tid[TEMPLATE_ID_SIZE];
} gxfp_enroll_init_t, *pgxfp_enroll_init_t;
#pragma pack(push, 1)
typedef struct _template_format
{
uint8_t type;
uint8_t finger_index;
uint8_t accountid[32];
uint8_t tid[32];
struct
{
uint32_t size;
uint8_t data[56];
} payload;
uint8_t reserve[2];
} template_format_t, *ptemplate_format_t;
#pragma pack(pop)
typedef struct _gxfp_verify
{
bool match;
uint32_t rejectdetail;
template_format_t template;
} gxfp_verify_t, *pgxfp_verify_t;
typedef struct _gxfp_capturedata
{
uint8_t img_quality;
uint8_t img_coverage;
} gxfp_capturedata_t, *pgxfp_capturedata_t;
typedef struct _gxfp_check_duplicate
{
bool duplicate;
template_format_t template;
} gxfp_check_duplicate_t, *pgxfp_check_duplicate_t;
typedef struct _gxfp_enroll_update
{
bool rollback;
uint8_t img_overlay;
uint8_t img_preoverlay;
} gxfp_enroll_update_t, *Pgxfp_enroll_update_t;
typedef struct _gxfp_enum_fingerlist
{
uint8_t finger_num;
template_format_t finger_list[FP_MAX_FINGERNUM];
} gxfp_enum_fingerlist_t, *pgxfp_enum_fingerlist_t;
typedef struct _gxfp_enroll_commit
{
uint8_t result;
} gxfp_enroll_commit_t, *pgxfp_enroll_commit_t;
typedef struct _fp_finger_status
{
uint8_t status;
} fp_finger_status_t, *pfp_finger_status_t;
typedef struct _fp_cmd_response
{
uint8_t result;
union
{
gxfp_parse_msg_t parse_msg;
gxfp_verify_t verify;
gxfp_enroll_init_t enroll_init;
gxfp_capturedata_t capture_data_resp;
gxfp_check_duplicate_t check_duplicate_resp;
gxfp_enroll_commit_t enroll_commit;
gxfp_enroll_update_t enroll_update;
gxfp_enum_fingerlist_t finger_list_resp;
gxfp_version_info_t version_info;
fp_finger_status_t finger_status;
};
} gxfp_cmd_response_t, *pgxfp_cmd_response_t;
typedef struct _pack_header
{
uint8_t cmd0;
uint8_t cmd1;
uint8_t packagenum;
uint8_t reserved;
uint16_t len;
uint8_t crc8;
uint8_t rev_crc8;
} pack_header, *ppack_header;
typedef struct _gxfp_sensor_cfg
{
uint8_t config[26];
uint8_t reserved[98];
uint8_t crc_value[4];
} gxfp_sensor_cfg_t, *pgxfp_sensor_cfg_t;
/* */
int gx_proto_build_package (uint8_t *ppackage,
uint32_t *package_len,
uint16_t cmd,
const uint8_t *payload,
uint32_t payload_size);
int gx_proto_parse_header (uint8_t *buffer,
uint32_t buffer_len,
pack_header *pheader);
int gx_proto_parse_body (uint16_t cmd,
uint8_t *buffer,
uint32_t buffer_len,
pgxfp_cmd_response_t presponse);
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
uint8_t gx_proto_crc8_calc (uint8_t *lubp_date,
uint32_t lui_len);
uint8_t gx_proto_crc32_calc (uint8_t *pchMsg,
uint32_t wDataLen,
uint8_t *pchMsgDst);

View File

@@ -206,6 +206,7 @@ parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *res
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
int n = 0;
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
{
if (offset >= msg_resp->payload_len)

View File

@@ -316,7 +316,7 @@ typedef struct bmkt_init_resp
*/
typedef struct bmkt_enroll_resp
{
int progress; /**< Shows current progress stutus [0-100] */
int progress; /**< Shows current progress status [0-100] */
uint8_t finger_id; /**< User's finger id [1-10] */
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
} bmkt_enroll_resp_t;

View File

@@ -29,13 +29,14 @@ G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xE9, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xDF, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
};
static void
cmd_recieve_cb (FpiUsbTransfer *transfer,
cmd_receive_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer user_data,
GError *error)
@@ -234,7 +235,7 @@ synaptics_cmd_run_state (FpiSsm *ssm,
fpi_usb_transfer_submit (transfer,
5000,
NULL,
cmd_recieve_cb,
cmd_receive_cb,
fpi_ssm_get_data (ssm));
break;
@@ -321,7 +322,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
g_assert (payload || payload_len == 0);
/* seq_num of 0 means a normal command, -1 means the current commands
* sequence number should not be udpated (i.e. second async command which
* sequence number should not be updated (i.e. second async command which
* may only be a cancellation currently). */
if (seq_num <= 0)
{
@@ -515,39 +516,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
{
g_autofree gchar *copy = g_strdup (userid);
g_autoptr(GDate) date = NULL;
gint32 date_ymd;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
}
fpi_print_fill_from_user_id (print, userid);
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
}
@@ -635,7 +604,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
else if (resp->result == BMKT_FP_NO_MATCH)
{
fp_info ("Print didn't match");
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL);
verify_complete_after_finger_removal (self);
}
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
@@ -730,7 +699,7 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
if (enroll_resp->progress < 100)
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
/* Emit a retry error if there has been no discernable
/* Emit a retry error if there has been no discernible
* progress. Some firmware revisions report more required
* touches. */
if (self->enroll_stage == done_stages)
@@ -795,8 +764,6 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
}
}
#define TEMPLATE_ID_SIZE 20
static void
enroll (FpDevice *device)
{
@@ -804,52 +771,21 @@ enroll (FpDevice *device)
FpPrint *print = NULL;
GVariant *data = NULL;
GVariant *uid = NULL;
const gchar *username;
guint finger;
g_autofree gchar *user_id = NULL;
gssize user_id_len;
g_autofree guint8 *payload = NULL;
const GDate *date;
gint y, m, d;
gint32 rand_id = 0;
fpi_device_get_enroll_data (device, &print);
G_DEBUG_HERE ();
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
else
{
y = 0;
m = 0;
d = 0;
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
user_id = fpi_print_generate_user_id (print);
user_id_len = strlen (user_id);
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
/* We currently always use finger 1 from the devices piont of view */
/* We currently always use finger 1 from the devices point of view */
finger = 1;
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
@@ -962,6 +898,7 @@ dev_probe (FpDevice *device)
const guint8 *data;
gboolean read_ok = TRUE;
g_autofree gchar *serial = NULL;
gboolean retry = TRUE;
G_DEBUG_HERE ();
@@ -979,35 +916,43 @@ dev_probe (FpDevice *device)
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
goto err_close;
/* TODO: Do not do this synchronous. */
transfer = fpi_usb_transfer_new (device);
fpi_usb_transfer_fill_bulk (transfer, USB_EP_REQUEST, SENSOR_FW_CMD_HEADER_LEN);
transfer->short_is_error = TRUE;
transfer->buffer[0] = SENSOR_CMD_GET_VERSION;
if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error))
goto err_close;
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))
goto err_close;
fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length);
if (!fpi_byte_reader_get_uint16_le (&reader, &status))
while(1)
{
g_warning ("Transfer in response to version query was too short");
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}
if (status != 0)
{
g_warning ("Device responded with error: %d", status);
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}
/* TODO: Do not do this synchronous. */
transfer = fpi_usb_transfer_new (device);
fpi_usb_transfer_fill_bulk (transfer, USB_EP_REQUEST, SENSOR_FW_CMD_HEADER_LEN);
transfer->short_is_error = TRUE;
transfer->buffer[0] = SENSOR_CMD_GET_VERSION;
if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error))
goto err_close;
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))
goto err_close;
fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length);
if (!fpi_byte_reader_get_uint16_le (&reader, &status))
{
g_warning ("Transfer in response to version query was too short");
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}
if (status != 0)
{
g_warning ("Device responded with error: %d retry: %d", status, retry);
if(retry)
{
retry = FALSE;
continue;
}
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}
break;
}
read_ok &= fpi_byte_reader_get_uint32_le (&reader, &self->mis_version.build_time);
read_ok &= fpi_byte_reader_get_uint32_le (&reader, &self->mis_version.build_num);
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.version_major);
@@ -1029,7 +974,7 @@ dev_probe (FpDevice *device)
if (!read_ok)
{
g_warning ("Transfer in response to verison query was too short");
g_warning ("Transfer in response to version query was too short");
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}

View File

@@ -47,17 +47,11 @@ enum {
enum sonly_kill_transfers_action {
NOT_KILLING = 0,
/* abort a SSM with an error code */
ABORT_SSM,
/* report an image session error */
IMG_SESSION_ERROR,
/* iterate a SSM to the next state */
ITERATE_SSM,
/* call a callback */
EXEC_CALLBACK,
};
enum sonly_fs {
@@ -97,13 +91,9 @@ struct _FpiDeviceUpeksonly
enum sonly_kill_transfers_action killing_transfers;
GError *kill_error;
union
{
FpiSsm *kill_ssm;
void (*kill_cb)(FpImageDevice *dev);
};
FpiSsm *kill_ssm;
struct fpi_line_asmbl_ctx assembling_ctx;
struct fpi_line_asmbl_ctx assembling_ctx;
};
G_DECLARE_FINAL_TYPE (FpiDeviceUpeksonly, fpi_device_upeksonly, FPI,
DEVICE_UPEKSONLY, FpImageDevice);
@@ -176,11 +166,6 @@ last_transfer_killed (FpImageDevice *dev)
switch (self->killing_transfers)
{
case ABORT_SSM:
fp_dbg ("abort ssm error %s", self->kill_error->message);
fpi_ssm_mark_failed (self->kill_ssm, g_steal_pointer (&self->kill_error));
return;
case ITERATE_SSM:
fp_dbg ("iterate ssm");
fpi_ssm_next_state (self->kill_ssm);
@@ -531,6 +516,14 @@ img_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
return;
}
/* NOTE: The old code assume 4096 bytes are received each time
* but there is no reason we need to enforce that. However, we
* always need full lines. */
if (transfer->actual_length % 64 != 0)
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Data packets need to be multiple of 64 bytes, got %zi bytes",
transfer->actual_length);
if (error)
{
fp_warn ("bad status %s, terminating session", error->message);
@@ -551,7 +544,7 @@ img_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
* the first 2 bytes are a sequence number
* then there are 62 bytes for image data
*/
for (i = 0; i < 4096; i += 64)
for (i = 0; i + 64 <= transfer->actual_length; i += 64)
{
if (!is_capturing (self))
return;
@@ -560,7 +553,7 @@ img_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
if (is_capturing (self))
{
fpi_usb_transfer_submit (transfer,
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
0,
self->img_cancellable,
img_data_cb,
@@ -588,6 +581,8 @@ write_regs_finished (struct write_regs_data *wrdata, GError *error)
fpi_ssm_next_state (wrdata->ssm);
else
fpi_ssm_mark_failed (wrdata->ssm, error);
g_free (wrdata);
}
static void write_regs_iterate (struct write_regs_data *wrdata);
@@ -634,9 +629,9 @@ write_regs_iterate (struct write_regs_data *wrdata)
1);
transfer->short_is_error = TRUE;
transfer->ssm = wrdata->ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, write_regs_cb, NULL);
transfer->buffer[0] = regwrite->value;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, write_regs_cb, wrdata);
}
static void
@@ -675,10 +670,10 @@ sm_write_reg (FpiSsm *ssm,
1);
transfer->short_is_error = TRUE;
transfer->ssm = ssm;
transfer->buffer[0] = value;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
transfer->buffer[0] = value;
}
static void
@@ -908,7 +903,7 @@ capsm_fire_bulk (FpiSsm *ssm,
self->img_cancellable = g_cancellable_new ();
for (i = 0; i < self->img_transfers->len; i++)
{
fpi_usb_transfer_submit (g_ptr_array_index (self->img_transfers, i),
fpi_usb_transfer_submit (fpi_usb_transfer_ref (g_ptr_array_index (self->img_transfers, i)),
0,
self->img_cancellable,
img_data_cb,
@@ -1406,8 +1401,12 @@ dev_activate (FpImageDevice *dev)
self->capturing = FALSE;
self->num_flying = 0;
self->img_transfers = g_ptr_array_new_with_free_func ((GFreeFunc) fpi_usb_transfer_unref);
for (i = 0; i < self->img_transfers->len; i++)
/* This might seem odd, but we do need multiple in-flight URBs so that
* we never stop polling the device for more data.
*/
for (i = 0; i < NUM_BULK_TRANSFERS; i++)
{
FpiUsbTransfer *transfer;

View File

@@ -171,7 +171,7 @@ finger_present (unsigned char *img, size_t len, int sum_threshold)
if (img[i] < 160)
sum++;
fp_dbg ("finger_present: sum is %d\n", sum);
fp_dbg ("finger_present: sum is %d", sum);
return sum < sum_threshold ? 0 : 1;
}
@@ -184,7 +184,7 @@ finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
if (error)
{
fp_dbg ("data transfer status %s\n", error->message);
fp_dbg ("data transfer status %s", error->message);
fpi_image_device_session_error (dev, error);
return;
}
@@ -212,7 +212,7 @@ finger_det_cmd_cb (FpiUsbTransfer *t, FpDevice *device,
if (error)
{
fp_dbg ("req transfer status %s\n", error->message);
fp_dbg ("req transfer status %s", error->message);
fpi_image_device_session_error (dev, error);
return;
}
@@ -411,7 +411,7 @@ dev_init (FpImageDevice *dev)
break;
default:
fp_err ("Device variant %lu is not known\n", driver_data);
fp_err ("Device variant %lu is not known", driver_data);
g_assert_not_reached ();
fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
return;

View File

@@ -193,7 +193,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
if (self->deactivating)
{
fp_dbg ("Deactivate requested\n");
fp_dbg ("Deactivate requested");
fpi_ssm_mark_completed (transfer->ssm);
return;
}
@@ -208,7 +208,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
if (fpi_ssm_get_cur_state (transfer->ssm) == CAPTURE_READ_DATA_TERM)
{
fp_dbg ("Terminating SSM\n");
fp_dbg ("Terminating SSM");
fpi_ssm_mark_completed (transfer->ssm);
return;
}
@@ -219,7 +219,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
response_size += 9; /* 7 bytes for header, 2 for CRC */
if (response_size > transfer->actual_length)
{
fp_dbg ("response_size is %lu, actual_length is %d\n",
fp_dbg ("response_size is %lu, actual_length is %d",
response_size, (gint) transfer->actual_length);
fp_dbg ("Waiting for rest of transfer");
BUG_ON (self->response_rest);
@@ -237,7 +237,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
{
/* No finger */
case 0x28:
fp_dbg ("18th byte is %.2x\n", data[18]);
fp_dbg ("18th byte is %.2x", data[18]);
switch (data[18])
{
case 0x0c:
@@ -254,7 +254,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
case 0x1e:
/* short scan */
fp_err ("short scan, aborting\n");
fp_err ("short scan, aborting");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY_TOO_SHORT);
fpi_image_device_report_finger_status (dev,
@@ -265,7 +265,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
case 0x1d:
/* too much horisontal movement */
fp_err ("too much horisontal movement, aborting\n");
fp_err ("too much horisontal movement, aborting");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY_CENTER_FINGER);
fpi_image_device_report_finger_status (dev,
@@ -276,7 +276,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
default:
/* some error happened, cancel scan */
fp_err ("something bad happened, stop scan\n");
fp_err ("something bad happened, stop scan");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY);
fpi_image_device_report_finger_status (dev,
@@ -307,9 +307,10 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
upektc_img_process_image_frame (self->image_bits + self->image_size,
data);
BUG_ON (self->image_size != IMAGE_SIZE);
fp_dbg ("Image size is %lu\n",
fp_dbg ("Image size is %lu",
self->image_size);
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
img->flags |= FPI_IMAGE_PARTIAL;
memcpy (img->data, self->image_bits,
IMAGE_SIZE);
fpi_image_device_image_captured (dev, img);
@@ -319,7 +320,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
break;
default:
fp_err ("Unknown response!\n");
fp_err ("Unknown response!");
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
break;
}
@@ -330,7 +331,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
break;
default:
fp_err ("Not handled response!\n");
fp_err ("Not handled response!");
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
}
}

View File

@@ -35,7 +35,6 @@
#define TIMEOUT 5000
#define MSG_READ_BUF_SIZE 0x40
#define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
struct _FpiDeviceUpekts
{
@@ -236,12 +235,18 @@ __handle_incoming_msg (FpDevice *device,
{
GError *error = NULL;
guint8 *buf = udata->buffer;
guint16 len = ((buf[5] & 0xf) << 8) | buf[6];
guint16 computed_crc = udf_crc (buf + 4, len + 3);
guint16 msg_crc = (buf[len + 8] << 8) | buf[len + 7];
unsigned char *retdata = NULL;
guint16 len;
guint16 computed_crc;
guint16 msg_crc;
unsigned char code_a, code_b;
g_assert (udata->buflen >= 6);
len = ((buf[5] & 0xf) << 8) | buf[6];
g_assert (udata->buflen >= len + 9);
computed_crc = udf_crc (buf + 4, len + 3);
msg_crc = (buf[len + 8] << 8) | buf[len + 7];
if (computed_crc != msg_crc)
{
fp_err ("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
@@ -267,12 +272,7 @@ __handle_incoming_msg (FpDevice *device,
return;
}
if (len > 0)
{
retdata = g_malloc (len);
memcpy (retdata, buf + 7, len);
}
udata->callback (device, READ_MSG_CMD, code_a, 0, retdata, len,
udata->callback (device, READ_MSG_CMD, code_a, 0, buf + 7, len,
udata->user_data, NULL);
goto done;
}
@@ -309,14 +309,8 @@ __handle_incoming_msg (FpDevice *device,
innerlen = innerlen - 3;
_subcmd = innerbuf[5];
fp_dbg ("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
if (innerlen > 0)
{
retdata = g_malloc (innerlen);
memcpy (retdata, innerbuf + 6, innerlen);
}
udata->callback (device, READ_MSG_RESPONSE, code_b, _subcmd,
retdata, innerlen, udata->user_data, NULL);
g_free (retdata);
innerbuf + 6, innerlen, udata->user_data, NULL);
goto done;
}
else
@@ -358,7 +352,8 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
struct read_msg_data *udata = user_data;
guint16 len;
guint16 payload_len;
gsize packet_len;
if (error)
{
@@ -383,14 +378,15 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
goto err;
}
len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
payload_len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
packet_len = payload_len + 9;
if (transfer->actual_length != MSG_READ_BUF_SIZE &&
(len + 9) > transfer->actual_length)
packet_len > transfer->actual_length)
{
/* Check that the length claimed inside the message is in line with
* the amount of data that was transferred over USB. */
fp_err ("msg didn't include enough data, expected=%d recv=%d",
len + 9, (gint) transfer->actual_length);
(gint) packet_len, (gint) transfer->actual_length);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Packet from device didn't include data");
goto err;
@@ -399,14 +395,14 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
/* We use a 64 byte buffer for reading messages. However, sometimes
* messages are longer, in which case we have to do another USB bulk read
* to read the remainder. This is handled below. */
if (len > MAX_DATA_IN_READ_BUF)
if (packet_len > MSG_READ_BUF_SIZE)
{
int needed = len - MAX_DATA_IN_READ_BUF;
int needed = packet_len - MSG_READ_BUF_SIZE;
FpiUsbTransfer *etransfer = fpi_usb_transfer_new (device);
fp_dbg ("didn't fit in buffer, need to extend by %d bytes", needed);
udata->buffer = g_realloc ((gpointer) udata->buffer, len);
udata->buflen = len;
udata->buffer = g_realloc ((gpointer) udata->buffer, packet_len);
udata->buflen = packet_len;
fpi_usb_transfer_fill_bulk_full (etransfer, EP_IN,
udata->buffer + MSG_READ_BUF_SIZE,
@@ -700,7 +696,7 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
break;
case SEND_RESP03:;
transfer = alloc_send_cmd28_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
transfer = alloc_send_cmdresponse_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
@@ -856,21 +852,14 @@ dev_init (FpDevice *dev)
fpi_ssm_start (ssm, initsm_done);
}
static void
deinitsm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, NULL);
fpi_device_close_complete (dev, error);
}
static void
dev_exit (FpDevice *dev)
{
FpiSsm *ssm;
GError *error = NULL;
ssm = fpi_ssm_new (dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
fpi_ssm_start (ssm, deinitsm_done);
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, &error);
fpi_device_close_complete (dev, error);
}
static const unsigned char enroll_init[] = {
@@ -983,7 +972,9 @@ enroll_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
if (error)
fp_warn ("Error deinitializing: %s", error->message);
fpi_device_enroll_complete (dev, data->print, data->error);
fpi_device_enroll_complete (dev,
g_steal_pointer (&data->print),
g_steal_pointer (&data->error));
}
static void
@@ -992,7 +983,7 @@ do_enroll_stop (FpDevice *dev, FpPrint *print, GError *error)
EnrollStopData *data = g_new0 (EnrollStopData, 1);
FpiSsm *ssm = deinitsm_new (dev, data);
data->print = g_object_ref (print);
data->print = print;
data->error = error;
fpi_ssm_start (ssm, enroll_stop_deinit_cb);
@@ -1119,7 +1110,6 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
else
{
GVariant *fp_data;
print = fp_print_new (dev);
fpi_device_get_enroll_data (dev, &print);
@@ -1128,6 +1118,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
data_len - sizeof (scan_comp),
1);
fpi_print_set_type (print, FPI_PRINT_RAW);
g_object_set (print, "fpi-data", fp_data, NULL);
g_object_ref (print);
}
@@ -1246,11 +1237,11 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
fp_warn ("Error deinitializing: %s", error->message);
if (data->error)
fpi_device_verify_complete (dev, data->error);
fpi_device_verify_complete (dev, g_steal_pointer (&data->error));
else
fpi_device_verify_complete (dev, g_steal_pointer (&error));
g_error_free (error);
g_clear_error (&error);
}
static void
@@ -1260,7 +1251,7 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
FpiSsm *ssm = deinitsm_new (dev, data);
/* Report the error immediately if possible, otherwise delay it. */
if (!error && error->domain != FP_DEVICE_RETRY)
if (error && error->domain == FP_DEVICE_RETRY)
fpi_device_verify_report (dev, res, NULL, error);
else
data->error = error;
@@ -1302,7 +1293,7 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
case VERIFY_INIT:
fpi_device_get_verify_data (dev, &print);
g_object_get (dev, "fpi-data", &fp_data, NULL);
g_object_get (print, "fpi-data", &fp_data, NULL);
data = g_variant_get_fixed_array (fp_data, &data_len, 1);

View File

@@ -81,7 +81,7 @@ static const struct uru4k_dev_profile
{
const char *name;
gboolean auth_cr;
gboolean encryption;
gboolean image_not_flipped;
} uru4k_dev_info[] = {
[MS_KBD] = {
.name = "Microsoft Keyboard with Fingerprint Reader",
@@ -106,7 +106,7 @@ static const struct uru4k_dev_profile
[DP_URU4000B] = {
.name = "Digital Persona U.are.U 4000B",
.auth_cr = FALSE,
.encryption = TRUE,
.image_not_flipped = TRUE, /* See comment in the code where it is used. */
},
};
@@ -680,17 +680,17 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE);
return;
}
if (!self->profile->encryption)
/* Detect whether image is encrypted (by checking how noisy it is) */
dev2 = calc_dev2 (img);
fp_dbg ("dev2: %d", dev2);
if (dev2 < ENC_THRESHOLD)
{
dev2 = calc_dev2 (img);
fp_dbg ("dev2: %d", dev2);
if (dev2 < ENC_THRESHOLD)
{
fpi_ssm_jump_to_state (ssm, IMAGING_REPORT_IMAGE);
return;
}
fp_info ("image seems to be encrypted");
fpi_ssm_jump_to_state (ssm, IMAGING_REPORT_IMAGE);
return;
}
fp_info ("image seems to be encrypted");
buf[0] = img->key_number;
buf[1] = self->img_enc_seed;
buf[2] = self->img_enc_seed >> 8;
@@ -723,7 +723,7 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
num_lines);
if (flags & BLOCKF_CHANGE_KEY)
{
fp_dbg ("changing encryption keys.\n");
fp_dbg ("changing encryption keys.");
img->block_info[self->img_block].flags &= ~BLOCKF_CHANGE_KEY;
img->key_number++;
self->img_enc_seed = rand ();
@@ -769,7 +769,13 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
}
fpimg->flags = FPI_IMAGE_COLORS_INVERTED;
if (!self->profile->encryption)
/* NOTE: For some reason all but U4000B (or rather U4500?) flipped the
* image, we retain this behaviour here, but it is not clear whether it
* is correct.
* It may be that there are different models with the same USB ID that
* behave differently.
*/
if (self->profile->image_not_flipped)
fpimg->flags |= FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
fpi_image_device_image_captured (dev, fpimg);

View File

@@ -117,9 +117,10 @@ async_abort_callback (FpiUsbTransfer *transfer, FpDevice *device,
int ep = transfer->endpoint;
/* In normal case endpoint is empty */
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT))
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) ||
(g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0 && transfer->actual_length == 0))
{
g_free (error);
g_clear_error (&error);
fpi_ssm_next_state (transfer->ssm);
return;
}
@@ -156,6 +157,8 @@ async_abort (FpDevice *dev, FpiSsm *ssm, int ep)
else
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
async_abort_callback, NULL);
}
@@ -240,6 +243,7 @@ prepare_image (FpDeviceVfs0050 *vdev)
/* Building GSList */
GSList *lines = NULL;
for (int i = height - 1; i >= 0; --i)
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
@@ -464,8 +468,8 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
if (error)
g_error_free (error);
/* Check if fingerprint data is over */
if (transfer->actual_length == 0)
/* Capture is done when there is no more data to transfer or device timed out */
if (transfer->actual_length <= 0)
{
fpi_ssm_next_state (transfer->ssm);
}
@@ -473,7 +477,7 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
{
self->bytes += transfer->actual_length;
/* We need more data */
/* Try reading more data */
fpi_ssm_jump_to_state (transfer->ssm,
fpi_ssm_get_cur_state (transfer->ssm));
}
@@ -595,8 +599,7 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
/* Receive chunk of data */
transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
(guint8 *)
(self->lines_buffer + self->bytes),
(guint8 *) self->lines_buffer + self->bytes,
VFS_USB_BUFFER_SIZE, NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
@@ -668,6 +671,7 @@ dev_activate (FpImageDevice *idev)
self->ssm_active = 1;
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
fpi_ssm_start (ssm, dev_activate_callback);
}
@@ -711,6 +715,7 @@ dev_open (FpImageDevice *idev)
/* Clearing previous device state */
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
fpi_ssm_start (ssm, dev_open_callback);
}

View File

@@ -177,6 +177,7 @@ translate_str (const char **srcL, gssize *len)
src_len += tmp;
}
g_assert (src_len >= 2);
*len = src_len / 2;
res = g_malloc0 (*len);
dst = res;
@@ -437,7 +438,7 @@ img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int l
usb_send (dev, data, len, NULL); \
}
#define RAW_DATA(x) x, sizeof (x)
#define RAW_DATA(x) g_memdup (x, sizeof (x)), sizeof (x)
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))

View File

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

View File

@@ -21,7 +21,7 @@
/*
* This is a virtual driver to debug the image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to be sent to this device programatically.
* prints to be sent to this device programmatically.
* Using this it is possible to test libfprint and fprintd.
*/
@@ -252,6 +252,7 @@ dev_init (FpImageDevice *dev)
g_autoptr(GSocketListener) listener = NULL;
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
const char *env;
g_autoptr(GSocketAddress) addr = NULL;
G_DEBUG_HERE ();
@@ -287,7 +288,8 @@ dev_init (FpImageDevice *dev)
start_listen (self);
fpi_image_device_open_complete (dev, NULL);
/* Delay result to open up the possibility of testing race conditions. */
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_open_complete, NULL, NULL);
}
static void
@@ -302,7 +304,8 @@ dev_deinit (FpImageDevice *dev)
g_clear_object (&self->listener);
g_clear_object (&self->connection);
fpi_image_device_close_complete (dev, NULL);
/* Delay result to open up the possibility of testing race conditions. */
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_close_complete, NULL, NULL);
}
static void

View File

@@ -94,22 +94,21 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
FpContext *context;
FpContextPrivate *priv;
device = (FpDevice *) g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error);
if (!device)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
g_message ("Ignoring device due to initialization error: %s", error->message);
return;
}
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
res, &error));
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
if (error)
{
g_message ("Ignoring device due to initialization error: %s", error->message);
return;
}
g_ptr_array_add (priv->devices, device);
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
}
@@ -159,7 +158,7 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
if (found_driver == G_TYPE_NONE)
{
g_debug ("No driver found for USB device %04X:%04X", pid, vid);
g_debug ("No driver found for USB device %04X:%04X", vid, pid);
return;
}
@@ -211,7 +210,8 @@ fp_context_finalize (GObject *object)
g_clear_object (&priv->cancellable);
g_clear_pointer (&priv->drivers, g_array_unref);
g_object_run_dispose (G_OBJECT (priv->usb_ctx));
if (priv->usb_ctx)
g_object_run_dispose (G_OBJECT (priv->usb_ctx));
g_clear_object (&priv->usb_ctx);
G_OBJECT_CLASS (fp_context_parent_class)->finalize (object);
@@ -290,7 +290,7 @@ fp_context_init (FpContext *self)
priv->usb_ctx = g_usb_context_new (&error);
if (!priv->usb_ctx)
{
fp_warn ("Could not initialise USB Subsystem: %s", error->message);
g_message ("Could not initialise USB Subsystem: %s", error->message);
}
else
{
@@ -343,7 +343,8 @@ fp_context_enumerate (FpContext *context)
priv->enumerated = TRUE;
/* USB devices are handled from callbacks */
g_usb_context_enumerate (priv->usb_ctx);
if (priv->usb_ctx)
g_usb_context_enumerate (priv->usb_ctx);
/* Handle Virtual devices based on environment variables */
for (i = 0; i < priv->drivers->len; i++)

View File

@@ -24,16 +24,11 @@
#include "fp-device-private.h"
/**
* SECTION: fpi-device
* @title: Internal FpDevice
* @short_description: Internal device routines
* SECTION: fp-device
* @title: FpDevice
* @short_description: Fingerpint device routines
*
* The methods that are availabe for drivers to manipulate a device. See
* #FpDeviceClass for more information. Also note that most of these are
* not relevant for image based devices, see #FpImageDeviceClass in that
* case.
*
* Also see the public #FpDevice routines.
* These are the public #FpDevice routines.
*/
static void fp_device_async_initable_iface_init (GAsyncInitableIface *iface);
@@ -339,7 +334,7 @@ fp_device_class_init (FpDeviceClass *klass)
properties[PROP_OPEN] =
g_param_spec_boolean ("open",
"Opened",
"Wether the device is open or not", FALSE,
"Whether the device is open or not", FALSE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
/**

View File

@@ -79,7 +79,7 @@ typedef enum {
/**
* FpDeviceError:
* @FP_DEVICE_ERROR_GENERAL: A general error occured.
* @FP_DEVICE_ERROR_GENERAL: A general error occurred.
* @FP_DEVICE_ERROR_NOT_SUPPORTED: The device does not support the requested
* operation.
* @FP_DEVICE_ERROR_NOT_OPEN: The device needs to be opened to start this
@@ -90,6 +90,7 @@ typedef enum {
* @FP_DEVICE_ERROR_DATA_INVALID: The passed data is invalid
* @FP_DEVICE_ERROR_DATA_NOT_FOUND: Requested print was not found on device
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
*
* Error codes for device operations. More specific errors from other domains
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
@@ -104,6 +105,7 @@ typedef enum {
FP_DEVICE_ERROR_DATA_INVALID,
FP_DEVICE_ERROR_DATA_NOT_FOUND,
FP_DEVICE_ERROR_DATA_FULL,
FP_DEVICE_ERROR_DATA_DUPLICATE,
} FpDeviceError;
GQuark fp_device_retry_quark (void);
@@ -113,7 +115,7 @@ GQuark fp_device_error_quark (void);
* FpEnrollProgress:
* @device: a #FpDevice
* @completed_stages: Number of completed stages
* @print: (nullable) (transfer none): The last scaned print
* @print: (nullable) (transfer none): The last scanned print
* @user_data: (nullable) (transfer none): User provided data
* @error: (nullable) (transfer none): #GError or %NULL
*

View File

@@ -62,17 +62,34 @@ static gboolean
pending_activation_timeout (gpointer user_data)
{
FpImageDevice *self = FP_IMAGE_DEVICE (user_data);
FpDevice *device = FP_DEVICE (self);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action = fpi_device_get_current_action (device);
GError *error;
priv->pending_activation_timeout_id = 0;
if (priv->pending_activation_timeout_waiting_finger_off)
fpi_device_action_error (FP_DEVICE (self),
fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER,
"Remove finger before requesting another scan operation"));
error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER,
"Remove finger before requesting another scan operation");
else
fpi_device_action_error (FP_DEVICE (self),
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
if (action == FPI_DEVICE_ACTION_VERIFY)
{
fpi_device_verify_report (device, FPI_MATCH_ERROR, NULL, error);
fpi_device_verify_complete (device, NULL);
}
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
{
fpi_device_identify_report (device, NULL, NULL, error);
fpi_device_identify_complete (device, NULL);
}
else
{
/* Can this happen for enroll? */
fpi_device_action_error (device, error);
}
return G_SOURCE_REMOVE;
}
@@ -100,7 +117,7 @@ fp_image_device_close (FpDevice *device)
* 1. We are inactive
* -> immediately close
* 2. We are waiting for finger off
* -> imediately deactivate
* -> immediately deactivate
* 3. We are deactivating
* -> handled by deactivate_complete */

View File

@@ -19,7 +19,7 @@
#pragma once
#include <fp-device.h>
#include "fp-device.h"
G_BEGIN_DECLS

View File

@@ -184,10 +184,8 @@ fp_image_detect_minutiae_cb (GObject *source_object,
GTask *task = G_TASK (res);
FpImage *image;
DetectMinutiaeData *data = g_task_get_task_data (task);
GCancellable *cancellable;
cancellable = g_task_get_cancellable (task);
if (!cancellable || !g_cancellable_is_cancelled (cancellable))
if (!g_task_had_error (task))
{
gint i;
image = FP_IMAGE (source_object);
@@ -283,6 +281,7 @@ fp_image_detect_minutiae_thread_func (GTask *task,
gint map_w, map_h;
gint bw, bh, bd;
gint r;
g_autofree LFSPARMS *lfsparms;
/* Normalize the image first */
if (data->flags & FPI_IMAGE_H_FLIPPED)
@@ -296,12 +295,15 @@ fp_image_detect_minutiae_thread_func (GTask *task,
data->flags &= ~(FPI_IMAGE_H_FLIPPED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_COLORS_INVERTED);
lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS));
lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE;
timer = g_timer_new ();
r = get_minutiae (&minutiae, &quality_map, &direction_map,
&low_contrast_map, &low_flow_map, &high_curve_map,
&map_w, &map_h, &bdata, &bw, &bh, &bd,
data->image, data->width, data->height, 8,
data->ppmm, &g_lfsparms_V2);
data->ppmm, lfsparms);
g_timer_stop (timer);
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
@@ -316,6 +318,14 @@ fp_image_detect_minutiae_thread_func (GTask *task,
return;
}
if (!data->minutiae || data->minutiae->num == 0)
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
"No minutiae found");
g_object_unref (task);
return;
}
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}

View File

@@ -51,7 +51,7 @@ enum {
PROP_IMAGE,
/* The following is metadata that is stored by default for each print.
* Drivers may make use of these during enrollment (e.g. to additionaly store
* Drivers may make use of these during enrollment (e.g. to additionally store
* the metadata on the device). */
PROP_FINGER,
PROP_USERNAME,
@@ -588,7 +588,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
}
else if (self->type == FPI_PRINT_NBIS)
{
gint i;
guint i;
if (self->prints->len != other->prints->len)
return FALSE;
@@ -661,7 +661,7 @@ fp_print_serialize (FpPrint *print,
if (print->type == FPI_PRINT_NBIS)
{
GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))"));
gint i;
guint i;
g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)"));
for (i = 0; i < print->prints->len; i++)
@@ -812,7 +812,7 @@ fp_print_deserialize (const guchar *data,
if (type == FPI_PRINT_NBIS)
{
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
gint i;
guint i;
result = g_object_new (FP_TYPE_PRINT,
"driver", driver,
@@ -822,7 +822,7 @@ fp_print_deserialize (const guchar *data,
fpi_print_set_type (result, FPI_PRINT_NBIS);
for (i = 0; i < g_variant_n_children (prints); i++)
{
g_autofree struct xyt_struct *xyt = g_new0 (struct xyt_struct, 1);
g_autofree struct xyt_struct *xyt = NULL;
const gint32 *xcol, *ycol, *thetacol;
gsize xlen, ylen, thetalen;
g_autoptr(GVariant) xyt_data = NULL;
@@ -848,6 +848,7 @@ fp_print_deserialize (const guchar *data,
if (xlen > G_N_ELEMENTS (xyt->xcol))
goto invalid_format;
xyt = g_new0 (struct xyt_struct, 1);
xyt->nrows = xlen;
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);

View File

@@ -28,7 +28,7 @@
* @title: Internal FpDevice
* @short_description: Internal device routines
*
* The methods that are availabe for drivers to manipulate a device. See
* The methods that are available for drivers to manipulate a device. See
* #FpDeviceClass for more information. Also note that most of these are
* not relevant for image based devices, see #FpImageDeviceClass in that
* case.
@@ -100,7 +100,7 @@ fpi_device_error_new (FpDeviceError error)
switch (error)
{
case FP_DEVICE_ERROR_GENERAL:
msg = "An unspecified error occured!";
msg = "An unspecified error occurred!";
break;
case FP_DEVICE_ERROR_NOT_SUPPORTED:
@@ -135,10 +135,14 @@ fpi_device_error_new (FpDeviceError error)
msg = "Print was not found on the devices storage.";
break;
case FP_DEVICE_ERROR_DATA_DUPLICATE:
msg = "This finger has already enrolled, please try a different finger";
break;
default:
g_warning ("Unsupported error, returning general error instead!");
error = FP_DEVICE_ERROR_GENERAL;
msg = "An unspecified error occured!";
msg = "An unspecified error occurred!";
}
return g_error_new_literal (FP_DEVICE_ERROR, error, msg);
@@ -391,7 +395,7 @@ fpi_device_action_is_cancelled (FpDevice *device)
cancellable = g_task_get_cancellable (priv->current_task);
return cancellable ? g_cancellable_is_cancelled (cancellable) : FALSE;
return g_cancellable_is_cancelled (cancellable);
}
/**
@@ -593,7 +597,11 @@ fpi_device_action_error (FpDevice *device,
if (error != NULL)
{
g_debug ("Device reported generic error during action; action was: %i", priv->current_action);
g_autofree char *action_str = NULL;
action_str = g_enum_to_string (FPI_TYPE_DEVICE_ACTION, priv->current_action);
g_debug ("Device reported generic error (%s) during action; action was: %s",
error->message, action_str);
}
else
{
@@ -682,10 +690,13 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
{
FpDeviceTaskReturnData *data = user_data;
FpDevicePrivate *priv = fp_device_get_instance_private (data->device);
g_autofree char *action_str = NULL;
g_autoptr(GTask) task = NULL;
g_debug ("Completing action %d in idle!", priv->current_action);
action_str = g_enum_to_string (FPI_TYPE_DEVICE_ACTION, priv->current_action);
g_debug ("Completing action %s in idle!", action_str);
task = g_steal_pointer (&priv->current_task);
priv->current_action = FPI_DEVICE_ACTION_NONE;
@@ -912,6 +923,20 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
{
if (FP_IS_PRINT (print))
{
FpiPrintType print_type;
g_object_get (print, "fpi-type", &print_type, NULL);
if (print_type == FPI_PRINT_UNDEFINED)
{
g_warning ("Driver did not set the type on the returned print!");
g_clear_object (&print);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Driver provided incorrect print data!");
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
return;
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
}
else

View File

@@ -65,10 +65,10 @@ struct _FpIdEntry
* @probe: Called immediately for all devices. Most drivers will not need to
* implement this. Drivers should setup the device identifier from the probe
* callback which will be used to verify the compatibility of stored
* #FpPrint's. It is permissable to temporarily open the USB device if this
* #FpPrint's. It is permissible to temporarily open the USB device if this
* is required for the operation. If an error is returned, then the device
* will be destroyed again immediately and never reported to the API user.
* @open: Open the device for futher operations. Any of the normal actions are
* @open: Open the device for further operations. Any of the normal actions are
* guaranteed to only happen when the device is open (this includes delete).
* @close: Close the device again
* @enroll: Start an enroll operation

View File

@@ -24,12 +24,11 @@
#include "fp-image-device.h"
/**
* SECTION: fpi-image
* @title: Internal FpImage
* @short_description: Internal image handling routines
* SECTION: fpi-image-device
* @title: Internal FpImageDevice
* @short_description: Internal image device functions
*
* Internal image handling routines. Also see the public <ulink
* url="libfprint-FpImage.html">FpImage routines</ulink>.
* Internal image device functions. See #FpImageDevice for public routines.
*/
/* Manually redefine what G_DEFINE_* macro does */
@@ -61,7 +60,7 @@ fpi_image_device_activate (FpImageDevice *self)
* starting the next operation. */
g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove);
fp_dbg ("Activating image device\n");
fp_dbg ("Activating image device");
cls->activate (self);
}
@@ -72,7 +71,7 @@ fpi_image_device_deactivate (FpImageDevice *self)
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (device);
if (!priv->active)
if (!priv->active || priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
{
/* XXX: We currently deactivate both from minutiae scan result
* and finger off report. */
@@ -85,7 +84,7 @@ fpi_image_device_deactivate (FpImageDevice *self)
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
fp_dbg ("Deactivating image device\n");
fp_dbg ("Deactivating image device");
cls->deactivate (self);
}
@@ -95,6 +94,8 @@ static void
fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
g_autofree char *prev_state_str = NULL;
g_autofree char *state_str = NULL;
/* Cannot change to inactive using this function. */
g_assert (state != FPI_IMAGE_DEVICE_STATE_INACTIVE);
@@ -103,7 +104,10 @@ fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
* next operation. */
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);
prev_state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, priv->state);
state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, state);
fp_dbg ("Image device internal state change from %s to %s",
prev_state_str, state_str);
priv->state = state;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
@@ -122,6 +126,7 @@ fp_image_device_enroll_maybe_await_finger_on (FpImageDevice *self)
}
else
{
fp_dbg ("Awaiting finger on");
priv->enroll_await_on_pending = TRUE;
}
}
@@ -171,7 +176,16 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
print = fp_print_new (device);
fpi_print_set_type (print, FPI_PRINT_NBIS);
if (!fpi_print_add_from_image (print, image, &error))
g_clear_object (&print);
{
g_clear_object (&print);
if (error->domain != FP_DEVICE_RETRY)
{
fpi_device_action_error (device, error);
fpi_image_device_deactivate (self);
return;
}
}
}
if (action == FPI_DEVICE_ACTION_ENROLL)

View File

@@ -72,9 +72,8 @@ typedef enum {
* fpi_device_action_error() function but doing so is not recommended in most
* usecases.
*
* Drivers *must* also handle cancellation properly for any long running
* operation (i.e. any operation that requires capturing). It is entirely fine
* to ignore cancellation requests for short operations (e.g. open/close).
* Image drivers must expect a @deactivate call to happen at any point during
* image capture.
*
* This API is solely intended for drivers. It is purely internal and neither
* API nor ABI stable.

View File

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

View File

@@ -37,6 +37,7 @@ typedef enum {
FPI_IMAGE_V_FLIPPED = 1 << 0,
FPI_IMAGE_H_FLIPPED = 1 << 1,
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
FPI_IMAGE_PARTIAL = 1 << 3,
} FpiImageFlags;
/**

View File

@@ -23,6 +23,7 @@
#include "fp-print-private.h"
#include "fpi-device.h"
#include "fpi-compat.h"
/**
* SECTION: fpi-print
@@ -239,7 +240,7 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
gint score;
gstruct = g_ptr_array_index (template->prints, i);
score = bozorth_to_gallery (probe_len, pstruct, gstruct);
fp_dbg ("score %d", score);
fp_dbg ("score %d/%d", score, bz3_threshold);
if (score >= bz3_threshold)
return FPI_MATCH_SUCCESS;
@@ -247,3 +248,115 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
return FPI_MATCH_FAIL;
}
/**
* fpi_print_generate_user_id:
* @print: #FpPrint to generate the ID for
*
* Generates a string identifier for the represented print. This identifier
* encodes some metadata about the print. It also includes a random string
* and may be assumed to be unique.
*
* This is useful if devices are able to store a string identifier, but more
* storing more metadata may be desirable. In effect, this means the driver
* can provide somewhat more meaningful data to fp_device_list_prints().
*
* The generated ID may be truncated after 23 characters. However, more space
* is required to include the username, and it is recommended to store at
* at least 31 bytes.
*
* The generated format may change in the future. It is versioned though and
* decoding should remain functional.
*
* Returns: A unique string of 23 + strlen(username) characters
*/
gchar *
fpi_print_generate_user_id (FpPrint *print)
{
const gchar *username = NULL;
gchar *user_id = NULL;
const GDate *date;
gint y = 0, m = 0, d = 0;
gint32 rand_id = 0;
g_assert (print);
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
return user_id;
}
/**
* fpi_print_fill_from_user_id:
* @print: #FpPrint to fill metadata into
* @user_id: An ID that was likely encoded using fpi_print_generate_user_id()
*
* This is the reverse operation of fpi_print_generate_user_id(), allowing
* the driver to encode some print metadata in a string.
*
* Returns: Whether a valid ID was found
*/
gboolean
fpi_print_fill_from_user_id (FpPrint *print, const char *user_id)
{
g_return_val_if_fail (user_id, FALSE);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (user_id, "FP1-") && strlen (user_id) >= 24 &&
user_id[12] == '-' && user_id[14] == '-' && user_id[23] == '-')
{
g_autofree gchar *copy = g_strdup (user_id);
g_autoptr(GDate) date = NULL;
gint32 date_ymd;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
return TRUE;
}
return FALSE;
}

View File

@@ -20,7 +20,7 @@ typedef enum {
/**
* FpiMatchResult:
* @FPI_MATCH_ERROR: An error occured during matching
* @FPI_MATCH_ERROR: An error occurred during matching
* @FPI_MATCH_FAIL: The prints did not match
* @FPI_MATCH_SUCCESS: The prints matched
*/
@@ -47,4 +47,9 @@ FpiMatchResult fpi_print_bz3_match (FpPrint * template,
gint bz3_threshold,
GError **error);
/* Helpers to encode metadata into user ID strings. */
gchar * fpi_print_generate_user_id (FpPrint *print);
gboolean fpi_print_fill_from_user_id (FpPrint *print,
const char *user_id);
G_END_DECLS

View File

@@ -105,6 +105,7 @@ fpi_usb_transfer_new (FpDevice * device)
self = g_slice_new0 (FpiUsbTransfer);
self->ref_count = 1;
self->type = FP_TRANSFER_NONE;
self->device = device;
@@ -353,6 +354,24 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
fpi_usb_transfer_unref (transfer);
}
static gboolean
transfer_cancel_cb (FpiUsbTransfer *transfer)
{
GError *error;
FpiUsbTransferCallback callback;
error = g_error_new_literal (G_IO_ERROR,
G_IO_ERROR_CANCELLED,
"Transfer was cancelled before being started");
callback = transfer->callback;
transfer->callback = NULL;
transfer->actual_length = -1;
callback (transfer, transfer->device, transfer->user_data, error);
fpi_usb_transfer_unref (transfer);
return G_SOURCE_REMOVE;
}
/**
* fpi_usb_transfer_submit:
@@ -366,7 +385,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
*
* Note that #FpiUsbTransfer will be stolen when this function is called.
* So that all associated data will be free'ed automatically, after the
* callback ran unless fpi_usb_transfer_ref() is explictly called.
* callback ran unless fpi_usb_transfer_ref() is explicitly called.
*/
void
fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
@@ -386,6 +405,18 @@ fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
log_transfer (transfer, TRUE, NULL);
/* Work around libgusb cancellation issue, see
* https://github.com/hughsie/libgusb/pull/42
* should be fixed with libgusb 0.3.7.
* Note that this is not race free, we rely on libfprint and API users
* not cancelling from a different thread here.
*/
if (cancellable && g_cancellable_is_cancelled (cancellable))
{
g_idle_add ((GSourceFunc) transfer_cancel_cb, transfer);
return;
}
switch (transfer->type)
{
case FP_TRANSFER_BULK:

View File

@@ -47,10 +47,10 @@ typedef void (*FpiUsbTransferCallback)(FpiUsbTransfer *transfer,
* Type of the transfer.
*/
typedef enum {
FP_TRANSFER_NONE = 0,
FP_TRANSFER_BULK,
FP_TRANSFER_CONTROL,
FP_TRANSFER_INTERRUPT,
FP_TRANSFER_NONE = -1,
FP_TRANSFER_CONTROL = 0,
FP_TRANSFER_BULK = 2,
FP_TRANSFER_INTERRUPT = 3,
} FpiTransferType;
/**
@@ -61,7 +61,7 @@ typedef enum {
* @length: The requested length of the transfer in bytes.
* @actual_length: The actual length of the transfer
* (see also fpi_usb_transfer_set_short_error())
* @buffer: The transfered data.
* @buffer: The transferred data.
*
* Helper for handling USB transfers.
*/

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -31,6 +31,7 @@ libfprint_private_headers = [
'fpi-byte-reader.h',
'fpi-byte-utils.h',
'fpi-byte-writer.h',
'fpi-compat.h',
'fpi-context.h',
'fpi-device.h',
'fpi-image-device.h',
@@ -160,6 +161,12 @@ foreach driver: drivers
'drivers/synaptics/bmkt_message.c',
]
endif
if driver == 'goodixmoc'
drivers_sources += [
'drivers/goodixmoc/goodix.c',
'drivers/goodixmoc/goodix_proto.c',
]
endif
endforeach
if aeslib
@@ -203,6 +210,7 @@ deps = [
enums_dep,
gio_dep,
glib_dep,
gobject_dep,
gusb_dep,
imaging_dep,
mathlib_dep,
@@ -258,7 +266,7 @@ libfprint = library(versioned_libname.split('lib')[1],
version: libversion,
link_args : vflag,
link_depends : mapfile,
link_with: [libfprint_private, libfprint_drivers],
link_with: [libfprint_drivers, libfprint_private],
dependencies: deps,
install: true)
@@ -268,6 +276,7 @@ libfprint_dep = declare_dependency(link_with: libfprint,
enums_dep,
gio_dep,
glib_dep,
gobject_dep,
gusb_dep,
])
@@ -324,6 +333,7 @@ if get_option('introspection')
link_with : libfprint,
dependencies : [
gio_dep,
gobject_dep,
gusb_dep,
],
includes : [

View File

@@ -0,0 +1,57 @@
diff --git a/libfprint/nbis/mindtct/contour.c b/libfprint/nbis/mindtct/contour.c
index 3e9416c..31f32d0 100644
--- mindtct/contour.c
+++ mindtct/contour.c
@@ -440,6 +440,8 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
int i, j, ret;
+ g_assert (half_contour > 0);
+
/* Compute maximum length of complete contour */
/* (2 half contours + feature point). */
max_contour = (half_contour<<1) + 1;
diff --git a/libfprint/nbis/mindtct/minutia.c b/libfprint/nbis/mindtct/minutia.c
index 0b29aa0..77cf09d 100644
--- mindtct/minutia.c
+++ mindtct/minutia.c
@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
dmapval, bdata, iw, ih, lfsparms);
/* If minuitia IGNORED and not added to the minutia list ... */
- if(ret == IGNORE)
+ if(ret != 0)
/* Deallocate the minutia. */
free_minutia(minutia);
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
dmapval, bdata, iw, ih, lfsparms);
/* If minuitia IGNORED and not added to the minutia list ... */
- if(ret == IGNORE)
+ if(ret != 0)
/* Deallocate the minutia. */
free_minutia(minutia);
diff --git a/libfprint/nbis/mindtct/ridges.c b/libfprint/nbis/mindtct/ridges.c
index f0d9cd3..9902585 100644
--- mindtct/ridges.c
+++ mindtct/ridges.c
@@ -147,6 +147,8 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
{
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
+ g_assert (lfsparms->max_nbrs > 0);
+
/* Find up to the maximum number of qualifying neighbors. */
nbr_list = NULL;
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
@@ -407,6 +409,8 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
{
int i;
+ g_assert (pos >= 0);
+
/* If the desired insertion position is beyond one passed the last */
/* neighbor in the lists OR greater than equal to the maximum ... */
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */

View File

@@ -260,6 +260,8 @@ typedef struct g_lfsparms{
int pores_steps_bwd;
double pores_min_dist2;
double pores_max_ratio;
int remove_perimeter_pts;
int min_pp_distance;
/* Ridge Counting Controls */
int max_nbrs;
@@ -609,6 +611,9 @@ typedef struct g_lfsparms{
/* contour points to be considered a pore. */
#define PORES_MAX_RATIO 2.25
/* Points which are closer than this distance to scan perimeter will be removed */
#define PERIMETER_PTS_DISTANCE 10
/***** RIDGE COUNTING CONSTANTS *****/
@@ -1123,6 +1128,9 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
unsigned char *, const int, const int,
int *, const int, const int, const LFSPARMS *);
extern int remove_perimeter_pts(MINUTIAE *minutiae,
unsigned char *bdata, const int iw, const int ih,
const LFSPARMS *lfsparms);
/* results.c */
extern int write_text_results(char *, const int, const int, const int,

View File

@@ -440,6 +440,8 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
int i, j, ret;
g_assert (half_contour > 0);
/* Compute maximum length of complete contour */
/* (2 half contours + feature point). */
max_contour = (half_contour<<1) + 1;

View File

@@ -150,6 +150,8 @@ LFSPARMS g_lfsparms = {
PORES_STEPS_BWD,
PORES_MIN_DIST2,
PORES_MAX_RATIO,
FALSE, /* not removing perimeter points by default */
PERIMETER_PTS_DISTANCE,
/* Ridge Counting Controls */
MAX_NBRS,
@@ -234,6 +236,8 @@ LFSPARMS g_lfsparms_V2 = {
PORES_STEPS_BWD,
PORES_MIN_DIST2,
PORES_MAX_RATIO,
FALSE, /* not removing perimeter points by default */
PERIMETER_PTS_DISTANCE,
/* Ridge Counting Controls */
MAX_NBRS,

View File

@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
dmapval, bdata, iw, ih, lfsparms);
/* If minuitia IGNORED and not added to the minutia list ... */
if(ret == IGNORE)
if(ret != 0)
/* Deallocate the minutia. */
free_minutia(minutia);
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
dmapval, bdata, iw, ih, lfsparms);
/* If minuitia IGNORED and not added to the minutia list ... */
if(ret == IGNORE)
if(ret != 0)
/* Deallocate the minutia. */
free_minutia(minutia);

View File

@@ -195,6 +195,11 @@ int remove_false_minutia_V2(MINUTIAE *minutiae,
return(ret);
}
/* 11. Remove minutiae on image edge */
if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) {
return (ret);
}
return(0);
}
@@ -1329,6 +1334,159 @@ int remove_pointing_invblock_V2(MINUTIAE *minutiae,
return(0);
}
static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y,
const LFSPARMS *lfsparms)
{
int i, dist;
for (i = 0; i < minutiae->num; i++) {
if (to_remove[i])
continue;
dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) +
(y - minutiae->list[i]->y) * (y - minutiae->list[i]->y));
if (dist < lfsparms->min_pp_distance) {
to_remove[i] = 1;
}
}
}
/*************************************************************************
**************************************************************************
#cat: remove_perimeter_pts - Takes a list of true and false minutiae and
#cat: attempts to detect and remove those false minutiae that
#cat: belong to image edge
Input:
minutiae - list of true and false minutiae
bdata - binary image data (0==while & 1==black)
iw - width (in pixels) of image
ih - height (in pixels) of image
lfsparms - parameters and thresholds for controlling LFS
Output:
minutiae - list of pruned minutiae
Return Code:
Zero - successful completion
Negative - system error
**************************************************************************/
int remove_perimeter_pts(MINUTIAE *minutiae,
unsigned char *bdata, const int iw, const int ih,
const LFSPARMS *lfsparms)
{
int i, j, ret, *to_remove;
int *left, *left_up, *left_down;
int *right, *right_up, *right_down;
int removed = 0;
int left_min, right_max;
if (!lfsparms->remove_perimeter_pts)
return(0);
to_remove = calloc(minutiae->num, sizeof(int));
left = calloc(ih, sizeof(int));
left_up = calloc(ih, sizeof(int));
left_down = calloc(ih, sizeof(int));
right = calloc(ih, sizeof(int));
right_up = calloc(ih, sizeof(int));
right_down = calloc(ih, sizeof(int));
/* Pass downwards */
left_min = iw - 1;
right_max = 0;
for (i = 0; i < ih; i++) {
for (j = 0; j < left_min; j++) {
if ((bdata[i * iw + j] != 0)) {
left_min = j;
break;
}
}
if (left_min == (iw - 1))
left_down[i] = -1;
else
left_down[i] = left_min;
for (j = iw - 1; j >= right_max; j--) {
if ((bdata[i * iw + j] != 0)) {
right_max = j;
break;
}
}
if (right_max == 0)
right_down[i] = -1;
else
right_down[i] = right_max;
}
/* Pass upwards */
left_min = iw - 1;
right_max = 0;
for (i = ih - 1; i >= 0; i--) {
for (j = 0; j < left_min; j++) {
if ((bdata[i * iw + j] != 0)) {
left_min = j;
break;
}
}
if (left_min == (iw - 1))
left_up[i] = -1;
else
left_up[i] = left_min;
for (j = iw - 1; j >= right_max; j--) {
if ((bdata[i * iw + j] != 0)) {
right_max = j;
break;
}
}
if (right_max == 0)
right_up[i] = -1;
else
right_up[i] = right_max;
}
/* Merge */
left_min = left_down[ih - 1];
right_max = right_down[ih - 1];
for (i = 0; i < ih; i++) {
if (left_down[i] != left_min)
left[i] = left_down[i];
else
left[i] = left_up[i];
if (right_down[i] != right_max)
right[i] = right_down[i];
else
right[i] = right_up[i];
}
free(left_up);
free(left_down);
free(right_up);
free(right_down);
/* Mark minitiae close to the edge */
for (i = 0; i < ih; i++) {
if (left[i] != -1)
mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms);
if (right[i] != -1)
mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms);
}
free(left);
free(right);
for (i = minutiae->num - 1; i >= 0; i--) {
/* If the current minutia index is flagged for removal ... */
if (to_remove[i]){
removed ++;
/* Remove the minutia from the minutiae list. */
if((ret = remove_minutia(i, minutiae))){
free(to_remove);
return(ret);
}
}
}
free(to_remove);
return (0);
}
/*************************************************************************
**************************************************************************
#cat: remove_overlaps - Takes a list of true and false minutiae and

View File

@@ -147,6 +147,8 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
{
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
g_assert (lfsparms->max_nbrs > 0);
/* Find up to the maximum number of qualifying neighbors. */
nbr_list = NULL;
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
@@ -407,6 +409,8 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
{
int i;
g_assert (pos >= 0);
/* If the desired insertion position is beyond one passed the last */
/* neighbor in the lists OR greater than equal to the maximum ... */
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */

View File

@@ -0,0 +1,231 @@
diff --git nbis/include/lfs.h nbis/include/lfs.h
index f4f38d7..8b12e73 100644
--- nbis/include/lfs.h
+++ nbis/include/lfs.h
@@ -260,6 +260,8 @@ typedef struct g_lfsparms{
int pores_steps_bwd;
double pores_min_dist2;
double pores_max_ratio;
+ int remove_perimeter_pts;
+ int min_pp_distance;
/* Ridge Counting Controls */
int max_nbrs;
@@ -609,6 +611,9 @@ typedef struct g_lfsparms{
/* contour points to be considered a pore. */
#define PORES_MAX_RATIO 2.25
+/* Points which are closer than this distance to scan perimeter will be removed */
+#define PERIMETER_PTS_DISTANCE 10
+
/***** RIDGE COUNTING CONSTANTS *****/
@@ -1123,6 +1128,9 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
unsigned char *, const int, const int,
int *, const int, const int, const LFSPARMS *);
+extern int remove_perimeter_pts(MINUTIAE *minutiae,
+ unsigned char *bdata, const int iw, const int ih,
+ const LFSPARMS *lfsparms);
/* results.c */
extern int write_text_results(char *, const int, const int, const int,
diff --git nbis/mindtct/globals.c nbis/mindtct/globals.c
index da10c15..79bc583 100644
--- nbis/mindtct/globals.c
+++ nbis/mindtct/globals.c
@@ -150,6 +150,8 @@ LFSPARMS g_lfsparms = {
PORES_STEPS_BWD,
PORES_MIN_DIST2,
PORES_MAX_RATIO,
+ FALSE, /* not removing perimeter points by default */
+ PERIMETER_PTS_DISTANCE,
/* Ridge Counting Controls */
MAX_NBRS,
@@ -234,6 +236,8 @@ LFSPARMS g_lfsparms_V2 = {
PORES_STEPS_BWD,
PORES_MIN_DIST2,
PORES_MAX_RATIO,
+ FALSE, /* not removing perimeter points by default */
+ PERIMETER_PTS_DISTANCE,
/* Ridge Counting Controls */
MAX_NBRS,
diff --git nbis/mindtct/remove.c nbis/mindtct/remove.c
index af5ab7d..7311f1c 100644
--- nbis/mindtct/remove.c
+++ nbis/mindtct/remove.c
@@ -195,6 +195,11 @@ int remove_false_minutia_V2(MINUTIAE *minutiae,
return(ret);
}
+ /* 11. Remove minutiae on image edge */
+ if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) {
+ return (ret);
+ }
+
return(0);
}
@@ -1329,6 +1334,159 @@ int remove_pointing_invblock_V2(MINUTIAE *minutiae,
return(0);
}
+static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y,
+ const LFSPARMS *lfsparms)
+{
+ int i, dist;
+ for (i = 0; i < minutiae->num; i++) {
+ if (to_remove[i])
+ continue;
+ dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) +
+ (y - minutiae->list[i]->y) * (y - minutiae->list[i]->y));
+ if (dist < lfsparms->min_pp_distance) {
+ to_remove[i] = 1;
+ }
+ }
+}
+
+/*************************************************************************
+**************************************************************************
+#cat: remove_perimeter_pts - Takes a list of true and false minutiae and
+#cat: attempts to detect and remove those false minutiae that
+#cat: belong to image edge
+
+ Input:
+ minutiae - list of true and false minutiae
+ bdata - binary image data (0==while & 1==black)
+ iw - width (in pixels) of image
+ ih - height (in pixels) of image
+ lfsparms - parameters and thresholds for controlling LFS
+ Output:
+ minutiae - list of pruned minutiae
+ Return Code:
+ Zero - successful completion
+ Negative - system error
+**************************************************************************/
+int remove_perimeter_pts(MINUTIAE *minutiae,
+ unsigned char *bdata, const int iw, const int ih,
+ const LFSPARMS *lfsparms)
+{
+ int i, j, ret, *to_remove;
+ int *left, *left_up, *left_down;
+ int *right, *right_up, *right_down;
+ int removed = 0;
+ int left_min, right_max;
+
+ if (!lfsparms->remove_perimeter_pts)
+ return(0);
+
+ to_remove = calloc(minutiae->num, sizeof(int));
+ left = calloc(ih, sizeof(int));
+ left_up = calloc(ih, sizeof(int));
+ left_down = calloc(ih, sizeof(int));
+ right = calloc(ih, sizeof(int));
+ right_up = calloc(ih, sizeof(int));
+ right_down = calloc(ih, sizeof(int));
+
+ /* Pass downwards */
+ left_min = iw - 1;
+ right_max = 0;
+ for (i = 0; i < ih; i++) {
+ for (j = 0; j < left_min; j++) {
+ if ((bdata[i * iw + j] != 0)) {
+ left_min = j;
+ break;
+ }
+ }
+ if (left_min == (iw - 1))
+ left_down[i] = -1;
+ else
+ left_down[i] = left_min;
+ for (j = iw - 1; j >= right_max; j--) {
+ if ((bdata[i * iw + j] != 0)) {
+ right_max = j;
+ break;
+ }
+ }
+ if (right_max == 0)
+ right_down[i] = -1;
+ else
+ right_down[i] = right_max;
+ }
+
+ /* Pass upwards */
+ left_min = iw - 1;
+ right_max = 0;
+ for (i = ih - 1; i >= 0; i--) {
+ for (j = 0; j < left_min; j++) {
+ if ((bdata[i * iw + j] != 0)) {
+ left_min = j;
+ break;
+ }
+ }
+ if (left_min == (iw - 1))
+ left_up[i] = -1;
+ else
+ left_up[i] = left_min;
+ for (j = iw - 1; j >= right_max; j--) {
+ if ((bdata[i * iw + j] != 0)) {
+ right_max = j;
+ break;
+ }
+ }
+ if (right_max == 0)
+ right_up[i] = -1;
+ else
+ right_up[i] = right_max;
+ }
+
+ /* Merge */
+ left_min = left_down[ih - 1];
+ right_max = right_down[ih - 1];
+ for (i = 0; i < ih; i++) {
+ if (left_down[i] != left_min)
+ left[i] = left_down[i];
+ else
+ left[i] = left_up[i];
+
+ if (right_down[i] != right_max)
+ right[i] = right_down[i];
+ else
+ right[i] = right_up[i];
+ }
+ free(left_up);
+ free(left_down);
+ free(right_up);
+ free(right_down);
+
+ /* Mark minitiae close to the edge */
+ for (i = 0; i < ih; i++) {
+ if (left[i] != -1)
+ mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms);
+ if (right[i] != -1)
+ mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms);
+ }
+
+ free(left);
+ free(right);
+
+ for (i = minutiae->num - 1; i >= 0; i--) {
+ /* If the current minutia index is flagged for removal ... */
+ if (to_remove[i]){
+ removed ++;
+ /* Remove the minutia from the minutiae list. */
+ if((ret = remove_minutia(i, minutiae))){
+ free(to_remove);
+ return(ret);
+ }
+ }
+ }
+
+ free(to_remove);
+
+ return (0);
+}
+
/*************************************************************************
**************************************************************************
#cat: remove_overlaps - Takes a list of true and false minutiae and

View File

@@ -192,3 +192,9 @@ spatch --sp-file remove-global-y.cocci bozorth3/* include/bozorth.h --in-place
# The above leaves an unused variable around, triggering a warning
# remove it.
patch -p0 < glib-mem-warning.patch
# Also fix some scan-build warnings, mostly by adding assertions
patch -p0 < fix-scan-build-reports.patch
# Add pass to remove perimeter points
patch -p0 < remove-perimeter-pts.patch

View File

@@ -1,5 +1,5 @@
project('libfprint', [ 'c', 'cpp' ],
version: '1.90.1',
version: '1.90.3',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',
@@ -79,6 +79,7 @@ versioned_libname = meson.project_name() + '-' + soversion.to_string()
# Dependencies
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
gusb_dep = dependency('gusb', version: '>= 0.2.0')
mathlib_dep = cc.find_library('m', required: false)
@@ -109,6 +110,7 @@ default_drivers = [
'upektc',
'upeksonly',
'upekts',
'goodixmoc',
]
all_drivers = default_drivers + virtual_drivers
@@ -210,6 +212,7 @@ pkgconfig.generate(
description: 'Generic C API for fingerprint reader access',
version: meson.project_version(),
libraries: libfprint,
requires: [gio_dep, gobject_dep],
subdirs: versioned_libname,
filebase: versioned_libname,
)

94
tests/README.md Normal file
View File

@@ -0,0 +1,94 @@
`umockdev` Tests
================
`umockdev` tests use fingerprint devices mocked by [`umockdev`
toolchain][umockdev].
This document describes how to create a 'capture' test: a test that
captures a picture of a fingerprint from the device (mocked by
`umockdev`) and compares it with the standard one.
Other kinds of `umockdev` tests could be created in a similar manner.
'Capture' Test Creation
-----------------------
A new 'capture' test is created by means of `capture.py` script:
1. Create (if needed) a directory for the driver under `tests`
directory:
`mkdir DRIVER`
2. Prepare your execution environment.
In the next step a working and up to date libfprint is needed. This can be
achieved by installing it into your system. Alternatively, you can set
the following environment variables to run a local build:
- `export LD_PRELOAD=<meson-build-dir>/libfprint/libfprint-2.so`
- `export GI_TYPELIB_PATH=<meson-build-dir>/libfprint`
Also, sometimes the driver must be adopted to the emulated environment
(mainly if it uses random numbers, see `synaptics.c` for an example).
Set the following environment variable to enable this adaptation:
- `export FP_DEVICE_EMULATION=1`
Run the next steps in the same terminal.
3. Find the real USB fingerprint device with `lsusb`, e.g.:
`Bus 001 Device 005: ID 138a:0090 Validity Sensors, Inc. VFS7500 Touch Fingerprint Sensor`
The following USB device is used in the example above:
`/dev/bus/usb/001/005`.
4. Record information about this device:
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`
5. Record interaction of `capture.py` (or other test) with the device:
`umockdev-record -i /dev/bus/usb/001/005=DRIVER/capture.ioctl -- python3 ./capture.py DRIVER/capture.png`
Files `capture.ioctl` and `capture.png` will be created as the
result of this command.
6. Add driver's name to `drivers_tests` in the `meson.build`.
7. Check whether everything works as expected.
**Note.** To avoid submitting a real fingerprint, the side of finger,
arm, or anything else producing an image with the device can be used.
Possible Issues
---------------
`umockdev-record` aggressively groups URBs. In most cases, manual
intervention is unfortunately required. Often, drivers do a chain of
commands like: A then B each with a different reply. However,
`umockdev-record` could create a file like this:
A
reply 1
reply 2
B
reply 1
reply 2
In that case, records must be re-ordered:
A
reply 1
B
reply 1
A
reply 2
B
reply 2
Other changes may be needed to get everything working. For example the
`elan` driver relies on a timeout that is not reported correctly. In
this case the driver works around it by interpreting the protocol
error differently in the virtual environment (by means of
`FP_DEVICE_EMULATION` environment variable).
[umockdev]: https://github.com/martinpitt/umockdev

File diff suppressed because one or more lines are too long

BIN
tests/aes3500/capture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

561
tests/aes3500/device Normal file
View File

@@ -0,0 +1,561 @@
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0/0000:39:00.0/usb3/3-1/3-1.1/3-1.1.3
N: bus/usb/003/004=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
E: BUSNUM=003
E: DEVNAME=/dev/bus/usb/003/004
E: DEVNUM=004
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_MODEL=Fingerprint_Sensor
E: ID_MODEL_ENC=Fingerprint\x20Sensor
E: ID_MODEL_FROM_DATABASE=AES3500 TruePrint Sensor
E: ID_MODEL_ID=5731
E: ID_REVISION=0000
E: ID_SERIAL=08ff_Fingerprint_Sensor
E: ID_USB_INTERFACES=:ffffff:
E: ID_VENDOR=08ff
E: ID_VENDOR_ENC=08ff
E: ID_VENDOR_FROM_DATABASE=AuthenTec, Inc.
E: ID_VENDOR_ID=08ff
E: LIBFPRINT_DRIVER=AuthenTec AES3500
E: MAJOR=189
E: MINOR=259
E: PRODUCT=8ff/5731/0
E: SUBSYSTEM=usb
E: TYPE=255/255/255
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=ff
A: bDeviceProtocol=ff
A: bDeviceSubClass=ff
A: bMaxPacketSize0=8
A: bMaxPower=100mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0000
A: bmAttributes=80
A: busnum=3
A: configuration=
H: descriptors=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
A: dev=189:259
A: devnum=4
A: devpath=1.1.3
L: driver=../../../../../../../../../../bus/usb/drivers/usb
A: idProduct=5731
A: idVendor=08ff
A: ltm_capable=no
A: maxchild=0
L: port=../3-1.1:1.0/3-1.1-port3
A: power/active_duration=3601332
A: power/async=enabled
A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000
A: power/connected_duration=3601332
A: power/control=auto
A: power/level=auto
A: power/persist=1
A: power/runtime_active_kids=0
A: power/runtime_active_time=3601128
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=0
A: product=Fingerprint Sensor
A: quirks=0x0
A: removable=removable
A: speed=12
A: urbnum=82
A: version= 1.10
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0/0000:39:00.0/usb3/3-1/3-1.1
N: bus/usb/003/003=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
E: BUSNUM=003
E: DEVNAME=/dev/bus/usb/003/003
E: DEVNUM=003
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_39_00_0-usb-0_1_1
E: ID_MODEL=USB2.0_Hub
E: ID_MODEL_ENC=USB2.0\x20Hub\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_MODEL_ID=0006
E: ID_PATH=pci-0000:39:00.0-usb-0:1.1
E: ID_PATH_TAG=pci-0000_39_00_0-usb-0_1_1
E: ID_REVISION=9100
E: ID_SERIAL=VIA_Labs__Inc._USB2.0_Hub
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR=VIA_Labs__Inc.
E: ID_VENDOR_ENC=VIA\x20Labs\x2c\x20Inc.\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_VENDOR_ID=2230
E: MAJOR=189
E: MINOR=258
E: PRODUCT=2230/6/9100
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=9/0/1
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=9100
A: bmAttributes=e0
A: busnum=3
A: configuration=
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
A: dev=189:258
A: devnum=3
A: devpath=1.1
L: driver=../../../../../../../../../bus/usb/drivers/usb
A: idProduct=0006
A: idVendor=2230
A: ltm_capable=no
A: manufacturer=VIA Labs, Inc.
A: maxchild=4
L: port=../3-1:1.0/3-1-port1
A: power/active_duration=3601776
A: power/async=enabled
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=3601776
A: power/control=auto
A: power/level=auto
A: power/runtime_active_kids=2
A: power/runtime_active_time=3601572
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=USB2.0 Hub
A: quirks=0x0
A: removable=fixed
A: speed=480
A: urbnum=40
A: version= 2.10
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0/0000:39:00.0/usb3/3-1
N: bus/usb/003/002=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
E: BUSNUM=003
E: DEVNAME=/dev/bus/usb/003/002
E: DEVNUM=002
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_39_00_0-usb-0_1
E: ID_MODEL=USB2.0_Hub
E: ID_MODEL_ENC=USB2.0\x20Hub\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_MODEL_ID=0006
E: ID_PATH=pci-0000:39:00.0-usb-0:1
E: ID_PATH_TAG=pci-0000_39_00_0-usb-0_1
E: ID_REVISION=9100
E: ID_SERIAL=VIA_Labs__Inc._USB2.0_Hub
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR=VIA_Labs__Inc.
E: ID_VENDOR_ENC=VIA\x20Labs\x2c\x20Inc.\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_VENDOR_ID=2230
E: MAJOR=189
E: MINOR=257
E: PRODUCT=2230/6/9100
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=9/0/1
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=9100
A: bmAttributes=e0
A: busnum=3
A: configuration=
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
A: dev=189:257
A: devnum=2
A: devpath=1
L: driver=../../../../../../../../bus/usb/drivers/usb
A: idProduct=0006
A: idVendor=2230
A: ltm_capable=no
A: manufacturer=VIA Labs, Inc.
A: maxchild=4
L: port=../3-0:1.0/usb3-port1
A: power/active_duration=3602292
A: power/async=enabled
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=3602292
A: power/control=auto
A: power/level=auto
A: power/runtime_active_kids=1
A: power/runtime_active_time=3602016
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=USB2.0 Hub
A: quirks=0x0
A: removable=removable
A: speed=480
A: urbnum=31
A: version= 2.10
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0/0000:39:00.0/usb3
N: bus/usb/003/001=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
E: BUSNUM=003
E: DEVNAME=/dev/bus/usb/003/001
E: DEVNUM=001
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_39_00_0
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_MODEL_ID=0002
E: ID_PATH=pci-0000:39:00.0
E: ID_PATH_TAG=pci-0000_39_00_0
E: ID_REVISION=0415
E: ID_SERIAL=Linux_4.15.0-117-generic_xhci-hcd_xHCI_Host_Controller_0000:39:00.0
E: ID_SERIAL_SHORT=0000:39:00.0
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR=Linux_4.15.0-117-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x204.15.0-117-generic\x20xhci-hcd
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_VENDOR_ID=1d6b
E: MAJOR=189
E: MINOR=256
E: PRODUCT=1d6b/2/415
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=9/0/1
A: authorized=1
A: authorized_default=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0415
A: bmAttributes=e0
A: busnum=3
A: configuration=
H: descriptors=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
A: dev=189:256
A: devnum=1
A: devpath=0
L: driver=../../../../../../../bus/usb/drivers/usb
A: idProduct=0002
A: idVendor=1d6b
A: interface_authorized_default=1
A: ltm_capable=no
A: manufacturer=Linux 4.15.0-117-generic xhci-hcd
A: maxchild=2
A: power/active_duration=3602700
A: power/async=enabled
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=3602700
A: power/control=auto
A: power/level=auto
A: power/runtime_active_kids=1
A: power/runtime_active_time=3602700
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=xHCI Host Controller
A: quirks=0x0
A: removable=unknown
A: serial=0000:39:00.0
A: speed=480
A: urbnum=24
A: version= 2.00
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0/0000:39:00.0
E: DRIVER=xhci_hcd
E: ID_MODEL_FROM_DATABASE=DSL6340 USB 3.1 Controller [Alpine Ridge]
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d000015B5sv00002222sd00001111bc0Csc03i30
E: PCI_CLASS=C0330
E: PCI_ID=8086:15B5
E: PCI_SLOT_NAME=0000:39:00.0
E: PCI_SUBSYS_ID=2222:1111
E: SUBSYSTEM=pci
A: broken_parity_status=0
A: class=0x0c0330
H: config=8680B515060410000030030C200000000000F0D9000000000000000000000000000000000000000000000000222211110000000080000000000000000B010000
A: consistent_dma_mask_bits=64
A: current_link_speed=2.5 GT/s
A: current_link_width=4
A: d3cold_allowed=1
A: dbc=disabled
A: device=0x15b5
A: dma_mask_bits=64
L: driver=../../../../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)
A: enable=1
L: iommu=../../../../../virtual/iommu/dmar1
L: iommu_group=../../../../../../kernel/iommu_groups/17
A: irq=141
A: local_cpulist=0-3
A: local_cpus=f
A: max_link_speed=2.5 GT/s
A: max_link_width=4
A: modalias=pci:v00008086d000015B5sv00002222sd00001111bc0Csc03i30
A: msi_bus=1
A: msi_irqs/141=msi
A: numa_node=-1
A: pools=poolinfo - 0.1\nbuffer-2048 3 6 2048 3\nbuffer-512 12 16 512 2\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 15 15 2112 15\nxHCI ring segments 44 46 4096 46\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 3 32 128 1\nbuffer-32 0 0 32 0
A: power/async=enabled
A: power/control=on
A: power/runtime_active_kids=2
A: power/runtime_active_time=3602712
A: power/runtime_enabled=forbidden
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=1
A: power/wakeup=enabled
A: power/wakeup_abort_count=0
A: power/wakeup_active=0
A: power/wakeup_active_count=0
A: power/wakeup_count=0
A: power/wakeup_expire_count=0
A: power/wakeup_last_time_ms=224549241
A: power/wakeup_max_time_ms=0
A: power/wakeup_total_time_ms=0
A: resource=0x00000000d9f00000 0x00000000d9f0ffff 0x0000000000040200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0x00
A: subsystem_device=0x1111
A: subsystem_vendor=0x2222
A: vendor=0x8086
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/0000:02:02.0
E: DRIVER=pcieport
E: ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 Bridge [Alpine Ridge 2C 2015]
E: ID_PCI_CLASS_FROM_DATABASE=Bridge
E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode
E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d00001576sv00002222sd00001111bc06sc04i00
E: PCI_CLASS=60400
E: PCI_ID=8086:1576
E: PCI_SLOT_NAME=0000:02:02.0
E: PCI_SUBSYS_ID=2222:1111
E: SUBSYSTEM=pci
A: broken_parity_status=0
A: class=0x060400
H: config=86807615060410000000040620000100000000000000000002393900F1010000F0D9F0D9F1FF010000000000000000000000000080000000000000000B011000
A: consistent_dma_mask_bits=32
A: current_link_speed=2.5 GT/s
A: current_link_width=4
A: d3cold_allowed=1
A: device=0x1576
A: dma_mask_bits=32
L: driver=../../../../../bus/pci/drivers/pcieport
A: driver_override=(null)
A: enable=1
L: iommu=../../../../virtual/iommu/dmar1
L: iommu_group=../../../../../kernel/iommu_groups/17
A: irq=140
A: local_cpulist=0-3
A: local_cpus=f
A: max_link_speed=2.5 GT/s
A: max_link_width=4
A: modalias=pci:v00008086d00001576sv00002222sd00001111bc06sc04i00
A: msi_bus=1
A: msi_irqs/140=msi
A: numa_node=-1
A: power/async=enabled
A: power/clk_ctl=0
A: power/control=on
A: power/link_state=0
A: power/runtime_active_kids=1
A: power/runtime_active_time=3602728
A: power/runtime_enabled=forbidden
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=2
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: resource=0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x00000000d9f00000 0x00000000d9ffffff 0x0000000000000200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0x00
A: secondary_bus_number=57
A: subordinate_bus_number=57
A: subsystem_device=0x1111
A: subsystem_vendor=0x2222
A: vendor=0x8086
P: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0
E: DRIVER=pcieport
E: ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 Bridge [Alpine Ridge 2C 2015]
E: ID_PCI_CLASS_FROM_DATABASE=Bridge
E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode
E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d00001576sv00002222sd00001111bc06sc04i00
E: PCI_CLASS=60400
E: PCI_ID=8086:1576
E: PCI_SLOT_NAME=0000:01:00.0
E: PCI_SUBSYS_ID=2222:1111
E: SUBSYSTEM=pci
A: broken_parity_status=0
A: class=0x060400
H: config=86807615060410000000040620000100000000000000000001023900F101000000C400DA01A0F1C100000000000000000000000080000000000000000B011000
A: consistent_dma_mask_bits=32
A: current_link_speed=8 GT/s
A: current_link_width=2
A: d3cold_allowed=1
A: device=0x1576
A: dma_mask_bits=32
L: driver=../../../../bus/pci/drivers/pcieport
A: driver_override=(null)
A: enable=1
L: iommu=../../../virtual/iommu/dmar1
L: iommu_group=../../../../kernel/iommu_groups/14
A: irq=137
A: local_cpulist=0-3
A: local_cpus=f
A: max_link_speed=8 GT/s
A: max_link_width=4
A: modalias=pci:v00008086d00001576sv00002222sd00001111bc06sc04i00
A: msi_bus=1
A: msi_irqs/137=msi
A: numa_node=-1
A: power/async=enabled
A: power/control=on
A: power/runtime_active_kids=2
A: power/runtime_active_time=3602740
A: power/runtime_enabled=forbidden
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=2
A: power/wakeup=enabled
A: power/wakeup_abort_count=0
A: power/wakeup_active=0
A: power/wakeup_active_count=0
A: power/wakeup_count=0
A: power/wakeup_expire_count=0
A: power/wakeup_last_time_ms=224549237
A: power/wakeup_max_time_ms=0
A: power/wakeup_total_time_ms=0
A: resource=0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x00000000c4000000 0x00000000da0fffff 0x0000000000000200\n0x00000000a0000000 0x00000000c1ffffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0x00
A: secondary_bus_number=2
A: subordinate_bus_number=57
A: subsystem_device=0x1111
A: subsystem_vendor=0x2222
A: vendor=0x8086
P: /devices/pci0000:00/0000:00:1c.0
E: DRIVER=pcieport
E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port
E: ID_PCI_CLASS_FROM_DATABASE=Bridge
E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode
E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d00009D10sv00001028sd0000075Bbc06sc04i00
E: PCI_CLASS=60400
E: PCI_ID=8086:9D10
E: PCI_SLOT_NAME=0000:00:1c.0
E: PCI_SUBSYS_ID=1028:075B
E: SUBSYSTEM=pci
A: broken_parity_status=0
A: class=0x060400
H: config=8680109D07041000F1000406000081000000000000000000000139002020002000C400DA01A0F1C100000000000000000000000040000000000000000B011000
A: consistent_dma_mask_bits=32
A: current_link_speed=8 GT/s
A: current_link_width=2
A: d3cold_allowed=1
A: device=0x9d10
A: dma_mask_bits=32
L: driver=../../../bus/pci/drivers/pcieport
A: driver_override=(null)
A: enable=1
L: iommu=../../virtual/iommu/dmar1
L: iommu_group=../../../kernel/iommu_groups/6
A: irq=123
A: local_cpulist=0-3
A: local_cpus=f
A: max_link_speed=8 GT/s
A: max_link_width=2
A: modalias=pci:v00008086d00009D10sv00001028sd0000075Bbc06sc04i00
A: msi_bus=1
A: msi_irqs/123=msi
A: numa_node=-1
A: power/async=enabled
A: power/control=on
A: power/runtime_active_kids=1
A: power/runtime_active_time=228151860
A: power/runtime_enabled=forbidden
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/runtime_usage=2
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: resource=0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000002000 0x0000000000002fff 0x0000000000000100\n0x00000000c4000000 0x00000000da0fffff 0x0000000000000200\n0x00000000a0000000 0x00000000c1ffffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0xf1
A: secondary_bus_number=1
A: subordinate_bus_number=57
A: subsystem_device=0x075b
A: subsystem_vendor=0x1028
A: vendor=0x8086

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,307 @@
@DEV /dev/bus/usb/001/003
USBDEVFS_GET_CAPABILITIES 0 FD010000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 D00000000500BA4500611A297F
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000008009D6200D00001B5A57582000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980001FE415050000000000030313030303232384C454E4F564F0000474D3138384230004746333230360000312E30322E30310055534200000000005642530000000000303030303030303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051239DE6303030303033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F410C0A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F3EB36C6A
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000208004BB400C00101C96A6C6B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030500FB040093B3ED01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000002050049B600C27E4B39
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000004080036C900A60001F1AFC9FB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000050600609F000094D6C40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000030700AC53000F411A349263
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000060800E01F00A20001605AE410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A2000007070007F8005564FA6B157100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000042400F40B000000000000000000000000000000000000000000000000000000000000000095D4A28A
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000080800CC3300A500013F9036A9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A50000090500DE2103D6515435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A10000050500807F007BE269C4
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000A08001AE500A10001AE651B42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000B250002FD00B786B17D6A044D24C1651C2B1A76F6396D790639F58CA6D62DDDB8E179A9BD4A6C5C6C9200000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000607006C93000F41A33C2AB4
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000C0800679800A200011C98B985000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000D0700807F0059643EDA283F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000007070055AA016450891085EC
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000E0800B14E00A000013F11196A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000000F070004FB000000E0109A2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200080500629D004A354747
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001008003FC000B002017532670A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200114500A15E008E0091009E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000988D37C39E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000907002BD4000F41D2CA1A81
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000120800E91600A20001A47AD7CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001307000EF1004B640F46BD2D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000A0700C43B016450398D1A9E
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000140800946B00A0000121EDB70D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000015070021DE0000007BC22C5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000B0500DF200052FA3E5D
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000016080042BD00B002019E7183CF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200174500DC23008200A200AA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000F1B14CECAA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000C0700EB14000F416BC2A256
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001808006E9100A20001D8B88A5E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001907008976005664DBD4593000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000D0700D22D01645041EE0D0E
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001A0800B84700A00001FB312AB1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001B07000DF2000000CA0273AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000E05001FE000EF2AA657
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001C0800C53A00B00201E2B3DE5A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001D45005BA400A8009100AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C000000000000000000000000008A57E0B3AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000F070056A9000F416A9F62DF
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001E080013EC00A2000133FB6E9B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001F0700F40B005A625A6BF72B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000100700E11E016450A25FACED
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000200800DE2100A000011D15EAC2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002107006B94002900A6F807F200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200110500FA0500438F0629
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000022080008F700B00201A289DE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200234500966900870088008800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D0000000000000000000000000074CA825A8800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000120700659A000F41892EC33C
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000240800758A00A20001D5DFAEE8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000250700926D00556427B73E5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001307005CA3016450A3026C64
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000260800A35C00A00001F6560E07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000027070016E90058265460564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001405003AC500FE5F9E23
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002808008F7000B00201DE4B8395000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020029450011EE007B00950097006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D000000000000000000000000007AB44F7697006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000150700738C000F41F14DD4AC
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002A080059A600A200010F033354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002B0700BE4100566455244C8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001607009C630164501A0AD4B3
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002C080024DB00A000018A945392000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002D0700916E005F2DD3D14D7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200170500877800E690E739
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002E0800F20D00B0020135086750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002F45006C9300A80083008A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000DD3369188A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000180700E21D000F4141D04BDE
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003008007C8300A2000111FF9D33000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003107009B6400586440DB796400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000190700DB240164506BFCE486
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000320800AA5500A0000132763DDC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003307001FE072635FE0E8A18200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001A050016E900A4EAF211
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000340800D72800B002012BF4C937000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020035450049B6007D00920094008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000000000000000000000520A47F394008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001B07005FA0000F41408D8B57
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000036080001FE00A20001FABC79F6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000370700E619005964B9BF1A2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001C07001BE4016450D2F45C51
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003808002DD200A000014EB46049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003907009867725F526A136B6D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001D050000FF0009B0C408
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003A0800FB0400B00201F128548B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003B4500659A0084007D008B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000BAEEF1FA8B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001E07009F60000F41F9853380
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003C0800867900A20001867E2463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003D0700619E005864307089D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001F0700A659016450D3A99CD8
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003E080050AF00A00001A5F7848C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003F0700E51A0063324BE2275A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200200500708F00DCB5EECB
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004008001BE400B00201E7BD49D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200414500857A0078006F0074009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C0000000000000000000000000079DB6FC674009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000021070039C6000F41C7E8B94B
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000420800CD3200A2000136F5F911000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004307002AD5005A647427533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000220700D6290164502CAFB954
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000440800B04F00A00001B36299D7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000045070005FA0061447F5F4C1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200230500CD3200C47A97D1
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000460800669900B002010CFEAD15000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200474500F807009500860087008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C0000000000000000000000000074D7CC3787008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000240700F906000F417EE0019C
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004808004AB500A200014A37A484000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000490700AD52005764F1A7756700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000250700C03F01645054CCAEC4
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004A08009C6300A0000169BE046B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000004B070029D60041281F96933800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002605000DF20079AA0FDB
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004C0800E11E00B00201703CF080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002004D45007F80009E008E008E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000D393E7738E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB000F417FBDC115
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004E080037C800A20001A1744041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0700D02F005964C7DF8EA700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000028070051AE016450E45131B6
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000500800B94600A000017742AA0C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005107000CF300624F1EC75A2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002905004AB5002B5AB4E0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005208006F9000B00201C8DE9ECE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200534500F10E0077007A00720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000000000000000000000C5190965720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002A0700D52A000F41CF205E67
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000054080012ED00A20001BF88EE26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000550700F50A0058641D3C23CD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002B0700EC13016450E50CF13F
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000560800C43B00A000019C014EC9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000570700718E726054F685049700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002C05008A7500968A2CEA
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000580800E81700B00201B41CC35B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005945007689008C007100780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000D98A26F0780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002D0700C33C000F41B74349F7
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005A08003EC100A200016554739A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200005B0700D926005964EDCD672F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002E07002CD30164505C0449E8
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005C080043BC00A00001E0C3135C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005D0700F609725F58291DE42400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002F050037C8008E4555F0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005E0800956A00B002015F5F279E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005F45000BF400A30088009D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C000000000000000000000000001A1438ED9D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000300700F00F000F4154F2E814
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000060080058A700A200018370B3E9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000610700BF400059646AA8553300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000310700C9360164507EDE474C
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006208008E7100A00001A0F91306000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000006307003BC4006432979DA1E700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020032050004FB00326A5B9D
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000640800F30C00B00201B97BE7ED000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002006545006D92008D008F008A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000394AB8458A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200003307004DB2000F4155AF289D
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000066080025DA00A200016833572C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000670700C23D0057645CD0AEF300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000034070009F6016450C7D6FF9B
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000068080009F600A00001DC3B4E93000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000690700BC43002E00509568C700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A3000035070019E6000F41EC883513
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006A0800DF2000A30001C8D82C7D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A300006B05003BC40055C25B16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A40000366A006798640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900B5C8699F
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006C0800A25D00A40001A68D87BD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A400006D0500996600E41BAEE2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A60000370500689700E8D1ECD8
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006E0800748B00A6000185042752000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 A600006F6C0055AA0001640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479006EA4C362000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000380700A15E010023D1112994
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000392400847B000000000000000000000000000000000000000000000000000000000000000038910386
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 a200003a07007788010023107a86d3
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 a500003b240052ad0000000000000000000000000000000000000000000000000000000000000000828af704
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 a700003c6a009b64640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4650312d30303030303030302d302d30303030303030302d6e6f626f647900473c9b29
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000074080051AE00A70001AC924B34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000075050011EE00ACFFDA28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

50
tests/goodixmoc/custom.py Executable file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/python3
import gi
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib
ctx = GLib.main_context_default()
c = FPrint.Context()
c.enumerate()
devices = c.get_devices()
d = devices[0]
del devices
assert d.get_driver() == "goodixmoc"
d.open_sync()
template = FPrint.Print.new(d)
def enroll_progress(*args):
print('enroll progress: ' + str(args))
# List, enroll, list, verify, identify, delete
print("enrolling")
p = d.enroll_sync(template, None, enroll_progress, None)
print("enroll done")
print("listing")
stored = d.list_prints_sync()
print("listing done")
assert len(stored) == 1
assert stored[0].equal(p)
print("verifying")
verify_res, verify_print = d.verify_sync(p)
print("verify done")
assert verify_res == True
print("identifying")
identify_match, identify_print = d.identify_sync(stored)
print("identify done")
assert identify_match.equal(identify_print)
print("deleting")
d.delete_print_sync(p)
print("delete done")
d.close_sync()
del d
del c

171
tests/goodixmoc/device Normal file
View File

@@ -0,0 +1,171 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8
N: bus/usb/001/003=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/001/003
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=27c6/60a2/100
E: TYPE=239/0/0
E: BUSNUM=001
E: DEVNUM=003
E: MAJOR=189
E: MINOR=2
E: SUBSYSTEM=usb
E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
E: ID_VENDOR_ID=27c6
E: ID_MODEL=Goodix_USB2.0_MISC
E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC
E: ID_MODEL_ID=60a2
E: ID_REVISION=0100
E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDCBEE4D7B_XXXX_MOC_B0
E: ID_SERIAL_SHORT=UIDCBEE4D7B_XXXX_MOC_B0
E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
E: ID_PATH=pci-0000:00:14.0-usb-0:8
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8
E: LIBFPRINT_DRIVER=AuthenTec AES1610
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=ef
A: bDeviceProtocol=00
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=100mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0100
A: bmAttributes=a0
A: busnum=1
A: configuration=UIDCBEE4D7B_XXXX_MOC_B0
H: descriptors=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
A: dev=189:2
A: devnum=3
A: devpath=8
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=60a2
A: idVendor=27c6
A: ltm_capable=no
A: manufacturer=Goodix Technology Co., Ltd.
A: maxchild=0
L: port=../1-0:1.0/usb1-port8
A: power/active_duration=324448
A: power/async=enabled
A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000
A: power/connected_duration=5916532
A: power/control=auto
A: power/level=auto
A: power/persist=1
A: power/runtime_active_kids=0
A: power/runtime_active_time=327268
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=5588987
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=Goodix USB2.0 MISC
A: quirks=0x0
A: removable=fixed
A: rx_lanes=1
A: serial=UIDCBEE4D7B_XXXX_MOC_B0
A: speed=12
A: tx_lanes=1
A: urbnum=2180
A: version= 2.00
P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d6b/2/504
E: TYPE=9/0/1
E: BUSNUM=001
E: DEVNUM=001
E: MAJOR=189
E: MINOR=0
E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.4.0-29-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.4.0-29-generic\x20xhci-hcd
E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002
E: ID_REVISION=0504
E: ID_SERIAL=Linux_5.4.0-29-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_PATH=pci-0000:00:14.0
E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: TAGS=:seat:
A: authorized=1
A: authorized_default=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0504
A: bmAttributes=e0
A: busnum=1
A: configuration=
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0
A: devnum=1
A: devpath=0
L: driver=../../../../bus/usb/drivers/usb
A: idProduct=0002
A: idVendor=1d6b
A: interface_authorized_default=1
A: ltm_capable=no
A: manufacturer=Linux 5.4.0-29-generic xhci-hcd
A: maxchild=12
A: power/active_duration=5879432
A: power/async=enabled
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=5916912
A: power/control=auto
A: power/level=auto
A: power/runtime_active_kids=2
A: power/runtime_active_time=5879430
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=37481
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=xHCI Host Controller
A: quirks=0x0
A: removable=unknown
A: rx_lanes=1
A: serial=0000:00:14.0
A: speed=480
A: tx_lanes=1
A: urbnum=1319
A: version= 2.00

View File

@@ -17,9 +17,12 @@ envs.set('FP_DRIVERS_WHITELIST', 'virtual_image')
envs.set('NO_AT_BRIDGE', '1')
drivers_tests = [
'aes3500',
'elan',
'vfs5011',
'synaptics',
'vfs0050',
'vfs5011',
'goodixmoc',
]
if get_option('introspection')

View File

@@ -100,7 +100,10 @@ fpi_device_fake_enroll (FpDevice *device)
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
if (!print && !fake_dev->ret_error)
fpi_device_get_enroll_data (device, &print);
{
fpi_device_get_enroll_data (device, &print);
fpi_print_set_type (print, FPI_PRINT_RAW);
}
fpi_device_enroll_complete (device,
print ? g_object_ref (print) : NULL,
@@ -189,6 +192,7 @@ static void
fpi_device_fake_capture (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean wait_for_finger;
fake_dev->last_called_function = fpi_device_fake_capture;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CAPTURE);
@@ -199,7 +203,8 @@ fpi_device_fake_capture (FpDevice *device)
return;
}
fpi_device_get_capture_data (device, (gboolean *) &fake_dev->action_data);
fpi_device_get_capture_data (device, &wait_for_finger);
fake_dev->action_data = GINT_TO_POINTER (wait_for_finger);
fpi_device_capture_complete (device, fake_dev->ret_image, fake_dev->ret_error);
}
@@ -234,7 +239,7 @@ fpi_device_fake_delete (FpDevice *device)
return;
}
fpi_device_get_delete_data (device, (gpointer) (&fake_dev->action_data));
fpi_device_get_delete_data (device, (FpPrint **) (&fake_dev->action_data));
fpi_device_delete_complete (device, fake_dev->ret_error);
}

View File

@@ -81,6 +81,8 @@ test_frame_assembling (void)
ctx.frame_height = 20;
ctx.image_width = width;
g_assert (height > ctx.frame_height);
offset = 10;
test_height = height - (height - ctx.frame_height) % offset;

View File

@@ -541,6 +541,24 @@ test_driver_enroll_error_no_print (void)
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (out_print);
g_assert_null (fake_dev->ret_print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver did not set the type on the returned print*");
fake_dev->ret_error = NULL;
fake_dev->ret_print = fp_print_new (device); /* Type not set. */
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
(gpointer) (&fake_dev->ret_print));
out_print =
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
g_test_assert_expected_messages ();
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_null (out_print);
g_assert_null (fake_dev->ret_print);
g_clear_error (&error);
}
typedef struct
@@ -635,7 +653,7 @@ test_driver_enroll_progress (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
ExpectedEnrollData expected_enroll_data = {0};
FpiDeviceFake *fake_dev;
@@ -959,7 +977,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
@@ -981,7 +999,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
@@ -1001,7 +1019,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
@@ -1296,7 +1314,7 @@ test_driver_identify_complete_retry (void)
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
@@ -1355,7 +1373,7 @@ test_driver_identify_report_no_callback (void)
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) match = NULL;
g_autoptr(GError) error = NULL;
@@ -1493,6 +1511,7 @@ test_driver_list (void)
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
unsigned int i;
@@ -1515,6 +1534,7 @@ test_driver_list_error (void)
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_autoptr(GPtrArray) prints = NULL;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
@@ -1891,7 +1911,7 @@ test_driver_action_error_all (void)
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
g_autoptr(GError) error = NULL;
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpiDeviceFake *fake_dev;
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->return_action_error = TRUE;
@@ -1962,7 +1982,7 @@ test_driver_action_error_fallback_all (void)
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
g_autoptr(GError) error = NULL;
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpiDeviceFake *fake_dev;
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->return_action_error = TRUE;

View File

@@ -200,7 +200,7 @@ test_ssm_new_full (void)
static void
test_ssm_new_no_handler (void)
{
g_autoptr(FpiSsm) ssm = NULL;
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*BUG:*handler*");
@@ -211,7 +211,7 @@ test_ssm_new_no_handler (void)
static void
test_ssm_new_wrong_states (void)
{
g_autoptr(FpiSsm) ssm = NULL;
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*BUG:*nr_states*");
@@ -1172,6 +1172,7 @@ test_ssm_subssm_start (void)
g_autoptr(FpiSsm) subssm =
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
g_autoptr(FpiSsmTestData) subdata =
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
@@ -1262,6 +1263,7 @@ test_ssm_subssm_start_with_started (void)
g_autoptr(FpiSsm) subssm =
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
g_autoptr(FpiSsmTestData) subdata =
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
@@ -1305,6 +1307,7 @@ test_ssm_subssm_start_with_delayed (void)
g_autoptr(FpiSsm) subssm =
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
g_autoptr(FpiSsmTestData) subdata =
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
gpointer timeout_tracker = GUINT_TO_POINTER (TRUE);

File diff suppressed because one or more lines are too long

110
tests/vfs0050/capture.ioctl Normal file

File diff suppressed because one or more lines are too long

BIN
tests/vfs0050/capture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

83
tests/vfs0050/device Normal file
View File

@@ -0,0 +1,83 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-9
N: bus/usb/001/004=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
E: DEVNAME=/dev/bus/usb/001/004
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=138a/50/60
E: TYPE=255/16/255
E: BUSNUM=001
E: DEVNUM=004
E: MAJOR=189
E: MINOR=3
E: SUBSYSTEM=usb
E: ID_VENDOR=138a
E: ID_VENDOR_ENC=138a
E: ID_VENDOR_ID=138a
E: ID_MODEL=0050
E: ID_MODEL_ENC=0050
E: ID_MODEL_ID=0050
E: ID_REVISION=0060
E: ID_SERIAL=138a_0050_6d1900a1a0c0
E: ID_SERIAL_SHORT=6d1900a1a0c0
E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc.
E: ID_MODEL_FROM_DATABASE=Swipe Fingerprint Sensor
E: ID_PATH=pci-0000:00:14.0-usb-0:9
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
E: LIBFPRINT_DRIVER=Validity VFS0050
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=ff
A: bDeviceProtocol=ff
A: bDeviceSubClass=10
A: bMaxPacketSize0=8
A: bMaxPower=100mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0060
A: bmAttributes=a0
A: busnum=1
A: configuration=
H: descriptors=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
A: dev=189:3
A: devnum=4
A: devpath=9
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=0050
A: idVendor=138a
A: ltm_capable=no
A: maxchild=0
L: port=../1-0:1.0/usb1-port9
A: power/active_duration=19312
A: power/async=enabled
A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000
A: power/connected_duration=1037732
A: power/control=auto
A: power/level=auto
A: power/persist=1
A: power/runtime_active_kids=0
A: power/runtime_active_time=19151
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=1018305
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: quirks=0x0
A: removable=fixed
A: rx_lanes=1
A: serial=6d1900a1a0c0
A: speed=12
A: tx_lanes=1
A: urbnum=8
A: version= 1.10

View File

@@ -3,11 +3,10 @@
import sys
try:
import gi
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib, Gio
import os
import sys
from gi.repository import GLib, Gio
import unittest
import socket
import struct
@@ -20,6 +19,8 @@ except Exception as e:
print("Missing dependencies: %s" % str(e))
sys.exit(77)
FPrint = None
# Re-run the test with the passed wrapper if set
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
if wrapper:
@@ -101,12 +102,14 @@ class VirtualImage(unittest.TestCase):
del self.con
self.dev.close_sync()
def send_retry(self, retry_error=FPrint.DeviceRetry.TOO_SHORT, iterate=True):
def send_retry(self, retry_error=None, iterate=True):
retry_error = retry_error if retry_error else FPrint.DeviceRetry.TOO_SHORT
self.con.sendall(struct.pack('ii', -1, retry_error))
while iterate and ctx.pending():
ctx.iteration(False)
def send_error(self, device_error=FPrint.DeviceError.GENERAL, iterate=True):
def send_error(self, device_error=None, iterate=True):
device_error = device_error if device_error else FPrint.DeviceError.GENERAL
self.con.sendall(struct.pack('ii', -2, device_error))
while iterate and ctx.pending():
ctx.iteration(False)
@@ -346,5 +349,12 @@ class VirtualImage(unittest.TestCase):
assert(not self._verify_match)
if __name__ == '__main__':
try:
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint
except Exception as e:
print("Missing dependencies: %s" % str(e))
sys.exit(77)
# avoid writing to stderr
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))