Compare commits

..

119 Commits

Author SHA1 Message Date
Benjamin Berg
3f13ddc40d list-supported: Relativate "support" statement for website
The website suggest that the devices are "supported", however, it is not
clear what this means and can be read to imply that all of the devices
are expected to work well and upstream will fix issues.

Unfortunately, that is not really the case for all drivers. As such, add
a statement that the quality and supportability of drivers varies widely.
2021-03-08 12:34:41 +01:00
Benjamin Berg
e0f081c6e3 sdcp-device: Use a key DB for testing 2021-02-18 12:28:19 +01:00
Benjamin Berg
ae1fb4094b sdcp-device: Use predictable keys and random numbers for testing
If FP_DEVICE_EMULATION is set, then switch to using predictable EC
ephemeral key and random numbers. This should allow recording and
replaying real device interactions using umockdev.
2021-02-18 12:28:19 +01:00
Benjamin Berg
13350e05a2 port to low level EC key functions
This will allow creating a fixed key for testing
2021-02-18 12:28:19 +01:00
Benjamin Berg
3ea9cc90fe saner public key param 2021-02-18 12:28:19 +01:00
Benjamin Berg
e862e8e881 fixups: use static OID data 2021-02-18 12:28:19 +01:00
Benjamin Berg
60f5cd650a ci: Enable SDCP helper for tests 2021-02-18 12:28:19 +01:00
Benjamin Berg
7ff36888b7 tests: Add SDCP virtual device test 2021-02-18 12:28:19 +01:00
Benjamin Berg
e3043123f5 virtual-sdcp: Add a virtual SDCP device
This device is designed to talk to an external executable. This
executable can be provided/created using the test implementation from
Microsoft.
2021-02-18 12:28:18 +01:00
Benjamin Berg
77400b7a60 sdcp: Add SDCP base class
This adds a base class for SDCP devices. Not all functionality has been
fully tested, in particular the code to verify the model certificate is
most likely broken or incomplete. One problem there is that there is no
code to find the root CA to trust.

See: #257
2021-02-18 12:27:57 +01:00
Benjamin Berg
8d83e5eb38 meson: Shuffle around driver/helper definition
This is in order to add a new SDCP helper without having to define more
complicated logic.
2021-02-18 12:27:56 +01:00
Benjamin Berg
e59d5451cc meson: Move source generation into libfprint meson file 2021-02-18 12:04:25 +01:00
Benjamin Berg
798bc4ee1e scripts: Speed up uncrustify by running 4 jobs in parallel
There are some large files, and in most setups (including CI runners) we
have multiple cores available. Use xargs to run multiple parallel
uncrustify jobs rather than one large one. Just hardcode 4 jobs and 4
files at the same time for now.
2021-02-18 12:00:52 +01:00
Benjamin Berg
0e732dbafa ssm: Add API to get device
This can be useful in some cases and it was simply missing.
2021-02-18 12:00:52 +01:00
Benjamin Berg
84112abc71 device: Add new FP_DEVICE_ERROR_UNTRUSTED error code
Throw a specific error when we are unable to verify the integrety of the
device.
2021-02-18 12:00:51 +01:00
Benjamin Berg
c221c6b63e print: Add an SDCP print type
For now it is identical to a RAW print. However, this is likely to
change in the future.
2021-02-18 11:59:54 +01:00
Benjamin Berg
6e28b9a8c4 print: Fix pspec of print type to match real default
The default is actually FPI_PRINT_UNDEFINED and not FPI_PRINT_RAW.
2021-02-18 11:59:54 +01:00
Benjamin Berg
e5589a0ec2 ci: Include SDCP test binary in image 2021-02-18 11:59:54 +01:00
Benjamin Berg
966703057d synaptics: Fix lost messages when sequence counter overflows
The device will always use sequence number 0 for certain messages. We
use this knowledge to filter the messages and assume that it is one of
these special messages rather than a response to a command.

However, we could end up sending a command with a sequence counter of 0
which would result in the response being ignored. Fix this by ensuring
we correctly wrap from 255 to 1 instead of 0.

Fixes: #358
2021-02-05 16:09:24 +01:00
weilei
9e164485f0 goodixmoc:Add new PID
Add PID 6594 used by LENOVO
2021-02-04 18:51:36 +08:00
fengqiangguo
3bb38e2ff6 goodixmoc: support power button shield feature
Some OEM will integrate fingerprint device with powerButton. It's
possible that a user may press the power button during fingerprint
enroll or identify. This would lead to unintended PC shutdown or
hibernation. We add pwr_btn_shield cmd  and related process to shield
the power button function when the fingerprint functionality (enroll and
identify) is used and restore power button function afterwards.
2021-02-02 09:04:45 +08:00
Marco Trevisan (Treviño)
6a62d32c81 goodix: Consume the retry errors during verify/identify reports
We should not pass such kind of errors to complete functions, or we'll
fail the identification without ability to retry immediately.
2021-01-29 20:02:15 +01:00
Marco Trevisan (Treviño)
b2a64cc980 virtual-device: Do actual errors codes checks instead of regex checks 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
88117c172e tests/virtual-device: Add enroll and verify script test 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
27a62443a1 virtual-device: Add SET_KEEP_ALIVE command, to keep the listener up
We may want to be able to talk with the device while it's closed to
queue commands to be performed once it opens (could be even a script),
so to do this we need to close the device first, send those commands and
eventually process them.

We used a trick to send an invalid command before that was ignored by
release, but having the device available is just easier to handle.

So, when keep alive is enabled we don't stop the listener when closing
but only on actual device disposition.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
2f7c78eb97 virtual-device: Make possible to use a script to perform enroll operations 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
74f8a8ee27 virtual-device: Handle cancelled state gracefully in should_wait_to_sleep 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
acd0a10e76 virtual-device: Add test that open fails with a busy error if is still ongoing
The idea of the test was just checking what happens when we're opening a
device multiple times while a first request is still going.

However, it actually ends up also checking the previous commit change
because without it we'd stop the close iteration before the device is
actually closed and stop the open iteration before the device is
actually opened, leading to an infinite loop.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
27c2466bda fpi-device: Mark the device as open and notify it on idle callback
We're delaying any completed operation until we've completed an idle,
but the open/close state is changed and notified as soon as the device
completes the operation.

While this can be true, it means that we notify earlier than the finish
callback is actually called, while iterations are still needed to get
the actual state completed, and the current_task reset.

So if we'd open/close and iterate till fp_device_is_open() returns TRUE
we'd end up in a state in which the device is marked as ready, but it's
actually still busy since it's priv->current_task isn't unset yet.
The same if we'd try to do any action on notify::opened.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
33ba248c44 virtual-device: Add test checking for early errors during dev API calls 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
43cf28b9da fp-device: Do not try to deference potentially NULL task data
In case we do an early error return in verify and identify calls we
do not initialize the task data, but still in the finish functions we
still try to use it.

Avoid doing this, but just nullify the returned values.
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
4da52f78f6 virtual-device: Check properties match the getters 2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
e4e0937848 tests/virtual-*: Check for enrolled prints properties 2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
25a6c916aa fp-device: Fix property getters for enroll stages and driver ID
We were returning an invalid type for the enroll stages, while trying to
get the class from the private instance for the device driver
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
51009b48a0 virtual-device: Process supported commands on device open
When opening the device we can process commands that we left for that
after the previous close, to do that we only have to inject an invalid
command that will be processed (and ignored) while closing, so that at
next device opening we will be able to proceed with the previously
sent commands.

Add tests to finally check this case!
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
e1e3f6955e virtual-device: Remove messages we can't process from queue when not scanning
Commands that are not valid for non-scan operations should be removed
from queue, or these may be re-proposed forever.
2021-01-28 15:38:57 +01:00
Marco Trevisan (Treviño)
c495b82000 virtual-device: Use python's with idiom to check GLib expected error messages
And we can properly provide a real traceback as well
2021-01-28 15:38:56 +01:00
Marco Trevisan (Treviño)
d90ee96df8 virtual-device: Return an duplicated data error if trying to re-enroll a print 2021-01-28 15:38:56 +01:00
Marco Trevisan (Treviño)
36304b736b tests/virtual-device: Properly handle exceptions on enroll callback
We need to get them back to the caller function to be caught by the test
suite.
2021-01-28 15:38:29 +01:00
Marco Trevisan (Treviño)
31e34bd4bd virtual-device: Emit data not found during verify/identify
If trying to identify a print not in the storage we emit data not found
error, this can be helpful to do further fprintd testing too
2021-01-28 15:38:29 +01:00
Marco Trevisan (Treviño)
ec4c7ca5a9 virtual-device-storage: Don't listed prints 2021-01-28 02:32:28 +01:00
Benjamin Berg
8d21a9c27c ssm: Catch more errors in FpiSsm without crashing 2021-01-27 17:03:59 +00:00
Marco Trevisan (Treviño)
c4069065f9 virtual-device: Ensure we've an error before dereferencing it 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
31541edc58 tests/virtual-device: Use a sleep multiplier when under valgrind 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
549718753f fpi-device: Fix argument name on report_finger_status() annotation 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
cfde050220 virtual-device: Add ability to close a device with delay or with error 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
88a38c38af virtual-device: Add support for sleeping and sending errors on list and delete 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
7ffcc2f9e7 virtual-device: Make possible to inject sleep events while verifying/identifying
Each command should be separated by SLEEP to be considered as something
we want to perform during the current operation, otherwise will be used
by next operation consuming it.
2021-01-26 16:53:24 +01:00
Marco Trevisan (Treviño)
1dae6796f7 virtual-device: Report finger presency when we receive a 'SCAN' event 2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
0bb0492025 virtual-device: Mark finger as needed only after we start scanning
In case we sent a sleep event to the device we may want to wait it to
emit the finger needed state before the timeout is completed.

So add a function to manage this for all the scan cases
2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
3db0858fb0 tests/virtual-device: Add a class function to wait for a timeout 2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
2382506491 virtual-device: Add checks for verify reports 2021-01-26 04:49:50 +01:00
Benjamin Berg
08f4be707c uru4000: Call irq stop handler immediately if the transfer is cancelled
The irq handler may already be stopped if stop_irq_handler is called. In
that case, we should immediately call the handler rather than just never
calling it.

This fixes deactivation when the device is unexpectedly unplugged.

Closes: #355
2021-01-25 16:56:12 +00:00
Marco Trevisan (Treviño)
3693c39bc5 virtual-device: Make cancellation support toggable
We may want to have the device to sleep while releasing an operation,
this will allow to do it.
2021-01-25 17:40:49 +01:00
Marco Trevisan (Treviño)
993109a7f8 virtual-device: Implement cancel vfunc, to stop timeouts 2021-01-25 17:40:49 +01:00
Marco Trevisan (Treviño)
18db20d160 virtual-device: Add support for sleep command
It can be used to delay operations, simulating a busy device.
2021-01-25 17:40:48 +01:00
Marco Trevisan (Treviño)
89b4c4ee75 virtual-device: Test unplug operation while we're verifying 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
153b24a95a virtual-device: Use identify function for verify tests when possible 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
8c45c0952e virtual-device: Split verify check function in two parts to be reusable
We can so inject further operations in the middle, such as for the
finger status check
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
c3ece8621d virtual-device: Implement UNPLUG operation 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
67cb61cc18 tests/virtual-device: Add identification tests
Reusing most of the logic of the `check_verify` utility function
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
33ffadf402 tests/virtual-device: Cleanup device storage on teardown 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
162a83e484 tests/virtual-device: Add ability to enroll with a retry step and test it 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
dfb27222eb tests/virtual-device: Add function that figures out the command from type 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
81e53c422d virtual-device: Add support for changing the device scan type 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
be0b4ae2bb tests/virtual-device: Trigger new scans when we got progress callback 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
56bcf1ffdd virtual-device: Add command to change the number of enroll stages
As per this don't use the class value anymore at enroll phase, as it may
differ.
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
665de7813b fpi-device: Ensure we're receiving a valid number of enroll stages 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
a291d17f26 virtual-device: Properly cleanup the virtual devices data
Ensure we call the parent finalize function and cleanup local data
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
e8886dbc6b virtual-device: Support all the configured enrolling stages 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
3d6fb15b5c virtual-device: Add API to change current finger status 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
43d0dfdd8f virtual-device-storage: Set needed finger state on enroll and verify 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
50f522583e virtual-device: Set needed finger state on enroll and verify 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
f0443ba2f3 virtual-device: Add support for reporting device Retry "errors" 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
546f35132c tests/virtual-device: Use FPrint.DeviceError values to send errors 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
ce9527d2cb virtual-device: Wait for delayed commands to be processed
This allows to mimick the image device better, so that we can start an
operation and send the commands within some delay.
2021-01-25 17:40:13 +01:00
Benjamin Berg
89890dbd1f build: Explicitly mark libfprint as a shared library
While meson suggests to always use 'library' this leads to some unwanted
behaviors when it comes to generate pkg-config files for it, as they
will include `Libs.Private` / `Required.private` fields that should not
be really part of a shared library as libfprint is meant to be used.
2021-01-21 17:36:41 +01:00
fengqiangguo
e0c41c5444 goodixmoc: Fix some big/little endian support issues
Goodix driver is not working fine in BigEndian architectures. This
commit fixes some of these issues.

Related: #236
2021-01-21 16:21:06 +00:00
Marco Trevisan (Treviño)
3b83157e9b build: Skip the hwdb test if not all drivers are really enabled 2021-01-21 15:55:44 +00:00
Marco Trevisan (Treviño)
57f836a0f6 udev-hwdb: Generate autosuspend list using a sorted list 2021-01-21 15:55:44 +00:00
Marco Trevisan (Treviño)
170924ee4f test-generated-hwdb: Just use diff to compare for being more informative 2021-01-21 15:55:44 +00:00
Benjamin Berg
63bfaf4f60 tests: Add trailing newline to busname/devname sysfs attributes
libusb 1.0.24 now expects busnum/devnum to be \n terminated. Update the
device descriptions accordingly.

https://github.com/martinpitt/umockdev/issues/115
2021-01-21 11:28:47 +00:00
Marco Trevisan (Treviño)
2f6adce2fa data: Keep using versioned libname for hwdb file 2021-01-21 01:17:02 +01:00
Marco Trevisan (Treviño)
018641ad20 build: Ensure we process the data dir 2021-01-21 00:58:08 +01:00
Benjamin Berg
8ded064e65 tests: Add test based on the new virtual devices
Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:41 +01:00
Benjamin Berg
3f7a638eed virtual-device: Add non-image mock devices
There are two variants one with storage and identify support and the
other without storage.

It implements the following commands:
 * INSERT id
 * REMOVE id
 * SCAN id
 * ERROR error-code
 * LIST (returns saved print)

The INSERT/REMOVE/LIST commands are only available in the storage
driver. The SCAN command emulates presenting a finger.

These commands can be send ahead of time, and will be queued and
processed when appropriate. i.e. for INSERT/REMOVE that is immediately
when possible, for SCAN/ERROR processing is delayed.

The LIST command is always processed immediately.

Note that only a single command can be send per socket connection and
the command must be send in a single message. The socket will be closed
after the command has been processed.

Co-authored-by: Bastien Nocera <hadess@hadess.net>
Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:41 +01:00
Benjamin Berg
253750ec08 virtual-device-listener: Add a device socket handler class
Instead of repeating the same code in both the virtual-image and the
virtual-device drivers, implement a class to handle the socket listening
an data reading.

Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:04 +01:00
Benjamin Berg
5df14206d8 tests: Add support for creating other virtual readers
Add support for creating more virtual readers.

Co-authored-by: Bastien Nocera <hadess@hadess.net>
2021-01-20 23:21:04 +01:00
Marco Trevisan (Treviño)
2f2da87240 list-udev-hwdb: Add SPDX license to the generated file
And update it...
2021-01-20 22:03:40 +01:00
Marco Trevisan (Treviño)
533180a2e6 data: Use auto-generated but hardcoded autosuspend hwdb file
This solves various problems:
 1. It stays the same also if some drivers have been disabled
 2. It uses a stable path for being imported by systemd
 3. It is still checked for its validity by tests
 4. It can be auto-generated using a simple command
2021-01-20 21:17:42 +01:00
Marco Trevisan (Treviño)
99c269b3fe meson: Do not support drivers known to fail in Big Endian archs
When building in big endian architectures some device tests will fail,
as per this we're pretty sure that most of the drivers are not ready
to work in big-endian architectures.
Since we're aware of this, better to just stop supporting those drivers
instead of having each distribution to handle the problem.

So, add a list of supported drivers that is filled depending the
architecture type we're building on. Keep continue building those
drivers since we want to at least test-build them, but do not expose
them as libfprint drivers, so if a device in the system uses any of them
will be ignored.

At the same time, we keep track of the problem, so that we can fix the
drivers.

Related to #236
2021-01-20 18:29:05 +01:00
Benjamin Berg
66fc93eeff udev-hwdb: Prevent devices from being listed twice
The change to print a warning (for testing purposes) from commit
944e0d0383 (udev-rules: Print warning if an ID is supported) was
incorrect because it prevented duplicated to be suppressed if a device
is listed by two independent drivers.
2021-01-20 18:02:31 +01:00
Benjamin Berg
284f6f1ef8 ci: Add check that wiki and generator are in sync
Add a new test that checks that the unsupported list is not out of date.
As the wiki can be edited at any time, add this as a further optional
check into the CI pipeline.
2021-01-20 17:21:38 +01:00
Benjamin Berg
1f2d723485 Drop version from libfprint hwdb
As we are shipping a hwdb file now, we cannot have a collision with the
old libfprint version. Also, we are going to pull these rules into
systemd and they will not be installed via libfprint in the future. As
such, collisions will not happen again and it makes more sense like this
for systemd.
2021-01-20 17:21:38 +01:00
Benjamin Berg
f6179d6cc4 ci: Export hwdb into artefacts 2021-01-20 17:19:42 +01:00
Benjamin Berg
cbce56c142 meson: Always build hwdb file
We want systemd to pull our hwdb. In order to ease this, always build
the hwdb file, even if it is disabled.

Once systemd has merged the rules, downstream should turn off the rules
in libfprint. The default in libfprint will also be changed to not build
the hwdb (udev_rules option) eventually.
2021-01-19 14:22:05 +01:00
Benjamin Berg
55a2bb5536 Generate a hwdb instead of udev rules
We only use the rules/hwdb to enable auto-suspend. So, instead of
shipping our own rules, we can just use the existing autosuspend rules
and ship a hwdb that sets the appropriate flag.

Closes: #336
2021-01-19 14:21:44 +01:00
Benjamin Berg
16095a21fd tests: Add check that no supported device is whitelisted 2021-01-19 13:47:21 +01:00
Benjamin Berg
80dbc9c0cb udev-rules: Remove supported synaptics devices 2021-01-19 13:47:21 +01:00
Benjamin Berg
944e0d0383 udev-rules: Print warning if an ID is supported 2021-01-19 13:47:21 +01:00
Benjamin Berg
349fbeb834 drivers: Disable reindent and disable uncrustify for large headers
There are static data and take a long time to process. Also, the VFS301
fragments were really badly indented, fix that.
2021-01-18 16:25:25 +01:00
Benjamin Berg
17a8bacfaf usb-transfer: Remove incorrect statement from documentation
The string was still written without having the _full function in mind.
2021-01-18 14:37:53 +01:00
Benjamin Berg
6d4b498dae tests: Mark umockdev-test.py executable
This makes it easier to execute it for out-of-tree tests.
2021-01-13 14:45:07 +01:00
Benjamin Berg
7c2a67a954 Release 1.90.7 2021-01-13 13:28:45 +01:00
Aris Lin
a6c2509ca8 synaptics: check if current firmware supports during device probe
Fixes: #239 and #351
2021-01-12 18:49:36 +08:00
boger
8254b9e99e goodixmoc: support finger status report
there is no specific API for report finger status,
finger needed status is set when captrue sample cmd send, once cmd receive correct,
finger is pressing on sensor.
2021-01-05 13:36:17 +00:00
Vincent Huang
943c64d96f synaptics: modify the command to only identify the provided print list 2021-01-05 11:48:51 +00:00
Benjamin Berg
f852d972a5 goodix: Add missing return to fp_verify_capture_cb
Found by coverity. While quite bad in theory, proper safeguards are in
place, so it will only result in a g_return_val_if_fail to be hit rather
than causing more severe side effects.
2021-01-04 12:56:50 +00:00
Benjamin Berg
35d2d78e67 synaptics: Delay verify operation completion until finger remoal
We used to return early in the case where the print matched in order to
report the result more quickly. However, with the early reporting
mechanism and the fprintd side implementation of it, this is not
necessary anymore.

As such, only stop the "verify" and "identify" operations when the
finger is removed (or the operation is cancelled, which is actually what
will happen currently).
2021-01-04 11:14:16 +01:00
Benjamin Berg
3d5db6a391 synaptics: Improve identify handler and return a new print
It is easier (and more correct) to create a new print from the reported
data and match that against the prints in the gallery.

We continue to return NULL during verify as we cannot provide any
additional information in that case.
2021-01-04 10:11:00 +00:00
fengqiangguo
2ee0d16784 goodixmoc: fetch max_stored_prints from device
During updating configuration, device will send back the max_stored_prints
back. The number of max_stored_prints is different among different devices.
2021-01-04 10:29:55 +01:00
fengqiangguo
e6712fbcca goodixmoc: add two new Goodix PID support.
Add two new Goodix PID 0x63AC and 0x639C, to support two more Goodix fingerprint devices on Linux platform.
2021-01-04 09:22:04 +00:00
Torstein Husebø
ee928db5b2 treewide: Correct typos 2020-12-17 20:35:11 +01:00
Bastien Nocera
d6ca8ff2b0 tests: Fix typo in comment 2020-12-17 13:59:53 +01:00
Bastien Nocera
b1b20f8ab9 tests: Mention permissions in test docs 2020-12-17 13:59:53 +01:00
Bastien Nocera
7e2b89791e tests: Fix typo in instructions 2020-12-17 13:59:53 +01:00
Marco Trevisan (Treviño)
3560a0f1e7 vfs5011: Remove the stray ; 2020-12-14 18:16:43 +01:00
Marco Trevisan (Treviño)
ed5339c4f5 vfs5011: Unset the recorded rows list when freeing them
Ensure that we unset the rows list when closing the device, so that we
won't try to append to invalid rows list new ones again.
2020-12-14 18:15:37 +01:00
Benjamin Berg
2d10d864d8 nbis: Disable array-parameter and array-bounds warnings
NBIS just does weird things and while the array-parameter warning is
easy to fix, the other is not trivial. So disable these warnings so that
we can still build using newer GCC versions.
2020-12-09 15:53:26 +01:00
69 changed files with 7140 additions and 1110 deletions

View File

@@ -61,7 +61,7 @@ test:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
script:
- meson --werror -Ddrivers=all -Db_coverage=true . _build
- meson --werror -Ddrivers=all -Db_coverage=true -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
- ninja -C _build coverage
@@ -78,7 +78,7 @@ test_valgrind:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
script:
- meson -Ddrivers=all . _build
- meson -Ddrivers=all -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
@@ -109,6 +109,15 @@ test_indent:
- git diff
- "! git status -s | grep -q ."
test_unsupported_list:
stage: check-source
except:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
allow_failure: true
script:
- tests/hwdb-check-unsupported.py
flatpak:
stage: flatpak
extends: .flatpak
@@ -140,5 +149,17 @@ container_fedora_build:
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
# a list of packages to install
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES
# a list of packages to install; we only include mbedtls here
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES mbedtls-devel
FDO_DISTRIBUTION_EXEC: |
cd /tmp
mkdir -p /usr/local/bin
git clone https://github.com/benzea/SecureDeviceConnectionProtocol.git
# Don't bother with cmake
gcc -l mbedcrypto -I SecureDeviceConnectionProtocol/src/include \
SecureDeviceConnectionProtocol/src/test/virt_device.c \
SecureDeviceConnectionProtocol/src/client/client.c \
SecureDeviceConnectionProtocol/src/test/helpers.c \
SecureDeviceConnectionProtocol/src/test/testkeys.c \
-o /usr/local/bin/sdcp_virt_device
rm -rf SecureDeviceConnectionProtocol

10
NEWS
View File

@@ -1,6 +1,16 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
2020-12-01: v1.90.7 release
Highlights:
* vfs5011: Fix possible use-after-free
* goodixmoc: Add two new PIDs (0x63AC, 0x639C)
* goodixmoc: Support finger status API
* synaptics: Only identify within provided prints
* synaptics: Reject devices with old firmware during probe (#239)
2020-12-01: v1.90.6 release
This release is primarily a bugfix release for some older issues.

264
data/autosuspend.hwdb Normal file
View File

@@ -0,0 +1,264 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# This file has been generated using fprint-list-udev-hwdb with all drivers enabled
# Supported by libfprint driver aes1610
usb:v08FFp1600*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes1660
usb:v08FFp1660*
usb:v08FFp1680*
usb:v08FFp1681*
usb:v08FFp1682*
usb:v08FFp1683*
usb:v08FFp1684*
usb:v08FFp1685*
usb:v08FFp1686*
usb:v08FFp1687*
usb:v08FFp1688*
usb:v08FFp1689*
usb:v08FFp168A*
usb:v08FFp168B*
usb:v08FFp168C*
usb:v08FFp168D*
usb:v08FFp168E*
usb:v08FFp168F*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes2501
usb:v08FFp2500*
usb:v08FFp2580*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes2550
usb:v08FFp2550*
usb:v08FFp2810*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes2660
usb:v08FFp2660*
usb:v08FFp2680*
usb:v08FFp2681*
usb:v08FFp2682*
usb:v08FFp2683*
usb:v08FFp2684*
usb:v08FFp2685*
usb:v08FFp2686*
usb:v08FFp2687*
usb:v08FFp2688*
usb:v08FFp2689*
usb:v08FFp268A*
usb:v08FFp268B*
usb:v08FFp268C*
usb:v08FFp268D*
usb:v08FFp268E*
usb:v08FFp268F*
usb:v08FFp2691*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes3500
usb:v08FFp5731*
ID_AUTOSUSPEND=1
# Supported by libfprint driver aes4000
usb:v5501p08FF*
ID_AUTOSUSPEND=1
# Supported by libfprint driver elan
usb:v04F3p0903*
usb:v04F3p0907*
usb:v04F3p0C01*
usb:v04F3p0C02*
usb:v04F3p0C03*
usb:v04F3p0C04*
usb:v04F3p0C05*
usb:v04F3p0C06*
usb:v04F3p0C07*
usb:v04F3p0C08*
usb:v04F3p0C09*
usb:v04F3p0C0A*
usb:v04F3p0C0B*
usb:v04F3p0C0C*
usb:v04F3p0C0D*
usb:v04F3p0C0E*
usb:v04F3p0C0F*
usb:v04F3p0C10*
usb:v04F3p0C11*
usb:v04F3p0C12*
usb:v04F3p0C13*
usb:v04F3p0C14*
usb:v04F3p0C15*
usb:v04F3p0C16*
usb:v04F3p0C17*
usb:v04F3p0C18*
usb:v04F3p0C19*
usb:v04F3p0C1A*
usb:v04F3p0C1B*
usb:v04F3p0C1C*
usb:v04F3p0C1D*
usb:v04F3p0C1E*
usb:v04F3p0C1F*
usb:v04F3p0C20*
usb:v04F3p0C21*
usb:v04F3p0C22*
usb:v04F3p0C23*
usb:v04F3p0C24*
usb:v04F3p0C25*
usb:v04F3p0C26*
usb:v04F3p0C27*
usb:v04F3p0C28*
usb:v04F3p0C29*
usb:v04F3p0C2A*
usb:v04F3p0C2B*
usb:v04F3p0C2C*
usb:v04F3p0C2D*
usb:v04F3p0C2E*
usb:v04F3p0C2F*
usb:v04F3p0C30*
usb:v04F3p0C31*
usb:v04F3p0C32*
usb:v04F3p0C33*
usb:v04F3p0C42*
usb:v04F3p0C4D*
ID_AUTOSUSPEND=1
# Supported by libfprint driver etes603
usb:v1C7Ap0603*
ID_AUTOSUSPEND=1
# Supported by libfprint driver goodixmoc
usb:v27C6p5840*
usb:v27C6p6496*
usb:v27C6p60A2*
usb:v27C6p63AC*
usb:v27C6p639C*
usb:v27C6p6594*
ID_AUTOSUSPEND=1
# Supported by libfprint driver synaptics
usb:v06CBp00BD*
usb:v06CBp00E9*
usb:v06CBp00DF*
usb:v06CBp00F9*
usb:v06CBp00FC*
usb:v06CBp00C2*
usb:v06CBp00C9*
usb:v06CBp00E7*
ID_AUTOSUSPEND=1
# Supported by libfprint driver upeksonly
usb:v147Ep2016*
usb:v147Ep1000*
usb:v147Ep1001*
ID_AUTOSUSPEND=1
# Supported by libfprint driver upektc
usb:v0483p2015*
usb:v147Ep3001*
ID_AUTOSUSPEND=1
# Supported by libfprint driver upektc_img
usb:v147Ep2020*
ID_AUTOSUSPEND=1
# Supported by libfprint driver uru4000
usb:v045Ep00BC*
usb:v045Ep00BD*
usb:v045Ep00CA*
usb:v05BAp0007*
usb:v05BAp0008*
usb:v05BAp000A*
ID_AUTOSUSPEND=1
# Supported by libfprint driver vcom5s
usb:v061Ap0110*
ID_AUTOSUSPEND=1
# Supported by libfprint driver vfs0050
usb:v138Ap0050*
ID_AUTOSUSPEND=1
# Supported by libfprint driver vfs101
usb:v138Ap0001*
ID_AUTOSUSPEND=1
# Supported by libfprint driver vfs301
usb:v138Ap0005*
usb:v138Ap0008*
ID_AUTOSUSPEND=1
# Supported by libfprint driver vfs5011
usb:v138Ap0010*
usb:v138Ap0011*
usb:v138Ap0015*
usb:v138Ap0017*
usb:v138Ap0018*
ID_AUTOSUSPEND=1
# Known unsupported devices
usb:v04F3p036B*
usb:v04F3p0C00*
usb:v04F3p0C4B*
usb:v04F3p0C4C*
usb:v04F3p0C4F*
usb:v04F3p0C57*
usb:v04F3p2706*
usb:v06CBp0081*
usb:v06CBp0088*
usb:v06CBp008A*
usb:v06CBp009A*
usb:v06CBp009B*
usb:v06CBp00A2*
usb:v06CBp00B7*
usb:v06CBp00BB*
usb:v06CBp00BE*
usb:v06CBp00CB*
usb:v06CBp00D8*
usb:v06CBp00DA*
usb:v0A5Cp5801*
usb:v0A5Cp5805*
usb:v0A5Cp5834*
usb:v0A5Cp5843*
usb:v10A5p0007*
usb:v1188p9545*
usb:v138Ap0007*
usb:v138Ap003A*
usb:v138Ap003C*
usb:v138Ap003D*
usb:v138Ap003F*
usb:v138Ap0090*
usb:v138Ap0091*
usb:v138Ap0092*
usb:v138Ap0094*
usb:v138Ap0097*
usb:v138Ap009D*
usb:v138Ap00AB*
usb:v147Ep1002*
usb:v1491p0088*
usb:v16D1p1027*
usb:v1C7Ap0300*
usb:v1C7Ap0570*
usb:v1C7Ap0575*
usb:v27C6p5042*
usb:v27C6p5110*
usb:v27C6p5117*
usb:v27C6p5201*
usb:v27C6p521D*
usb:v27C6p5301*
usb:v27C6p530C*
usb:v27C6p532D*
usb:v27C6p533C*
usb:v27C6p5381*
usb:v27C6p5385*
usb:v27C6p538C*
usb:v27C6p538D*
usb:v27C6p5395*
usb:v27C6p5584*
usb:v27C6p55A2*
usb:v27C6p55A4*
usb:v27C6p55B4*
usb:v27C6p5740*
usb:v2808p9338*
usb:v298Dp2033*
usb:v3538p0930*
ID_AUTOSUSPEND=1

9
data/meson.build Normal file
View File

@@ -0,0 +1,9 @@
if get_option('udev_rules')
# This file has to be updated using
# ninja -C <builddir> libfprint/sync-udev-hwdb
install_data('autosuspend.hwdb',
rename: '60-autosuspend-@0@.hwdb'.format(versioned_libname),
install_dir: udev_hwdb_dir,
)
endif

View File

@@ -85,6 +85,12 @@ FP_TYPE_IMAGE_DEVICE
FpImageDevice
</SECTION>
<SECTION>
<FILE>fp-sdcp-device</FILE>
FP_TYPE_SDCP_DEVICE
FpSdcpDevice
</SECTION>
<SECTION>
<FILE>fp-print</FILE>
FP_TYPE_PRINT
@@ -186,6 +192,26 @@ fpi_image_device_image_captured
fpi_image_device_retry_scan
</SECTION>
<SECTION>
<FILE>fpi-sdcp-device</FILE>
<TITLE>Internal FpSdcpDevice</TITLE>
FpiSdcpClaim
FpSdcpDeviceClass
fpi_sdcp_claim_copy
fpi_sdcp_claim_free
fpi_sdcp_claim_get_type
fpi_sdcp_claim_new
fpi_sdcp_device_connect_complete
fpi_sdcp_device_get_connect_data
fpi_sdcp_device_get_reconnect_data
fpi_sdcp_device_reconnect_complete
fpi_sdcp_device_enroll_commit_complete
fpi_sdcp_device_enroll_ready
fpi_sdcp_device_enroll_set_nonce
fpi_sdcp_device_identify_retry
fpi_sdcp_device_identify_complete
</SECTION>
<SECTION>
<FILE>fpi-log</FILE>
fp_dbg

View File

@@ -28,6 +28,7 @@
<xi:include href="xml/fp-context.xml"/>
<xi:include href="xml/fp-device.xml"/>
<xi:include href="xml/fp-image-device.xml"/>
<xi:include href="xml/fp-sdcp-device.xml"/>
<xi:include href="xml/fp-print.xml"/>
<xi:include href="xml/fp-image.xml"/>
</part>
@@ -38,6 +39,7 @@
<title>Device methods for drivers</title>
<xi:include href="xml/fpi-device.xml"/>
<xi:include href="xml/fpi-image-device.xml"/>
<xi:include href="xml/fpi-sdcp-device.xml"/>
</chapter>
<chapter id="driver-helpers">

View File

@@ -22,6 +22,8 @@
#define AES1660_FRAME_SIZE 0x244
/* *INDENT-OFF* */
/* First init sequence, 0x07 cmd returns following before INIT1:
* { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x00 }
*/

View File

@@ -21,6 +21,8 @@
#define AES2660_FRAME_SIZE 0x354
/* *INDENT-OFF* */
/* First init sequence, 0x07 cmd returns following before INIT1:
* { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x00 }
*/

View File

@@ -53,10 +53,12 @@ struct _FpiDeviceGoodixMoc
pgxfp_sensor_cfg_t sensorcfg;
gint enroll_stage;
gint max_enroll_stage;
gint max_stored_prints;
GCancellable *cancellable;
GPtrArray *list_result;
guint8 template_id[TEMPLATE_ID_SIZE];
gboolean is_enroll_identify;
gboolean is_power_button_shield_on;
};
@@ -126,7 +128,7 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
}
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
if(crc32_calc != *(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len))
if(crc32_calc != GUINT32_FROM_LE (*(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)))
{
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
@@ -308,6 +310,35 @@ goodix_sensor_cmd (FpiDeviceGoodixMoc *self,
}
/******************************************************************************
*
* fp_pwr_btn_shield_cb Function
*
*****************************************************************************/
static void
fp_pwr_btn_shield_cb (FpiDeviceGoodixMoc *self,
gxfp_cmd_response_t *resp,
GError *error)
{
if (error)
{
fpi_ssm_mark_failed (self->task_ssm, error);
return;
}
if (resp->result >= GX_FAILED)
{
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
return;
}
if (resp->power_button_shield_resp.resp_cmd1 == MOC_CMD1_PWR_BTN_SHIELD_ON)
self->is_power_button_shield_on = true;
else
self->is_power_button_shield_on = false;
fpi_ssm_next_state (self->task_ssm);
}
/******************************************************************************
*
* fp_verify_xxxx Function
@@ -330,7 +361,9 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self,
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
return;
}
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_PRESENT,
FP_FINGER_STATUS_NONE);
if (resp->capture_data_resp.img_quality == 0)
{
fpi_ssm_mark_failed (self->task_ssm,
@@ -341,6 +374,7 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self,
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
return;
}
fpi_ssm_next_state (self->task_ssm);
}
@@ -415,7 +449,7 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
fpi_device_identify_report (device, NULL, NULL, error);
}
fpi_ssm_mark_completed (self->task_ssm);
fpi_ssm_next_state (self->task_ssm);
}
@@ -432,7 +466,18 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
switch (fpi_ssm_get_cur_state (ssm))
{
case FP_VERIFY_PWR_BTN_SHIELD_ON:
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
false,
NULL,
0,
fp_pwr_btn_shield_cb);
break;
case FP_VERIFY_CAPTURE:
fpi_device_report_finger_status_changes (device,
FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE);
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
true,
(const guint8 *) &param,
@@ -447,6 +492,14 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
TEMPLATE_ID_SIZE,
fp_verify_cb);
break;
case FP_VERIFY_PWR_BTN_SHIELD_OFF:
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
false,
NULL,
0,
fp_pwr_btn_shield_cb);
break;
}
}
@@ -461,9 +514,9 @@ fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
if (error && error->domain == FP_DEVICE_RETRY)
{
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, error);
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
else
fpi_device_identify_report (dev, NULL, NULL, error);
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
}
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
@@ -560,6 +613,13 @@ fp_enroll_enum_cb (FpiDeviceGoodixMoc *self,
resp->result));
return;
}
if (resp->finger_list_resp.finger_num >= self->max_stored_prints)
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
return;
}
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
}
@@ -620,7 +680,9 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
return;
}
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_PRESENT,
FP_FINGER_STATUS_NONE);
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
{
@@ -742,7 +804,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
fpi_ssm_mark_failed (self->task_ssm, error);
return;
}
/* if reach max timeout(5sec) finger not up, swtich to finger up again */
/* if reach max timeout(5sec) finger not up, switch to finger up again */
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
{
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP);
@@ -755,6 +817,9 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
"Switch finger mode failed"));
return;
}
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_PRESENT);
if (self->enroll_stage < self->max_enroll_stage)
{
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
@@ -793,6 +858,16 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
}
break;
case FP_ENROLL_PWR_BTN_SHIELD_ON:
{
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
false,
NULL,
0,
fp_pwr_btn_shield_cb);
}
break;
case FP_ENROLL_IDENTIFY:
{
dummy[0] = 0x01;
@@ -817,6 +892,9 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
break;
case FP_ENROLL_CAPTURE:
fpi_device_report_finger_status_changes (device,
FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE);
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
true,
(const guint8 *) &dummy,
@@ -904,9 +982,17 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
}
break;
case FP_ENROLL_PWR_BTN_SHIELD_OFF:
{
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
false,
NULL,
0,
fp_pwr_btn_shield_cb);
}
break;
}
}
static void
@@ -975,7 +1061,7 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
fpi_ssm_mark_failed (self->task_ssm, error);
return;
}
self->max_stored_prints = resp->finger_config.max_stored_prints;
fpi_ssm_next_state (self->task_ssm);
}
@@ -1259,6 +1345,9 @@ gx_fp_init (FpDevice *device)
GError *error = NULL;
int ret = 0;
self->max_stored_prints = FP_MAX_FINGERNUM;
self->is_power_button_shield_on = false;
self->cancellable = g_cancellable_new ();
self->sensorcfg = g_new0 (gxfp_sensor_cfg_t, 1);
@@ -1293,20 +1382,59 @@ gx_fp_init (FpDevice *device)
}
static void
gx_fp_exit (FpDevice *device)
gx_fp_release_interface (FpiDeviceGoodixMoc *self,
GError *error)
{
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
GError *error = NULL;
g_autoptr(GError) release_error = NULL;
g_clear_object (&self->cancellable);
g_clear_pointer (&self->sensorcfg, g_free);
/* Release usb interface */
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
0, 0, &error);
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)),
0, 0, &release_error);
/* Retain passed error if set, otherwise propagate error from release. */
if (error == NULL)
error = g_steal_pointer (&release_error);
/* Notify close complete */
fpi_device_close_complete (FP_DEVICE (self), error);
}
static void
gx_fp_exit_cb (FpiDeviceGoodixMoc *self,
gxfp_cmd_response_t *resp,
GError *error)
{
if (resp->result >= GX_FAILED)
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
self->is_power_button_shield_on = false;
gx_fp_release_interface (self, error);
}
static void
gx_fp_exit (FpDevice *device)
{
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
if (self->is_power_button_shield_on)
{
goodix_sensor_cmd (self,
MOC_CMD0_PWR_BTN_SHIELD,
MOC_CMD1_PWR_BTN_SHIELD_OFF,
false,
NULL,
0,
gx_fp_exit_cb);
}
else
{
gx_fp_release_interface (self, NULL);
}
}
@@ -1408,7 +1536,6 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
static void
gx_fp_cancel (FpDevice *device)
{
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
/* Cancel any current interrupt transfer (resulting us to go into
@@ -1424,6 +1551,9 @@ static const FpIdEntry id_table[] = {
{ .vid = 0x27c6, .pid = 0x5840, },
{ .vid = 0x27c6, .pid = 0x6496, },
{ .vid = 0x27c6, .pid = 0x60A2, },
{ .vid = 0x27c6, .pid = 0x63AC, },
{ .vid = 0x27c6, .pid = 0x639C, },
{ .vid = 0x27c6, .pid = 0x6594, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
};

View File

@@ -40,7 +40,8 @@ typedef enum {
typedef enum {
FP_ENROLL_ENUM = 0,
FP_ENROLL_PWR_BTN_SHIELD_ON = 0,
FP_ENROLL_ENUM,
FP_ENROLL_IDENTIFY,
FP_ENROLL_CREATE,
FP_ENROLL_CAPTURE,
@@ -48,11 +49,14 @@ typedef enum {
FP_ENROLL_WAIT_FINGER_UP,
FP_ENROLL_CHECK_DUPLICATE,
FP_ENROLL_COMMIT,
FP_ENROLL_PWR_BTN_SHIELD_OFF,
FP_ENROLL_NUM_STATES,
} FpEnrollState;
typedef enum {
FP_VERIFY_CAPTURE = 0,
FP_VERIFY_PWR_BTN_SHIELD_ON = 0,
FP_VERIFY_CAPTURE,
FP_VERIFY_IDENTIFY,
FP_VERIFY_PWR_BTN_SHIELD_OFF,
FP_VERIFY_NUM_STATES,
} FpVerifyState;

View File

@@ -141,8 +141,11 @@ crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
static void
crc32_final (gf_crc32_context *ctx, uint8_t *md)
{
uint32_t crc = 0;
ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
memcpy (md, &ctx->crc, 4);
crc = GUINT32_TO_LE (ctx->crc);
memcpy (md, &crc, 4);
}
uint8_t
@@ -184,7 +187,7 @@ init_pack_header (
pheader->cmd1 = LOBYTE (cmd);
pheader->packagenum = packagenum;
pheader->reserved = dump_seq++;
pheader->len = len + PACKAGE_CRC_SIZE;
pheader->len = GUINT16_TO_LE (len + PACKAGE_CRC_SIZE);
pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
pheader->rev_crc8 = ~pheader->crc8;
}
@@ -224,14 +227,14 @@ gx_proto_parse_header (
{
if (!buffer || !pheader)
return -1;
if (buffer_len < PACKAGE_HEADER_SIZE)
if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
return -1;
memcpy (pheader, buffer, sizeof (pack_header));
pheader->len = GUINT16_FROM_LE ( *(uint16_t *) (buffer + 4));
pheader->len = GUINT16_FROM_LE (pheader->len);
if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
return -1;
pheader->len -= PACKAGE_CRC_SIZE;
return 0;
}
@@ -248,7 +251,7 @@ gx_proto_parse_fingerid (
if (!template || !fid_buffer)
return -1;
if (fid_buffer_size < 70)
if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
return -1;
buffer = fid_buffer;
@@ -256,28 +259,30 @@ gx_proto_parse_fingerid (
if (buffer[Offset++] != 67)
return -1;
fid_buffer_size--;
template->type = buffer[Offset++];
fid_buffer_size--;
template->finger_index = buffer[Offset++];
fid_buffer_size--;
Offset++;
memcpy (template->accountid, &buffer[Offset], 32);
Offset += 32;
memcpy (template->tid, &buffer[Offset], 32);
Offset += 32; // Offset == 68
memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
Offset += sizeof (template->accountid);
memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
Offset += sizeof (template->tid); // Offset == 68
template->payload.size = buffer[Offset++];
memset (template->payload.data, 0, 56);
if (template->payload.size > sizeof (template->payload.data))
return -1;
memset (template->payload.data, 0, template->payload.size);
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)
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
{
uint32_t offset = 0;
uint16_t offset = 0;
uint8_t *fingerlist = NULL;
if (!buffer || !presp)
@@ -289,33 +294,65 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
{
case RESPONSE_PACKAGE_CMD:
{
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
return -1;
presp->parse_msg.ack_cmd = buffer[1];
}
break;
case MOC_CMD0_UPDATE_CONFIG:
{
presp->finger_config.status = buffer[0];
if (buffer_len >= 3)
presp->finger_config.max_stored_prints = buffer[2];
else
/* to compatiable old version firmware */
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
}
break;
case MOC_CMD0_COMMITENROLLMENT:
case MOC_CMD0_DELETETEMPLATE:
/* just check result */
break;
case MOC_CMD0_PWR_BTN_SHIELD:
presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
if (buffer_len >= 2)
{
uint8_t support_pwr_shield = buffer[1];
if (support_pwr_shield == 0xFF)
g_debug ("Power button shield feature not supported!\n");
}
break;
case MOC_CMD0_GET_VERSION:
if (buffer_len < sizeof (gxfp_version_info_t) + 1)
return -1;
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
break;
case MOC_CMD0_CAPTURE_DATA:
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
{
if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
return -1;
presp->capture_data_resp.img_quality = buffer[1];
presp->capture_data_resp.img_coverage = buffer[2];
}
break;
case MOC_CMD0_ENROLL_INIT:
if (buffer_len < sizeof (gxfp_enroll_init_t) + 1)
return -1;
if (presp->result == GX_SUCCESS)
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
break;
case MOC_CMD0_ENROLL:
if (buffer_len < sizeof (gxfp_enroll_update_t))
return -1;
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
presp->enroll_update.img_overlay = buffer[1];
presp->enroll_update.img_preoverlay = buffer[2];
@@ -325,7 +362,11 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
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));
if (buffer_len < 3)
return -1;
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
if ((buffer_len < tid_size + 3) || (buffer_len > sizeof (template_format_t)) + 3)
return -1;
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
}
break;
@@ -333,18 +374,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
case MOC_CMD0_GETFINGERLIST:
if (presp->result != GX_SUCCESS)
break;
if (buffer_len < 2)
return -1;
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));
uint16_t fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
offset += 2;
if (buffer_len < fingerid_length + offset + 2)
return -1;
if (gx_proto_parse_fingerid (fingerlist + offset,
fingerid_length,
&presp->finger_list_resp.finger_list[num]) != 0)
@@ -366,14 +405,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
presp->verify.match = (buffer[0] == 0) ? true : false;
if (presp->verify.match)
{
if (buffer_len < sizeof (template_format_t) + 10)
return -1;
offset += 1;
presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset));
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2;
score = GUINT32_FROM_LE (*(buffer + offset));
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
offset += 4;
study = GUINT16_FROM_LE (*(buffer + offset));
study = buffer[offset];
offset += 1;
fingerid_size = GUINT16_FROM_LE (*(buffer + offset));
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
offset += 2;
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
{
@@ -411,7 +452,7 @@ gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig)
memset (pconfig, 0, sizeof (*pconfig));
//NOTICE: Do not change any value!
memcpy (&pconfig->config, sensor_config, 26);
memcpy (&pconfig->config, sensor_config, G_N_ELEMENTS (sensor_config));
pconfig->reserved[0] = 1;
gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);

View File

@@ -25,7 +25,7 @@
#define PACKAGE_CRC_SIZE (4)
#define PACKAGE_HEADER_SIZE (8)
#define FP_MAX_FINGERNUM (10)
#define FP_MAX_FINGERNUM (20)
#define TEMPLATE_ID_SIZE (32)
@@ -75,6 +75,11 @@
#define MOC_CMD1_GET_FINGER_MODE 0x00
#define MOC_CMD1_SET_FINGER_DOWN 0x01
#define MOC_CMD1_SET_FINGER_UP 0x02
#define MOC_CMD0_PWR_BTN_SHIELD 0xE0
#define MOC_CMD1_PWR_BTN_SHIELD_OFF 0x00
#define MOC_CMD1_PWR_BTN_SHIELD_ON 0x01
/* */
typedef struct _gxfp_version_info
@@ -89,7 +94,7 @@ typedef struct _gxfp_version_info
uint8_t interface[GX_VERSION_LEN];
uint8_t protocol[GX_VERSION_LEN];
uint8_t flashVersion[GX_VERSION_LEN];
uint8_t reserved[62];
uint8_t reserved[38];
} gxfp_version_info_t, *pgxfp_version_info_t;
@@ -167,6 +172,16 @@ typedef struct _fp_finger_status
uint8_t status;
} fp_finger_status_t, *pfp_finger_status_t;
typedef struct _fp_finger_config
{
uint8_t status;
uint8_t max_stored_prints;
} fp_finger_config_t, *pfp_finger_config_t;
typedef struct _fp_pwr_btn_shield
{
uint8_t resp_cmd1;
} fp_pwr_btn_shield_t, *pfp_pwr_btn_shield_t;
typedef struct _fp_cmd_response
{
@@ -183,6 +198,8 @@ typedef struct _fp_cmd_response
gxfp_enum_fingerlist_t finger_list_resp;
gxfp_version_info_t version_info;
fp_finger_status_t finger_status;
fp_finger_config_t finger_config;
fp_pwr_btn_shield_t power_button_shield_resp;
};
} gxfp_cmd_response_t, *pgxfp_cmd_response_t;
@@ -219,7 +236,7 @@ int gx_proto_parse_header (uint8_t *buffer,
int gx_proto_parse_body (uint16_t cmd,
uint8_t *buffer,
uint32_t buffer_len,
uint16_t buffer_len,
pgxfp_cmd_response_t presponse);
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);

View File

@@ -27,6 +27,9 @@
G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
static void init_identify_msg (FpDevice *device);
static void compose_and_send_identify_msg (FpDevice *device);
static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xE9, },
@@ -121,7 +124,7 @@ cmd_receive_cb (FpiUsbTransfer *transfer,
{
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK)
{
fp_dbg ("Received cancellation success resonse");
fp_dbg ("Received cancellation success response");
fpi_ssm_mark_failed (transfer->ssm,
g_error_new_literal (G_IO_ERROR,
G_IO_ERROR_CANCELLED,
@@ -345,7 +348,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
* may only be a cancellation currently). */
if (seq_num <= 0)
{
self->last_seq_num = MAX (1, self->last_seq_num + 1);
self->last_seq_num = MAX (1, (self->last_seq_num + 1) & 0xff);
real_seq_num = self->last_seq_num;
if (seq_num == 0)
self->cmd_seq_num = self->last_seq_num;
@@ -451,6 +454,37 @@ parse_print_data (GVariant *data,
return TRUE;
}
static FpPrint *
create_print (FpiDeviceSynaptics *self,
guint8 *user_id,
guint8 finger_id)
{
FpPrint *print;
g_autofree gchar *user_id_safe;
GVariant *data = NULL;
GVariant *uid = NULL;
user_id_safe = g_strndup ((char *) user_id, BMKT_MAX_USER_ID_LEN);
print = fp_print_new (FP_DEVICE (self));
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
user_id_safe,
strlen (user_id_safe),
1);
data = g_variant_new ("(y@ay)",
finger_id,
uid);
fpi_print_set_type (print, FPI_PRINT_RAW);
fpi_print_set_device_stored (print, TRUE);
g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "description", user_id_safe, NULL);
fpi_print_fill_from_user_id (print, user_id_safe);
return print;
}
static void
list_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
@@ -503,10 +537,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
{
GVariant *data = NULL;
GVariant *uid = NULL;
FpPrint *print;
gchar *userid;
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
continue;
@@ -519,23 +550,9 @@ list_msg_cb (FpiDeviceSynaptics *self,
get_enroll_templates_resp->templates[n].user_id,
get_enroll_templates_resp->templates[n].finger_id);
userid = (gchar *) get_enroll_templates_resp->templates[n].user_id;
print = fp_print_new (FP_DEVICE (self));
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
get_enroll_templates_resp->templates[n].user_id,
get_enroll_templates_resp->templates[n].user_id_len,
1);
data = g_variant_new ("(y@ay)",
get_enroll_templates_resp->templates[n].finger_id,
uid);
fpi_print_set_type (print, FPI_PRINT_RAW);
fpi_print_set_device_stored (print, TRUE);
g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
fpi_print_fill_from_user_id (print, userid);
print = create_print (self,
get_enroll_templates_resp->templates[n].user_id,
get_enroll_templates_resp->templates[n].finger_id);
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
}
@@ -649,7 +666,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL);
fpi_device_verify_complete (device, NULL);
verify_complete_after_finger_removal (self);
break;
}
}
@@ -725,6 +742,12 @@ identify_msg_cb (FpiDeviceSynaptics *self,
fp_info ("Place Finger on the Sensor!");
break;
case BMKT_RSP_SEND_NEXT_USER_ID:
{
compose_and_send_identify_msg (device);
break;
}
case BMKT_RSP_ID_FAIL:
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
{
@@ -760,45 +783,47 @@ identify_msg_cb (FpiDeviceSynaptics *self,
FpPrint *print = NULL;
GPtrArray *prints = NULL;
g_autoptr(GVariant) data = NULL;
guint8 finger;
const guint8 *user_id;
gsize user_id_len = 0;
gint cnt = 0;
gboolean find = FALSE;
gboolean found = FALSE;
guint index;
print = create_print (self,
resp->response.id_resp.user_id,
resp->response.id_resp.finger_id);
fpi_device_get_identify_data (device, &prints);
for (cnt = 0; cnt < prints->len; cnt++)
{
print = g_ptr_array_index (prints, cnt);
g_object_get (print, "fpi-data", &data, NULL);
g_debug ("data is %p", data);
parse_print_data (data, &finger, &user_id, &user_id_len);
if (user_id)
{
if (memcmp (resp->response.id_resp.user_id, user_id, user_id_len) == 0)
{
find = TRUE;
break;
}
}
}
if(find)
{
fpi_device_identify_report (device, print, print, NULL);
fpi_device_identify_complete (device, NULL);
}
found = g_ptr_array_find_with_equal_func (prints,
print,
(GEqualFunc) fp_print_equal,
&index);
if (found)
fpi_device_identify_report (device, g_ptr_array_index (prints, index), print, NULL);
else
{
fpi_device_identify_report (device, NULL, NULL, NULL);
identify_complete_after_finger_removal (self);
}
fpi_device_identify_report (device, NULL, print, NULL);
identify_complete_after_finger_removal (self);
}
}
}
static void
identify (FpDevice *device)
{
init_identify_msg (device);
compose_and_send_identify_msg (device);
}
static void
init_identify_msg (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
self->id_idx = 0;
}
static void
compose_and_send_identify_msg (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
FpPrint *print = NULL;
@@ -808,28 +833,77 @@ identify (FpDevice *device)
guint8 finger;
const guint8 *user_id;
gsize user_id_len = 0;
gint cnt = 0;
g_autofree guint8 *payload = NULL;
guint8 payload_len = 0;
guint8 payloadOffset = 0;
fpi_device_get_identify_data (device, &prints);
for (cnt = 0; cnt < prints->len; cnt++)
if (prints->len > UINT8_MAX)
{
print = g_ptr_array_index (prints, cnt);
g_object_get (print, "fpi-data", &data, NULL);
g_debug ("data is %p", data);
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
{
fpi_device_identify_complete (device,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
fpi_device_identify_complete (device,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
G_DEBUG_HERE ();
if(self->id_idx >= prints->len)
{
fp_warn ("Device asked for more prints than we are providing.");
fpi_device_identify_complete (device,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Unexpected index"));
return;
}
print = g_ptr_array_index (prints, self->id_idx);
g_object_get (print, "fpi-data", &data, NULL);
g_debug ("data is %p", data);
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
{
fpi_device_identify_complete (device,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if(self->id_idx == 0)
{
/*
* Construct payload.
* 1st byte is total number of IDs in list.
* 2nd byte is number of IDs in list.
* 1 byte for each ID length, maximum id length is 100.
* user_id_len bytes of each ID
*/
payload_len = 2 + 1 + user_id_len;
payload = g_malloc0 (payload_len);
payload[payloadOffset] = prints->len;
payloadOffset += 1;
payload[payloadOffset] = 1; /* send one id per message */
payloadOffset += 1;
payload[payloadOffset] = user_id_len;
payloadOffset += 1;
memcpy (&payload[payloadOffset], user_id, user_id_len);
payloadOffset += user_id_len;
synaptics_sensor_cmd (self, 0, BMKT_CMD_ID_USER, NULL, 0, identify_msg_cb);
G_DEBUG_HERE ();
synaptics_sensor_cmd (self, 0, BMKT_CMD_ID_USER_IN_ORDER, payload, payloadOffset, identify_msg_cb);
}
else
{
/*
* 1st byte is the number of IDs
* 1 byte for each ID length
* id_length bytes for each ID
*/
payload_len = 1 + 1 + user_id_len;
payload = g_malloc0 (payload_len);
payload[payloadOffset] = 1; /* send one id per message */
payloadOffset += 1;
payload[payloadOffset] = user_id_len;
payloadOffset += 1;
memcpy (&payload[payloadOffset], user_id, user_id_len);
payloadOffset += user_id_len;
synaptics_sensor_cmd (self, self->cmd_seq_num, BMKT_CMD_ID_NEXT_USER, payload, payloadOffset, NULL);
}
self->id_idx++;
}
static void
enroll_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
@@ -1059,6 +1133,44 @@ delete_print (FpDevice *device)
synaptics_sensor_cmd (self, 0, BMKT_CMD_DEL_USER_FP, payload, user_id_len + 1, delete_msg_cb);
}
static void
prob_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
GUsbDevice *usb_dev = NULL;
g_autofree gchar *serial = NULL;
usb_dev = fpi_device_get_usb_device (FP_DEVICE (self));
if (error)
{
g_usb_device_close (usb_dev, NULL);
fpi_device_probe_complete (FP_DEVICE (self), NULL, NULL,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "unsupported firmware version"));
return;
}
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
serial = g_strdup ("emulated-device");
else
serial = g_usb_device_get_string_descriptor (usb_dev,
g_usb_device_get_serial_number_index (usb_dev),
&error);
if (resp->result == BMKT_SUCCESS)
{
g_usb_device_close (usb_dev, NULL);
fpi_device_probe_complete (FP_DEVICE (self), serial, NULL, error);
}
else
{
g_warning ("Probe fingerprint sensor failed with %d!", resp->result);
g_usb_device_close (usb_dev, NULL);
fpi_device_probe_complete (FP_DEVICE (self), serial, NULL, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
}
}
static void
dev_probe (FpDevice *device)
{
@@ -1159,40 +1271,7 @@ dev_probe (FpDevice *device)
fp_dbg ("Target: %d", self->mis_version.target);
fp_dbg ("Product: %d", self->mis_version.product);
/* We need at least firmware version 10.1, and for 10.1 build 2989158 */
if (self->mis_version.version_major < 10 ||
self->mis_version.version_minor < 1 ||
(self->mis_version.version_major == 10 &&
self->mis_version.version_minor == 1 &&
self->mis_version.build_num < 2989158))
{
fp_warn ("Firmware version %d.%d with build number %d is unsupported",
self->mis_version.version_major,
self->mis_version.version_minor,
self->mis_version.build_num);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Unsupported firmware version "
"(%d.%d with build number %d)",
self->mis_version.version_major,
self->mis_version.version_minor,
self->mis_version.build_num);
goto err_close;
}
/* This is the same as the serial_number from above, hex encoded and somewhat reordered */
/* Should we add in more, e.g. the chip revision? */
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
serial = g_strdup ("emulated-device");
else
serial = g_usb_device_get_string_descriptor (usb_dev,
g_usb_device_get_serial_number_index (usb_dev),
&error);
g_usb_device_close (usb_dev, NULL);
fpi_device_probe_complete (device, serial, NULL, error);
synaptics_sensor_cmd (self, 0, BMKT_CMD_FPS_INIT, NULL, 0, prob_msg_cb);
return;

View File

@@ -110,6 +110,7 @@ struct _FpiDeviceSynaptics
FpiSsm *cmd_ssm;
FpiUsbTransfer *cmd_pending_transfer;
gboolean cmd_complete_on_removal;
guint8 id_idx;
bmkt_sensor_version_t mis_version;

View File

@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* *INDENT-OFF* */
#pragma once
#define UPEKTC_CMD_LEN 0x40

View File

@@ -375,6 +375,10 @@ stop_irq_handler (FpImageDevice *dev, irqs_stopped_cb_fn cb)
g_cancellable_cancel (self->irq_cancellable);
self->irqs_stopped_cb = cb;
}
else
{
cb (dev);
}
}
/***** STATE CHANGING *****/

View File

@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* *INDENT-OFF* */
/* There are many similar blocks in the data below, also the data are
* self-similar (looks like some config blocks? pokes like in vfs101?) */
@@ -1621,56 +1623,56 @@ static const unsigned char vfs301_24[] = { /* 119 B */
#define vfs301_02D0_ALIGNED_BLOB \
PACKET ("0200", "8005", \
"FF830720" "5F820720" "FF830720" \
"5F820720" "FF830720" "5F820720" "FF830720" \
"5F820720" "FF830720" "5F820720" "FF8B0720" \
"608A0720" "FF930720" "61920720" "FF9B0720" \
"629A0720" "FFA30720" "63A20720" "FFAB0720" \
"64AA0720" "FFB30720" "65B20720" "FFBB0720" \
"66BA0720" "FFC30720" "67C20720" "FFCB0720" \
"68CA0720" "FFD30720" "69D20720" "FFDB0720" \
"6ADA0720" "FFE30720" "6BE20720" "FFEB0720" \
"6CEA0720" "FFF30720" "6DF20720" "FFFB0720" \
"6EFA0720" "FF850720" "6F840720" "FF8D0720" \
"708C0720" "FF950720" "71940720" "FF9D0720" \
"729C0720" "FFA50720" "73A40720" "FFAD0720" \
"74AC0720" "FFB50720" "75B40720" "FFBD0720" \
"76BC0720" "FFC50720" "77C40720" "FFCD0720" \
"78CC0720" "FFD50720" "79D40720" "FFDD0720" \
"7ADC0720" "FFE50720" "7BE40720" "FFED0720" \
"7CEC0720" "FFF50720" "7DF40720" "FFFD0720" \
"7EFC0720" "FF870720" "7F860720" "FF8F0720" \
"808E0720" "FF970720" "81960720" "FF9F0720" \
"829E0720" "FFA70720" "83A60720" "FFAF0720" \
"84AE0720" "FFB70720" "85B60720" "FFBF0720" \
"86BE0720" "FFC70720" "87C60720" "FFCF0720" \
"88CE0720" "FFD70720" "89D60720" "FFDF0720" \
"8ADE0720" "FFE70720" "8BE60720" "FFEF0720" \
"8CEE0720" "FFF70720" "8DF60720" "FFFF0720" \
"8EFE0720" \
"FFFF0720" "8EFE0720" "FFF70720" "8DF60720" \
"FFEF0720" "8CEE0720" "FFE70720" "8BE60720" \
"FFDF0720" "8ADE0720" "FFD70720" "89D60720" \
"FFCF0720" "88CE0720" "FFC70720" "87C60720" \
"FFBF0720" "86BE0720" "FFB70720" "85B60720" \
"FFAF0720" "84AE0720" "FFA70720" "83A60720" \
"FF9F0720" "829E0720" "FF970720" "81960720" \
"FF8F0720" "808E0720" "FF870720" "7F860720" \
"FFFD0720" "7EFC0720" "FFF50720" "7DF40720" \
"FFED0720" "7CEC0720" "FFE50720" "7BE40720" \
"FFDD0720" "7ADC0720" "FFD50720" "79D40720" \
"FFCD0720" "78CC0720" "FFC50720" "77C40720" \
"FFBD0720" "76BC0720" "FFB50720" "75B40720" \
"FFAD0720" "74AC0720" "FFA50720" "73A40720" \
"FF9D0720" "729C0720" "FF950720" "71940720" \
"FF8D0720" "708C0720" "FF850720" "6F840720" \
"FFFB0720" "6EFA0720" "FFF30720" "6DF20720" \
"FFEB0720" "6CEA0720" "FFE30720" "6BE20720" \
"FFDB0720" "6ADA0720" "FFD30720" "69D20720" \
"FFCB0720" "68CA0720" "FFC30720" "67C20720" \
"FFBB0720" "66BA0720" "FFB30720" "65B20720" \
"FFAB0720" "64AA0720" "FFA30720" "63A20720" \
"FF9B0720" "629A0720" "FF930720" "61920720" \
"FF8B0720" "608A0720" "FF830720" "5F820720" \
"5F820720" "FF830720" "5F820720" "FF830720" \
"5F820720" "FF830720" "5F820720" "FF8B0720" \
"608A0720" "FF930720" "61920720" "FF9B0720" \
"629A0720" "FFA30720" "63A20720" "FFAB0720" \
"64AA0720" "FFB30720" "65B20720" "FFBB0720" \
"66BA0720" "FFC30720" "67C20720" "FFCB0720" \
"68CA0720" "FFD30720" "69D20720" "FFDB0720" \
"6ADA0720" "FFE30720" "6BE20720" "FFEB0720" \
"6CEA0720" "FFF30720" "6DF20720" "FFFB0720" \
"6EFA0720" "FF850720" "6F840720" "FF8D0720" \
"708C0720" "FF950720" "71940720" "FF9D0720" \
"729C0720" "FFA50720" "73A40720" "FFAD0720" \
"74AC0720" "FFB50720" "75B40720" "FFBD0720" \
"76BC0720" "FFC50720" "77C40720" "FFCD0720" \
"78CC0720" "FFD50720" "79D40720" "FFDD0720" \
"7ADC0720" "FFE50720" "7BE40720" "FFED0720" \
"7CEC0720" "FFF50720" "7DF40720" "FFFD0720" \
"7EFC0720" "FF870720" "7F860720" "FF8F0720" \
"808E0720" "FF970720" "81960720" "FF9F0720" \
"829E0720" "FFA70720" "83A60720" "FFAF0720" \
"84AE0720" "FFB70720" "85B60720" "FFBF0720" \
"86BE0720" "FFC70720" "87C60720" "FFCF0720" \
"88CE0720" "FFD70720" "89D60720" "FFDF0720" \
"8ADE0720" "FFE70720" "8BE60720" "FFEF0720" \
"8CEE0720" "FFF70720" "8DF60720" "FFFF0720" \
"8EFE0720" \
"FFFF0720" "8EFE0720" "FFF70720" "8DF60720" \
"FFEF0720" "8CEE0720" "FFE70720" "8BE60720" \
"FFDF0720" "8ADE0720" "FFD70720" "89D60720" \
"FFCF0720" "88CE0720" "FFC70720" "87C60720" \
"FFBF0720" "86BE0720" "FFB70720" "85B60720" \
"FFAF0720" "84AE0720" "FFA70720" "83A60720" \
"FF9F0720" "829E0720" "FF970720" "81960720" \
"FF8F0720" "808E0720" "FF870720" "7F860720" \
"FFFD0720" "7EFC0720" "FFF50720" "7DF40720" \
"FFED0720" "7CEC0720" "FFE50720" "7BE40720" \
"FFDD0720" "7ADC0720" "FFD50720" "79D40720" \
"FFCD0720" "78CC0720" "FFC50720" "77C40720" \
"FFBD0720" "76BC0720" "FFB50720" "75B40720" \
"FFAD0720" "74AC0720" "FFA50720" "73A40720" \
"FF9D0720" "729C0720" "FF950720" "71940720" \
"FF8D0720" "708C0720" "FF850720" "6F840720" \
"FFFB0720" "6EFA0720" "FFF30720" "6DF20720" \
"FFEB0720" "6CEA0720" "FFE30720" "6BE20720" \
"FFDB0720" "6ADA0720" "FFD30720" "69D20720" \
"FFCB0720" "68CA0720" "FFC30720" "67C20720" \
"FFBB0720" "66BA0720" "FFB30720" "65B20720" \
"FFAB0720" "64AA0720" "FFA30720" "63A20720" \
"FF9B0720" "629A0720" "FF930720" "61920720" \
"FF8B0720" "608A0720" "FF830720" "5F820720" \
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () \
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () \
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () \
@@ -1871,49 +1873,49 @@ const char *vfs301_0220_01[] = {
"A46C0420"
"A46C0400"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420" "83688420" "83688420"
"83688420" "83688420"
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
@@ -2268,55 +2270,55 @@ const char *vfs301_02D0_04[] = {
* any troubles. */
PACKET ("0200", "8005",
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
"FFF30720" "80F20720" "FFF30720" "80F20720"
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
@@ -2437,55 +2439,55 @@ const char *vfs301_02D0_05[] = {
* any troubles. */
PACKET ("0200", "8005",
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
"FFF34720" "80F24720" "FFF34720" "80F24720"
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()
Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 () Z8 ()

View File

@@ -815,13 +815,11 @@ dev_close (FpImageDevice *dev)
GError *error = NULL;
FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011 (dev);
;
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
g_free (self->capture_buffer);
g_slist_free_full (self->rows, g_free);
g_slist_free_full (g_steal_pointer (&self->rows), g_free);
fpi_image_device_close_complete (dev, error);
}

View File

@@ -1,5 +1,7 @@
#pragma once
/* *INDENT-OFF* */
#define VFS5011_LINE_SIZE 240
#define VFS5011_IMAGE_WIDTH 160

View File

@@ -0,0 +1,355 @@
/*
* Socket utilities for "simple" device debugging
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* 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 "virtual_device_connection"
#include "fpi-log.h"
#include <glib/gstdio.h>
#include <gio/gunixsocketaddress.h>
#include "virtual-device-private.h"
struct _FpDeviceVirtualListener
{
GSocketListener parent_instance;
GSocketConnection *connection;
GCancellable *cancellable;
guint cancellable_id;
FpDeviceVirtualListenerConnectionCb ready_cb;
gpointer ready_cb_data;
gint socket_fd;
gint client_fd;
};
G_DEFINE_TYPE (FpDeviceVirtualListener, fp_device_virtual_listener, G_TYPE_SOCKET_LISTENER)
static void start_listen (FpDeviceVirtualListener *self);
FpDeviceVirtualListener *
fp_device_virtual_listener_new (void)
{
return g_object_new (fp_device_virtual_listener_get_type (), NULL);
}
static void
fp_device_virtual_listener_dispose (GObject *object)
{
FpDeviceVirtualListener *self = FP_DEVICE_VIRTUAL_LISTENER (object);
if (self->cancellable_id)
{
g_cancellable_disconnect (self->cancellable, self->cancellable_id);
self->cancellable_id = 0;
}
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->connection);
self->ready_cb = NULL;
G_OBJECT_CLASS (fp_device_virtual_listener_parent_class)->dispose (object);
}
static void
fp_device_virtual_listener_class_init (FpDeviceVirtualListenerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = fp_device_virtual_listener_dispose;
}
static void
fp_device_virtual_listener_init (FpDeviceVirtualListener *self)
{
}
static void
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualListener *self = user_data;
GSocketConnection *connection;
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
res,
NULL,
&error);
if (!connection)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Error accepting a new connection: %s", error->message);
start_listen (self);
return;
}
/* Always allow further connections.
* If we get a new one, we generally just close the old connection. */
start_listen (self);
if (self->connection)
{
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
}
self->connection = connection;
fp_dbg ("Got a new connection!");
self->ready_cb (self, self->ready_cb_data);
}
static void
start_listen (FpDeviceVirtualListener *self)
{
g_socket_listener_accept_async (G_SOCKET_LISTENER (self),
self->cancellable,
new_connection_cb,
self);
}
static void
on_cancelled (GCancellable *cancellable,
FpDeviceVirtualListener *self)
{
fp_device_virtual_listener_connection_close (self);
g_socket_listener_close (G_SOCKET_LISTENER (self));
g_clear_object (&self->cancellable);
self->ready_cb = NULL;
}
gboolean
fp_device_virtual_listener_start (FpDeviceVirtualListener *self,
const char *address,
GCancellable *cancellable,
FpDeviceVirtualListenerConnectionCb cb,
gpointer user_data,
GError **error)
{
g_autoptr(GSocketAddress) addr = NULL;
G_DEBUG_HERE ();
g_return_val_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self), FALSE);
g_return_val_if_fail (cb != NULL, FALSE);
g_return_val_if_fail (self->ready_cb == NULL, FALSE);
self->client_fd = -1;
g_socket_listener_set_backlog (G_SOCKET_LISTENER (self), 1);
/* Remove any left over socket. */
g_unlink (address);
addr = g_unix_socket_address_new (address);
if (!g_socket_listener_add_address (G_SOCKET_LISTENER (self),
addr,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
NULL,
NULL,
error))
{
g_warning ("Could not listen on unix socket: %s", (*error)->message);
return FALSE;
}
self->ready_cb = cb;
self->ready_cb_data = user_data;
self->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
if (self->cancellable)
self->cancellable_id = g_cancellable_connect (self->cancellable,
G_CALLBACK (on_cancelled), self, NULL);
start_listen (self);
return TRUE;
}
gboolean
fp_device_virtual_listener_connection_close (FpDeviceVirtualListener *self)
{
g_return_val_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self), FALSE);
if (!self->connection)
return FALSE;
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
return TRUE;
}
static void
on_stream_read_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(GError) error = NULL;
g_autoptr(GTask) task = user_data;
FpDeviceVirtualListener *self = g_task_get_source_object (task);
gboolean all;
gboolean success;
gsize bytes;
all = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "all"));
if (all)
{
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
}
else
{
gssize sbytes;
sbytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
bytes = sbytes;
success = (sbytes >= 0);
}
if (g_task_return_error_if_cancelled (task))
return;
/* If we are cancelled, just return immediately. */
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
{
g_task_return_int (task, 0);
return;
}
/* If this error is for an old connection (that should be closed already),
* then just give up immediately with a CLOSED error.
*/
if (self->connection &&
g_io_stream_get_input_stream (G_IO_STREAM (self->connection)) != G_INPUT_STREAM (source_object))
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_CLOSED,
"Error on old connection, ignoring.");
return;
}
if (!success || bytes == 0)
{
/* We accept it if someone tries to read twice and just return that error. */
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
{
if (self->connection)
{
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
}
}
if (error)
{
g_task_return_error (task, g_steal_pointer (&error));
return;
}
else
{
// g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Got empty data");
return;
}
}
g_task_return_int (task, bytes);
}
void
fp_device_virtual_listener_read (FpDeviceVirtualListener *self,
gboolean all,
void *buffer,
gsize count,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
GInputStream *stream;
g_return_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self));
task = g_task_new (self, self->cancellable, callback, user_data);
g_object_set_data (G_OBJECT (task), "all", GINT_TO_POINTER (all));
if (!self->connection || g_io_stream_is_closed (G_IO_STREAM (self->connection)))
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
"Listener not connected to any stream");
return;
}
stream = g_io_stream_get_input_stream (G_IO_STREAM (self->connection));
if (all)
{
g_input_stream_read_all_async (stream, buffer, count,
G_PRIORITY_DEFAULT,
self->cancellable,
on_stream_read_cb,
g_steal_pointer (&task));
}
else
{
g_input_stream_read_async (stream, buffer, count,
G_PRIORITY_DEFAULT,
self->cancellable,
on_stream_read_cb,
g_steal_pointer (&task));
}
}
gsize
fp_device_virtual_listener_read_finish (FpDeviceVirtualListener *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, self), 0);
return g_task_propagate_int (G_TASK (result), error);
}
gboolean
fp_device_virtual_listener_write_sync (FpDeviceVirtualListener *self,
const char *buffer,
gsize count,
GError **error)
{
if (!self->connection || g_io_stream_is_closed (G_IO_STREAM (self->connection)))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
"Listener not connected to any stream");
return FALSE;
}
return g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (self->connection)),
buffer,
count,
NULL,
self->cancellable,
error);
}

View File

@@ -0,0 +1,109 @@
/*
* Virtual driver for "simple" device debugging
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual driver to debug the non-image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to registered programmatically.
* Using this, it is possible to test libfprint and fprintd.
*/
#include <gio/gio.h>
#include "fpi-device.h"
#define MAX_LINE_LEN 1024
G_DECLARE_FINAL_TYPE (FpDeviceVirtualListener, fp_device_virtual_listener, FP, DEVICE_VIRTUAL_LISTENER, GSocketListener)
typedef void (*FpDeviceVirtualListenerConnectionCb) (FpDeviceVirtualListener *listener,
gpointer user_data);
FpDeviceVirtualListener * fp_device_virtual_listener_new (void);
gboolean fp_device_virtual_listener_start (FpDeviceVirtualListener *listener,
const char *address,
GCancellable *cancellable,
FpDeviceVirtualListenerConnectionCb cb,
gpointer user_data,
GError **error);
gboolean fp_device_virtual_listener_connection_close (FpDeviceVirtualListener *listener);
void fp_device_virtual_listener_read (FpDeviceVirtualListener *listener,
gboolean all,
void *buffer,
gsize count,
GAsyncReadyCallback callback,
gpointer user_data);
gsize fp_device_virtual_listener_read_finish (FpDeviceVirtualListener *listener,
GAsyncResult *result,
GError **error);
gboolean fp_device_virtual_listener_write_sync (FpDeviceVirtualListener *self,
const char *buffer,
gsize count,
GError **error);
struct _FpDeviceVirtualDevice
{
FpDevice parent;
FpDeviceVirtualListener *listener;
GCancellable *cancellable;
char recv_buf[MAX_LINE_LEN];
GPtrArray *pending_commands;
GHashTable *prints_storage;
guint wait_command_id;
guint sleep_timeout_id;
guint enroll_stages_passed;
gboolean match_reported;
gboolean supports_cancellation;
gboolean injected_synthetic_cmd;
gboolean ignore_wait;
gboolean keep_alive;
};
/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
* contents without having to use a shared private struct instead. */
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP, DEVICE_VIRTUAL_DEVICE, FpDevice)
struct _FpDeviceVirtualDeviceStorage
{
FpDeviceVirtualDevice parent;
};
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_storage, FP, DEVICE_VIRTUAL_DEVICE_STORAGE, FpDeviceVirtualDevice)
char * process_cmds (FpDeviceVirtualDevice * self, gboolean scan, GError **error);
char * start_scan_command (FpDeviceVirtualDevice *self,
GError **error);
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
GError *error);
gboolean should_wait_to_sleep (FpDeviceVirtualDevice *self,
const char *scan_id,
GError *error);

View File

@@ -0,0 +1,247 @@
/*
* Virtual driver for "simple" device debugging with storage
*
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual driver to debug the non-image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to registered programmatically.
* Using this, it is possible to test libfprint and fprintd.
*/
#define FP_COMPONENT "virtual_device_storage"
#include "virtual-device-private.h"
#include "fpi-log.h"
G_DEFINE_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_storage, fpi_device_virtual_device_get_type ())
static GPtrArray * get_stored_prints (FpDeviceVirtualDevice * self);
static void
dev_identify (FpDevice *dev)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
g_autofree char *scan_id = NULL;
scan_id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
if (scan_id)
{
g_autoptr(GPtrArray) stored = get_stored_prints (self);
GPtrArray *prints;
GVariant *data = NULL;
FpPrint *new_scan;
FpPrint *match = NULL;
guint idx;
new_scan = fp_print_new (dev);
fpi_print_set_type (new_scan, FPI_PRINT_RAW);
fpi_print_set_device_stored (new_scan, TRUE);
data = g_variant_new_string (scan_id);
g_object_set (new_scan, "fpi-data", data, NULL);
fpi_device_get_identify_data (dev, &prints);
g_debug ("Trying to identify print '%s' against a gallery of %u prints", scan_id, prints->len);
if (!g_ptr_array_find_with_equal_func (stored,
new_scan,
(GEqualFunc) fp_print_equal,
NULL))
error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND);
else if (g_ptr_array_find_with_equal_func (prints,
new_scan,
(GEqualFunc) fp_print_equal,
&idx))
match = g_ptr_array_index (prints, idx);
if (!self->match_reported)
{
self->match_reported = TRUE;
fpi_device_identify_report (dev,
match,
new_scan,
NULL);
}
}
else if (error && error->domain == FP_DEVICE_RETRY)
{
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
}
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_PRESENT);
if (should_wait_to_sleep (self, scan_id, error))
return;
self->match_reported = FALSE;
fpi_device_identify_complete (dev, g_steal_pointer (&error));
}
struct ListData
{
FpDevice *dev;
GPtrArray *res;
};
static void
dev_list_insert_print (gpointer key,
gpointer value,
gpointer user_data)
{
struct ListData *data = user_data;
FpPrint *print = fp_print_new (data->dev);
GVariant *var = NULL;
fpi_print_fill_from_user_id (print, key);
fpi_print_set_type (print, FPI_PRINT_RAW);
var = g_variant_new_string (key);
g_object_set (print, "fpi-data", var, NULL);
g_object_ref_sink (print);
g_ptr_array_add (data->res, print);
}
static GPtrArray *
get_stored_prints (FpDeviceVirtualDevice *self)
{
GPtrArray * prints_list;
struct ListData data;
prints_list = g_ptr_array_new_full (g_hash_table_size (self->prints_storage),
g_object_unref);
data.dev = FP_DEVICE (self);
data.res = prints_list;
g_hash_table_foreach (self->prints_storage, dev_list_insert_print, &data);
return prints_list;
}
static void
dev_list (FpDevice *dev)
{
g_autoptr(GPtrArray) prints_list = NULL;
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
process_cmds (vdev, FALSE, &error);
if (should_wait_for_command (vdev, error))
return;
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
return;
}
fpi_device_list_complete (dev, get_stored_prints (vdev), NULL);
}
static void
dev_delete (FpDevice *dev)
{
g_autoptr(GVariant) data = NULL;
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
FpPrint *print = NULL;
const char *id = NULL;
process_cmds (vdev, FALSE, &error);
if (should_wait_for_command (vdev, error))
return;
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_delete_complete (dev, g_steal_pointer (&error));
return;
}
fpi_device_get_delete_data (dev, &print);
g_object_get (print, "fpi-data", &data, NULL);
if (data == NULL)
{
fpi_device_delete_complete (dev,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
id = g_variant_get_string (data, NULL);
fp_dbg ("Deleting print %s for user %s",
id,
fp_print_get_username (print));
if (g_hash_table_remove (vdev->prints_storage, id))
fpi_device_delete_complete (dev, NULL);
else
fpi_device_delete_complete (dev,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
}
static void
fpi_device_virtual_device_storage_init (FpDeviceVirtualDeviceStorage *self)
{
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (self);
vdev->prints_storage = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
}
static void
fpi_device_virtual_device_storage_finalize (GObject *object)
{
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (object);
G_DEBUG_HERE ();
g_clear_pointer (&vdev->prints_storage, g_hash_table_destroy);
G_OBJECT_CLASS (fpi_device_virtual_device_storage_parent_class)->finalize (object);
}
static const FpIdEntry driver_ids[] = {
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE" },
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_IDENT" },
{ .virtual_envvar = NULL }
};
static void
fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fpi_device_virtual_device_storage_finalize;
dev_class->id = FP_COMPONENT;
dev_class->full_name = "Virtual device with storage and identification for debugging";
dev_class->id_table = driver_ids;
dev_class->identify = dev_identify;
dev_class->list = dev_list;
dev_class->delete = dev_delete;
}

View File

@@ -0,0 +1,779 @@
/*
* Virtual driver for "simple" device debugging
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual driver to debug the non-image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to registered programmatically.
* Using this, it is possible to test libfprint and fprintd.
*/
#define FP_COMPONENT "virtual_device"
#include "virtual-device-private.h"
#include "fpi-log.h"
G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE)
#define INSERT_CMD_PREFIX "INSERT "
#define REMOVE_CMD_PREFIX "REMOVE "
#define SCAN_CMD_PREFIX "SCAN "
#define ERROR_CMD_PREFIX "ERROR "
#define RETRY_CMD_PREFIX "RETRY "
#define FINGER_CMD_PREFIX "FINGER "
#define SLEEP_CMD_PREFIX "SLEEP "
#define SET_ENROLL_STAGES_PREFIX "SET_ENROLL_STAGES "
#define SET_SCAN_TYPE_PREFIX "SET_SCAN_TYPE "
#define SET_CANCELLATION_PREFIX "SET_CANCELLATION_ENABLED "
#define SET_KEEP_ALIVE_PREFIX "SET_KEEP_ALIVE "
#define LIST_CMD "LIST"
#define UNPLUG_CMD "UNPLUG"
static void
maybe_continue_current_action (FpDeviceVirtualDevice *self)
{
FpDevice *dev = FP_DEVICE (self);
if (self->sleep_timeout_id)
return;
switch (fpi_device_get_current_action (dev))
{
case FPI_DEVICE_ACTION_ENROLL:
FP_DEVICE_GET_CLASS (self)->enroll (dev);
break;
case FPI_DEVICE_ACTION_VERIFY:
FP_DEVICE_GET_CLASS (self)->verify (dev);
break;
case FPI_DEVICE_ACTION_IDENTIFY:
FP_DEVICE_GET_CLASS (self)->identify (dev);
break;
case FPI_DEVICE_ACTION_LIST:
FP_DEVICE_GET_CLASS (self)->list (dev);
break;
case FPI_DEVICE_ACTION_DELETE:
FP_DEVICE_GET_CLASS (self)->delete (dev);
break;
case FPI_DEVICE_ACTION_OPEN:
FP_DEVICE_GET_CLASS (self)->open (dev);
break;
case FPI_DEVICE_ACTION_CLOSE:
FP_DEVICE_GET_CLASS (self)->close (dev);
break;
default:
break;
}
}
static gboolean
sleep_timeout_cb (gpointer data)
{
FpDeviceVirtualDevice *self = data;
self->sleep_timeout_id = 0;
if (g_cancellable_is_cancelled (self->cancellable))
return FALSE;
g_debug ("Sleeping completed");
maybe_continue_current_action (self);
return FALSE;
}
char *
process_cmds (FpDeviceVirtualDevice * self,
gboolean scan,
GError **error)
{
if (g_cancellable_is_cancelled (self->cancellable) ||
(fpi_device_get_current_action (FP_DEVICE (self)) != FPI_DEVICE_ACTION_NONE &&
g_cancellable_is_cancelled (fpi_device_get_cancellable (FP_DEVICE (self)))))
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
"Operation was cancelled");
return NULL;
}
while (self->pending_commands->len > 0)
{
gchar *cmd = g_ptr_array_index (self->pending_commands, 0);
g_debug ("Processing command %s", cmd);
/* These are always processed. */
if (g_str_has_prefix (cmd, INSERT_CMD_PREFIX))
{
g_assert (self->prints_storage);
g_hash_table_add (self->prints_storage,
g_strdup (cmd + strlen (INSERT_CMD_PREFIX)));
g_ptr_array_remove_index (self->pending_commands, 0);
continue;
}
else if (g_str_has_prefix (cmd, REMOVE_CMD_PREFIX))
{
g_assert (self->prints_storage);
if (!g_hash_table_remove (self->prints_storage,
cmd + strlen (REMOVE_CMD_PREFIX)))
g_warning ("ID %s was not found in storage", cmd + strlen (REMOVE_CMD_PREFIX));
g_ptr_array_remove_index (self->pending_commands, 0);
continue;
}
else if (g_str_has_prefix (cmd, SLEEP_CMD_PREFIX))
{
guint64 sleep_ms = g_ascii_strtoull (cmd + strlen (SLEEP_CMD_PREFIX), NULL, 10);
g_debug ("Sleeping %lums", sleep_ms);
self->sleep_timeout_id = g_timeout_add (sleep_ms, sleep_timeout_cb, self);
g_ptr_array_remove_index (self->pending_commands, 0);
return NULL;
}
else if (g_str_has_prefix (cmd, ERROR_CMD_PREFIX))
{
g_propagate_error (error,
fpi_device_error_new (g_ascii_strtoull (cmd + strlen (ERROR_CMD_PREFIX), NULL, 10)));
g_ptr_array_remove_index (self->pending_commands, 0);
return NULL;
}
/* If we are not scanning, then we have to stop here. */
if (!scan)
{
g_warning ("Could not process command: %s", cmd);
g_ptr_array_remove_index (self->pending_commands, 0);
break;
}
if (g_str_has_prefix (cmd, SCAN_CMD_PREFIX))
{
char *res = g_strdup (cmd + strlen (SCAN_CMD_PREFIX));
g_ptr_array_remove_index (self->pending_commands, 0);
return res;
}
else if (g_str_has_prefix (cmd, RETRY_CMD_PREFIX))
{
g_propagate_error (error,
fpi_device_retry_new (g_ascii_strtoull (cmd + strlen (RETRY_CMD_PREFIX), NULL, 10)));
g_ptr_array_remove_index (self->pending_commands, 0);
return NULL;
}
else if (g_str_has_prefix (cmd, FINGER_CMD_PREFIX))
{
gboolean finger_present;
finger_present = g_ascii_strtoull (cmd + strlen (FINGER_CMD_PREFIX), NULL, 10) != 0;
fpi_device_report_finger_status_changes (FP_DEVICE (self),
finger_present ? FP_FINGER_STATUS_PRESENT : FP_FINGER_STATUS_NONE,
finger_present ? FP_FINGER_STATUS_NONE : FP_FINGER_STATUS_PRESENT);
g_ptr_array_remove_index (self->pending_commands, 0);
continue;
}
else
{
g_warning ("Could not process command: %s", cmd);
g_ptr_array_remove_index (self->pending_commands, 0);
}
}
/* No commands left, throw a timeout error. */
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No commands left that can be run!");
return NULL;
}
static void
write_key_to_listener (void *key, void *val, void *user_data)
{
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (user_data);
if (!fp_device_virtual_listener_write_sync (listener, key, strlen (key), NULL) ||
!fp_device_virtual_listener_write_sync (listener, "\n", 1, NULL))
g_warning ("Error writing reply to LIST command");
}
static void
recv_instruction_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
gsize bytes;
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
fp_dbg ("Got instructions of length %ld", bytes);
if (error)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Error receiving instruction data: %s", error->message);
return;
}
if (bytes > 0)
{
FpDeviceVirtualDevice *self;
g_autofree char *cmd = NULL;
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
cmd = g_strndup (self->recv_buf, bytes);
fp_dbg ("Received command %s", cmd);
if (g_str_has_prefix (cmd, LIST_CMD))
{
if (self->prints_storage)
g_hash_table_foreach (self->prints_storage, write_key_to_listener, listener);
}
else if (g_str_has_prefix (cmd, UNPLUG_CMD))
{
fpi_device_remove (FP_DEVICE (self));
}
else if (g_str_has_prefix (cmd, SET_ENROLL_STAGES_PREFIX))
{
guint stages;
stages = g_ascii_strtoull (cmd + strlen (SET_ENROLL_STAGES_PREFIX), NULL, 10);
fpi_device_set_nr_enroll_stages (FP_DEVICE (self), stages);
}
else if (g_str_has_prefix (cmd, SET_SCAN_TYPE_PREFIX))
{
const char *scan_type = cmd + strlen (SET_SCAN_TYPE_PREFIX);
g_autoptr(GEnumClass) scan_types = g_type_class_ref (fp_scan_type_get_type ());
GEnumValue *value = g_enum_get_value_by_nick (scan_types, scan_type);
if (value)
fpi_device_set_scan_type (FP_DEVICE (self), value->value);
else
g_warning ("Scan type '%s' not found", scan_type);
}
else if (g_str_has_prefix (cmd, SET_CANCELLATION_PREFIX))
{
self->supports_cancellation = g_ascii_strtoull (
cmd + strlen (SET_CANCELLATION_PREFIX), NULL, 10) != 0;
g_debug ("Cancellation support toggled: %d",
self->supports_cancellation);
}
else if (g_str_has_prefix (cmd, SET_KEEP_ALIVE_PREFIX))
{
self->keep_alive = g_ascii_strtoull (
cmd + strlen (SET_KEEP_ALIVE_PREFIX), NULL, 10) != 0;
g_debug ("Keep alive toggled: %d", self->keep_alive);
}
else
{
g_ptr_array_add (self->pending_commands, g_steal_pointer (&cmd));
g_clear_handle_id (&self->wait_command_id, g_source_remove);
maybe_continue_current_action (self);
}
}
fp_device_virtual_listener_connection_close (listener);
}
static void
recv_instruction (FpDeviceVirtualDevice *self)
{
fp_device_virtual_listener_read (self->listener,
FALSE,
self->recv_buf,
sizeof (self->recv_buf),
recv_instruction_cb,
self);
}
static void
on_listener_connected (FpDeviceVirtualListener *listener,
gpointer user_data)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
recv_instruction (self);
}
static void
dev_init (FpDevice *dev)
{
g_autoptr(GError) error = NULL;
g_autoptr(GCancellable) cancellable = NULL;
g_autoptr(FpDeviceVirtualListener) listener = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
G_DEBUG_HERE ();
process_cmds (self, FALSE, &error);
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_open_complete (dev, g_steal_pointer (&error));
return;
}
else if (self->sleep_timeout_id)
{
return;
}
else if (self->listener)
{
fpi_device_open_complete (dev, NULL);
return;
}
listener = fp_device_virtual_listener_new ();
cancellable = g_cancellable_new ();
if (!fp_device_virtual_listener_start (listener,
fpi_device_get_virtual_env (FP_DEVICE (self)),
cancellable,
on_listener_connected,
self,
&error))
{
fpi_device_open_complete (dev, g_steal_pointer (&error));
return;
}
self->listener = g_steal_pointer (&listener);
self->cancellable = g_steal_pointer (&cancellable);
fpi_device_open_complete (dev, NULL);
}
static gboolean
wait_for_command_timeout (gpointer data)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (data);
GError *error = NULL;
self->wait_command_id = 0;
switch (fpi_device_get_current_action (FP_DEVICE (self)))
{
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_DELETE:
self->ignore_wait = TRUE;
maybe_continue_current_action (self);
self->ignore_wait = FALSE;
return FALSE;
default:
break;
}
error = g_error_new (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "No commands arrived in time to run!");
fpi_device_action_error (FP_DEVICE (self), error);
return FALSE;
}
gboolean
should_wait_for_command (FpDeviceVirtualDevice *self,
GError *error)
{
if (!error && self->sleep_timeout_id)
return TRUE;
if (self->ignore_wait)
return FALSE;
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
return FALSE;
if (self->wait_command_id)
return FALSE;
self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self);
return TRUE;
}
char *
start_scan_command (FpDeviceVirtualDevice *self,
GError **error)
{
g_autoptr(GError) local_error = NULL;
g_autofree char *scan_id = NULL;
if (fp_device_get_finger_status (FP_DEVICE (self)) == FP_FINGER_STATUS_NONE)
self->injected_synthetic_cmd = FALSE;
scan_id = process_cmds (self, TRUE, &local_error);
if (!self->sleep_timeout_id)
{
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE);
}
if (should_wait_for_command (self, local_error))
{
g_assert (!scan_id);
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
"Still waiting for command");
return NULL;
}
if (local_error)
g_propagate_error (error, g_steal_pointer (&local_error));
else
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_PRESENT,
FP_FINGER_STATUS_NONE);
return g_steal_pointer (&scan_id);
}
gboolean
should_wait_to_sleep (FpDeviceVirtualDevice *self,
const char *scan_id,
GError *error)
{
const gchar *cmd;
if (self->sleep_timeout_id)
return TRUE;
if (!self->pending_commands->len)
return FALSE;
cmd = g_ptr_array_index (self->pending_commands, 0);
if (g_str_has_prefix (cmd, SLEEP_CMD_PREFIX))
{
g_autoptr(GError) local_error = NULL;
g_free (process_cmds (self, FALSE, &local_error));
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return FALSE;
g_assert (!self->injected_synthetic_cmd);
g_assert (self->sleep_timeout_id != 0);
if (!self->pending_commands->len)
{
g_autofree char *injected_cmd = NULL;
if (scan_id)
injected_cmd = g_strconcat (SCAN_CMD_PREFIX, scan_id, NULL);
else if (error && error->domain == FP_DEVICE_ERROR)
injected_cmd = g_strdup_printf (ERROR_CMD_PREFIX " %d", error->code);
else if (error && error->domain == FP_DEVICE_RETRY)
injected_cmd = g_strdup_printf (RETRY_CMD_PREFIX " %d", error->code);
else
return TRUE;
g_debug ("Sleeping now, command queued for later: %s", injected_cmd);
g_ptr_array_insert (self->pending_commands, 0, g_steal_pointer (&injected_cmd));
self->injected_synthetic_cmd = TRUE;
}
}
return self->sleep_timeout_id != 0;
}
static void
dev_verify (FpDevice *dev)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
g_autofree char *scan_id = NULL;
scan_id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
if (scan_id)
{
GVariant *data = NULL;
FpPrint *new_scan;
FpPrint *print;
gboolean success;
g_debug ("Virtual device scanned print %s", scan_id);
fpi_device_get_verify_data (dev, &print);
new_scan = fp_print_new (dev);
fpi_print_set_type (new_scan, FPI_PRINT_RAW);
if (self->prints_storage)
fpi_print_set_device_stored (new_scan, TRUE);
data = g_variant_new_string (scan_id);
g_object_set (new_scan, "fpi-data", data, NULL);
if (self->prints_storage && !g_hash_table_contains (self->prints_storage, scan_id))
{
error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND);
success = FALSE;
}
else
{
success = fp_print_equal (print, new_scan);
}
if (!self->match_reported)
{
self->match_reported = TRUE;
fpi_device_verify_report (dev,
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
new_scan,
NULL);
}
}
else if (error)
{
g_debug ("Virtual device scan failed with error: %s", error->message);
}
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_PRESENT);
if (error && error->domain == FP_DEVICE_RETRY)
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
if (should_wait_to_sleep (self, scan_id, error))
return;
self->match_reported = FALSE;
fpi_device_verify_complete (dev, g_steal_pointer (&error));
}
static void
dev_enroll (FpDevice *dev)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
FpPrint *print = NULL;
g_autofree char *id = NULL;
id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
fpi_device_get_enroll_data (dev, &print);
if (id)
{
GVariant *data;
gboolean completed;
if (self->prints_storage && g_hash_table_contains (self->prints_storage, id))
{
if (should_wait_to_sleep (self, id, error))
return;
fpi_device_enroll_complete (dev, NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE));
return;
}
if (self->enroll_stages_passed == 0)
{
fpi_print_set_type (print, FPI_PRINT_RAW);
data = g_variant_new_string (id);
g_object_set (print, "fpi-data", data, NULL);
}
else
{
gboolean changed;
g_object_get (print, "fpi-data", &data, NULL);
changed = !g_str_equal (id, g_variant_get_string (data, NULL));
g_variant_unref (data);
if (changed)
{
g_set_error (&error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL, "ID Mismatch");
fpi_device_enroll_progress (dev, self->enroll_stages_passed, NULL,
g_steal_pointer (&error));
if (!should_wait_to_sleep (self, id, error))
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
return;
}
}
self->enroll_stages_passed++;
completed = self->enroll_stages_passed == fp_device_get_nr_enroll_stages (FP_DEVICE (self));
fpi_device_report_finger_status_changes (FP_DEVICE (self),
completed ?
FP_FINGER_STATUS_NEEDED :
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_PRESENT);
fpi_device_enroll_progress (dev, self->enroll_stages_passed, print, NULL);
if (completed)
{
if (self->prints_storage)
{
fpi_print_set_device_stored (print, TRUE);
g_hash_table_add (self->prints_storage, g_strdup (id));
}
fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
self->enroll_stages_passed = 0;
}
else if (!should_wait_to_sleep (self, id, error))
{
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
}
}
else
{
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_PRESENT);
if (error && error->domain == FP_DEVICE_RETRY)
{
fpi_device_enroll_progress (dev, self->enroll_stages_passed, NULL, g_steal_pointer (&error));
if (!should_wait_to_sleep (self, id, error))
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
}
else
{
if (should_wait_to_sleep (self, id, error))
return;
self->enroll_stages_passed = 0;
fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
}
}
}
static void
dev_cancel (FpDevice *dev)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
if (self->injected_synthetic_cmd)
{
self->injected_synthetic_cmd = FALSE;
g_ptr_array_remove_index (self->pending_commands, 0);
}
if (!self->supports_cancellation)
return;
g_debug ("Got cancellation!");
g_clear_handle_id (&self->sleep_timeout_id, g_source_remove);
maybe_continue_current_action (self);
}
static void
stop_listener (FpDeviceVirtualDevice *self)
{
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->listener);
}
static void
dev_deinit (FpDevice *dev)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
process_cmds (self, FALSE, &error);
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_close_complete (dev, g_steal_pointer (&error));
return;
}
else if (self->sleep_timeout_id)
{
return;
}
g_clear_handle_id (&self->wait_command_id, g_source_remove);
g_clear_handle_id (&self->sleep_timeout_id, g_source_remove);
if (!self->keep_alive)
stop_listener (self);
fpi_device_close_complete (dev, NULL);
}
static void
fpi_device_virtual_device_finalize (GObject *object)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
G_DEBUG_HERE ();
stop_listener (self);
g_clear_pointer (&self->pending_commands, g_ptr_array_unref);
G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->finalize (object);
}
static void
fpi_device_virtual_device_init (FpDeviceVirtualDevice *self)
{
self->supports_cancellation = TRUE;
self->pending_commands = g_ptr_array_new_with_free_func (g_free);
}
static const FpIdEntry driver_ids[] = {
{ .virtual_envvar = "FP_VIRTUAL_DEVICE", },
{ .virtual_envvar = NULL }
};
static void
fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fpi_device_virtual_device_finalize;
dev_class->id = FP_COMPONENT;
dev_class->full_name = "Virtual device for debugging";
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
dev_class->id_table = driver_ids;
dev_class->nr_enroll_stages = 5;
dev_class->open = dev_init;
dev_class->close = dev_deinit;
dev_class->verify = dev_verify;
dev_class->enroll = dev_enroll;
dev_class->cancel = dev_cancel;
}

View File

@@ -29,36 +29,27 @@
#include "fpi-log.h"
#include "virtual-device-private.h"
#include "../fpi-image.h"
#include "../fpi-image-device.h"
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
struct _FpDeviceVirtualImage
{
FpImageDevice parent;
FpImageDevice parent;
GSocketListener *listener;
GSocketConnection *connection;
GCancellable *listen_cancellable;
GCancellable *cancellable;
FpDeviceVirtualListener *listener;
GCancellable *cancellable;
gint socket_fd;
gint client_fd;
gboolean automatic_finger;
FpImage *recv_img;
gint recv_img_hdr[2];
gboolean automatic_finger;
FpImage *recv_img;
gint recv_img_hdr[2];
};
G_DECLARE_FINAL_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FPI, DEVICE_VIRTUAL_IMAGE, FpImageDevice)
G_DEFINE_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FP_TYPE_IMAGE_DEVICE)
static void start_listen (FpDeviceVirtualImage *dev);
static void recv_image (FpDeviceVirtualImage *dev,
GInputStream *stream);
static void recv_image (FpDeviceVirtualImage *self);
static void
recv_image_img_recv_cb (GObject *source_object,
@@ -66,35 +57,20 @@ recv_image_img_recv_cb (GObject *source_object,
gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
FpDeviceVirtualImage *self;
FpImageDevice *device;
gboolean success;
gsize bytes = 0;
gsize bytes;
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
/* Can't use self if the operation was cancelled. */
if (!success && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
if (!bytes || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
return;
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
device = FP_IMAGE_DEVICE (self);
/* Consider success if we received the right amount of data, otherwise
* an error must have happened. */
if (bytes < self->recv_img->width * self->recv_img->height)
{
if (!success)
g_warning ("Error receiving image data: %s", error->message);
else
g_warning ("Error receiving image data: end of stream before all data was read");
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
return;
}
if (self->automatic_finger)
fpi_image_device_report_finger_status (device, TRUE);
fpi_image_device_image_captured (device, g_steal_pointer (&self->recv_img));
@@ -102,7 +78,7 @@ recv_image_img_recv_cb (GObject *source_object,
fpi_image_device_report_finger_status (device, FALSE);
/* And, listen for more images from the same client. */
recv_image (self, G_INPUT_STREAM (source_object));
recv_image (self);
}
static void
@@ -112,37 +88,30 @@ recv_image_hdr_recv_cb (GObject *source_object,
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualImage *self;
gboolean success;
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
gsize bytes;
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
if (!success || bytes != sizeof (self->recv_img_hdr))
if (error)
{
if (!success)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
return;
g_warning ("Error receiving header for image data: %s", error->message);
}
else if (bytes != 0)
{
g_warning ("Received incomplete header before end of stream.");
}
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
g_warning ("Error receiving header for image data: %s", error->message);
return;
}
if (!bytes)
return;
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000)
{
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
fp_device_virtual_listener_connection_close (listener);
}
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
@@ -178,153 +147,80 @@ recv_image_hdr_recv_cb (GObject *source_object,
default:
/* disconnect client, it didn't play fair */
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
fp_device_virtual_listener_connection_close (listener);
}
/* And, listen for more images from the same client. */
recv_image (self, G_INPUT_STREAM (source_object));
recv_image (self);
return;
}
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
g_debug ("image data: %p", self->recv_img->data);
g_input_stream_read_all_async (G_INPUT_STREAM (source_object),
(guint8 *) self->recv_img->data,
self->recv_img->width * self->recv_img->height,
G_PRIORITY_DEFAULT,
self->cancellable,
recv_image_img_recv_cb,
self);
fp_device_virtual_listener_read (listener,
TRUE,
(guint8 *) self->recv_img->data,
self->recv_img->width * self->recv_img->height,
recv_image_img_recv_cb,
self);
}
static void
recv_image (FpDeviceVirtualImage *self, GInputStream *stream)
recv_image (FpDeviceVirtualImage *self)
{
fp_device_virtual_listener_read (self->listener,
TRUE,
self->recv_img_hdr,
sizeof (self->recv_img_hdr),
recv_image_hdr_recv_cb,
self);
}
static void
on_listener_connected (FpDeviceVirtualListener *listener,
gpointer user_data)
{
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
FpiImageDeviceState state;
g_object_get (self, "fpi-image-device-state", &state, NULL);
self->automatic_finger = TRUE;
g_debug ("Starting image receive (if active), state is: %i", state);
g_object_get (self,
"fpi-image-device-state", &state,
NULL);
/* Only read if we are in AWAIT_FINGER_* or CAPTURE states */
if (state <= FPI_IMAGE_DEVICE_STATE_DEACTIVATING)
return;
/* Only register if the state is active. */
if (state >= FPI_IMAGE_DEVICE_STATE_IDLE)
{
g_input_stream_read_all_async (stream,
self->recv_img_hdr,
sizeof (self->recv_img_hdr),
G_PRIORITY_DEFAULT,
self->cancellable,
recv_image_hdr_recv_cb,
self);
}
}
static void
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GError) error = NULL;
GSocketConnection *connection;
GInputStream *stream;
FpDeviceVirtualImage *dev = user_data;
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
res,
NULL,
&error);
if (!connection)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Error accepting a new connection: %s", error->message);
start_listen (dev);
}
/* Always accept further connections (but we disconnect them immediately
* if we already have a connection). */
start_listen (dev);
if (dev->connection)
{
/* We may not have noticed that the stream was closed,
* if the device is deactivated.
* Cancel any ongoing operation on the old connection. */
g_cancellable_cancel (dev->cancellable);
g_clear_object (&dev->cancellable);
dev->cancellable = g_cancellable_new ();
g_clear_object (&dev->connection);
}
if (dev->connection)
{
g_warning ("Rejecting new connection");
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
g_object_unref (connection);
return;
}
dev->connection = connection;
dev->automatic_finger = TRUE;
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
fp_dbg ("Got a new connection!");
recv_image (dev, stream);
}
static void
start_listen (FpDeviceVirtualImage *dev)
{
g_socket_listener_accept_async (dev->listener,
dev->listen_cancellable,
new_connection_cb,
dev);
recv_image (self);
}
static void
dev_init (FpImageDevice *dev)
{
g_autoptr(GError) error = NULL;
g_autoptr(GSocketListener) listener = NULL;
g_autoptr(FpDeviceVirtualListener) listener = NULL;
g_autoptr(GCancellable) cancellable = NULL;
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
const char *env;
g_autoptr(GSocketAddress) addr = NULL;
G_DEBUG_HERE ();
self->client_fd = -1;
listener = fp_device_virtual_listener_new ();
cancellable = g_cancellable_new ();
env = fpi_device_get_virtual_env (FP_DEVICE (self));
listener = g_socket_listener_new ();
g_socket_listener_set_backlog (listener, 1);
/* Remove any left over socket. */
g_unlink (env);
addr = g_unix_socket_address_new (env);
if (!g_socket_listener_add_address (listener,
addr,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
NULL,
NULL,
&error))
if (!fp_device_virtual_listener_start (listener,
fpi_device_get_virtual_env (FP_DEVICE (self)),
cancellable,
on_listener_connected,
self,
&error))
{
g_warning ("Could not listen on unix socket: %s", error->message);
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
fpi_image_device_open_complete (dev, g_steal_pointer (&error));
return;
}
self->listener = g_steal_pointer (&listener);
self->cancellable = g_cancellable_new ();
self->listen_cancellable = g_cancellable_new ();
start_listen (self);
self->cancellable = g_steal_pointer (&cancellable);
/* 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);
@@ -338,11 +234,8 @@ dev_deinit (FpImageDevice *dev)
G_DEBUG_HERE ();
g_cancellable_cancel (self->cancellable);
g_cancellable_cancel (self->listen_cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->listen_cancellable);
g_clear_object (&self->listener);
g_clear_object (&self->connection);
/* 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);
@@ -353,23 +246,16 @@ dev_activate (FpImageDevice *dev)
{
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
fpi_image_device_activate_complete (dev, NULL);
/* Start reading (again). */
recv_image (self);
if (self->connection)
recv_image (self, g_io_stream_get_input_stream (G_IO_STREAM (self->connection)));
fpi_image_device_activate_complete (dev, NULL);
}
static void
dev_deactivate (FpImageDevice *dev)
{
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
self->cancellable = g_cancellable_new ();
/* XXX: Need to wait for the operation to be cancelled. */
fpi_device_add_timeout (FP_DEVICE (dev), 10, (FpTimeoutFunc) fpi_image_device_deactivate_complete, NULL, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void

View File

@@ -0,0 +1,676 @@
/*
* Virtual driver for SDCP device debugging
*
* Copyright (C) 2020 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual test driver to test the basic SDCP functionality.
* It uses the test binaries from Microsoft, which were extended to allow
* a simple chat with the device.
* The environment variable contains the to be executed binary including
* arguments. This binary should be compiled from the code in
* https://github.com/Microsoft/SecureDeviceConnectionProtocol
* or, until it is merged upstream
* https://github.com/benzea/SecureDeviceConnectionProtocol
*
* Note that using this as an external executable has the advantage that we
* do not need to link against mbedtls or any other crypto library.
*/
#define FP_COMPONENT "virtual_sdcp"
#include "fpi-log.h"
#include "fpi-ssm.h"
#include "../fpi-sdcp-device.h"
#include <glib/gstdio.h>
#include <gio/gio.h>
struct _FpDeviceVirtualSdcp
{
FpSdcpDevice parent;
GSubprocess *proc;
GOutputStream *proc_stdin;
GInputStream *proc_stdout;
/* Only valid while a read/write is pending */
GByteArray *msg_out;
GByteArray *msg_in;
GByteArray *connect_msg;
};
G_DECLARE_FINAL_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FPI, DEVICE_VIRTUAL_SDCP, FpSdcpDevice)
G_DEFINE_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FP_TYPE_SDCP_DEVICE)
guint8 ca_1[] = {
0x30, 0x82, 0x03, 0xFD, 0x30, 0x82, 0x03, 0x82, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
0x00, 0x00, 0x00, 0x07, 0xE8, 0x9D, 0x61, 0x62, 0x4D, 0x46, 0x0F, 0x95, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81,
0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25,
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65,
0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41,
0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x33, 0x31, 0x31,
0x39, 0x35, 0x34, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x31, 0x33, 0x31, 0x32, 0x30,
0x30, 0x34, 0x35, 0x33, 0x5A, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57,
0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06,
0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20,
0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06,
0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65,
0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20,
0x32, 0x30, 0x31, 0x38, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBE,
0x4B, 0x90, 0x6E, 0x24, 0xFC, 0xA1, 0x53, 0xC8, 0xA7, 0x3C, 0x70, 0xE8, 0x97, 0xCD, 0x1B, 0x31,
0xE4, 0x95, 0x91, 0x7A, 0x58, 0xA2, 0x86, 0xA8, 0x70, 0xF6, 0x09, 0x30, 0x77, 0x99, 0x3D, 0x10,
0xDF, 0xF7, 0x95, 0x0F, 0x68, 0x83, 0xE6, 0xA4, 0x11, 0x7C, 0xDA, 0x82, 0xE7, 0x0B, 0x8B, 0xF2,
0x9D, 0x6B, 0x5B, 0xF5, 0x3E, 0x77, 0xB4, 0xC1, 0x0E, 0x49, 0x00, 0x83, 0xBA, 0x94, 0xF8, 0xA3,
0x82, 0x01, 0xD7, 0x30, 0x82, 0x01, 0xD3, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01,
0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
0x04, 0x16, 0x04, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB,
0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04,
0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B,
0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06,
0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A,
0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E,
0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F,
0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30,
0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A,
0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D,
0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01,
0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04,
0x18, 0x30, 0x16, 0x80, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB,
0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x68, 0x06, 0x03, 0x55, 0x1D, 0x1F,
0x04, 0x61, 0x30, 0x5F, 0x30, 0x5D, 0xA0, 0x5B, 0xA0, 0x59, 0x86, 0x57, 0x68, 0x74, 0x74, 0x70,
0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F,
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25,
0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63,
0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E,
0x63, 0x72, 0x6C, 0x30, 0x75, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86,
0x59, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32,
0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25,
0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25,
0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86,
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x87, 0xB6,
0x82, 0xF3, 0xDA, 0xBE, 0xB1, 0x7B, 0x98, 0x7D, 0x3D, 0x0A, 0x90, 0xA8, 0xF5, 0xBF, 0x15, 0xC3,
0xEE, 0x8A, 0x4E, 0xC0, 0x7B, 0x10, 0x1D, 0xA9, 0xE3, 0x0B, 0xEC, 0x2C, 0x53, 0x4E, 0xA7, 0xBD,
0xF1, 0x6C, 0xAD, 0x18, 0x55, 0xBA, 0x25, 0x73, 0x55, 0xB7, 0x5B, 0x12, 0x24, 0xF4, 0x02, 0x31,
0x00, 0xAF, 0x02, 0x9C, 0x4B, 0x92, 0xD0, 0x72, 0xA5, 0x80, 0xCA, 0x69, 0x2B, 0x38, 0x50, 0x64,
0xD8, 0x58, 0x9E, 0xEA, 0xD6, 0x35, 0xCF, 0x68, 0x98, 0x92, 0x81, 0x09, 0x61, 0xC2, 0xBD, 0xB1,
0x4C, 0x7F, 0xAE, 0x55, 0x7B, 0xFC, 0x22, 0xDD, 0xD6, 0xB7, 0x7C, 0xB5, 0xA8, 0x18, 0x5D, 0x33,
0x04
};
guint8 ca_2[] = {
0x30, 0x82, 0x04, 0x56, 0x30, 0x82, 0x03, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
0x00, 0x00, 0x00, 0x03, 0x6C, 0xCF, 0xED, 0xE2, 0x44, 0x70, 0x19, 0xBF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81,
0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x3E, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35,
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x44, 0x65,
0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
0x20, 0x32, 0x30, 0x31, 0x37, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x31,
0x39, 0x34, 0x39, 0x33, 0x38, 0x5A, 0x17, 0x0D, 0x33, 0x33, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39,
0x35, 0x39, 0x33, 0x38, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A,
0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C,
0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C,
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48,
0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69,
0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x76, 0x30, 0x10,
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22,
0x03, 0x62, 0x00, 0x04, 0x1D, 0xDD, 0x08, 0x02, 0x03, 0x25, 0x75, 0x20, 0xE2, 0x71, 0x8B, 0xAD,
0x28, 0x09, 0x82, 0xE9, 0x06, 0xEE, 0x83, 0xC5, 0x3A, 0x6C, 0x4B, 0x71, 0x92, 0x50, 0x4E, 0x20,
0xE9, 0x72, 0xB4, 0xFC, 0x53, 0x2A, 0xEF, 0x5D, 0xCC, 0x9A, 0xB4, 0xCD, 0x76, 0xB8, 0x94, 0x97,
0x44, 0xB2, 0x71, 0x0E, 0xC9, 0xB1, 0x16, 0x03, 0xA1, 0x65, 0x2B, 0xB9, 0xE8, 0x5D, 0x5F, 0xF2,
0x30, 0x2E, 0xDD, 0xB1, 0x2B, 0x20, 0xFC, 0xBE, 0x00, 0x88, 0xEA, 0x1F, 0xA7, 0x7F, 0x99, 0x84,
0x98, 0x7C, 0x71, 0x3E, 0x4D, 0x34, 0x83, 0x69, 0x9B, 0x08, 0xCB, 0x78, 0xB2, 0x4B, 0xBD, 0xD7,
0x3E, 0xBE, 0x67, 0xA0, 0xA3, 0x82, 0x01, 0xFC, 0x30, 0x82, 0x01, 0xF8, 0x30, 0x10, 0x06, 0x09,
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D,
0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03,
0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x65, 0x06,
0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00,
0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01,
0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34,
0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F,
0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F,
0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E,
0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30,
0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03,
0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06,
0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x14, 0xDA, 0x5B, 0xF1, 0x0E, 0x66,
0x47, 0xD1, 0x5D, 0x13, 0x5F, 0x5B, 0x7A, 0xEB, 0xEB, 0x5F, 0x01, 0x08, 0xB5, 0x49, 0x30, 0x7A,
0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x73, 0x30, 0x71, 0x30, 0x6F, 0xA0, 0x6D, 0xA0, 0x6B, 0x86,
0x69, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32,
0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32,
0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25,
0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x81, 0x87, 0x06, 0x08, 0x2B,
0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7B, 0x30, 0x79, 0x30, 0x77, 0x06, 0x08, 0x2B,
0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x6B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F,
0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x4D,
0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32,
0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25,
0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30,
0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37,
0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x56, 0x2A, 0xAD, 0x72, 0x4C, 0xB9, 0x8C, 0xB3, 0x23,
0x80, 0xF5, 0x5F, 0xF8, 0x21, 0x94, 0x66, 0x0F, 0x76, 0x77, 0xE2, 0x7B, 0x03, 0xDD, 0x30, 0x5E,
0xCB, 0x90, 0xCA, 0x78, 0xE6, 0x0B, 0x2D, 0x12, 0xE5, 0xF7, 0x67, 0x31, 0x58, 0x71, 0xE6, 0xF3,
0x64, 0xC1, 0x04, 0xB3, 0x8B, 0xE9, 0xE2, 0x02, 0x31, 0x00, 0xB9, 0x20, 0x61, 0xB9, 0xD0, 0x5E,
0x3A, 0xA4, 0xA2, 0x8A, 0xFE, 0x1D, 0xFC, 0x27, 0x61, 0x0B, 0x98, 0x16, 0x8C, 0x02, 0x9C, 0x20,
0x7F, 0xEE, 0xF3, 0xCB, 0x1F, 0x0A, 0x37, 0x62, 0xB1, 0x8E, 0xCE, 0xD9, 0x9A, 0x9E, 0xAC, 0xE6,
0x1A, 0xD4, 0xB8, 0xF1, 0xA8, 0x2B, 0xB1, 0xB4, 0x40, 0x9B
};
static void
msg_written_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
FpiSsm *ssm = user_data;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
g_clear_pointer (&self->msg_out, g_byte_array_unref);
g_assert (self->msg_out == NULL);
if (!g_output_stream_write_all_finish (stream, res, NULL, &error))
{
fpi_ssm_mark_failed (ssm, error);
return;
}
fpi_ssm_next_state (ssm);
}
static void
msg_received_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
GInputStream *stream = G_INPUT_STREAM (source_object);
FpiSsm *ssm = user_data;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
gsize read;
g_assert (self->msg_out == NULL);
if (!g_input_stream_read_all_finish (stream, res, &read, &error) ||
read != self->msg_in->len)
{
g_clear_pointer (&self->msg_in, g_byte_array_unref);
if (!error)
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Received EOF while reading from test binary.");
fpi_ssm_mark_failed (ssm, error);
return;
}
fpi_ssm_next_state (ssm);
}
enum {
SEND_MESSAGE,
RECV_MESSAGE,
SEND_RECV_STATES
};
static void
send_recv_ssm (FpiSsm *ssm, FpDevice *dev)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
switch (fpi_ssm_get_cur_state (ssm))
{
case SEND_MESSAGE:
g_output_stream_write_all_async (self->proc_stdin,
self->msg_out->data,
self->msg_out->len,
G_PRIORITY_DEFAULT,
fpi_device_get_cancellable (FP_DEVICE (dev)),
msg_written_cb,
ssm);
break;
case RECV_MESSAGE:
g_input_stream_read_all_async (self->proc_stdout,
self->msg_in->data,
self->msg_in->len,
G_PRIORITY_DEFAULT,
fpi_device_get_cancellable (FP_DEVICE (dev)),
msg_received_cb,
ssm);
break;
}
}
static void
connect_2_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) recv_data = NULL;
g_autoptr(GBytes) r_d = NULL;
g_autoptr(FpiSdcpClaim) claim = NULL;
g_autoptr(GBytes) mac = NULL;
g_autoptr(GBytes) ca_1_bytes = NULL, ca_2_bytes = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
guint16 cert_size;
if (error)
{
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
return;
}
memcpy (&cert_size, self->connect_msg->data + 32, 2);
g_byte_array_append (self->connect_msg, self->msg_in->data, self->msg_in->len);
g_clear_pointer (&self->msg_in, g_byte_array_unref);
/* Double check that the size is correct. */
g_assert (self->connect_msg->len == 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32);
recv_data = g_byte_array_free_to_bytes (g_steal_pointer (&self->connect_msg));
claim = fpi_sdcp_claim_new ();
r_d = g_bytes_new_from_bytes (recv_data, 0, 32);
claim->cert_m = g_bytes_new_from_bytes (recv_data, 34, cert_size);
claim->pk_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size, 65);
claim->pk_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65, 65);
claim->h_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65, 32);
claim->s_m = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32, 64);
claim->s_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64, 64);
mac = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64 + 64, 32);
ca_1_bytes = g_bytes_new_static (ca_1, G_N_ELEMENTS (ca_1));
ca_2_bytes = g_bytes_new_static (ca_2, G_N_ELEMENTS (ca_2));
fpi_sdcp_device_set_intermediat_cas (FP_SDCP_DEVICE (dev),
ca_1_bytes,
ca_2_bytes);
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), r_d, claim, mac, NULL);
}
static void
connect_1_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
guint16 cert_size;
if (error)
{
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
return;
}
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
self->connect_msg = g_steal_pointer (&self->msg_in);
memcpy (&cert_size, self->connect_msg->data + 32, 2);
/* Nothing to send and the rest to receive. */
self->msg_out = g_byte_array_new ();
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32 - self->connect_msg->len);
/* New SSM */
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect 2");
fpi_ssm_start (ssm, connect_2_cb);
}
static void
connect (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
g_autoptr(GBytes) pk_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
g_assert (self->connect_msg == NULL);
fpi_sdcp_device_get_connect_data (dev, &r_h, &pk_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "C", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (r_h, NULL),
g_bytes_get_size (r_h));
g_byte_array_append (self->msg_out,
g_bytes_get_data (pk_h, NULL),
g_bytes_get_size (pk_h));
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 34);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect");
fpi_ssm_start (ssm, connect_1_cb);
}
static void
reconnect_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) mac = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, error);
return;
}
mac = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, NULL);
}
static void
reconnect (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "R", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (r_h, NULL),
g_bytes_get_size (r_h));
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect 2");
fpi_ssm_start (ssm, reconnect_cb);
}
static void
enroll_begin_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) nonce = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
return;
}
nonce = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
fpi_sdcp_device_enroll_set_nonce (FP_SDCP_DEVICE (dev), nonce);
/* Claim that we completed one enroll step. */
fpi_device_enroll_progress (dev, 1, NULL, NULL);
/* And signal that we are ready to commit. */
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), NULL);
}
static void
enroll_begin (FpSdcpDevice *dev)
{
g_autoptr(GBytes) r_h = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "E", 1);
/* Expect 32 byte nonce */
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 32);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "enroll_begin");
fpi_ssm_start (ssm, enroll_begin_cb);
}
static void
enroll_commit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
g_clear_pointer (&self->msg_in, g_byte_array_unref);
if (error)
{
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
return;
}
/* Signal that we have committed. We don't expect a response
* from the virtual device (even though that is kind of broken).
*/
fpi_sdcp_device_enroll_commit_complete (FP_SDCP_DEVICE (dev), NULL);
}
static void
enroll_commit (FpSdcpDevice *dev, GBytes *id_in)
{
g_autoptr(GBytes) r_h = NULL;
g_autoptr(GBytes) id = id_in;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
self->msg_out = g_byte_array_new ();
self->msg_in = g_byte_array_new ();
if (id)
{
g_byte_array_append (self->msg_out, (const guint8 *) "F", 1);
g_byte_array_append (self->msg_out,
g_bytes_get_data (id, NULL),
g_bytes_get_size (id));
/* NOTE: No response from device, assume commit works. */
}
else
{
/* Cancel enroll (does not receive a reply) */
g_byte_array_append (self->msg_out, (const guint8 *) "G", 1);
/* NOTE: No response from device, assume cancellation works. */
}
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "enroll_commit");
fpi_ssm_start (ssm, enroll_commit_cb);
}
static void
identify_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
{
g_autoptr(GBytes) reply = NULL;
g_autoptr(GBytes) id = NULL;
g_autoptr(GBytes) mac = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
if (error)
{
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (dev), NULL, NULL, error);
return;
}
reply = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
id = g_bytes_new_from_bytes (reply, 0, 32);
mac = g_bytes_new_from_bytes (reply, 32, 32);
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (self), id, mac, NULL);
}
static void
identify (FpSdcpDevice *dev)
{
g_autoptr(GBytes) nonce = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
FpiSsm *ssm;
G_DEBUG_HERE ();
g_assert (self->proc);
fpi_sdcp_device_get_identify_data (dev, &nonce);
self->msg_out = g_byte_array_new ();
g_byte_array_append (self->msg_out, (const guint8 *) "I", 1);
g_byte_array_append (self->msg_out, g_bytes_get_data (nonce, NULL), g_bytes_get_size (nonce));
/* Expect 64 byte nonce */
self->msg_in = g_byte_array_new ();
g_byte_array_set_size (self->msg_in, 64);
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "identify");
fpi_ssm_start (ssm, identify_cb);
}
static void
probe (FpDevice *dev)
{
g_auto(GStrv) argv = NULL;
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
GError *error = NULL;
const char *env;
/* We launch the test binary alread at probe time and quit only when
* the object is finalized. This allows testing reconnect properly.
*
* Also, we'll fail probe if something goes wrong executing it.
*/
env = fpi_device_get_virtual_env (FP_DEVICE (self));
if (!g_shell_parse_argv (env, NULL, &argv, &error))
goto out;
self->proc = g_subprocess_newv ((const char * const *) argv,
G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
&error);
if (!self->proc)
goto out;
self->proc_stdin = g_object_ref (g_subprocess_get_stdin_pipe (self->proc));
self->proc_stdout = g_object_ref (g_subprocess_get_stdout_pipe (self->proc));
out:
fpi_device_probe_complete (dev, "virtual-sdcp", NULL, error);
}
static void
dev_close (FpDevice *dev)
{
/* No-op, needs to be defined. */
fpi_device_close_complete (dev, NULL);
}
static void
fpi_device_virtual_sdcp_init (FpDeviceVirtualSdcp *self)
{
}
static void
fpi_device_virtual_sdcp_finalize (GObject *obj)
{
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (obj);
/* Just kill the subprocess, no need to be graceful here. */
if (self->proc)
g_subprocess_force_exit (self->proc);
g_clear_object (&self->proc);
g_clear_object (&self->proc_stdin);
g_clear_object (&self->proc_stdout);
G_OBJECT_CLASS (fpi_device_virtual_sdcp_parent_class)->finalize (obj);
}
static const FpIdEntry driver_ids[] = {
{ .virtual_envvar = "FP_VIRTUAL_SDCP" },
{ .virtual_envvar = NULL }
};
static void
fpi_device_virtual_sdcp_class_init (FpDeviceVirtualSdcpClass *klass)
{
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpSdcpDeviceClass *sdcp_class = FP_SDCP_DEVICE_CLASS (klass);
obj_class->finalize = fpi_device_virtual_sdcp_finalize;
dev_class->id = FP_COMPONENT;
dev_class->full_name = "Virtual SDCP device talking to MS test code";
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
dev_class->id_table = driver_ids;
dev_class->nr_enroll_stages = 1;
/* The SDCP base class may need to override this in the long run */
dev_class->probe = probe;
dev_class->close = dev_close;
sdcp_class->connect = connect;
sdcp_class->reconnect = reconnect;
sdcp_class->enroll_begin = enroll_begin;
sdcp_class->enroll_commit = enroll_commit;
sdcp_class->identify = identify;
}

View File

@@ -185,7 +185,7 @@ fp_device_get_property (GObject *object,
switch (prop_id)
{
case PROP_NR_ENROLL_STAGES:
g_value_set_int (value, priv->nr_enroll_stages);
g_value_set_uint (value, priv->nr_enroll_stages);
break;
case PROP_SCAN_TYPE:
@@ -197,7 +197,7 @@ fp_device_get_property (GObject *object,
break;
case PROP_DRIVER:
g_value_set_static_string (value, FP_DEVICE_GET_CLASS (priv)->id);
g_value_set_static_string (value, FP_DEVICE_GET_CLASS (self)->id);
break;
case PROP_DEVICE_ID:
@@ -792,7 +792,7 @@ fp_device_close_finish (FpDevice *device,
* in. The driver may make use of this metadata, when e.g. storing the print on
* device memory. It is undefined whether this print is filled in by the driver
* and returned, or whether the driver will return a newly created print after
* enrollment successed.
* enrollment succeeded.
*/
void
fp_device_enroll (FpDevice *device,
@@ -979,7 +979,7 @@ fp_device_verify_finish (FpDevice *device,
data = g_task_get_task_data (G_TASK (result));
*print = data->print;
*print = data ? data->print : NULL;
if (*print)
g_object_ref (*print);
}
@@ -1092,13 +1092,13 @@ fp_device_identify_finish (FpDevice *device,
if (print)
{
*print = data->print;
*print = data ? data->print : NULL;
if (*print)
g_object_ref (*print);
}
if (match)
{
*match = data->match;
*match = data ? data->match : NULL;
if (*match)
g_object_ref (*match);
}

View File

@@ -92,6 +92,7 @@ typedef enum {
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
* @FP_DEVICE_ERROR_REMOVED: The device has been removed.
* @FP_DEVICE_ERROR_UNTRUSTED: Device cannot be trusted
*
* 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.
@@ -109,6 +110,7 @@ typedef enum {
FP_DEVICE_ERROR_DATA_DUPLICATE,
/* Leave some room to add more DATA related errors */
FP_DEVICE_ERROR_REMOVED = 0x100,
FP_DEVICE_ERROR_UNTRUSTED,
} FpDeviceError;
GQuark fp_device_retry_quark (void);

View File

@@ -281,7 +281,7 @@ fp_print_class_init (FpPrintClass *klass)
"Type",
"Private: The type of the print data",
FPI_TYPE_PRINT_TYPE,
FPI_PRINT_RAW,
FPI_PRINT_UNDEFINED,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
@@ -582,7 +582,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
if (g_strcmp0 (self->device_id, other->device_id))
return FALSE;
if (self->type == FPI_PRINT_RAW)
if (self->type == FPI_PRINT_RAW || self->type == FPI_PRINT_SDCP)
{
return g_variant_equal (self->data, other->data);
}
@@ -847,7 +847,7 @@ fp_print_deserialize (const guchar *data,
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
}
}
else if (type == FPI_PRINT_RAW)
else if (type == FPI_PRINT_RAW || type == FPI_PRINT_SDCP)
{
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);

View File

@@ -0,0 +1,58 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 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
* 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-sdcp-device.h"
#include <nss.h>
#include <keyhi.h>
#include <keythi.h>
#include <pk11pub.h>
typedef struct
{
GError *enroll_pre_commit_error;
/* XXX: Do we want a separate SDCP session object?
*/
GPtrArray *intermediate_cas;
/* Host random for the connection */
guint8 host_random[32];
NSSInitContext *nss_init_context;
PK11SlotInfo *slot;
SECKEYPrivateKey *host_key_private;
SECKEYPublicKey *host_key_public;
/* Master secret is required for reconnects.
* TODO: We probably want to serialize this to disk so it can survive
* fprintd idle shutdown. */
PK11SymKey *master_secret;
PK11SymKey *mac_secret;
} FpSdcpDevicePrivate;
void fpi_sdcp_device_connect (FpSdcpDevice *self);
void fpi_sdcp_device_reconnect (FpSdcpDevice *self);
void fpi_sdcp_device_enroll (FpSdcpDevice *self);
void fpi_sdcp_device_identify (FpSdcpDevice *self);

141
libfprint/fp-sdcp-device.c Normal file
View File

@@ -0,0 +1,141 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 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
* 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 "sdcp_device"
#include "fpi-log.h"
#include "fp-sdcp-device-private.h"
/**
* SECTION: fp-sdcp-device
* @title: FpSdcpDevice
* @short_description: SDCP device subclass
*
* This is a base class for devices implementing the SDCP security protocol.
*/
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpSdcpDevice, fp_sdcp_device, FP_TYPE_DEVICE)
#if 0
/* XXX: We'll very likely want/need some properties on this class. */
enum {
PROP_0,
N_PROPS
};
static GParamSpec *properties[N_PROPS];
#endif
/*******************************************************/
/* Callbacks/vfuncs */
static void
fp_sdcp_device_open (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
/* Try a reconnect if we still have the mac secret. */
if (priv->mac_secret)
fpi_sdcp_device_reconnect (self);
else
fpi_sdcp_device_connect (self);
}
static void
fp_sdcp_device_enroll (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
fpi_sdcp_device_enroll (self);
}
static void
fp_sdcp_device_identify (FpDevice *device)
{
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
fpi_sdcp_device_identify (self);
}
/*********************************************************/
static void
fp_sdcp_device_finalize (GObject *object)
{
FpSdcpDevice *self = (FpSdcpDevice *) object;
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
g_clear_pointer (&priv->intermediate_cas, g_ptr_array_unref);
g_clear_pointer (&priv->slot, PK11_FreeSlot);
g_clear_pointer (&priv->host_key_private, SECKEY_DestroyPrivateKey);
g_clear_pointer (&priv->host_key_public, SECKEY_DestroyPublicKey);
g_clear_pointer (&priv->master_secret, PK11_FreeSymKey);
g_clear_pointer (&priv->mac_secret, PK11_FreeSymKey);
g_clear_pointer (&priv->nss_init_context, NSS_ShutdownContext);
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->finalize (object);
}
static void
fp_sdcp_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
fp_sdcp_device_constructed (GObject *obj)
{
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->constructed (obj);
}
static void
fp_sdcp_device_class_init (FpSdcpDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FpDeviceClass *fp_device_class = FP_DEVICE_CLASS (klass);
object_class->finalize = fp_sdcp_device_finalize;
object_class->get_property = fp_sdcp_device_get_property;
object_class->constructed = fp_sdcp_device_constructed;
fp_device_class->open = fp_sdcp_device_open;
fp_device_class->enroll = fp_sdcp_device_enroll;
fp_device_class->verify = fp_sdcp_device_identify;
fp_device_class->identify = fp_sdcp_device_identify;
#if 0
g_object_class_install_properties (object_class, N_PROPS, properties);
#endif
}
static void
fp_sdcp_device_init (FpSdcpDevice *self)
{
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
priv->intermediate_cas = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
}

View File

@@ -0,0 +1,29 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 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
* 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 <fp-device.h>
G_BEGIN_DECLS
#define FP_TYPE_SDCP_DEVICE (fp_sdcp_device_get_type ())
G_DECLARE_DERIVABLE_TYPE (FpSdcpDevice, fp_sdcp_device, FP, SDCP_DEVICE, FpDevice)
G_END_DECLS

View File

@@ -143,6 +143,10 @@ fpi_device_error_new (FpDeviceError error)
msg = "This device has been removed from the system.";
break;
case FP_DEVICE_ERROR_UNTRUSTED:
msg = "Could not verify integrity of the device, it cannot be trusted!";
break;
default:
g_warning ("Unsupported error, returning general error instead!");
error = FP_DEVICE_ERROR_GENERAL;
@@ -216,6 +220,7 @@ fpi_device_set_nr_enroll_stages (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (enroll_stages > 0);
priv->nr_enroll_stages = enroll_stages;
g_object_notify (G_OBJECT (device), "nr-enroll-stages");
@@ -751,6 +756,21 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
priv->current_action = FPI_DEVICE_ACTION_NONE;
priv->current_task_idle_return_source = NULL;
if (action == FPI_DEVICE_ACTION_OPEN &&
data->type != FP_DEVICE_TASK_RETURN_ERROR)
{
priv->is_open = TRUE;
g_object_notify (G_OBJECT (data->device), "open");
}
else if (action == FPI_DEVICE_ACTION_CLOSE)
{
/* Always consider the device closed. Drivers should try hard to close the
* device. Generally, e.g. cancellations should be ignored.
*/
priv->is_open = FALSE;
g_object_notify (G_OBJECT (data->device), "open");
}
/* Return FP_DEVICE_ERROR_REMOVED if the device is removed,
* with the exception of a successful open, which is an odd corner case. */
if (priv->is_removed &&
@@ -760,7 +780,7 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
g_task_return_error (task, fpi_device_error_new (FP_DEVICE_ERROR_REMOVED));
/* NOTE: The removed signal will be emitted from the GTask
* notify::completed if that is neccessary. */
* notify::completed if that is necessary. */
return G_SOURCE_REMOVE;
}
@@ -920,12 +940,6 @@ fpi_device_open_complete (FpDevice *device, GError *error)
clear_device_cancel_action (device);
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
if (!error)
{
priv->is_open = TRUE;
g_object_notify (G_OBJECT (device), "open");
}
if (!error)
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE));
@@ -976,12 +990,6 @@ fpi_device_close_complete (FpDevice *device, GError *error)
return;
}
/* Always consider the device closed. Drivers should try hard to close the
* device. Generally, e.g. cancellations should be ignored.
*/
priv->is_open = FALSE;
g_object_notify (G_OBJECT (device), "open");
if (!error)
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE));
@@ -1529,7 +1537,7 @@ fpi_device_report_finger_status (FpDevice *device,
* fpi_device_report_finger_status_changes:
* @device: The #FpDevice
* @added_status: The #FpFingerStatusFlags to add
* @added_status: The #FpFingerStatusFlags to remove
* @removed_status: The #FpFingerStatusFlags to remove
*
* Report the finger status for the @device adding the @added_status flags
* and removing the @removed_status flags.

View File

@@ -11,11 +11,13 @@ G_BEGIN_DECLS
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
* @FPI_PRINT_RAW: A raw print where the data is directly compared
* @FPI_PRINT_NBIS: NBIS minutiae comparison
* @FPI_PRINT_SDCP: Print from an SDCP conforming device
*/
typedef enum {
FPI_PRINT_UNDEFINED = 0,
FPI_PRINT_RAW,
FPI_PRINT_NBIS,
FPI_PRINT_SDCP,
} FpiPrintType;
/**

1469
libfprint/fpi-sdcp-device.c Normal file

File diff suppressed because it is too large Load Diff

142
libfprint/fpi-sdcp-device.h Normal file
View File

@@ -0,0 +1,142 @@
/*
* FpSdcpDevice - A base class for SDCP enabled devices
* Copyright (C) 2020 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
* 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 <glib-2.0/glib.h>
#include "fpi-device.h"
#include "fp-sdcp-device.h"
/**
* FpiSdcpClaim:
* @cert_m: The per-model ECDSA certificate (x509 ASN.1 DER encoded)
* @pk_d: The device public key (65 bytes)
* @pk_f: The firmware public key (65 bytes)
* @h_f: The firmware hash
* @s_m: Signature over @pk_d using the per-model private key (64 bytes)
* @s_d: Signature over h_f and pk_f using the device private key (64 bytes)
*
* Structure to hold the claim as produced by the device during a secure
* connect. See the SDCP specification for more details.
*
* Note all of these may simply be memory views into a larger #GBytes created
* using g_bytes_new_from_bytes().
*/
struct _FpiSdcpClaim
{
/*< public >*/
GBytes *cert_m;
GBytes *pk_d;
GBytes *pk_f;
GBytes *h_f;
GBytes *s_m;
GBytes *s_d;
};
typedef struct _FpiSdcpClaim FpiSdcpClaim;
GType fpi_sdcp_claim_get_type (void) G_GNUC_CONST;
FpiSdcpClaim *fpi_sdcp_claim_new (void);
FpiSdcpClaim *fpi_sdcp_claim_copy (FpiSdcpClaim *other);
void fpi_sdcp_claim_free (FpiSdcpClaim *claim);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSdcpClaim, fpi_sdcp_claim_free)
/**
* FpSdcpDeviceClass:
* @connect: Establish SDCP connection. Similar to open in #FpDeviceClass
* but called connect to mirror the SDCP specification.
* @reconnect: Perform a faster reconnect. Drivers do not need to provide this
* function. If reconnect fails, then a normal connect will be tried.
* @enroll_begin: Start the enrollment procedure. In the absence of an error,
* the driver must call fpi_sdcp_device_enroll_set_nonce() at any point. It
* also must report enrollment progress using fpi_device_enroll_progress().
* It should also store available metadata about the print in device memory.
* The operation is completed with fpi_sdcp_device_enroll_ready().
* @enroll_commit: Complete the enrollment procedure. This commits the newly
* enrolled print to the device memory. Will only be called if enroll_begin
* succeeded. The passed id may be %NULL, in that case the driver must
* abort the enrollment process. id is owned by the base class and remains
* valid throughout the operation.
* @identify: Start identification process. On completion, the driver must call
* fpi_sdcp_device_identify_complete(). To request the user to retry the
* fpi_sdcp_device_identify_retry() function is used.
*
*
* These are the main entry points for drivers implementing SDCP.
*
* Drivers *must* eventually call the corresponding function to finish the
* operation.
*
* XXX: Is the use of fpi_device_action_error() acceptable?
*
* 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).
*
* This API is solely intended for drivers. It is purely internal and neither
* API nor ABI stable.
*/
struct _FpSdcpDeviceClass
{
FpDeviceClass parent_class;
void (*connect) (FpSdcpDevice *dev);
void (*reconnect) (FpSdcpDevice *dev);
void (*close) (FpSdcpDevice *dev);
void (*enroll_begin) (FpSdcpDevice *dev);
void (*enroll_commit) (FpSdcpDevice *dev,
GBytes *id);
void (*identify) (FpSdcpDevice *dev);
};
void fpi_sdcp_device_set_intermediat_cas (FpSdcpDevice *self,
GBytes *ca_1,
GBytes *ca_2);
void fpi_sdcp_device_get_connect_data (FpSdcpDevice *self,
GBytes **r_h,
GBytes **pk_h);
void fpi_sdcp_device_connect_complete (FpSdcpDevice *self,
GBytes *r_d,
FpiSdcpClaim *claim,
GBytes *mac,
GError *error);
void fpi_sdcp_device_get_reconnect_data (FpSdcpDevice *self,
GBytes **r_h);
void fpi_sdcp_device_reconnect_complete (FpSdcpDevice *self,
GBytes *mac,
GError *error);
void fpi_sdcp_device_enroll_set_nonce (FpSdcpDevice *self,
GBytes *nonce);
void fpi_sdcp_device_enroll_ready (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_enroll_commit_complete (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_get_identify_data (FpSdcpDevice *self,
GBytes **nonce);
void fpi_sdcp_device_identify_retry (FpSdcpDevice *self,
GError *error);
void fpi_sdcp_device_identify_complete (FpSdcpDevice *self,
GBytes *id,
GBytes *mac,
GError *error);

View File

@@ -74,7 +74,7 @@
* upon success (or fails).
*
* Your completion callback should examine the return value of
* fpi_ssm_get_error() in ordater to determine whether the #FpiSsm completed or
* fpi_ssm_get_error() in order to determine whether the #FpiSsm completed or
* failed. An error code of zero indicates successful completion.
*/
@@ -130,6 +130,7 @@ fpi_ssm_new_full (FpDevice *dev,
{
FpiSsm *machine;
BUG_ON (dev == NULL);
BUG_ON (nr_states < 1);
BUG_ON (handler == NULL);
@@ -155,6 +156,8 @@ fpi_ssm_set_data (FpiSsm *machine,
gpointer ssm_data,
GDestroyNotify ssm_data_destroy)
{
g_return_if_fail (machine);
if (machine->ssm_data_destroy && machine->ssm_data)
machine->ssm_data_destroy (machine->ssm_data);
@@ -173,12 +176,16 @@ fpi_ssm_set_data (FpiSsm *machine,
void *
fpi_ssm_get_data (FpiSsm *machine)
{
g_return_val_if_fail (machine, NULL);
return machine->ssm_data;
}
static void
fpi_ssm_clear_delayed_action (FpiSsm *machine)
{
g_return_if_fail (machine);
if (machine->cancellable_id)
{
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
@@ -235,6 +242,8 @@ fpi_ssm_set_delayed_action_timeout (FpiSsm *machine,
gpointer user_data,
GDestroyNotify destroy_func)
{
g_return_if_fail (machine);
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
@@ -302,6 +311,8 @@ __ssm_call_handler (FpiSsm *machine)
void
fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
{
g_return_if_fail (ssm != NULL);
BUG_ON (!ssm->completed);
ssm->callback = callback;
ssm->cur_state = 0;
@@ -336,6 +347,9 @@ __subsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
void
fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
{
g_return_if_fail (parent != NULL);
g_return_if_fail (child != NULL);
BUG_ON (parent->timeout);
child->parentsm = parent;
@@ -355,6 +369,8 @@ fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
void
fpi_ssm_mark_completed (FpiSsm *machine)
{
g_return_if_fail (machine != NULL);
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
@@ -427,6 +443,7 @@ fpi_ssm_mark_completed_delayed (FpiSsm *machine,
void
fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
{
g_return_if_fail (machine != NULL);
g_assert (error);
if (machine->error)
{
@@ -534,6 +551,8 @@ fpi_ssm_next_state_delayed (FpiSsm *machine,
void
fpi_ssm_jump_to_state (FpiSsm *machine, int state)
{
g_return_if_fail (machine != NULL);
BUG_ON (machine->completed);
BUG_ON (state < 0 || state >= machine->nr_states);
BUG_ON (machine->timeout != NULL);
@@ -598,6 +617,20 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
g_source_set_name (machine->timeout, source_name);
}
/**
* fpi_ssm_get_device:
* @machine: an #FpiSsm state machine
*
* Returns the device that the SSM has been associated with.
*
* Returns: (transfer none): the #FpDevice.
*/
FpDevice *
fpi_ssm_get_device (FpiSsm *machine)
{
return machine->dev;
}
/**
* fpi_ssm_get_cur_state:
* @machine: an #FpiSsm state machine
@@ -610,6 +643,8 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
int
fpi_ssm_get_cur_state (FpiSsm *machine)
{
g_return_val_if_fail (machine != NULL, 0);
return machine->cur_state;
}
@@ -624,6 +659,8 @@ fpi_ssm_get_cur_state (FpiSsm *machine)
GError *
fpi_ssm_get_error (FpiSsm *machine)
{
g_return_val_if_fail (machine != NULL, NULL);
return machine->error;
}
@@ -638,6 +675,8 @@ fpi_ssm_get_error (FpiSsm *machine)
GError *
fpi_ssm_dup_error (FpiSsm *machine)
{
g_return_val_if_fail (machine != NULL, NULL);
if (machine->error)
return g_error_copy (machine->error);

View File

@@ -92,6 +92,8 @@ void fpi_ssm_mark_failed (FpiSsm *machine,
void fpi_ssm_set_data (FpiSsm *machine,
gpointer ssm_data,
GDestroyNotify ssm_data_destroy);
FpDevice * fpi_ssm_get_device (FpiSsm *machine);
gpointer fpi_ssm_get_data (FpiSsm *machine);
GError * fpi_ssm_get_error (FpiSsm *machine);
GError * fpi_ssm_dup_error (FpiSsm *machine);

View File

@@ -187,7 +187,7 @@ fpi_usb_transfer_fill_bulk (FpiUsbTransfer *transfer,
* fpi_usb_transfer_fill_bulk_full:
* @transfer: The #FpiUsbTransfer
* @endpoint: The endpoint to send the transfer to
* @buffer: The data to send. A buffer will be created and managed for you if you pass NULL.
* @buffer: The data to send.
* @length: The size of @buffer
* @free_func: (destroy buffer): Destroy notify for @buffer
*
@@ -275,7 +275,7 @@ fpi_usb_transfer_fill_interrupt (FpiUsbTransfer *transfer,
* fpi_usb_transfer_fill_interrupt_full:
* @transfer: The #FpiUsbTransfer
* @endpoint: The endpoint to send the transfer to
* @buffer: The data to send. A buffer will be created and managed for you if you pass NULL.
* @buffer: The data to send.
* @length: The size of @buffer
* @free_func: (destroy buffer): Destroy notify for @buffer
*

View File

@@ -83,6 +83,8 @@ main (int argc, char **argv)
g_print ("\n");
g_print ("This is a list of supported devices in libfprint's development version. Those drivers might not all be available in the stable, released version. If in doubt, contact your distribution or systems integrator for details.\n");
g_print ("\n");
g_print ("The quality and functionality of drivers varies widely. libfprint maintainers may not be able to help with issues arising from their use.\n");
g_print ("\n");
g_print ("## USB devices\n");
g_print ("\n");
g_print ("USB ID | Driver\n");

View File

@@ -45,12 +45,9 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x06cb, .pid = 0x00b7 },
{ .vid = 0x06cb, .pid = 0x00bb },
{ .vid = 0x06cb, .pid = 0x00be },
{ .vid = 0x06cb, .pid = 0x00c2 },
{ .vid = 0x06cb, .pid = 0x00c9 },
{ .vid = 0x06cb, .pid = 0x00cb },
{ .vid = 0x06cb, .pid = 0x00d8 },
{ .vid = 0x06cb, .pid = 0x00da },
{ .vid = 0x06cb, .pid = 0x00e7 },
{ .vid = 0x0a5c, .pid = 0x5801 },
{ .vid = 0x0a5c, .pid = 0x5805 },
{ .vid = 0x0a5c, .pid = 0x5834 },
@@ -110,6 +107,7 @@ static const FpIdEntry blacklist_id_table[] = {
static const FpDeviceClass whitelist = {
.type = FP_DEVICE_TYPE_USB,
.id_table = whitelist_id_table,
.id = "whitelist",
.full_name = "Hardcoded whitelist"
};
@@ -140,33 +138,56 @@ print_driver (const FpDeviceClass *cls)
if (g_hash_table_lookup (printed, key) != NULL)
{
if (cls == &whitelist)
g_warning ("%s implemented by driver %s",
key, (const char *) g_hash_table_lookup (printed, key));
g_free (key);
continue;
}
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
g_hash_table_insert (printed, key, (void *) cls->id);
if (num_printed == 0)
g_print ("# %s\n", cls->full_name);
{
if (cls != &whitelist)
g_print ("\n# Supported by libfprint driver %s\n", cls->id);
else
g_print ("\n# Known unsupported devices\n");
}
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n",
g_print ("usb:v%04Xp%04X*\n",
entry->vid, entry->pid);
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n",
entry->vid, entry->pid, cls->full_name);
num_printed++;
}
if (num_printed > 0)
g_print ("\n");
g_print (" ID_AUTOSUSPEND=1\n");
}
static int
driver_compare (gconstpointer p1, gconstpointer p2)
{
g_autoptr(FpDeviceClass) cls1 = g_type_class_ref (*(GType *) p1);
g_autoptr(FpDeviceClass) cls2 = g_type_class_ref (*(GType *) p2);
return g_strcmp0 (cls1->id, cls2->id);
}
int
main (int argc, char **argv)
{
g_autoptr(GArray) drivers = fpi_get_driver_types ();
g_autofree char *program_name = NULL;
guint i;
program_name = g_path_get_basename (argv[0]);
g_print ("# SPDX-License-Identifier: LGPL-2.1-or-later\n");
g_print ("# This file has been generated using %s with all drivers enabled\n",
program_name);
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_array_sort (drivers, driver_compare);
for (i = 0; i < drivers->len; i++)
{

View File

@@ -78,108 +78,146 @@ nbis_sources = [
'nbis/mindtct/xytreps.c',
]
aeslib = false
aesx660 = false
aes3k = false
drivers_sources = []
drivers_cflags = []
foreach driver: drivers
if driver == 'upekts'
drivers_sources += [ 'drivers/upekts.c', 'drivers/upek_proto.c' ]
endif
if driver == 'upektc'
drivers_sources += [ 'drivers/upektc.c' ]
endif
if driver == 'upeksonly'
drivers_sources += [ 'drivers/upeksonly.c' ]
endif
if driver == 'uru4000'
drivers_sources += [ 'drivers/uru4000.c' ]
endif
if driver == 'aes1610'
drivers_sources += [ 'drivers/aes1610.c' ]
aeslib = true
endif
if driver == 'aes1660'
drivers_sources += [ 'drivers/aes1660.c' ]
aeslib = true
aesx660 = true
endif
if driver == 'aes2501'
drivers_sources += [ 'drivers/aes2501.c' ]
aeslib = true
endif
if driver == 'aes2550'
drivers_sources += [ 'drivers/aes2550.c' ]
aeslib = true
endif
if driver == 'aes2660'
drivers_sources += [ 'drivers/aes2660.c' ]
aeslib = true
aesx660 = true
endif
if driver == 'aes3500'
drivers_sources += [ 'drivers/aes3500.c' ]
aeslib = true
aes3k = true
endif
if driver == 'aes4000'
drivers_sources += [ 'drivers/aes4000.c' ]
aeslib = true
aes3k = true
endif
if driver == 'vcom5s'
drivers_sources += [ 'drivers/vcom5s.c' ]
endif
if driver == 'vfs101'
drivers_sources += [ 'drivers/vfs101.c' ]
endif
if driver == 'vfs301'
drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ]
endif
if driver == 'vfs5011'
drivers_sources += [ 'drivers/vfs5011.c' ]
endif
if driver == 'upektc_img'
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
endif
if driver == 'etes603'
drivers_sources += [ 'drivers/etes603.c' ]
endif
if driver == 'vfs0050'
drivers_sources += [ 'drivers/vfs0050.c' ]
endif
if driver == 'elan'
drivers_sources += [ 'drivers/elan.c' ]
endif
if driver == 'virtual_image'
drivers_sources += [ 'drivers/virtual-image.c' ]
endif
if driver == 'synaptics'
drivers_sources += [
'drivers/synaptics/synaptics.c',
'drivers/synaptics/bmkt_message.c',
]
endif
if driver == 'goodixmoc'
drivers_sources += [
'drivers/goodixmoc/goodix.c',
'drivers/goodixmoc/goodix_proto.c',
]
driver_sources = {
'upekts' :
[ 'drivers/upekts.c', 'drivers/upek_proto.c' ],
'upektc' :
[ 'drivers/upektc.c' ],
'upeksonly' :
[ 'drivers/upeksonly.c' ],
'uru4000' :
[ 'drivers/uru4000.c' ],
'aes1610' :
[ 'drivers/aes1610.c' ],
'aes1660' :
[ 'drivers/aes1660.c' ],
'aes2501' :
[ 'drivers/aes2501.c' ],
'aes2550' :
[ 'drivers/aes2550.c' ],
'aes2660' :
[ 'drivers/aes2660.c' ],
'aes3500' :
[ 'drivers/aes3500.c' ],
'aes4000' :
[ 'drivers/aes4000.c' ],
'vcom5s' :
[ 'drivers/vcom5s.c' ],
'vfs101' :
[ 'drivers/vfs101.c' ],
'vfs301' :
[ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ],
'vfs5011' :
[ 'drivers/vfs5011.c' ],
'upektc_img' :
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
'etes603' :
[ 'drivers/etes603.c' ],
'vfs0050' :
[ 'drivers/vfs0050.c' ],
'elan' :
[ 'drivers/elan.c' ],
'virtual_image' :
[ 'drivers/virtual-image.c' ],
'virtual_device' :
[ 'drivers/virtual-device.c' ],
'virtual_device_storage' :
[ 'drivers/virtual-device-storage.c' ],
'virtual_sdcp' :
[ 'drivers/virtual-sdcp.c' ],
'synaptics' :
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
'goodixmoc' :
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
}
helper_sources = {
'sdcp' :
[ 'fp-sdcp-device.c', 'fpi-sdcp-device.c' ],
'aeslib' :
[ 'drivers/aeslib.c' ],
'aesx660' :
[ 'drivers/aesx660.c' ],
'aes3k' :
[ 'drivers/aes3k.c' ],
'virtual' :
[ 'drivers/virtual-device-listener.c' ],
}
driver_helpers = {
'aes1610' : [ 'aeslib' ],
'aes1660' : [ 'aeslib', 'aesx660' ],
'aes2501' : [ 'aeslib' ],
'aes2550' : [ 'aeslib' ],
'aes2660' : [ 'aeslib', 'aesx660' ],
'aes3500' : [ 'aeslib', 'aes3k' ],
'aes4000' : [ 'aeslib', 'aes3k' ],
'virtual_image' : [ 'virtual' ],
'virtual_device' : [ 'virtual' ],
'virtual_device_storage' : [ 'virtual' ],
'virtual_sdcp' : [ 'sdcp' ],
}
helpers = []
foreach driver : drivers
if driver in driver_helpers
foreach helper : driver_helpers[driver]
if helper not in helpers
helpers += helper
endif
endforeach
endif
endforeach
if aeslib
drivers_sources += [ 'drivers/aeslib.c' ]
endif
if aesx660
drivers_sources += ['drivers/aesx660.c' ]
endif
if aes3k
drivers_sources += ['drivers/aes3k.c' ]
endif
drivers_sources = []
drivers_cflags = []
foreach driver: drivers
drivers_sources += driver_sources[driver]
endforeach
foreach helper : helpers
drivers_sources += helper_sources[helper]
endforeach
other_sources = []
optional_deps = []
# Resolve extra dependencies
foreach i : helpers + drivers
driver = i
foreach d, helper : driver_helpers
if i in helpers
driver = d
break
endif
endforeach
if i == 'aes3k'
imaging_dep = dependency('pixman-1', required: false)
if not imaging_dep.found()
error('pixman is required for @0@ and possibly others'.format(driver))
endif
libfprint_conf.set10('HAVE_PIXMAN', true)
optional_deps += imaging_dep
elif i == 'uru4000'
nss_dep = dependency('nss', required: false)
if not nss_dep.found()
error('nss is required for uru4000')
endif
optional_deps += nss_dep
elif i == 'sdcp'
nss_dep = dependency('nss', version: '>=3.55', required: false)
if not nss_dep.found()
error('nss >=3.55 is required for SDCP support (@0@ and possibly others)'.format(driver))
endif
optional_deps += nss_dep
else
deps = []
continue
endif
endforeach
fp_enums = gnome.mkenums_simple('fp-enums',
sources: libfprint_public_headers,
@@ -198,6 +236,28 @@ enums_dep = declare_dependency(
sources: [ fp_enums_h, fpi_enums_h ]
)
# Export the drivers' types to the core code
drivers_type_list = []
drivers_type_func = []
drivers_type_list += '#include <glib-object.h>'
drivers_type_list += '#include "fpi-context.h"'
drivers_type_list += ''
drivers_type_func += 'GArray *'
drivers_type_func += 'fpi_get_driver_types (void)'
drivers_type_func += '{'
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
drivers_type_func += ' GType t;'
drivers_type_func += ''
foreach driver: supported_drivers
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
drivers_type_func += ' g_array_append_val (drivers, t);'
drivers_type_func += ''
endforeach
drivers_type_list += ''
drivers_type_func += ' return drivers;'
drivers_type_func += '}'
drivers_sources += configure_file(input: 'empty_file',
output: 'fpi-drivers.c',
capture: true,
@@ -212,10 +272,8 @@ deps = [
glib_dep,
gobject_dep,
gusb_dep,
imaging_dep,
mathlib_dep,
nss_dep,
]
] + optional_deps
# These are empty and only exist so that the include directories are created
# in the build tree. This silences a build time warning.
@@ -234,6 +292,8 @@ libnbis = static_library('nbis',
'-Wno-error=redundant-decls',
'-Wno-redundant-decls',
'-Wno-discarded-qualifiers',
'-Wno-array-bounds',
'-Wno-array-parameter',
]),
install: false)
@@ -256,11 +316,10 @@ libfprint_drivers = static_library('fprint-drivers',
mapfile = files('libfprint.ver')
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
libfprint = library(versioned_libname.split('lib')[1],
libfprint = shared_library(versioned_libname.split('lib')[1],
sources: [
fp_enums,
libfprint_sources,
other_sources,
],
soversion: soversion,
version: libversion,
@@ -293,20 +352,30 @@ libfprint_private_dep = declare_dependency(
]
)
udev_rules = executable('fprint-list-udev-rules',
'fprint-list-udev-rules.c',
udev_hwdb = executable('fprint-list-udev-hwdb',
'fprint-list-udev-hwdb.c',
dependencies: libfprint_private_dep,
link_with: libfprint_drivers,
install: false)
if get_option('udev_rules')
custom_target('udev-rules',
output: '60-@0@-autosuspend.rules'.format(versioned_libname),
capture: true,
command: [ udev_rules ],
install: true,
install_dir: udev_rules_dir)
endif
udev_hwdb_generator = custom_target('udev-hwdb',
output: 'autosuspend.hwdb',
depend_files: drivers_sources,
capture: true,
command: [ udev_hwdb ],
install: false,
)
custom_target('sync-udev-hwdb',
depends: udev_hwdb_generator,
output: 'sync-udev-hwdb',
install: false,
command: [
'cp', '-v',
udev_hwdb_generator.full_path(),
meson.source_root() / 'data'
]
)
supported_devices = executable('fprint-list-supported-devices',
'fprint-list-supported-devices.c',

View File

@@ -1,5 +1,5 @@
project('libfprint', [ 'c', 'cpp' ],
version: '1.90.6',
version: '1.90.7',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',
@@ -88,7 +88,12 @@ cairo_dep = dependency('cairo', required: false)
# Drivers
drivers = get_option('drivers').split(',')
virtual_drivers = [ 'virtual_image' ]
virtual_drivers = [
'virtual_image',
'virtual_device',
'virtual_device_storage',
'virtual_sdcp',
]
default_drivers = [
'upektc_img',
'vfs5011',
@@ -113,6 +118,13 @@ default_drivers = [
'goodixmoc',
]
# FIXME: All the drivers should be fixed by adjusting the byte order.
# See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/236
endian_independent_drivers = virtual_drivers + [
'aes3500',
'synaptics',
]
all_drivers = default_drivers + virtual_drivers
if drivers == [ 'all' ]
@@ -127,60 +139,43 @@ if drivers.length() == 0 or drivers[0] == ''
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
endif
nss_dep = dependency('', required: false)
imaging_dep = dependency('', required: false)
libfprint_conf.set10('HAVE_PIXMAN', false)
foreach driver: drivers
if driver == 'uru4000'
nss_dep = dependency('nss', required: false)
if not nss_dep.found()
error('NSS is required for the URU4000/URU4500 driver')
endif
endif
if driver == 'aes3500' or driver == 'aes4000'
imaging_dep = dependency('pixman-1', required: false)
if not imaging_dep.found()
error('pixman is required for imaging support')
if drivers == all_drivers or drivers == default_drivers
default_drivers_are_enabled = true
else
default_drivers_are_enabled = true
foreach driver: default_drivers
if driver not in drivers
default_drivers_are_enabled = false
break
endif
endforeach
endif
libfprint_conf.set10('HAVE_PIXMAN', true)
endif
if not all_drivers.contains(driver)
error('Invalid driver \'' + driver + '\'')
supported_drivers = []
foreach driver: drivers
if build_machine.endian() == 'little' or driver in endian_independent_drivers
supported_drivers += driver
else
warning('Driver @0@ is not supported by big endian cpu @1@. Please, fix it!'.format(
driver, build_machine.cpu()))
endif
endforeach
# Export the drivers' types to the core code
drivers_type_list = []
drivers_type_func = []
drivers_type_list += '#include <glib-object.h>'
drivers_type_list += '#include "fpi-context.h"'
drivers_type_list += ''
drivers_type_func += 'GArray *'
drivers_type_func += 'fpi_get_driver_types (void)'
drivers_type_func += '{'
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
drivers_type_func += ' GType t;'
drivers_type_func += ''
foreach driver: drivers
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
drivers_type_func += ' g_array_append_val (drivers, t);'
drivers_type_func += ''
endforeach
drivers_type_list += ''
drivers_type_func += ' return drivers;'
drivers_type_func += '}'
if default_drivers_are_enabled and supported_drivers != drivers
default_drivers_are_enabled = false
endif
root_inc = include_directories('.')
if get_option('udev_rules')
udev_rules_dir = get_option('udev_rules_dir')
udev_hwdb_dir = get_option('udev_hwdb_dir')
if udev_rules_dir == 'auto'
if udev_hwdb_dir == 'auto'
udev_dep = dependency('udev')
udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/rules.d'
udev_hwdb_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/hwdb.d'
endif
else
udev_hwdb_dir = false
endif
if get_option('gtk-examples')
@@ -192,9 +187,11 @@ if get_option('gtk-examples')
endif
endif
# Some dependency resolving happens inside here
subdir('libfprint')
configure_file(output: 'config.h', configuration: libfprint_conf)
subdir('libfprint')
subdir('examples')
if get_option('doc')
gnome = import('gnome')
@@ -204,6 +201,7 @@ if get_option('gtk-examples')
subdir('demo')
endif
subdir('data')
subdir('tests')
pkgconfig = import('pkgconfig')

View File

@@ -10,8 +10,8 @@ option('udev_rules',
description: 'Whether to create a udev rules file',
type: 'boolean',
value: true)
option('udev_rules_dir',
description: 'Installation path for udev rules',
option('udev_hwdb_dir',
description: 'Installation path for udev hwdb',
type: 'string',
value: 'auto')
option('gtk-examples',
@@ -22,3 +22,8 @@ option('doc',
description: 'Whether to build the API documentation',
type: 'boolean',
value: true)
option('sdcp_virt_binary',
description: 'Path to virtual SDCP test binary, please refer to CI for more details.',
type: 'string',
value: '')

View File

@@ -12,8 +12,11 @@ case "$1" in
;;
esac
ARGS=4
JOBS=4
pushd "$SRCROOT"
uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/`
git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/ | xargs -n$ARGS -P $JOBS uncrustify -c "$CFG" $OPTS
RES=$?
popd
exit $RES
exit $RES

View File

@@ -27,7 +27,7 @@ A new 'capture' test is created by means of `capture.py` script:
- `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
Also, sometimes the driver must be adapted 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`
@@ -41,6 +41,11 @@ A new 'capture' test is created by means of `capture.py` script:
The following USB device is used in the example above:
`/dev/bus/usb/001/005`.
For the following commands, it is assumed that the user that's
running the commands has full access to the device node, whether
by running the commands as `root`, or changing the permissions for
that device node.
4. Record information about this device:
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`

View File

@@ -35,11 +35,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0000
A: bmAttributes=80
A: busnum=3
A: busnum=3\n
A: configuration=
H: descriptors=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
A: dev=189:259
A: devnum=4
A: devnum=4\n
A: devpath=1.1.3
L: driver=../../../../../../../../../../bus/usb/drivers/usb
A: idProduct=5731
@@ -106,11 +106,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=9100
A: bmAttributes=e0
A: busnum=3
A: busnum=3\n
A: configuration=
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
A: dev=189:258
A: devnum=3
A: devnum=3\n
A: devpath=1.1
L: driver=../../../../../../../../../bus/usb/drivers/usb
A: idProduct=0006
@@ -186,11 +186,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=9100
A: bmAttributes=e0
A: busnum=3
A: busnum=3\n
A: configuration=
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
A: dev=189:257
A: devnum=2
A: devnum=2\n
A: devpath=1
L: driver=../../../../../../../../bus/usb/drivers/usb
A: idProduct=0006
@@ -270,11 +270,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0415
A: bmAttributes=e0
A: busnum=3
A: busnum=3\n
A: configuration=
H: descriptors=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
A: dev=189:256
A: devnum=1
A: devnum=1\n
A: devpath=0
L: driver=../../../../../../../bus/usb/drivers/usb
A: idProduct=0002

View File

@@ -36,11 +36,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0140
A: bmAttributes=80
A: busnum=1
A: busnum=1\n
A: configuration=
H: descriptors=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
A: dev=189:93
A: devnum=94
A: devnum=94\n
A: devpath=4.4
L: driver=../../../../../../bus/usb/drivers/usb
A: idProduct=0c26
@@ -107,11 +107,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=5284
A: bmAttributes=e0
A: busnum=1
A: busnum=1\n
A: configuration=
H: descriptors=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
A: dev=189:82
A: devnum=83
A: devnum=83\n
A: devpath=4
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=1018
@@ -189,11 +189,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0503
A: bmAttributes=e0
A: busnum=1
A: busnum=1\n
A: configuration=
H: descriptors=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0
A: devnum=1
A: devnum=1\n
A: devpath=0
L: driver=../../../../bus/usb/drivers/usb
A: idProduct=0002

View File

@@ -1,307 +1,217 @@
@DEV /dev/bus/usb/001/003
@DEV /dev/bus/usb/003/008
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 64 0 AA00000008009D6200D00000239572F5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 192 0 D0000001850067980002FE4150500000000000303130303032343744454C4C00000000474D3138384230004746353238380000312E30342E30352E31302E3530000000000000000000000000000000000000005553420000000000564253000000000030303030303030330000000000000000000000000000000000000000000000000000000000003B5CB43C000000000000555342000000000056425300000000003030303030303033000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F41080A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F0558B152
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 64 0 AA00000208004BB400C001005F5A6B1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 C00100030700D12E0014140342C8AE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00100020400BE41BBC7BACE
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 64 0 AA000004080036C900E00101C26FC596000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E0010005080054AB00141441240D0ECF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000003050022DD00CA3B9C30
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 64 0 AA0000060800E01F00A60001BCF2ED17000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A60000070600B64900007A6860130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000040700BA45000F41625785F3
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 64 0 AA0000080800CC3300A20001BA8679AC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000090C00BC430054640027004D0084CD5EED0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A500000524009F60000000000000000000000000000000000000000000000000000000000000000048D9D8CB
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 64 0 AA00000A08001AE500A5000172CD1245000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A500000B050008F703C6DBFA26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A100000605003DC200632D10DE
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 64 0 AA00000C0800679800A100014526FF87000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A100000D25007F8000D7843025CC713EA1543DF81EBAAF6BE244543EB9F4BC6FA74E8F246A711CD8C3EA54665F00000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000007070007F8000F41630A457A
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 64 0 AA00000E0800B14E00A2000151C59D69000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A200000F0C00C13E003E620027005900101FD1980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000008070012ED016450F8E6B5D9
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 64 0 AA00001008003FC000A0000187F37724000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A000001107008A7500000002FCFB4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020009050009F6004270904E
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 64 0 AA0000120800E91600B00201386F43E6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B002001345007788008A009C009400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D000000000000000000BEDDBBB29400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000A07009669000F41D397DA08
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 64 0 AA0000140800946B00A200014F39330E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000150C00E41B004E640027004F00755632510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000B0700AF50016450F9BB7550
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 64 0 AA000016080042BD00A000016CB093E1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A00000170700F708000000BAA9831600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000C0500C93600FFA00844
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 64 0 AA00001808006E9100B0020144AD1E73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B00200194500F00F008C009C009600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C000000000000000000E3A1F2A19600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000D0700807F000F41ABF4CD98
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 64 0 AA00001A0800B84700A2000195E5AEB2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A200001B0C00C8370048640027005A00021B15CE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000E07006F9001645040B3CD87
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 64 0 AA00001C0800C53A00A000011072CE74000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A000001D0700708F003A000B89A2D100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000F0500748B00E76F715E
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 64 0 AA00001E080013EC00B00201AFEEFAB6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B002001F45008D720008009900920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D00000000000000000069C4E77C920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000100700B34C000F4148456C7B
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 64 0 AA0000200800DE2100A2000173C16EC1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000210C00AE510048640027005500DD002B870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001107008A750164506269C323
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 64 0 AA000022080008F700A000015048CE2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A00000230700BD420000008C0CEEF100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020012050047B8005B407F33
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 64 0 AA0000240800758A00B0020149CA3AC5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B00200254500EB14008D00A100900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C0000000000000000000F8D1061900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001307000EF1000F414918ACF2
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 64 0 AA0000260800A35C00A2000198828A04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000270C00D32C0057640027004E0017D2351D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001407004AB5016450DB617BF4
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 64 0 AA00002808008F7000A000012C8A93BB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A000002907003AC500000044F2661300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020015050051AE00F61A492A
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 64 0 AA00002A080059A600B002019316A779000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B002002B4500C7380089009C00920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D000000000000000000A0269EE8920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000160700CE31000F41F0101425
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 64 0 AA00002C080024DB00A20001E440D791000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A200002D0C0054AB004A64002700590057B20D220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000170700F708016450DA3CBB7D
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 64 0 AA00002E0800F20D00A00001C7C9777E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A000002F070047B8004C4C4EAAB86E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200180500C03F00B4605C02
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 64 0 AA00003008007C8300B002018DEA091E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B00200314500E21D00080008000800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C000000000000000000E0BA753D0800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001907008976000F4181E62410
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 64 0 AA0000320800AA5500A200015CA2B9DF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000330C00DA25005464002700500088A694DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001A070066990164506AA1240F
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 64 0 AA0000340800D72800A00001D935D919000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A00000350700629D0000006775A83E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001B05007D8200ACAF2518
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 64 0 AA000036080001FE00B0020166A9EDDB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 B002003745009F600008000800080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C000000000000000000F054EC42080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001C070049B6000F4138EE9CC7
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 64 0 AA00003808002DD200A200012060E44A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000390C005DA2004A640027004F005D569D1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001D0700708F01645012C2339F
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 64 0 AA00003A0800FB0400A0000103E944A5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A000003B07004EB1000000D6B5F7C500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A300001E0700B649000F41F8F75650
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 64 0 AA00003C0800867900A30001B114E662000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A300003D0500629D009DDA98C4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A400001F6A001EE1640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900E6F6BD05
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 64 0 AA00003E080050AF00A40001795F8D8B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A400003F05006B940099962233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E0000020040049B6AEA0E8AB
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 64 0 AA00004008001BE400E00001D5F1C38E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E000004108001BE400000000315A099D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A60000210500B74800B39B168D
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 64 0 AA0000420800CD3200A60001EA5DF016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 128 0 A60000436C00EC130001640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900FA60A49A000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00100220400FD0253E4FA3B
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 64 0 AA0000440800B04F00E0010132DE18BE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E00100450800D22D000000002B1189D3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000230700EF100100238AF5F029
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 64 0 AA0000460800669900A2000190EB3938000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 A20000470C0016E9004C640027004D005C10F4310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000242400B7480000000000000000000000000000000000000000000000000000000000000000664B5D3F
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 64 0 AA00004808004AB500A50001CF21EB81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 192 0 A50000499200D22D004C642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50C82BB7E8C2D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E000002504008976203A9633
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 64 0 AA00004A08009C6300E00001A9339E1B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E000004B08009C63004C642A9C8BFEAB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E0010026040056A9D15D8DC2
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 64 0 AA00004C0800E11E00E00101034161C7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E001004D0800837C004C642ACB9D5A09000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB010023F3CB2730
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 64 0 A200004F0C0047B80052640027004D00E19CE96F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A500002824004DB200000000000000000000000000000000000000000000000000000000000000003DB8032C
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 64 0 AA0000500800B94600A500019C80610A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 192 0 A5000051920021DE0052642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50CCC7D08E82D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00000290400738C14C55D45
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 64 0 AA00005208006F9000E00001FA921490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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 64 0 E000005308006F900052642AB5A4CC36000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A700002A6A0044BB640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479001CF66539
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 64 0 AA000054080012ED00A70001544A2520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
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
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000055050052AD00C5D5FE86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@@ -20,6 +20,7 @@ d.open_sync()
template = FPrint.Print.new(d)
def enroll_progress(*args):
assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
print('enroll progress: ' + str(args))
def identify_done(dev, res):
@@ -31,7 +32,9 @@ def identify_done(dev, res):
# List, enroll, list, verify, identify, delete
print("enrolling")
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
p = d.enroll_sync(template, None, enroll_progress, None)
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
print("enroll done")
print("listing")
@@ -40,7 +43,9 @@ print("listing done")
assert len(stored) == 1
assert stored[0].equal(p)
print("verifying")
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
verify_res, verify_print = d.verify_sync(p)
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
print("verify done")
del p
assert verify_res == True

View File

@@ -1,30 +1,30 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8
N: bus/usb/001/003=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/001/003
P: /devices/pci0000:00/0000:00:14.0/usb3/3-2
N: bus/usb/003/008=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/003/008
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=27c6/60a2/100
E: PRODUCT=27c6/5840/100
E: TYPE=239/0/0
E: BUSNUM=001
E: DEVNUM=003
E: BUSNUM=003
E: DEVNUM=008
E: MAJOR=189
E: MINOR=2
E: MINOR=263
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_MODEL_ID=5840
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_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDE1AD5CBA_XXXX_MOC_B0
E: ID_SERIAL_SHORT=UIDE1AD5CBA_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
E: ID_PATH=pci-0000:00:14.0-usb-0:2
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2
E: LIBFPRINT_DRIVER=Goodix MOC Fingerprint Sensor
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
@@ -37,32 +37,32 @@ 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
A: busnum=3\n
A: configuration=UIDE1AD5CBA_XXXX_MOC_B0
H: descriptors=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
A: dev=189:263
A: devnum=8\n
A: devpath=2
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=60a2
A: idProduct=5840
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
L: port=../3-0:1.0/usb3-port2
A: power/active_duration=2684
A: power/async=enabled
A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000
A: power/connected_duration=5916532
A: power/connected_duration=54348
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_active_time=2518
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=5588987
A: power/runtime_suspended_time=51550
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
@@ -75,38 +75,39 @@ 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: removable=removable
A: rx_lanes=1
A: serial=UIDCBEE4D7B_XXXX_MOC_B0
A: serial=UIDE1AD5CBA_XXXX_MOC_B0
A: speed=12
A: tx_lanes=1
A: urbnum=2180
A: urbnum=15
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
P: /devices/pci0000:00/0000:00:14.0/usb3
N: bus/usb/003/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/003/001
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d6b/2/504
E: PRODUCT=1d6b/2/508
E: TYPE=9/0/1
E: BUSNUM=001
E: BUSNUM=003
E: DEVNUM=001
E: MAJOR=189
E: MINOR=0
E: MINOR=256
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=Linux_5.8.0-38-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.8.0-38-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_REVISION=0508
E: ID_SERIAL=Linux_5.8.0-38-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_AUTOSUSPEND=1
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
@@ -123,33 +124,33 @@ A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0504
A: bcdDevice=0508
A: bmAttributes=e0
A: busnum=1
A: busnum=3\n
A: configuration=
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0
A: devnum=1
H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:256
A: devnum=1\n
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: manufacturer=Linux 5.8.0-38-generic xhci-hcd
A: maxchild=4
A: power/active_duration=2790916
A: power/async=enabled
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=5916912
A: power/connected_duration=15607832
A: power/control=auto
A: power/level=auto
A: power/runtime_active_kids=2
A: power/runtime_active_time=5879430
A: power/runtime_active_kids=1
A: power/runtime_active_time=2790874
A: power/runtime_enabled=enabled
A: power/runtime_status=active
A: power/runtime_suspended_time=37481
A: power/runtime_suspended_time=12816956
A: power/runtime_usage=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
@@ -167,5 +168,7 @@ A: rx_lanes=1
A: serial=0000:00:14.0
A: speed=480
A: tx_lanes=1
A: urbnum=1319
A: urbnum=584
A: version= 2.00

54
tests/hwdb-check-unsupported.py Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import os
import sys
import urllib
import urllib.request
import re
error = False
try:
response = urllib.request.urlopen('https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md')
except:
print("Could not download current list of unsupported devices, skipping test.")
sys.exit(77)
data = response.read().decode('utf-8')
devices = []
devices_re = re.compile(r'^.*([0-9a-fA-F]{4}):([0-9a-fA-F]{4}).*$', re.MULTILINE)
for m in devices_re.finditer(data):
vid = m.group(1)
pid = m.group(2)
devices.append((vid, pid))
generator = open(os.path.join(os.path.dirname(__file__), '..', 'libfprint', 'fprint-list-udev-hwdb.c')).read()
id_re = re.compile(' { .vid = 0x([a-fA-F0-9]*), .pid = 0x([a-fA-F0-9]*) }')
# Check everything is the same
started = False
for l in generator.split('\n'):
m = id_re.match(l)
if m is None:
# Stop on the first line that does not match anymore
if started:
break
continue
else:
started = True
vid_pid = (m.group(1), m.group(2))
try:
devices.remove(vid_pid)
except ValueError:
print("Generator has entry that is not on wiki: {}:{}".format(*vid_pid))
error = True
for vid_pid in devices:
print("New entry from wiki is missing: {}:{}".format(*vid_pid))
error = True
if error:
sys.exit(1)
else:
sys.exit(0)

View File

@@ -5,14 +5,22 @@ envs.set('G_MESSAGES_DEBUG', 'all')
# Setup paths
envs.set('MESON_SOURCE_ROOT', meson.source_root())
envs.set('MESON_BUILD_ROOT', meson.build_root())
envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
# Set FP_DEVICE_EMULATION so that drivers can adapt (e.g. to use fixed
# random numbers rather than proper ones)
envs.set('FP_DEVICE_EMULATION', '1')
# Path to SDCP virtual device binary, only used for virtual-sdcp test
envs.set('SDCP_VIRT_BINARY', get_option('sdcp_virt_binary'))
# Set a colon-separated list of native drivers we enable in tests
envs.set('FP_DRIVERS_WHITELIST', 'virtual_image')
envs.set('FP_DRIVERS_WHITELIST', ':'.join([
'virtual_image',
'virtual_device',
'virtual_device_storage',
]))
envs.set('NO_AT_BRIDGE', '1')
@@ -28,22 +36,70 @@ drivers_tests = [
if get_option('introspection')
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
virtual_devices_tests = [
'virtual-image',
'virtual-device',
]
if 'virtual_image' in drivers
unittest_inspector = find_program('unittest_inspector.py')
foreach vdtest: virtual_devices_tests
driver_name = '_'.join(vdtest.split('-'))
if driver_name in drivers
python3 = find_program('python3')
base_args = files(vdtest + '.py')
suite = ['virtual-driver']
r = run_command(unittest_inspector, files(vdtest + '.py'))
unit_tests = r.stdout().strip().split('\n')
if r.returncode() == 0 and unit_tests.length() > 0
suite += vdtest
else
unit_tests = [vdtest]
endif
foreach ut: unit_tests
ut_suite = suite
ut_args = base_args
if unit_tests.length() > 1
ut_args += ut
ut_suite += ut.split('.')[0]
endif
test(ut,
python3,
args: ut_args,
suite: ut_suite,
depends: libfprint_typelib,
env: envs,
workdir: meson.current_source_dir(),
)
endforeach
else
test(vdtest,
find_program('sh'),
args: ['-c', 'exit 77']
)
endif
endforeach
if 'virtual_sdcp' in drivers and get_option('sdcp_virt_binary') != ''
python3 = find_program('python3')
unittest_inspector = find_program('unittest_inspector.py')
base_args = files('virtual-image.py')
base_args = files('virtual-sdcp.py')
suite = []
r = run_command(unittest_inspector, files('virtual-image.py'))
r = run_command(unittest_inspector, files('virtual-sdcp.py'))
unit_tests = r.stdout().strip().split('\n')
if r.returncode() == 0 and unit_tests.length() > 0
suite += 'virtual-image'
suite += 'virtual-sdcp'
else
unit_tests = ['virtual-image']
unit_tests = ['virtual-sdcp']
endif
sdcp_envs = envs
sdcp_envs.set('FP_DEVICE_EMULATION', '0')
foreach ut: unit_tests
ut_suite = suite
ut_args = base_args
@@ -56,11 +112,12 @@ if get_option('introspection')
args: ut_args,
suite: ut_suite,
depends: libfprint_typelib,
env: envs,
env: sdcp_envs,
workdir: meson.current_source_dir(),
)
endforeach
else
test('virtual-image',
test('virtual-sdcp',
find_program('sh'),
args: ['-c', 'exit 77']
)
@@ -70,11 +127,13 @@ if get_option('introspection')
driver_envs = envs
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
if driver_test in drivers and gusb_dep.version().version_compare('>= 0.3.0')
if (driver_test in supported_drivers and
gusb_dep.version().version_compare('>= 0.3.0'))
test(driver_test,
find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), driver_test),
env: driver_envs,
workdir: meson.current_source_dir(),
suite: ['drivers'],
timeout: 10,
depends: libfprint_typelib,
@@ -168,6 +227,13 @@ foreach test_name: unit_tests
)
endforeach
# Run udev rule generator with fatal warnings
envs.set('UDEV_HWDB', udev_hwdb.full_path())
envs.set('UDEV_HWDB_CHECK_CONTENTS', default_drivers_are_enabled ? '1' : '0')
test('udev-hwdb',
find_program('test-generated-hwdb.sh'),
env: envs)
gdb = find_program('gdb', required: false)
if gdb.found()
add_test_setup('gdb',
@@ -188,6 +254,7 @@ if valgrind.found()
timeout_multiplier: 10,
env: [
'G_SLICE=always-malloc',
'UNDER_VALGRIND=1',
('LIBFPRINT_TEST_WRAPPER=@0@ --tool=memcheck --leak-check=full ' +
'--suppressions=@1@ --suppressions=@2@').format(
valgrind.path(), glib_suppressions, python_suppressions)

BIN
tests/sdcp-key-db/cert9.db Normal file

Binary file not shown.

BIN
tests/sdcp-key-db/key4.db Normal file

Binary file not shown.

View File

@@ -4,14 +4,16 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 01
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 40 38 0 00009C37FE5C669C2D000A01014101C10000D11BB7134A090FA1000000000100000000000003
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE011100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE01130100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE025400
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE021100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02130100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE03512000014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE035400
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
@@ -20,13 +22,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255010C
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355010C
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
@@ -35,19 +37,19 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550119
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550119
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550125
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550125
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -56,13 +58,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550125
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550125
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -71,13 +73,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550132
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550132
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -86,13 +88,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255013E
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355013E
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -101,13 +103,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255013E
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355013E
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -116,13 +118,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255014B
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355014B
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
@@ -131,7 +133,7 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
@@ -140,13 +142,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550157
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550157
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
@@ -155,21 +157,21 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550164
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550164
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE02591F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE03591F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE03752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037200
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE037600
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE04651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE046600
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE04752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047200
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE047600
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE05651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE056600
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE046000
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE056000
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
@@ -178,9 +180,9 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE04651E4650312D30303030303030302D302
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0468214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE05811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE05831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE06A100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE06A200
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0568214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE06811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE06831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE07A100
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE07A200

View File

@@ -34,11 +34,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0000
A: bmAttributes=a0
A: busnum=1
A: busnum=1\n
A: configuration=
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
A: dev=189:69
A: devnum=70
A: devnum=70\n
A: devpath=1
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=00bd

View File

@@ -50,7 +50,7 @@ test_context_has_virtual_device (void)
GPtrArray *devices;
unsigned int i;
fpt_setup_virtual_device_environment ();
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
context = fp_context_new ();
devices = fp_context_get_devices (context);
@@ -82,7 +82,7 @@ test_context_enumerates_new_devices (void)
context = fp_context_new ();
fpt_setup_virtual_device_environment ();
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
fp_context_enumerate (context);
devices = fp_context_get_devices (context);
@@ -120,7 +120,7 @@ context_device_removed_cb (FpContext *ctx, FpDevice *device, FptContext *tctx)
static void
test_context_remove_device_closed (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
gboolean removed;
tctx->user_data = NULL;
@@ -162,7 +162,7 @@ close_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
static void
test_context_remove_device_closing (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_autoptr(GError) close_error = NULL;
g_autoptr(GError) error = NULL;
gboolean removed;
@@ -207,7 +207,7 @@ test_context_remove_device_closing (void)
static void
test_context_remove_device_open (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_autoptr(GError) error = NULL;
gboolean removed = FALSE;
@@ -267,7 +267,7 @@ open_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
static void
test_context_remove_device_opening (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_autoptr(GError) close_error = NULL;
gboolean open_done = FALSE;
gboolean removed;
@@ -287,7 +287,7 @@ test_context_remove_device_opening (void)
g_assert_true (removed);
g_assert_null (tctx->user_data);
/* Running the mainloop now will cause the open to *succeed* dispite removal! */
/* Running the mainloop now will cause the open to *succeed* despite removal! */
while (!open_done)
g_main_context_iteration (NULL, TRUE);
@@ -327,7 +327,7 @@ enroll_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
static void
test_context_remove_device_active (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_autoptr(GError) error = NULL;
g_autoptr(GCancellable) cancellable = NULL;
g_autoptr(GError) enroll_error = NULL;

View File

@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
static void
test_device_open_async (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
@@ -59,7 +59,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
static void
test_device_close_async (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
while (!tctx->user_data)
@@ -76,7 +76,7 @@ static void
test_device_open_sync (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, &error);
g_assert_no_error (error);
@@ -97,7 +97,7 @@ static void
test_device_open_sync_notify (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
fp_device_open_sync (tctx->device, NULL, &error);
@@ -109,7 +109,7 @@ static void
test_device_close_sync (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
fp_device_close_sync (tctx->device, NULL, &error);
@@ -131,7 +131,7 @@ static void
test_device_close_sync_notify (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
static void
test_device_get_driver (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
@@ -153,7 +153,7 @@ test_device_get_driver (void)
static void
test_device_get_device_id (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
static void
test_device_get_name (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
@@ -172,7 +172,7 @@ test_device_get_name (void)
static void
test_device_get_scan_type (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
@@ -181,7 +181,7 @@ test_device_get_scan_type (void)
static void
test_device_get_finger_status (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpint (fp_device_get_finger_status (tctx->device), ==, FP_FINGER_STATUS_NONE);
@@ -190,7 +190,7 @@ test_device_get_finger_status (void)
static void
test_device_get_nr_enroll_stages (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
@@ -199,7 +199,7 @@ test_device_get_nr_enroll_stages (void)
static void
test_device_supports_identify (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_true (fp_device_supports_identify (tctx->device));
@@ -208,7 +208,7 @@ test_device_supports_identify (void)
static void
test_device_supports_capture (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_true (fp_device_supports_capture (tctx->device));
@@ -217,7 +217,7 @@ test_device_supports_capture (void)
static void
test_device_has_storage (void)
{
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_false (fp_device_has_storage (tctx->device));

View File

@@ -433,7 +433,7 @@ test_driver_set_nr_enroll_stages (void)
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
int expected_stages = g_random_int_range (G_MININT32, G_MAXINT32);
int expected_stages = g_random_int_range (1, G_MAXINT32);
g_signal_connect (device, "notify::nr-enroll-stages", G_CALLBACK (on_device_notify), NULL);
fpi_device_set_nr_enroll_stages (device, expected_stages);
@@ -443,6 +443,18 @@ test_driver_set_nr_enroll_stages (void)
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "nr-enroll-stages");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*enroll_stages > 0*");
fpi_device_set_nr_enroll_stages (device, 0);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*enroll_stages > 0*");
fpi_device_set_nr_enroll_stages (device, -2);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
g_test_assert_expected_messages ();
}
static void

24
tests/test-generated-hwdb.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -e
[ -x "$UDEV_HWDB" ] || exit 1
if [ "$UDEV_HWDB_CHECK_CONTENTS" == 1 ]; then
generated_rules=$(mktemp "${TMPDIR:-/tmp}/libfprint-XXXXXX.hwdb")
else
generated_rules=/dev/null
fi
$UDEV_HWDB > "$generated_rules"
if [ "$UDEV_HWDB_CHECK_CONTENTS" != 1 ]; then
exit 77
fi
if ! diff -u "$MESON_SOURCE_ROOT/data/autosuspend.hwdb" "$generated_rules"; then
echo "E: Autosuspend file needs to be re-generated!"
echo " ninja -C $MESON_BUILD_ROOT libfprint/sync-udev-hwdb"
exit 1
fi
rm "$generated_rules"

View File

@@ -22,16 +22,31 @@
#include "test-utils.h"
struct
{
const char *envvar;
const char *driver_id;
const char *device_id;
} devtype_vars[FPT_NUM_VIRTUAL_DEVICE_TYPES] = {
{ "FP_VIRTUAL_IMAGE", "virtual_image", "virtual_image" }, /* FPT_VIRTUAL_DEVICE_IMAGE */
{ "FP_VIRTUAL_DEVICE", "virtual_device", "virtual_device" }, /* FPT_VIRTUAL_DEVICE_NONIMAGE */
{ "FP_VIRTUAL_DEVICE_STORAGE", "virtual_device_storage", "virtual_device_storage" } /* FPT_VIRTUAL_DEVICE_NONIMAGE_STORAGE */
};
static FptVirtualDeviceType global_devtype;
void
fpt_teardown_virtual_device_environment (void)
{
const char *path = g_getenv ("FP_VIRTUAL_IMAGE");
const char *path;
path = g_getenv (devtype_vars[global_devtype].envvar);
if (path)
{
g_autofree char *temp_dir = g_path_get_dirname (path);
g_unsetenv ("FP_VIRTUAL_IMAGE");
g_unsetenv (devtype_vars[global_devtype].envvar);
g_unlink (path);
g_rmdir (temp_dir);
}
@@ -44,19 +59,23 @@ on_signal_event (int sig)
}
void
fpt_setup_virtual_device_environment (void)
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype)
{
g_autoptr(GError) error = NULL;
g_autofree char *temp_dir = NULL;
g_autofree char *temp_path = NULL;
g_autofree char *filename = NULL;
g_assert_null (g_getenv ("FP_VIRTUAL_IMAGE"));
g_assert_null (g_getenv (devtype_vars[devtype].envvar));
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
g_assert_no_error (error);
temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id);
temp_path = g_build_filename (temp_dir, filename, NULL);
g_setenv (devtype_vars[devtype].envvar, temp_path, TRUE);
global_devtype = devtype;
signal (SIGKILL, on_signal_event);
signal (SIGABRT, on_signal_event);
@@ -78,13 +97,16 @@ fpt_context_new (void)
}
FptContext *
fpt_context_new_with_virtual_imgdev (void)
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
{
FptContext *tctx;
GPtrArray *devices;
unsigned int i;
fpt_setup_virtual_device_environment ();
g_assert_true (devtype >= FPT_VIRTUAL_DEVICE_IMAGE &&
devtype < FPT_NUM_VIRTUAL_DEVICE_TYPES);
fpt_setup_virtual_device_environment (devtype);
tctx = fpt_context_new ();
devices = fp_context_get_devices (tctx->fp_context);
@@ -96,7 +118,7 @@ fpt_context_new_with_virtual_imgdev (void)
{
FpDevice *device = devices->pdata[i];
if (g_strcmp0 (fp_device_get_driver (device), "virtual_image") == 0)
if (g_strcmp0 (fp_device_get_driver (device), devtype_vars[devtype].driver_id) == 0)
{
tctx->device = device;
break;

View File

@@ -19,7 +19,14 @@
#include <glib.h>
void fpt_setup_virtual_device_environment (void);
typedef enum {
FPT_VIRTUAL_DEVICE_IMAGE = 0,
FPT_VIRTUAL_DEVICE_NONIMAGE,
FPT_VIRTUAL_DEVICE_NONIMAGE_STORAGE,
FPT_NUM_VIRTUAL_DEVICE_TYPES
} FptVirtualDeviceType;
void fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype);
void fpt_teardown_virtual_device_environment (void);
typedef struct _FptContext
@@ -30,7 +37,7 @@ typedef struct _FptContext
} FptContext;
FptContext * fpt_context_new (void);
FptContext * fpt_context_new_with_virtual_imgdev (void);
FptContext * fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype);
void fpt_context_free (FptContext *test_context);

0
tests/umockdev-test.py Normal file → Executable file
View File

View File

@@ -38,11 +38,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0060
A: bmAttributes=a0
A: busnum=1
A: busnum=1\n
A: configuration=
H: descriptors=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
A: dev=189:3
A: devnum=4
A: devnum=4\n
A: devpath=9
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=0050

View File

@@ -37,11 +37,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0c90
A: bmAttributes=a0
A: busnum=2
A: busnum=2\n
A: configuration=
H: descriptors=12011001FF10FF088A130500900C0000000109022700010100A0320904000003FF000000070501024000000705810240000007058202400000
A: dev=189:132
A: devnum=5
A: devnum=5\n
A: devpath=1.3
L: driver=../../../../../../bus/usb/drivers/usb
A: idProduct=0005
@@ -120,11 +120,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0000
A: bmAttributes=e0
A: busnum=2
A: busnum=2\n
A: configuration=
H: descriptors=12010002090001408780200000000000000109021900010100E0000904000001090000000705810302000C
A: dev=189:129
A: devnum=2
A: devnum=2\n
A: devpath=1
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=0020
@@ -204,11 +204,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0504
A: bmAttributes=e0
A: busnum=2
A: busnum=2\n
A: configuration=
H: descriptors=12010002090000406B1D020004050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:128
A: devnum=1
A: devnum=1\n
A: devpath=0
L: driver=../../../../bus/usb/drivers/usb
A: idProduct=0002

View File

@@ -35,11 +35,11 @@ A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0078
A: bmAttributes=a0
A: busnum=2
A: busnum=2\n
A: configuration=
H: descriptors=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
A: dev=189:144
A: devnum=17
A: devnum=17\n
A: devpath=6
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=0017

1112
tests/virtual-device.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -223,6 +223,10 @@ class VirtualImage(unittest.TestCase):
ctx.iteration(True)
self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NONE)
self.assertEqual(self._enrolled.props.driver, self.dev.get_driver())
self.assertEqual(self._enrolled.props.device_id, self.dev.get_device_id())
self.assertEqual(self._enrolled.props.device_stored, self.dev.has_storage())
self.assertIsNone(self._enrolled.get_image())
return self._enrolled
@@ -244,6 +248,7 @@ class VirtualImage(unittest.TestCase):
while self._verify_match is None:
ctx.iteration(True)
assert(self._verify_match)
self.assertIsNotNone(self._verify_fp.props.image)
self._verify_match = None
self._verify_fp = None

144
tests/virtual-sdcp.py Normal file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env python3
import sys
try:
import gi
import os
from gi.repository import GLib, Gio
import unittest
import subprocess
import shutil
import tempfile
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:
wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
sys.argv[1:]
os.unsetenv('LIBFPRINT_TEST_WRAPPER')
sys.exit(subprocess.check_call(wrap_cmd))
# Only permit loading virtual_sdcp driver for tests in this file
os.environ['FP_DRIVERS_WHITELIST'] = 'virtual_sdcp'
if hasattr(os.environ, 'MESON_SOURCE_ROOT'):
root = os.environ['MESON_SOURCE_ROOT']
else:
root = os.path.join(os.path.dirname(__file__), '..')
ctx = GLib.main_context_default()
class VirtualSDCP(unittest.TestCase):
@classmethod
def setUpClass(cls):
os.environ['FP_VIRTUAL_SDCP'] = os.environ['SDCP_VIRT_BINARY']
cls.ctx = FPrint.Context()
cls.dev = None
for dev in cls.ctx.get_devices():
cls.dev = dev
break
assert cls.dev is not None, "You need to compile with virtual_sdcp for testing"
@classmethod
def tearDownClass(cls):
del cls.dev
del cls.ctx
def setUp(self):
pass
def tearDown(self):
pass
def enroll(self, progress_cb=None):
# Enroll another print
template = FPrint.Print.new(self.dev)
template.props.finger = FPrint.Finger.LEFT_THUMB
template.props.username = "testuser"
template.props.description = "test print"
datetime = GLib.DateTime.new_now_local()
date = GLib.Date()
date.set_dmy(*datetime.get_ymd()[::-1])
template.props.enroll_date = date
return self.dev.enroll_sync(template, None, progress_cb, None)
def test_connect(self):
self.dev.open_sync()
self.dev.close_sync()
def test_reconnect(self):
# Ensure device was opened once before, this may be a reconnect if
# it is the same process as another test.
self.dev.open_sync()
self.dev.close_sync()
# Check that a reconnect happens on next open. To know about this, we
# need to parse check log messages for that.
success = [False]
def log_func(domain, level, msg):
print("log: '%s', '%s', '%s'" % (str(domain), str(level), msg))
if msg == 'Reconnect succeeded':
success[0] = True
# Call default handler
GLib.log_default_handler(domain, level, msg)
handler_id = GLib.log_set_handler('libfprint-sdcp_device', GLib.LogLevelFlags.LEVEL_DEBUG, log_func)
self.dev.open_sync()
self.dev.close_sync()
GLib.log_remove_handler('libfprint-sdcp_device', handler_id)
assert success[0]
def test_enroll(self):
self.dev.open_sync()
# Must return a print
assert isinstance(self.enroll(), FPrint.Print)
self.dev.close_sync()
def test_verify(self):
self.dev.open_sync()
# Enroll a new print (will be the last), check that it verifies
p = self.enroll()
match, dev_print = self.dev.verify_sync(p)
assert match
# The returned "device" print is identical
assert p.equal(dev_print)
# We can do the same with it
match, dev_print2 = self.dev.verify_sync(dev_print)
assert match
# Now, enroll a new print, causing the old one to not match anymore
# (the device always claims to see the last enrolled print).
self.enroll()
match, dev_print = self.dev.verify_sync(p)
assert match is False
self.dev.close_sync()
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))