mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-09-10 21:06:51 +00:00
Compare commits
187
Commits
@@ -0,0 +1,10 @@
|
|||||||
|
# The commits that did automated reformatting. You can ignore them
|
||||||
|
# during git-blame with `--ignore-rev` or `--ignore-revs-file`.
|
||||||
|
#
|
||||||
|
# $ git config --add 'blame.ignoreRevsFile' '.git-blame-ignore-revs'
|
||||||
|
#
|
||||||
|
|
||||||
|
d1fb1e26f3b79e54febc94496c1184763cf2af3d
|
||||||
|
e4f9935706be4c0e3253afe251c182019ff7ccef
|
||||||
|
65e602d8c72baa7020efb62d10bf28e621feb05d
|
||||||
|
4115ae7ced77d392ee11ea55212206d9404356f0
|
||||||
+11
-2
@@ -63,7 +63,7 @@ test:
|
|||||||
script:
|
script:
|
||||||
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
|
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
||||||
- ninja -C _build coverage
|
- ninja -C _build coverage
|
||||||
- cat _build/meson-logs/coverage.txt
|
- cat _build/meson-logs/coverage.txt
|
||||||
artifacts:
|
artifacts:
|
||||||
@@ -80,7 +80,7 @@ test_valgrind:
|
|||||||
script:
|
script:
|
||||||
- meson -Ddrivers=all . _build
|
- meson -Ddrivers=all . _build
|
||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
|
||||||
|
|
||||||
test_scan_build:
|
test_scan_build:
|
||||||
stage: test
|
stage: test
|
||||||
@@ -109,6 +109,15 @@ test_indent:
|
|||||||
- git diff
|
- git diff
|
||||||
- "! git status -s | grep -q ."
|
- "! 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:
|
flatpak:
|
||||||
stage: flatpak
|
stage: flatpak
|
||||||
extends: .flatpak
|
extends: .flatpak
|
||||||
|
|||||||
@@ -1,6 +1,65 @@
|
|||||||
This file lists notable changes in each release. For the full history of all
|
This file lists notable changes in each release. For the full history of all
|
||||||
changes, see ChangeLog.
|
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.
|
||||||
|
|
||||||
|
The major change is that fp_print_deserialize will now correctly return a
|
||||||
|
sunken reference rather than a floating one. Most API users will have
|
||||||
|
assumed this was true, and issues could happen at a later point.
|
||||||
|
If any API user worked around this libfprint bug, they will now leak the
|
||||||
|
returned print.
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
* Object reference management fixes for FpPrint and identify
|
||||||
|
* Fixed issues that caused problem on non-x86 machines (#236)
|
||||||
|
* Fix building with older GLib versions
|
||||||
|
* synaptics: Support PID 00e7
|
||||||
|
* goodix: Fix issue with long USB packages
|
||||||
|
|
||||||
|
|
||||||
|
2020-12-01: v1.90.5 release
|
||||||
|
|
||||||
|
The 1.90.4 release caused a major regression, as it included a USB hub in
|
||||||
|
UDEV the autosupend rule list.
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
* Remove USB hub from udev autosupend rules
|
||||||
|
* synaptics: Add PID 0x00c9 which is used in some HP laptops
|
||||||
|
|
||||||
|
|
||||||
|
2020-11-27: v1.90.4 release
|
||||||
|
|
||||||
|
This release contains a number of important bugfixes. On the feature side,
|
||||||
|
the USB hotplug support was improved. A lot of drivers received fixes and
|
||||||
|
improvements.
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
* Work around GUsb cancellation issue
|
||||||
|
* Redefine internal image device state machine for more robustness
|
||||||
|
* Add public finger-status reporting to FpDevice
|
||||||
|
* Rework device removal API to be convenient (#330)
|
||||||
|
* Enable powersave for unsupported USB devices
|
||||||
|
* Improvements to examples
|
||||||
|
* synaptics: Support identify operation
|
||||||
|
* synaptics: Fix possible crash when the interrupt transfer is resubmitted
|
||||||
|
* synaptics: Add support for PIDs 0x00f9, 0x00fc and 0x00c2
|
||||||
|
* elan: Add PID 0x0c4d to supported device list
|
||||||
|
* aes3k: Fix driver and add CI test (#306)
|
||||||
|
* uru4000: Fix reference counting of image transfer
|
||||||
|
* vfs301: Fix driver and add CI test (#320)
|
||||||
|
|
||||||
2020-06-08: v1.90.3 release
|
2020-06-08: v1.90.3 release
|
||||||
|
|
||||||
This release mostly contains support for a number of new match-on-chip
|
This release mostly contains support for a number of new match-on-chip
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
# 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 nb1010
|
||||||
|
usb:v298Dp1010*
|
||||||
|
ID_AUTOSUSPEND=1
|
||||||
|
|
||||||
|
# Supported by libfprint driver synaptics
|
||||||
|
usb:v06CBp00BD*
|
||||||
|
usb:v06CBp00E9*
|
||||||
|
usb:v06CBp00DF*
|
||||||
|
usb:v06CBp00F9*
|
||||||
|
usb:v06CBp00FC*
|
||||||
|
usb:v06CBp00C2*
|
||||||
|
usb:v06CBp00C9*
|
||||||
|
usb:v06CBp0100*
|
||||||
|
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
|
||||||
|
|
||||||
|
# Supported by libfprint driver vfs7552
|
||||||
|
usb:v138Ap0091*
|
||||||
|
ID_AUTOSUSPEND=1
|
||||||
|
|
||||||
|
# Known unsupported devices
|
||||||
|
usb:v04F3p036B*
|
||||||
|
usb:v04F3p0C00*
|
||||||
|
usb:v04F3p0C4B*
|
||||||
|
usb:v04F3p0C4C*
|
||||||
|
usb:v04F3p0C4F*
|
||||||
|
usb:v04F3p0C57*
|
||||||
|
usb:v04F3p0C5E*
|
||||||
|
usb:v04F3p2706*
|
||||||
|
usb:v06CBp0081*
|
||||||
|
usb:v06CBp0088*
|
||||||
|
usb:v06CBp008A*
|
||||||
|
usb:v06CBp009A*
|
||||||
|
usb:v06CBp009B*
|
||||||
|
usb:v06CBp00A2*
|
||||||
|
usb:v06CBp00B7*
|
||||||
|
usb:v06CBp00BB*
|
||||||
|
usb:v06CBp00BE*
|
||||||
|
usb:v06CBp00C4*
|
||||||
|
usb:v06CBp00CB*
|
||||||
|
usb:v06CBp00D8*
|
||||||
|
usb:v06CBp00DA*
|
||||||
|
usb:v0A5Cp5801*
|
||||||
|
usb:v0A5Cp5805*
|
||||||
|
usb:v0A5Cp5834*
|
||||||
|
usb:v0A5Cp5840*
|
||||||
|
usb:v0A5Cp5841*
|
||||||
|
usb:v0A5Cp5842*
|
||||||
|
usb:v0A5Cp5843*
|
||||||
|
usb:v0A5Cp5845*
|
||||||
|
usb:v10A5p0007*
|
||||||
|
usb:v1188p9545*
|
||||||
|
usb:v138Ap0007*
|
||||||
|
usb:v138Ap003A*
|
||||||
|
usb:v138Ap003C*
|
||||||
|
usb:v138Ap003D*
|
||||||
|
usb:v138Ap003F*
|
||||||
|
usb:v138Ap0090*
|
||||||
|
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
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
if udev_hwdb_dir != ''
|
||||||
|
# This file has to be updated using
|
||||||
|
# ninja -C <builddir> libfprint/sync-udev-hwdb
|
||||||
|
# Note that the unsupported device list needs to be manually synced from
|
||||||
|
# the wiki. See comment in libfprint/fprint-list-uev-hwdb.c
|
||||||
|
|
||||||
|
install_data('autosuspend.hwdb',
|
||||||
|
rename: '60-autosuspend-@0@.hwdb'.format(versioned_libname),
|
||||||
|
install_dir: udev_hwdb_dir,
|
||||||
|
)
|
||||||
|
endif
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
{
|
{
|
||||||
"name": "libfprint",
|
"name": "libfprint",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
"config-opts": [ "-Dudev_rules=false", "-Dx11-examples=false", "-Dgtk-examples=true", "-Ddrivers=all" ],
|
"config-opts": [ "-Dudev_hwdb=disabled", "-Dx11-examples=false", "-Dgtk-examples=true", "-Ddrivers=all" ],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -32,9 +32,11 @@ fp_device_get_device_id
|
|||||||
fp_device_get_name
|
fp_device_get_name
|
||||||
fp_device_get_scan_type
|
fp_device_get_scan_type
|
||||||
fp_device_get_nr_enroll_stages
|
fp_device_get_nr_enroll_stages
|
||||||
|
fp_device_get_finger_status
|
||||||
fp_device_has_storage
|
fp_device_has_storage
|
||||||
fp_device_supports_identify
|
fp_device_supports_identify
|
||||||
fp_device_supports_capture
|
fp_device_supports_capture
|
||||||
|
fp_device_is_open
|
||||||
fp_device_open
|
fp_device_open
|
||||||
fp_device_close
|
fp_device_close
|
||||||
fp_device_enroll
|
fp_device_enroll
|
||||||
@@ -91,8 +93,6 @@ FP_TYPE_PRINT
|
|||||||
FpFinger
|
FpFinger
|
||||||
FpPrint
|
FpPrint
|
||||||
fp_print_new
|
fp_print_new
|
||||||
fp_print_new_from_data
|
|
||||||
fp_print_to_data
|
|
||||||
fp_print_get_driver
|
fp_print_get_driver
|
||||||
fp_print_get_device_id
|
fp_print_get_device_id
|
||||||
fp_print_get_device_stored
|
fp_print_get_device_stored
|
||||||
@@ -131,8 +131,11 @@ fpi_get_driver_types
|
|||||||
FpDeviceClass
|
FpDeviceClass
|
||||||
FpTimeoutFunc
|
FpTimeoutFunc
|
||||||
FpiDeviceAction
|
FpiDeviceAction
|
||||||
|
FpiDeviceFeature
|
||||||
FpIdEntry
|
FpIdEntry
|
||||||
|
FpiDeviceUdevSubtypeFlags
|
||||||
fpi_device_get_usb_device
|
fpi_device_get_usb_device
|
||||||
|
fpi_device_get_udev_data
|
||||||
fpi_device_get_virtual_env
|
fpi_device_get_virtual_env
|
||||||
fpi_device_get_current_action
|
fpi_device_get_current_action
|
||||||
fpi_device_retry_new
|
fpi_device_retry_new
|
||||||
@@ -150,6 +153,9 @@ fpi_device_action_is_cancelled
|
|||||||
fpi_device_add_timeout
|
fpi_device_add_timeout
|
||||||
fpi_device_set_nr_enroll_stages
|
fpi_device_set_nr_enroll_stages
|
||||||
fpi_device_set_scan_type
|
fpi_device_set_scan_type
|
||||||
|
fpi_device_remove
|
||||||
|
fpi_device_report_finger_status
|
||||||
|
fpi_device_report_finger_status_changes
|
||||||
fpi_device_action_error
|
fpi_device_action_error
|
||||||
fpi_device_probe_complete
|
fpi_device_probe_complete
|
||||||
fpi_device_open_complete
|
fpi_device_open_complete
|
||||||
@@ -162,6 +168,8 @@ fpi_device_delete_complete
|
|||||||
fpi_device_enroll_progress
|
fpi_device_enroll_progress
|
||||||
fpi_device_verify_report
|
fpi_device_verify_report
|
||||||
fpi_device_identify_report
|
fpi_device_identify_report
|
||||||
|
fpi_device_list_complete
|
||||||
|
fpi_device_class_auto_initialize_features
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
@@ -186,6 +194,7 @@ fpi_image_device_deactivate_complete
|
|||||||
fpi_image_device_report_finger_status
|
fpi_image_device_report_finger_status
|
||||||
fpi_image_device_image_captured
|
fpi_image_device_image_captured
|
||||||
fpi_image_device_retry_scan
|
fpi_image_device_retry_scan
|
||||||
|
fpi_image_device_set_bz3_threshold
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
@@ -229,10 +238,10 @@ fpi_ssm_mark_completed
|
|||||||
fpi_ssm_mark_failed
|
fpi_ssm_mark_failed
|
||||||
fpi_ssm_set_data
|
fpi_ssm_set_data
|
||||||
fpi_ssm_get_data
|
fpi_ssm_get_data
|
||||||
|
fpi_ssm_get_device
|
||||||
fpi_ssm_get_error
|
fpi_ssm_get_error
|
||||||
fpi_ssm_dup_error
|
fpi_ssm_dup_error
|
||||||
fpi_ssm_get_cur_state
|
fpi_ssm_get_cur_state
|
||||||
fpi_ssm_next_state_timeout_cb
|
|
||||||
fpi_ssm_usb_transfer_cb
|
fpi_ssm_usb_transfer_cb
|
||||||
FpiSsm
|
FpiSsm
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include <libfprint-2/fprint.h>
|
||||||
|
#include <libfprint-2/fp-image-device.h>
|
||||||
|
|
||||||
|
fp_context_get_type
|
||||||
|
fp_device_get_type
|
||||||
|
fp_image_device_get_type
|
||||||
|
fp_image_get_type
|
||||||
|
fp_print_get_type
|
||||||
@@ -30,6 +30,7 @@ gnome.gtkdoc(versioned_libname,
|
|||||||
content_files: content_files,
|
content_files: content_files,
|
||||||
expand_content_files: expand_content_files,
|
expand_content_files: expand_content_files,
|
||||||
ignore_headers: private_headers,
|
ignore_headers: private_headers,
|
||||||
|
gobject_typesfile: 'libfprint-2.types',
|
||||||
fixxref_args: [
|
fixxref_args: [
|
||||||
'--html-dir=@0@'.format(docpath),
|
'--html-dir=@0@'.format(docpath),
|
||||||
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
|
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
|
||||||
|
|||||||
+8
-4
@@ -76,9 +76,14 @@ on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
{
|
{
|
||||||
enroll_data->ret_value = EXIT_SUCCESS;
|
enroll_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
||||||
if (!fp_device_has_storage (dev))
|
if (fp_device_has_storage (dev))
|
||||||
{
|
g_debug ("Device has storage, saving a print reference locally");
|
||||||
g_debug ("Device has not storage, saving locally");
|
else
|
||||||
|
g_debug ("Device has not storage, saving print only locally");
|
||||||
|
|
||||||
|
/* Even if the device has storage, it may not be able to save all the
|
||||||
|
* metadata that the print contains, so we can always save a local copy
|
||||||
|
* containing the handle to the device print */
|
||||||
int r = print_data_save (print, enroll_data->finger);
|
int r = print_data_save (print, enroll_data->finger);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
@@ -86,7 +91,6 @@ on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
enroll_data->ret_value = EXIT_FAILURE;
|
enroll_data->ret_value = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_warning ("Enroll failed with error %s", error->message);
|
g_warning ("Enroll failed with error %s", error->message);
|
||||||
|
|||||||
@@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Example fingerprint verification program, which verifies the
|
||||||
|
* finger which has been previously enrolled to disk.
|
||||||
|
* 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 "example-identify"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <libfprint/fprint.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
|
||||||
|
#include "storage.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
typedef struct _IdentifyData
|
||||||
|
{
|
||||||
|
GMainLoop *loop;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
unsigned int sigint_handler;
|
||||||
|
int ret_value;
|
||||||
|
} IdentifyData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
identify_data_free (IdentifyData *identify_data)
|
||||||
|
{
|
||||||
|
g_clear_handle_id (&identify_data->sigint_handler, g_source_remove);
|
||||||
|
g_clear_object (&identify_data->cancellable);
|
||||||
|
g_main_loop_unref (identify_data->loop);
|
||||||
|
g_free (identify_data);
|
||||||
|
}
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdentifyData, identify_data_free)
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
fp_device_close_finish (dev, res, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
g_warning ("Failed closing device %s", error->message);
|
||||||
|
|
||||||
|
g_main_loop_quit (identify_data->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
identify_quit (FpDevice *dev,
|
||||||
|
IdentifyData *identify_data)
|
||||||
|
{
|
||||||
|
if (!fp_device_is_open (dev))
|
||||||
|
{
|
||||||
|
g_main_loop_quit (identify_data->loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, identify_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_identification (FpDevice *dev,
|
||||||
|
IdentifyData *identify_data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_identify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
g_autoptr(FpPrint) print = NULL;
|
||||||
|
g_autoptr(FpPrint) match = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
char buffer[20];
|
||||||
|
|
||||||
|
if (!fp_device_identify_finish (dev, res, &match, &print, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to identify print: %s", error->message);
|
||||||
|
identify_data->ret_value = EXIT_FAILURE;
|
||||||
|
|
||||||
|
if (error->domain != FP_DEVICE_RETRY)
|
||||||
|
{
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("Identify again? [Y/n]? ");
|
||||||
|
if (fgets (buffer, sizeof (buffer), stdin) &&
|
||||||
|
(buffer[0] == 'Y' || buffer[0] == 'y' || buffer[0] == '\n'))
|
||||||
|
{
|
||||||
|
start_identification (dev, identify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FpPrint *
|
||||||
|
get_stored_print (FpDevice *dev, FpPrint *print)
|
||||||
|
{
|
||||||
|
g_autoptr(GPtrArray) gallery = gallery_data_load (dev);
|
||||||
|
guint index;
|
||||||
|
|
||||||
|
if (g_ptr_array_find_with_equal_func (gallery, print,
|
||||||
|
(GEqualFunc) fp_print_equal,
|
||||||
|
&index))
|
||||||
|
return g_object_ref (g_ptr_array_index (gallery, index));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_identify_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("Identify report: No finger matched, retry error reported: %s",
|
||||||
|
error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print && fp_print_get_image (print) &&
|
||||||
|
print_image_save (print, "identify.pgm"))
|
||||||
|
g_print ("Print image saved as identify.pgm\n");
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
g_autoptr(FpPrint) matched_print = g_object_ref (match);
|
||||||
|
char date_str[128] = {};
|
||||||
|
|
||||||
|
identify_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
if (fp_print_get_device_stored (match))
|
||||||
|
{
|
||||||
|
FpPrint *stored_print = get_stored_print (dev, match);
|
||||||
|
|
||||||
|
if (stored_print)
|
||||||
|
matched_print = g_steal_pointer (&stored_print);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp_print_get_enroll_date (matched_print))
|
||||||
|
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
||||||
|
fp_print_get_enroll_date (matched_print));
|
||||||
|
else
|
||||||
|
strcpy (date_str, "<unknown>");
|
||||||
|
|
||||||
|
g_debug ("Identify report: device %s matched finger %s successfully "
|
||||||
|
"with print '%s', enrolled on date %s by user %s",
|
||||||
|
fp_device_get_name (dev),
|
||||||
|
finger_to_string (fp_print_get_finger (matched_print)),
|
||||||
|
fp_print_get_description (matched_print), date_str,
|
||||||
|
fp_print_get_username (matched_print));
|
||||||
|
|
||||||
|
g_print ("IDENTIFIED!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_debug ("Identification report: No finger matched");
|
||||||
|
g_print ("NOT IDENTIFIED!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
g_autoptr(GPtrArray) gallery = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
gallery = fp_device_list_prints_finish (dev, res, &error);
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
if (!gallery->len)
|
||||||
|
{
|
||||||
|
g_warning ("No prints saved on device");
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("Identifying with %u prints in gallery", gallery->len);
|
||||||
|
fp_device_identify (dev, gallery, identify_data->cancellable,
|
||||||
|
on_identify_cb, identify_data, NULL,
|
||||||
|
(GAsyncReadyCallback) on_identify_completed,
|
||||||
|
identify_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Loading prints failed with error %s", error->message);
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_identification (FpDevice *dev, IdentifyData *identify_data)
|
||||||
|
{
|
||||||
|
if (fp_device_has_storage (dev))
|
||||||
|
{
|
||||||
|
g_print ("Creating finger template, using device storage...\n");
|
||||||
|
fp_device_list_prints (dev, NULL,
|
||||||
|
(GAsyncReadyCallback) on_list_completed,
|
||||||
|
identify_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_autoptr(GPtrArray) gallery = gallery_data_load (dev);
|
||||||
|
|
||||||
|
if (!gallery)
|
||||||
|
{
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("Gallery loaded. Time to identify!\n");
|
||||||
|
fp_device_identify (dev, gallery, identify_data->cancellable,
|
||||||
|
on_identify_cb, identify_data, NULL,
|
||||||
|
(GAsyncReadyCallback) on_identify_completed,
|
||||||
|
identify_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
|
identify_quit (dev, identify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("Opened device. ");
|
||||||
|
|
||||||
|
start_identification (dev, identify_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sigint_cb (void *user_data)
|
||||||
|
{
|
||||||
|
IdentifyData *identify_data = user_data;
|
||||||
|
|
||||||
|
g_cancellable_cancel (identify_data->cancellable);
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
g_autoptr(FpContext) ctx = NULL;
|
||||||
|
g_autoptr(IdentifyData) identify_data = NULL;
|
||||||
|
GPtrArray *devices;
|
||||||
|
FpDevice *dev;
|
||||||
|
|
||||||
|
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||||
|
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||||
|
|
||||||
|
ctx = fp_context_new ();
|
||||||
|
|
||||||
|
devices = fp_context_get_devices (ctx);
|
||||||
|
if (!devices)
|
||||||
|
{
|
||||||
|
g_warning ("Impossible to get devices");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = discover_device (devices);
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
g_warning ("No devices detected.");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fp_device_supports_identify (dev))
|
||||||
|
{
|
||||||
|
g_warning ("Device %s does not support identification.",
|
||||||
|
fp_device_get_name (dev));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
identify_data = g_new0 (IdentifyData, 1);
|
||||||
|
identify_data->ret_value = EXIT_FAILURE;
|
||||||
|
identify_data->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
identify_data->cancellable = g_cancellable_new ();
|
||||||
|
identify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
|
||||||
|
SIGINT,
|
||||||
|
sigint_cb,
|
||||||
|
identify_data,
|
||||||
|
NULL);
|
||||||
|
fp_device_open (dev, identify_data->cancellable,
|
||||||
|
(GAsyncReadyCallback) on_device_opened,
|
||||||
|
identify_data);
|
||||||
|
|
||||||
|
g_main_loop_run (identify_data->loop);
|
||||||
|
|
||||||
|
return identify_data->ret_value;
|
||||||
|
}
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
|
|
||||||
examples = [ 'enroll', 'verify', 'manage-prints', 'img-capture' ]
|
examples = [
|
||||||
|
'enroll',
|
||||||
|
'identify',
|
||||||
|
'img-capture',
|
||||||
|
'manage-prints',
|
||||||
|
'verify',
|
||||||
|
]
|
||||||
|
|
||||||
foreach example: examples
|
foreach example: examples
|
||||||
executable(example,
|
executable(example,
|
||||||
[ example + '.c', 'storage.c', 'utilities.c' ],
|
[ example + '.c', 'storage.c', 'utilities.c' ],
|
||||||
|
|||||||
+47
-1
@@ -2,7 +2,7 @@
|
|||||||
* Trivial storage driver for example programs
|
* Trivial storage driver for example programs
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
|
* Copyright (C) 2019-2020 Marco Trevisan <marco.trevisan@canonical.com>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -160,6 +160,52 @@ print_data_load (FpDevice *dev, FpFinger finger)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPtrArray *
|
||||||
|
gallery_data_load (FpDevice *dev)
|
||||||
|
{
|
||||||
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
|
g_autoptr(GVariant) dict_variant = NULL;
|
||||||
|
g_autofree char *dev_prefix = NULL;
|
||||||
|
GPtrArray *gallery;
|
||||||
|
const char *driver;
|
||||||
|
const char *dev_id;
|
||||||
|
GVariantIter iter;
|
||||||
|
GVariant *value;
|
||||||
|
gchar *key;
|
||||||
|
|
||||||
|
gallery = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
|
dict = load_data ();
|
||||||
|
dict_variant = g_variant_dict_end (dict);
|
||||||
|
driver = fp_device_get_driver (dev);
|
||||||
|
dev_id = fp_device_get_device_id (dev);
|
||||||
|
dev_prefix = g_strdup_printf ("%s/%s/", driver, dev_id);
|
||||||
|
|
||||||
|
g_variant_iter_init (&iter, dict_variant);
|
||||||
|
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
||||||
|
{
|
||||||
|
FpPrint *print;
|
||||||
|
const guchar *stored_data;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
gsize stored_len;
|
||||||
|
|
||||||
|
if (!g_str_has_prefix (key, dev_prefix))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stored_data = (const guchar *) g_variant_get_fixed_array (value, &stored_len, 1);
|
||||||
|
print = fp_print_deserialize (stored_data, stored_len, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("Error deserializing data: %s", error->message);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (gallery, print);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gallery;
|
||||||
|
}
|
||||||
|
|
||||||
FpPrint *
|
FpPrint *
|
||||||
print_create_template (FpDevice *dev, FpFinger finger)
|
print_create_template (FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ int print_data_save (FpPrint *print,
|
|||||||
FpFinger finger);
|
FpFinger finger);
|
||||||
FpPrint * print_data_load (FpDevice *dev,
|
FpPrint * print_data_load (FpDevice *dev,
|
||||||
FpFinger finger);
|
FpFinger finger);
|
||||||
|
GPtrArray * gallery_data_load (FpDevice *dev);
|
||||||
FpPrint * print_create_template (FpDevice *dev,
|
FpPrint * print_create_template (FpDevice *dev,
|
||||||
FpFinger finger);
|
FpFinger finger);
|
||||||
gboolean print_image_save (FpPrint *print,
|
gboolean print_image_save (FpPrint *print,
|
||||||
|
|||||||
+33
-10
@@ -152,6 +152,26 @@ on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FpPrint *
|
||||||
|
get_stored_print (FpDevice *dev, VerifyData *verify_data)
|
||||||
|
{
|
||||||
|
FpPrint *verify_print;
|
||||||
|
|
||||||
|
g_print ("Loading previously enrolled %s finger data...\n",
|
||||||
|
finger_to_string (verify_data->finger));
|
||||||
|
|
||||||
|
verify_print = print_data_load (dev, verify_data->finger);
|
||||||
|
|
||||||
|
if (!verify_print)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to load fingerprint data");
|
||||||
|
g_warning ("Did you remember to enroll your %s finger first?",
|
||||||
|
finger_to_string (verify_data->finger));
|
||||||
|
}
|
||||||
|
|
||||||
|
return verify_print;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -165,15 +185,27 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
|||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
FpPrint *verify_print = NULL;
|
FpPrint *verify_print = NULL;
|
||||||
|
g_autoptr(FpPrint) stored_print = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!prints->len)
|
if (!prints->len)
|
||||||
|
{
|
||||||
g_warning ("No prints saved on device");
|
g_warning ("No prints saved on device");
|
||||||
|
verify_quit (dev, verify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stored_print = get_stored_print (dev, verify_data);
|
||||||
|
|
||||||
for (i = 0; i < prints->len; ++i)
|
for (i = 0; i < prints->len; ++i)
|
||||||
{
|
{
|
||||||
FpPrint *print = prints->pdata[i];
|
FpPrint *print = prints->pdata[i];
|
||||||
|
|
||||||
|
if (stored_print && fp_print_equal (stored_print, print))
|
||||||
|
/* If the private print data matches, let's use the stored print
|
||||||
|
* as it contains more metadata to show */
|
||||||
|
print = stored_print;
|
||||||
|
|
||||||
if (fp_print_get_finger (print) == verify_data->finger &&
|
if (fp_print_get_finger (print) == verify_data->finger &&
|
||||||
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
|
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
|
||||||
{
|
{
|
||||||
@@ -191,8 +223,6 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
|||||||
|
|
||||||
if (!verify_print)
|
if (!verify_print)
|
||||||
{
|
{
|
||||||
g_warning ("Did you remember to enroll your %s finger first?",
|
|
||||||
finger_to_string (verify_data->finger));
|
|
||||||
verify_quit (dev, verify_data);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -239,17 +269,10 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_print ("Loading previously enrolled %s finger data...\n",
|
g_autoptr(FpPrint) verify_print = get_stored_print (dev, verify_data);
|
||||||
finger_to_string (verify_data->finger));
|
|
||||||
g_autoptr(FpPrint) verify_print = NULL;
|
|
||||||
|
|
||||||
verify_print = print_data_load (dev, verify_data->finger);
|
|
||||||
|
|
||||||
if (!verify_print)
|
if (!verify_print)
|
||||||
{
|
{
|
||||||
g_warning ("Failed to load fingerprint data");
|
|
||||||
g_warning ("Did you remember to enroll your %s finger first?",
|
|
||||||
finger_to_string (verify_data->finger));
|
|
||||||
verify_quit (dev, verify_data);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#define AES1660_FRAME_SIZE 0x244
|
#define AES1660_FRAME_SIZE 0x244
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
/* First init sequence, 0x07 cmd returns following before INIT1:
|
/* First init sequence, 0x07 cmd returns following before INIT1:
|
||||||
* { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x00 }
|
* { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x00 }
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#define AES2660_FRAME_SIZE 0x354
|
#define AES2660_FRAME_SIZE 0x354
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
/* First init sequence, 0x07 cmd returns following before INIT1:
|
/* First init sequence, 0x07 cmd returns following before INIT1:
|
||||||
* { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x00 }
|
* { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x00 }
|
||||||
*/
|
*/
|
||||||
|
|||||||
+27
-117
@@ -73,9 +73,8 @@ struct _FpiDeviceElan
|
|||||||
/* end commands */
|
/* end commands */
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
|
gboolean active;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
FpiImageDeviceState dev_state;
|
|
||||||
FpiImageDeviceState dev_state_next;
|
|
||||||
unsigned char *last_read;
|
unsigned char *last_read;
|
||||||
unsigned char calib_atts_left;
|
unsigned char calib_atts_left;
|
||||||
unsigned char calib_status;
|
unsigned char calib_status;
|
||||||
@@ -87,8 +86,6 @@ struct _FpiDeviceElan
|
|||||||
GSList *frames;
|
GSList *frames;
|
||||||
/* end state */
|
/* end state */
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
|
|
||||||
FpImageDevice);
|
|
||||||
G_DEFINE_TYPE (FpiDeviceElan, fpi_device_elan, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceElan, fpi_device_elan, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -487,7 +484,7 @@ stop_capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|||||||
|
|
||||||
|
|
||||||
/* The device is inactive at this point. */
|
/* The device is inactive at this point. */
|
||||||
self->dev_state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
self->active = FALSE;
|
||||||
|
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
{
|
{
|
||||||
@@ -505,16 +502,14 @@ stop_capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
elan_stop_capture (FpDevice *dev)
|
elan_stop_capture (FpiDeviceElan *self)
|
||||||
{
|
{
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
elan_dev_reset_state (self);
|
elan_dev_reset_state (self);
|
||||||
|
|
||||||
FpiSsm *ssm =
|
FpiSsm *ssm =
|
||||||
fpi_ssm_new (dev, stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
|
fpi_ssm_new (FP_DEVICE (self), stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, stop_capture_complete);
|
fpi_ssm_start (ssm, stop_capture_complete);
|
||||||
}
|
}
|
||||||
@@ -545,8 +540,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
self->dev_state = FPI_IMAGE_DEVICE_STATE_CAPTURE;
|
|
||||||
|
|
||||||
/* 0x55 - finger present
|
/* 0x55 - finger present
|
||||||
* 0xff - device not calibrated (probably) */
|
* 0xff - device not calibrated (probably) */
|
||||||
if (self->last_read && self->last_read[0] == 0x55)
|
if (self->last_read && self->last_read[0] == 0x55)
|
||||||
@@ -614,18 +607,21 @@ capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|||||||
fpi_image_device_session_error (dev, error);
|
fpi_image_device_session_error (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: We always stop capturing even if that may not be needed always.
|
||||||
|
* Doing this between captures appears to make it at least less likely for
|
||||||
|
* devices to end up in a bad state.
|
||||||
|
*/
|
||||||
|
elan_stop_capture (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
elan_capture (FpDevice *dev)
|
elan_capture (FpiDeviceElan *self)
|
||||||
{
|
{
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
elan_dev_reset_state (self);
|
elan_dev_reset_state (self);
|
||||||
FpiSsm *ssm =
|
FpiSsm *ssm =
|
||||||
fpi_ssm_new (dev, capture_run_state, CAPTURE_NUM_STATES);
|
fpi_ssm_new (FP_DEVICE (self), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, capture_complete);
|
fpi_ssm_start (ssm, capture_complete);
|
||||||
}
|
}
|
||||||
@@ -777,33 +773,31 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
|
|||||||
static void
|
static void
|
||||||
calibrate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
calibrate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
self->dev_state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
|
||||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
|
||||||
|
elan_stop_capture (FPI_DEVICE_ELAN (dev));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
elan_capture (dev);
|
elan_capture (FPI_DEVICE_ELAN (dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
elan_calibrate (FpDevice *dev)
|
elan_calibrate (FpiDeviceElan *self)
|
||||||
{
|
{
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
elan_dev_reset_state (self);
|
elan_dev_reset_state (self);
|
||||||
|
|
||||||
|
g_return_if_fail (!self->active);
|
||||||
|
self->active = TRUE;
|
||||||
self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS;
|
self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS;
|
||||||
|
|
||||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (self), calibrate_run_state,
|
||||||
CALIBRATE_NUM_STATES);
|
CALIBRATE_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (ssm, calibrate_complete);
|
fpi_ssm_start (ssm, calibrate_complete);
|
||||||
@@ -958,98 +952,19 @@ dev_activate (FpImageDevice *dev)
|
|||||||
elan_activate (dev);
|
elan_activate (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
elan_change_state (FpImageDevice *idev)
|
|
||||||
{
|
|
||||||
FpDevice *dev = FP_DEVICE (idev);
|
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
|
||||||
FpiImageDeviceState next_state = self->dev_state_next;
|
|
||||||
|
|
||||||
if (self->dev_state == next_state)
|
|
||||||
{
|
|
||||||
fp_dbg ("already in %d", next_state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fp_dbg ("changing to %d", next_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (next_state)
|
|
||||||
{
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
|
||||||
/* activation completed or another enroll stage started */
|
|
||||||
self->dev_state = FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
|
|
||||||
elan_calibrate (dev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
|
||||||
/* not used */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
|
||||||
elan_stop_capture (dev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
elan_change_state_async (FpDevice *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
fp_dbg ("state change dev: %p", dev);
|
|
||||||
elan_change_state (FP_IMAGE_DEVICE (dev));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
||||||
{
|
{
|
||||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||||
GSource *timeout;
|
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
/* Inactive and await finger off are equivalent for the elan driver. */
|
/* Note: We always calibrate even if that may not be needed always.
|
||||||
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
|
* Doing this for each capture appears to make it at least less likely for
|
||||||
state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
* devices to end up in a bad state.
|
||||||
|
*/
|
||||||
if (self->dev_state_next == state)
|
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
||||||
{
|
elan_calibrate (self);
|
||||||
fp_dbg ("change to state %d already queued", state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: {
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
/* schedule state change instead of calling it directly to allow all actions
|
|
||||||
* related to the previous state to complete */
|
|
||||||
self->dev_state_next = state;
|
|
||||||
timeout = fpi_device_add_timeout (FP_DEVICE (dev), 10,
|
|
||||||
elan_change_state_async,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
name = g_strdup_printf ("dev_change_state to %d", state);
|
|
||||||
g_source_set_name (timeout, name);
|
|
||||||
g_free (name);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
|
||||||
/* TODO MAYBE: split capture ssm into smaller ssms and use this state */
|
|
||||||
self->dev_state = state;
|
|
||||||
self->dev_state_next = state;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1059,19 +974,14 @@ dev_deactivate (FpImageDevice *dev)
|
|||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
if (self->dev_state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
if (!self->active)
|
||||||
{
|
|
||||||
/* The device is inactive already, complete the operation immediately. */
|
/* The device is inactive already, complete the operation immediately. */
|
||||||
fpi_image_device_deactivate_complete (dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* The device is not yet inactive, flag that we are deactivating (and
|
/* The device is not yet inactive, flag that we are deactivating (and
|
||||||
* need to signal back deactivation) and then ensure we will change
|
* need to signal back deactivation).
|
||||||
* to the inactive state eventually. */
|
* Note that any running capture will be cancelled already if needed. */
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
dev_change_state (dev, FPI_IMAGE_DEVICE_STATE_INACTIVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -70,6 +70,9 @@
|
|||||||
#define ELAN_CMD_TIMEOUT 10000
|
#define ELAN_CMD_TIMEOUT 10000
|
||||||
#define ELAN_FINGER_TIMEOUT 200
|
#define ELAN_FINGER_TIMEOUT 200
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
|
||||||
|
FpImageDevice);
|
||||||
|
|
||||||
struct elan_cmd
|
struct elan_cmd
|
||||||
{
|
{
|
||||||
unsigned char cmd[ELAN_CMD_LEN];
|
unsigned char cmd[ELAN_CMD_LEN];
|
||||||
@@ -211,6 +214,7 @@ static const FpIdEntry elan_id_table[] = {
|
|||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
||||||
|
{.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = 0, .pid = 0, .driver_data = 0},
|
{.vid = 0, .pid = 0, .driver_data = 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -218,8 +222,8 @@ static void elan_cmd_done (FpiSsm *ssm);
|
|||||||
static void elan_cmd_read (FpiSsm *ssm,
|
static void elan_cmd_read (FpiSsm *ssm,
|
||||||
FpDevice *dev);
|
FpDevice *dev);
|
||||||
|
|
||||||
static void elan_calibrate (FpDevice *dev);
|
static void elan_calibrate (FpiDeviceElan *self);
|
||||||
static void elan_capture (FpDevice *dev);
|
static void elan_capture (FpiDeviceElan *self);
|
||||||
|
|
||||||
static void dev_change_state (FpImageDevice *dev,
|
static void dev_change_state (FpImageDevice *dev,
|
||||||
FpiImageDeviceState state);
|
FpiImageDeviceState state);
|
||||||
|
|||||||
@@ -53,10 +53,12 @@ struct _FpiDeviceGoodixMoc
|
|||||||
pgxfp_sensor_cfg_t sensorcfg;
|
pgxfp_sensor_cfg_t sensorcfg;
|
||||||
gint enroll_stage;
|
gint enroll_stage;
|
||||||
gint max_enroll_stage;
|
gint max_enroll_stage;
|
||||||
|
gint max_stored_prints;
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
GPtrArray *list_result;
|
GPtrArray *list_result;
|
||||||
guint8 template_id[TEMPLATE_ID_SIZE];
|
guint8 template_id[TEMPLATE_ID_SIZE];
|
||||||
gboolean is_enroll_identify;
|
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);
|
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_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
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
|
* fp_verify_xxxx Function
|
||||||
@@ -330,7 +361,9 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self,
|
|||||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||||
return;
|
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)
|
if (resp->capture_data_resp.img_quality == 0)
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (self->task_ssm,
|
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_ssm_mark_failed (self->task_ssm,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
}
|
}
|
||||||
@@ -350,9 +384,9 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
|||||||
gxfp_cmd_response_t *resp,
|
gxfp_cmd_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
|
g_autoptr(GPtrArray) templates = NULL;
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
GPtrArray *templates = NULL;
|
|
||||||
gint cnt = 0;
|
gint cnt = 0;
|
||||||
gboolean find = false;
|
gboolean find = false;
|
||||||
|
|
||||||
@@ -365,15 +399,14 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
|||||||
{
|
{
|
||||||
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
||||||
{
|
{
|
||||||
|
templates = g_ptr_array_sized_new (1);
|
||||||
templates = g_ptr_array_new_with_free_func (g_object_unref);
|
|
||||||
fpi_device_get_verify_data (device, &print);
|
fpi_device_get_verify_data (device, &print);
|
||||||
g_ptr_array_add (templates, g_object_ref_sink (print));
|
g_ptr_array_add (templates, print);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_get_identify_data (device, &templates);
|
fpi_device_get_identify_data (device, &templates);
|
||||||
|
g_ptr_array_ref (templates);
|
||||||
}
|
}
|
||||||
for (cnt = 0; cnt < templates->len; cnt++)
|
for (cnt = 0; cnt < templates->len; cnt++)
|
||||||
{
|
{
|
||||||
@@ -416,7 +449,7 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
|||||||
fpi_device_identify_report (device, NULL, NULL, error);
|
fpi_device_identify_report (device, NULL, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_mark_completed (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +466,18 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
|||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
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:
|
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,
|
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
|
||||||
true,
|
true,
|
||||||
(const guint8 *) ¶m,
|
(const guint8 *) ¶m,
|
||||||
@@ -448,6 +492,14 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
|||||||
TEMPLATE_ID_SIZE,
|
TEMPLATE_ID_SIZE,
|
||||||
fp_verify_cb);
|
fp_verify_cb);
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -462,9 +514,9 @@ fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
if (error && error->domain == FP_DEVICE_RETRY)
|
if (error && error->domain == FP_DEVICE_RETRY)
|
||||||
{
|
{
|
||||||
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
|
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
|
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)
|
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
|
||||||
@@ -561,6 +613,13 @@ fp_enroll_enum_cb (FpiDeviceGoodixMoc *self,
|
|||||||
resp->result));
|
resp->result));
|
||||||
return;
|
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);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,7 +680,9 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
|||||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
return;
|
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]) ||
|
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
|
||||||
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
|
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
|
||||||
{
|
{
|
||||||
@@ -743,7 +804,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
|||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||||
return;
|
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)
|
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP);
|
||||||
@@ -756,6 +817,9 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
|||||||
"Switch finger mode failed"));
|
"Switch finger mode failed"));
|
||||||
return;
|
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)
|
if (self->enroll_stage < self->max_enroll_stage)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
@@ -794,6 +858,16 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case FP_ENROLL_IDENTIFY:
|
||||||
{
|
{
|
||||||
dummy[0] = 0x01;
|
dummy[0] = 0x01;
|
||||||
@@ -818,6 +892,9 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_ENROLL_CAPTURE:
|
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,
|
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
|
||||||
true,
|
true,
|
||||||
(const guint8 *) &dummy,
|
(const guint8 *) &dummy,
|
||||||
@@ -905,9 +982,17 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
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
|
static void
|
||||||
@@ -976,7 +1061,7 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
|
|||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self->max_stored_prints = resp->finger_config.max_stored_prints;
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1260,6 +1345,9 @@ gx_fp_init (FpDevice *device)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
self->max_stored_prints = FP_MAX_FINGERNUM;
|
||||||
|
self->is_power_button_shield_on = false;
|
||||||
|
|
||||||
self->cancellable = g_cancellable_new ();
|
self->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
self->sensorcfg = g_new0 (gxfp_sensor_cfg_t, 1);
|
self->sensorcfg = g_new0 (gxfp_sensor_cfg_t, 1);
|
||||||
@@ -1294,20 +1382,59 @@ gx_fp_init (FpDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gx_fp_exit (FpDevice *device)
|
gx_fp_release_interface (FpiDeviceGoodixMoc *self,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
g_autoptr(GError) release_error = NULL;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_clear_object (&self->cancellable);
|
g_clear_object (&self->cancellable);
|
||||||
g_clear_pointer (&self->sensorcfg, g_free);
|
g_clear_pointer (&self->sensorcfg, g_free);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)),
|
||||||
0, 0, &error);
|
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 */
|
/* Notify close complete */
|
||||||
fpi_device_close_complete (FP_DEVICE (self), error);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1409,7 +1536,6 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
|||||||
static void
|
static void
|
||||||
gx_fp_cancel (FpDevice *device)
|
gx_fp_cancel (FpDevice *device)
|
||||||
{
|
{
|
||||||
|
|
||||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||||
|
|
||||||
/* Cancel any current interrupt transfer (resulting us to go into
|
/* Cancel any current interrupt transfer (resulting us to go into
|
||||||
@@ -1425,6 +1551,9 @@ static const FpIdEntry id_table[] = {
|
|||||||
{ .vid = 0x27c6, .pid = 0x5840, },
|
{ .vid = 0x27c6, .pid = 0x5840, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6496, },
|
{ .vid = 0x27c6, .pid = 0x6496, },
|
||||||
{ .vid = 0x27c6, .pid = 0x60A2, },
|
{ .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 */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1450,4 +1579,7 @@ fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass)
|
|||||||
dev_class->cancel = gx_fp_cancel;
|
dev_class->cancel = gx_fp_cancel;
|
||||||
dev_class->verify = gx_fp_verify_identify;
|
dev_class->verify = gx_fp_verify_identify;
|
||||||
dev_class->identify = gx_fp_verify_identify;
|
dev_class->identify = gx_fp_verify_identify;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
|
dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FP_ENROLL_ENUM = 0,
|
FP_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||||
|
FP_ENROLL_ENUM,
|
||||||
FP_ENROLL_IDENTIFY,
|
FP_ENROLL_IDENTIFY,
|
||||||
FP_ENROLL_CREATE,
|
FP_ENROLL_CREATE,
|
||||||
FP_ENROLL_CAPTURE,
|
FP_ENROLL_CAPTURE,
|
||||||
@@ -48,11 +49,14 @@ typedef enum {
|
|||||||
FP_ENROLL_WAIT_FINGER_UP,
|
FP_ENROLL_WAIT_FINGER_UP,
|
||||||
FP_ENROLL_CHECK_DUPLICATE,
|
FP_ENROLL_CHECK_DUPLICATE,
|
||||||
FP_ENROLL_COMMIT,
|
FP_ENROLL_COMMIT,
|
||||||
|
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||||
FP_ENROLL_NUM_STATES,
|
FP_ENROLL_NUM_STATES,
|
||||||
} FpEnrollState;
|
} FpEnrollState;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FP_VERIFY_CAPTURE = 0,
|
FP_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||||
|
FP_VERIFY_CAPTURE,
|
||||||
FP_VERIFY_IDENTIFY,
|
FP_VERIFY_IDENTIFY,
|
||||||
|
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||||
FP_VERIFY_NUM_STATES,
|
FP_VERIFY_NUM_STATES,
|
||||||
} FpVerifyState;
|
} FpVerifyState;
|
||||||
|
|||||||
@@ -141,8 +141,11 @@ crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
|
|||||||
static void
|
static void
|
||||||
crc32_final (gf_crc32_context *ctx, uint8_t *md)
|
crc32_final (gf_crc32_context *ctx, uint8_t *md)
|
||||||
{
|
{
|
||||||
|
uint32_t crc = 0;
|
||||||
|
|
||||||
ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
|
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
|
uint8_t
|
||||||
@@ -184,7 +187,7 @@ init_pack_header (
|
|||||||
pheader->cmd1 = LOBYTE (cmd);
|
pheader->cmd1 = LOBYTE (cmd);
|
||||||
pheader->packagenum = packagenum;
|
pheader->packagenum = packagenum;
|
||||||
pheader->reserved = dump_seq++;
|
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->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
|
||||||
pheader->rev_crc8 = ~pheader->crc8;
|
pheader->rev_crc8 = ~pheader->crc8;
|
||||||
}
|
}
|
||||||
@@ -224,14 +227,14 @@ gx_proto_parse_header (
|
|||||||
{
|
{
|
||||||
if (!buffer || !pheader)
|
if (!buffer || !pheader)
|
||||||
return -1;
|
return -1;
|
||||||
if (buffer_len < PACKAGE_HEADER_SIZE)
|
if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy (pheader, buffer, sizeof (pack_header));
|
memcpy (pheader, buffer, sizeof (pack_header));
|
||||||
|
pheader->len = GUINT16_FROM_LE (pheader->len);
|
||||||
pheader->len = GUINT16_FROM_LE (*(buffer + 4));
|
if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
|
||||||
|
return -1;
|
||||||
pheader->len -= PACKAGE_CRC_SIZE;
|
pheader->len -= PACKAGE_CRC_SIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +251,7 @@ gx_proto_parse_fingerid (
|
|||||||
if (!template || !fid_buffer)
|
if (!template || !fid_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (fid_buffer_size < 70)
|
if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buffer = fid_buffer;
|
buffer = fid_buffer;
|
||||||
@@ -256,28 +259,30 @@ gx_proto_parse_fingerid (
|
|||||||
|
|
||||||
if (buffer[Offset++] != 67)
|
if (buffer[Offset++] != 67)
|
||||||
return -1;
|
return -1;
|
||||||
|
fid_buffer_size--;
|
||||||
|
|
||||||
template->type = buffer[Offset++];
|
template->type = buffer[Offset++];
|
||||||
|
fid_buffer_size--;
|
||||||
template->finger_index = buffer[Offset++];
|
template->finger_index = buffer[Offset++];
|
||||||
|
fid_buffer_size--;
|
||||||
Offset++;
|
Offset++;
|
||||||
|
memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
|
||||||
memcpy (template->accountid, &buffer[Offset], 32);
|
Offset += sizeof (template->accountid);
|
||||||
Offset += 32;
|
memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
|
||||||
|
Offset += sizeof (template->tid); // Offset == 68
|
||||||
memcpy (template->tid, &buffer[Offset], 32);
|
|
||||||
Offset += 32; // Offset == 68
|
|
||||||
|
|
||||||
template->payload.size = buffer[Offset++];
|
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);
|
memcpy (template->payload.data, &buffer[Offset], template->payload.size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
uint8_t *fingerlist = NULL;
|
||||||
|
|
||||||
if (!buffer || !presp)
|
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:
|
case RESPONSE_PACKAGE_CMD:
|
||||||
{
|
{
|
||||||
|
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
|
||||||
|
return -1;
|
||||||
presp->parse_msg.ack_cmd = buffer[1];
|
presp->parse_msg.ack_cmd = buffer[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_UPDATE_CONFIG:
|
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_COMMITENROLLMENT:
|
||||||
case MOC_CMD0_DELETETEMPLATE:
|
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;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_GET_VERSION:
|
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));
|
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_CAPTURE_DATA:
|
case MOC_CMD0_CAPTURE_DATA:
|
||||||
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
|
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_quality = buffer[1];
|
||||||
presp->capture_data_resp.img_coverage = buffer[2];
|
presp->capture_data_resp.img_coverage = buffer[2];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_ENROLL_INIT:
|
case MOC_CMD0_ENROLL_INIT:
|
||||||
|
if (buffer_len < sizeof (gxfp_enroll_init_t) + 1)
|
||||||
|
return -1;
|
||||||
if (presp->result == GX_SUCCESS)
|
if (presp->result == GX_SUCCESS)
|
||||||
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
|
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_ENROLL:
|
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.rollback = (buffer[0] < 0x80) ? false : true;
|
||||||
presp->enroll_update.img_overlay = buffer[1];
|
presp->enroll_update.img_overlay = buffer[1];
|
||||||
presp->enroll_update.img_preoverlay = buffer[2];
|
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;
|
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
|
||||||
if (presp->check_duplicate_resp.duplicate)
|
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);
|
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case MOC_CMD0_GETFINGERLIST:
|
||||||
if (presp->result != GX_SUCCESS)
|
if (presp->result != GX_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
if (buffer_len < 2)
|
||||||
|
return -1;
|
||||||
presp->finger_list_resp.finger_num = buffer[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;
|
fingerlist = buffer + 2;
|
||||||
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
|
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;
|
offset += 2;
|
||||||
|
if (buffer_len < fingerid_length + offset + 2)
|
||||||
|
return -1;
|
||||||
if (gx_proto_parse_fingerid (fingerlist + offset,
|
if (gx_proto_parse_fingerid (fingerlist + offset,
|
||||||
fingerid_length,
|
fingerid_length,
|
||||||
&presp->finger_list_resp.finger_list[num]) != 0)
|
&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;
|
presp->verify.match = (buffer[0] == 0) ? true : false;
|
||||||
if (presp->verify.match)
|
if (presp->verify.match)
|
||||||
{
|
{
|
||||||
|
if (buffer_len < sizeof (template_format_t) + 10)
|
||||||
|
return -1;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset));
|
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||||
offset += 2;
|
offset += 2;
|
||||||
score = GUINT32_FROM_LE (*(buffer + offset));
|
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
|
||||||
offset += 4;
|
offset += 4;
|
||||||
study = GUINT16_FROM_LE (*(buffer + offset));
|
study = buffer[offset];
|
||||||
offset += 1;
|
offset += 1;
|
||||||
fingerid_size = GUINT16_FROM_LE (*(buffer + offset));
|
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
|
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));
|
memset (pconfig, 0, sizeof (*pconfig));
|
||||||
|
|
||||||
//NOTICE: Do not change any value!
|
//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;
|
pconfig->reserved[0] = 1;
|
||||||
|
|
||||||
gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);
|
gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#define PACKAGE_CRC_SIZE (4)
|
#define PACKAGE_CRC_SIZE (4)
|
||||||
#define PACKAGE_HEADER_SIZE (8)
|
#define PACKAGE_HEADER_SIZE (8)
|
||||||
|
|
||||||
#define FP_MAX_FINGERNUM (10)
|
#define FP_MAX_FINGERNUM (20)
|
||||||
|
|
||||||
#define TEMPLATE_ID_SIZE (32)
|
#define TEMPLATE_ID_SIZE (32)
|
||||||
|
|
||||||
@@ -75,6 +75,11 @@
|
|||||||
#define MOC_CMD1_GET_FINGER_MODE 0x00
|
#define MOC_CMD1_GET_FINGER_MODE 0x00
|
||||||
#define MOC_CMD1_SET_FINGER_DOWN 0x01
|
#define MOC_CMD1_SET_FINGER_DOWN 0x01
|
||||||
#define MOC_CMD1_SET_FINGER_UP 0x02
|
#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
|
typedef struct _gxfp_version_info
|
||||||
@@ -89,7 +94,7 @@ typedef struct _gxfp_version_info
|
|||||||
uint8_t interface[GX_VERSION_LEN];
|
uint8_t interface[GX_VERSION_LEN];
|
||||||
uint8_t protocol[GX_VERSION_LEN];
|
uint8_t protocol[GX_VERSION_LEN];
|
||||||
uint8_t flashVersion[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;
|
} gxfp_version_info_t, *pgxfp_version_info_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -167,6 +172,16 @@ typedef struct _fp_finger_status
|
|||||||
uint8_t status;
|
uint8_t status;
|
||||||
} fp_finger_status_t, *pfp_finger_status_t;
|
} 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
|
typedef struct _fp_cmd_response
|
||||||
{
|
{
|
||||||
@@ -183,6 +198,8 @@ typedef struct _fp_cmd_response
|
|||||||
gxfp_enum_fingerlist_t finger_list_resp;
|
gxfp_enum_fingerlist_t finger_list_resp;
|
||||||
gxfp_version_info_t version_info;
|
gxfp_version_info_t version_info;
|
||||||
fp_finger_status_t finger_status;
|
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;
|
} 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,
|
int gx_proto_parse_body (uint16_t cmd,
|
||||||
uint8_t *buffer,
|
uint8_t *buffer,
|
||||||
uint32_t buffer_len,
|
uint16_t buffer_len,
|
||||||
pgxfp_cmd_response_t presponse);
|
pgxfp_cmd_response_t presponse);
|
||||||
|
|
||||||
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
||||||
|
|||||||
@@ -0,0 +1,445 @@
|
|||||||
|
/*
|
||||||
|
* Next Biometrics driver for libfprint
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Huan Wang <fredwanghuan@gmail.com>
|
||||||
|
* Copyright (C) 2011-2012 Andrej Krutak <dev@andree.sk>
|
||||||
|
*
|
||||||
|
* 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 "nb1010"
|
||||||
|
#include "fpi-log.h"
|
||||||
|
|
||||||
|
#include "drivers_api.h"
|
||||||
|
|
||||||
|
#define FRAME_HEIGHT 180
|
||||||
|
#define FRAME_WIDTH 256
|
||||||
|
|
||||||
|
#define NB1010_EP_OUT 0x02 | FPI_USB_ENDPOINT_OUT
|
||||||
|
#define NB1010_EP_IN 0x03 | FPI_USB_ENDPOINT_IN
|
||||||
|
|
||||||
|
#define NB1010_SENSITIVITY_BIT 12
|
||||||
|
|
||||||
|
#define NB1010_CMD_RECV_LEN 16
|
||||||
|
#define NB1010_CAPTURE_RECV_LEN 540
|
||||||
|
#define NB1010_CAPTURE_HEADER_LEN 25
|
||||||
|
|
||||||
|
#define NB1010_LINE_PER_PARTIAL 2
|
||||||
|
#define NB1010_N_PARTIAL (FRAME_HEIGHT / NB1010_LINE_PER_PARTIAL)
|
||||||
|
|
||||||
|
#define NB1010_DEFAULT_TIMEOUT 500
|
||||||
|
#define NB1010_TRANSITION_DELAY 50
|
||||||
|
|
||||||
|
/* Loop ssm states */
|
||||||
|
enum {
|
||||||
|
M_WAIT_PRINT,
|
||||||
|
M_REQUEST_PRINT,
|
||||||
|
M_CHECK_PRINT,
|
||||||
|
M_READ_PRINT_PRESTART,
|
||||||
|
M_READ_PRINT_START,
|
||||||
|
M_READ_PRINT_POLL,
|
||||||
|
M_SUBMIT_PRINT,
|
||||||
|
|
||||||
|
/* Number of states */
|
||||||
|
M_LOOP_NUM_STATES,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Follow Commands are obtained by decoding the usbcap, so it does not expose all the command available to the device.
|
||||||
|
* Known:
|
||||||
|
* 1. every command starts with 0x80
|
||||||
|
* 2. second byte is the comand, third byte is the seqence nubmer, init with rand, gets incremented
|
||||||
|
* everytime a new instruction is sent to the device. However device does not care or check the sequence, just echo back
|
||||||
|
* whatever chosen by the host.
|
||||||
|
* 3. cmd: 0x07 check, expect [0x80, 0x29...] as response
|
||||||
|
* 4. cmd: 0x16 ???, expect [0x80, 0x20...] as response. Happens during device init.
|
||||||
|
* 5. cmd: 0x13 print device, expect [0x80, 0x23...] as response. Response contains the device string
|
||||||
|
* 6. cmd: 0x38 check finger, expect [0x80, 0x37...] as response. The 14th byte indicate whether finger present [0-255]
|
||||||
|
* 7. cmd: 0x0d ???, expect [0x80, 0x20...] as response. Happens before capture.
|
||||||
|
* 8. cmd: 0x12 capture, expect [0x80, 0x20...] as response. After capture read 90 times in sequence to get all the frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static guint8 nb1010_cmd_check_finger[] = {
|
||||||
|
0x80, 0x38, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* pre capture, dont know what does it do, but appears everytime a capture begins */
|
||||||
|
static guint8 nb1010_cmd_precapture[] = {
|
||||||
|
0x80, 0x0d, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint8 nb1010_cmd_capture[] = {
|
||||||
|
0x80, 0x12, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _FpiDeviceNb1010
|
||||||
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
FpiSsm *ssm;
|
||||||
|
guint8 *scanline_buf;
|
||||||
|
gboolean deactivating;
|
||||||
|
int partial_received;
|
||||||
|
};
|
||||||
|
G_DECLARE_FINAL_TYPE (FpiDeviceNb1010, fpi_device_nb1010, FPI, DEVICE_NB1010, FpImageDevice);
|
||||||
|
G_DEFINE_TYPE (FpiDeviceNb1010, fpi_device_nb1010, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_init (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
|
self->scanline_buf = g_malloc0 (FRAME_WIDTH * FRAME_HEIGHT);
|
||||||
|
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
|
fp_dbg ("nb1010 Initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_deinit (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->scanline_buf, g_free);
|
||||||
|
|
||||||
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
fpi_image_device_close_complete (dev, error);
|
||||||
|
fp_dbg ("nb1010 Deinitialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_activate (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
|
||||||
|
self->deactivating = FALSE;
|
||||||
|
|
||||||
|
fpi_image_device_activate_complete (dev, NULL);
|
||||||
|
fp_dbg ("nb1010 Activated");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_deactivated (FpImageDevice *dev, GError * err)
|
||||||
|
{
|
||||||
|
fpi_image_device_deactivate_complete (dev, err);
|
||||||
|
fp_dbg ("nb1010 Deactivated");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_deactivate (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
|
||||||
|
self->deactivating = TRUE;
|
||||||
|
if (self->ssm == NULL)
|
||||||
|
nb1010_dev_deactivated (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_request_fingerprint (FpiDeviceNb1010 *dev)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = NULL;
|
||||||
|
|
||||||
|
transfer = fpi_usb_transfer_new (FP_DEVICE ( dev));
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
transfer->ssm = dev->ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, NB1010_EP_OUT,
|
||||||
|
nb1010_cmd_check_finger, G_N_ELEMENTS (nb1010_cmd_check_finger),
|
||||||
|
NULL);
|
||||||
|
fpi_usb_transfer_submit (transfer, NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
fpi_ssm_usb_transfer_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_check_fingerprint_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
|
gpointer unused_data, GError *error)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transfer->buffer[NB1010_SENSITIVITY_BIT] > 0x30)
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
else
|
||||||
|
fpi_ssm_jump_to_state (transfer->ssm, M_WAIT_PRINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_cmd_check_fingerprint (FpiDeviceNb1010 *dev)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = NULL;
|
||||||
|
|
||||||
|
transfer = fpi_usb_transfer_new (FP_DEVICE ( dev));
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
transfer->ssm = dev->ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (transfer, NB1010_EP_IN, NB1010_CMD_RECV_LEN);
|
||||||
|
fpi_usb_transfer_submit (transfer, NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
nb1010_check_fingerprint_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_read_ignore_data_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
|
gpointer unused_data, GError *error)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
FpiUsbTransfer *new_transfer = NULL;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_transfer = fpi_usb_transfer_new ( dev );
|
||||||
|
new_transfer->short_is_error = TRUE;
|
||||||
|
new_transfer->ssm = transfer->ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (new_transfer, NB1010_EP_IN, NB1010_CMD_RECV_LEN);
|
||||||
|
fpi_usb_transfer_submit (new_transfer, NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
fpi_ssm_usb_transfer_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_write_ignore_read (FpiDeviceNb1010 *dev, guint8 *buf, gsize len)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = NULL;
|
||||||
|
|
||||||
|
transfer = fpi_usb_transfer_new (FP_DEVICE ( dev));
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
transfer->ssm = dev->ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, NB1010_EP_OUT, buf, len, NULL);
|
||||||
|
fpi_usb_transfer_submit (transfer, NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
nb1010_read_ignore_data_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_read_capture_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
|
gpointer unused_data, GError *error)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (transfer->actual_length == NB1010_CAPTURE_RECV_LEN);
|
||||||
|
|
||||||
|
size_t offset = self->partial_received * NB1010_LINE_PER_PARTIAL * FRAME_WIDTH;
|
||||||
|
|
||||||
|
memcpy (self->scanline_buf + offset,
|
||||||
|
transfer->buffer + NB1010_CAPTURE_HEADER_LEN, NB1010_LINE_PER_PARTIAL * FRAME_WIDTH);
|
||||||
|
|
||||||
|
self->partial_received++;
|
||||||
|
if (self->partial_received == NB1010_N_PARTIAL)
|
||||||
|
{
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer), NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
nb1010_read_capture_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_read_capture (FpiDeviceNb1010 *dev)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = NULL;
|
||||||
|
|
||||||
|
transfer = fpi_usb_transfer_new ( FP_DEVICE ( dev));
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
transfer->ssm = dev->ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (transfer, NB1010_EP_IN, NB1010_CAPTURE_RECV_LEN);
|
||||||
|
fpi_usb_transfer_submit (transfer, NB1010_DEFAULT_TIMEOUT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
nb1010_read_capture_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
submit_image (FpiSsm *ssm,
|
||||||
|
FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
FpImage *img;
|
||||||
|
|
||||||
|
img = fp_image_new (FRAME_WIDTH, FRAME_HEIGHT);
|
||||||
|
if (img == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy (img->data, self->scanline_buf, FRAME_WIDTH * FRAME_HEIGHT);
|
||||||
|
fpi_image_device_image_captured (dev, img);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
m_loop_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
||||||
|
{
|
||||||
|
fp_dbg ("nb1010 ssm complete cb");
|
||||||
|
|
||||||
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (_dev);
|
||||||
|
|
||||||
|
self->ssm = NULL;
|
||||||
|
|
||||||
|
if (self->deactivating)
|
||||||
|
nb1010_dev_deactivated (dev, error);
|
||||||
|
else if (error != NULL)
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
{
|
||||||
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (_dev);
|
||||||
|
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
fp_dbg ("deactivating, marking completed");
|
||||||
|
fpi_ssm_mark_completed (ssm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
|
case M_WAIT_PRINT:
|
||||||
|
/* Wait fingerprint scanning */
|
||||||
|
fpi_ssm_next_state_delayed (ssm, NB1010_TRANSITION_DELAY, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_REQUEST_PRINT:
|
||||||
|
nb1010_request_fingerprint (self);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_CHECK_PRINT:
|
||||||
|
nb1010_cmd_check_fingerprint (self);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_READ_PRINT_PRESTART:
|
||||||
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
|
nb1010_write_ignore_read (self, nb1010_cmd_precapture, G_N_ELEMENTS (nb1010_cmd_precapture));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_READ_PRINT_START:
|
||||||
|
self->partial_received = 0;
|
||||||
|
nb1010_write_ignore_read (self, nb1010_cmd_capture, G_N_ELEMENTS (nb1010_cmd_capture));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_READ_PRINT_POLL:
|
||||||
|
nb1010_read_capture (self);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_SUBMIT_PRINT:
|
||||||
|
if (submit_image (ssm, dev))
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_completed (ssm);
|
||||||
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_jump_to_state (ssm, M_WAIT_PRINT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nb1010_dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
||||||
|
{
|
||||||
|
FpiDeviceNb1010 *self = FPI_DEVICE_NB1010 (dev);
|
||||||
|
FpiSsm *ssm_loop;
|
||||||
|
|
||||||
|
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
||||||
|
{
|
||||||
|
ssm_loop = fpi_ssm_new (FP_DEVICE (dev), m_loop_state, M_LOOP_NUM_STATES);
|
||||||
|
self->ssm = ssm_loop;
|
||||||
|
fpi_ssm_start (ssm_loop, m_loop_complete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const FpIdEntry id_table[] = {
|
||||||
|
{ .vid = 0x298d, .pid = 0x1010, },
|
||||||
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_nb1010_init (FpiDeviceNb1010 *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_nb1010_class_init (FpiDeviceNb1010Class *klass)
|
||||||
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
|
dev_class->id = FP_COMPONENT;
|
||||||
|
dev_class->full_name = "NextBiometrics NB-1010-U";
|
||||||
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
|
dev_class->id_table = id_table;
|
||||||
|
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||||
|
|
||||||
|
img_class->img_height = FRAME_HEIGHT;
|
||||||
|
img_class->img_width = FRAME_WIDTH;
|
||||||
|
|
||||||
|
img_class->bz3_threshold = 24;
|
||||||
|
|
||||||
|
img_class->img_open = nb1010_dev_init;
|
||||||
|
img_class->img_close = nb1010_dev_deinit;
|
||||||
|
img_class->activate = nb1010_dev_activate;
|
||||||
|
img_class->deactivate = nb1010_dev_deactivate;
|
||||||
|
img_class->change_state = nb1010_dev_change_state;
|
||||||
|
}
|
||||||
@@ -27,13 +27,18 @@
|
|||||||
|
|
||||||
G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
|
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[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00BD, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xE9, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00E9, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xDF, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00DF, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xF9, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F9, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xFC, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FC, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xC2, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C2, },
|
||||||
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C9, },
|
||||||
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0100, },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,10 +87,17 @@ cmd_receive_cb (FpiUsbTransfer *transfer,
|
|||||||
if (msg_resp.payload[0] == 0x01)
|
if (msg_resp.payload[0] == 0x01)
|
||||||
{
|
{
|
||||||
self->finger_on_sensor = TRUE;
|
self->finger_on_sensor = TRUE;
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_PRESENT,
|
||||||
|
FP_FINGER_STATUS_NONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->finger_on_sensor = FALSE;
|
self->finger_on_sensor = FALSE;
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_NONE,
|
||||||
|
FP_FINGER_STATUS_PRESENT);
|
||||||
|
|
||||||
if (self->cmd_complete_on_removal)
|
if (self->cmd_complete_on_removal)
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_completed (transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
@@ -112,7 +124,7 @@ cmd_receive_cb (FpiUsbTransfer *transfer,
|
|||||||
{
|
{
|
||||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK)
|
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,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
g_error_new_literal (G_IO_ERROR,
|
g_error_new_literal (G_IO_ERROR,
|
||||||
G_IO_ERROR_CANCELLED,
|
G_IO_ERROR_CANCELLED,
|
||||||
@@ -197,12 +209,19 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
|
|||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_clear_pointer (&error, g_error_free);
|
|
||||||
|
|
||||||
if (transfer->buffer[0] & USB_ASYNC_MESSAGE_PENDING || error)
|
if (transfer->buffer[0] & USB_ASYNC_MESSAGE_PENDING)
|
||||||
|
{
|
||||||
fpi_ssm_next_state (transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fpi_usb_transfer_submit (transfer, 1000, NULL, cmd_interrupt_cb, NULL);
|
{
|
||||||
|
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
cmd_interrupt_cb,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -329,7 +348,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
|||||||
* may only be a cancellation currently). */
|
* may only be a cancellation currently). */
|
||||||
if (seq_num <= 0)
|
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;
|
real_seq_num = self->last_seq_num;
|
||||||
if (seq_num == 0)
|
if (seq_num == 0)
|
||||||
self->cmd_seq_num = self->last_seq_num;
|
self->cmd_seq_num = self->last_seq_num;
|
||||||
@@ -435,6 +454,37 @@ parse_print_data (GVariant *data,
|
|||||||
return TRUE;
|
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
|
static void
|
||||||
list_msg_cb (FpiDeviceSynaptics *self,
|
list_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
@@ -487,10 +537,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
|
|
||||||
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||||
{
|
{
|
||||||
GVariant *data = NULL;
|
|
||||||
GVariant *uid = NULL;
|
|
||||||
FpPrint *print;
|
FpPrint *print;
|
||||||
gchar *userid;
|
|
||||||
|
|
||||||
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -503,23 +550,9 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
get_enroll_templates_resp->templates[n].user_id,
|
get_enroll_templates_resp->templates[n].user_id,
|
||||||
get_enroll_templates_resp->templates[n].finger_id);
|
get_enroll_templates_resp->templates[n].finger_id);
|
||||||
|
|
||||||
userid = (gchar *) get_enroll_templates_resp->templates[n].user_id;
|
print = create_print (self,
|
||||||
|
|
||||||
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,
|
||||||
get_enroll_templates_resp->templates[n].user_id_len,
|
get_enroll_templates_resp->templates[n].finger_id);
|
||||||
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);
|
|
||||||
|
|
||||||
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
|
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
|
||||||
}
|
}
|
||||||
@@ -589,6 +622,9 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
switch (resp->response_id)
|
switch (resp->response_id)
|
||||||
{
|
{
|
||||||
case BMKT_RSP_VERIFY_READY:
|
case BMKT_RSP_VERIFY_READY:
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_NEEDED,
|
||||||
|
FP_FINGER_STATUS_NONE);
|
||||||
fp_info ("Place Finger on the Sensor!");
|
fp_info ("Place Finger on the Sensor!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -630,7 +666,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
||||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
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_report (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
||||||
fpi_device_verify_complete (device, NULL);
|
verify_complete_after_finger_removal (self);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,6 +742,12 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
fp_info ("Place Finger on the Sensor!");
|
fp_info ("Place Finger on the Sensor!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BMKT_RSP_SEND_NEXT_USER_ID:
|
||||||
|
{
|
||||||
|
compose_and_send_identify_msg (device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ID_FAIL:
|
case BMKT_RSP_ID_FAIL:
|
||||||
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
||||||
{
|
{
|
||||||
@@ -741,45 +783,47 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
GPtrArray *prints = NULL;
|
GPtrArray *prints = NULL;
|
||||||
g_autoptr(GVariant) data = NULL;
|
g_autoptr(GVariant) data = NULL;
|
||||||
guint8 finger;
|
gboolean found = FALSE;
|
||||||
const guint8 *user_id;
|
guint index;
|
||||||
gsize user_id_len = 0;
|
|
||||||
gint cnt = 0;
|
print = create_print (self,
|
||||||
gboolean find = FALSE;
|
resp->response.id_resp.user_id,
|
||||||
|
resp->response.id_resp.finger_id);
|
||||||
|
|
||||||
fpi_device_get_identify_data (device, &prints);
|
fpi_device_get_identify_data (device, &prints);
|
||||||
|
|
||||||
for (cnt = 0; cnt < prints->len; cnt++)
|
found = g_ptr_array_find_with_equal_func (prints,
|
||||||
{
|
print,
|
||||||
print = g_ptr_array_index (prints, cnt);
|
(GEqualFunc) fp_print_equal,
|
||||||
g_object_get (print, "fpi-data", &data, NULL);
|
&index);
|
||||||
g_debug ("data is %p", data);
|
|
||||||
parse_print_data (data, &finger, &user_id, &user_id_len);
|
if (found)
|
||||||
if (user_id)
|
fpi_device_identify_report (device, g_ptr_array_index (prints, index), print, NULL);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
fpi_device_identify_report (device, NULL, print, NULL);
|
||||||
fpi_device_identify_report (device, NULL, NULL, NULL);
|
|
||||||
identify_complete_after_finger_removal (self);
|
identify_complete_after_finger_removal (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
identify (FpDevice *device)
|
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);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
@@ -789,13 +833,26 @@ identify (FpDevice *device)
|
|||||||
guint8 finger;
|
guint8 finger;
|
||||||
const guint8 *user_id;
|
const guint8 *user_id;
|
||||||
gsize user_id_len = 0;
|
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);
|
fpi_device_get_identify_data (device, &prints);
|
||||||
|
if (prints->len > UINT8_MAX)
|
||||||
for (cnt = 0; cnt < prints->len; cnt++)
|
|
||||||
{
|
{
|
||||||
print = g_ptr_array_index (prints, cnt);
|
fpi_device_identify_complete (device,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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_object_get (print, "fpi-data", &data, NULL);
|
||||||
g_debug ("data is %p", data);
|
g_debug ("data is %p", data);
|
||||||
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
||||||
@@ -804,13 +861,49 @@ identify (FpDevice *device)
|
|||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
return;
|
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;
|
||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_ID_USER, NULL, 0, identify_msg_cb);
|
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
|
static void
|
||||||
enroll_msg_cb (FpiDeviceSynaptics *self,
|
enroll_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
@@ -832,6 +925,9 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
case BMKT_RSP_ENROLL_READY:
|
case BMKT_RSP_ENROLL_READY:
|
||||||
{
|
{
|
||||||
self->enroll_stage = 0;
|
self->enroll_stage = 0;
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_NEEDED,
|
||||||
|
FP_FINGER_STATUS_NONE);
|
||||||
fp_info ("Place Finger on the Sensor!");
|
fp_info ("Place Finger on the Sensor!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1037,6 +1133,45 @@ delete_print (FpDevice *device)
|
|||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_DEL_USER_FP, payload, user_id_len + 1, delete_msg_cb);
|
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);
|
||||||
|
|
||||||
|
/* BMKT_OPERATION_DENIED is returned if the sensor is already initialized */
|
||||||
|
if (resp->result == BMKT_SUCCESS || resp->result == BMKT_OPERATION_DENIED)
|
||||||
|
{
|
||||||
|
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
|
static void
|
||||||
dev_probe (FpDevice *device)
|
dev_probe (FpDevice *device)
|
||||||
{
|
{
|
||||||
@@ -1062,9 +1197,6 @@ dev_probe (FpDevice *device)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_usb_device_reset (usb_dev, &error))
|
|
||||||
goto err_close;
|
|
||||||
|
|
||||||
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
||||||
goto err_close;
|
goto err_close;
|
||||||
|
|
||||||
@@ -1137,40 +1269,7 @@ dev_probe (FpDevice *device)
|
|||||||
fp_dbg ("Target: %d", self->mis_version.target);
|
fp_dbg ("Target: %d", self->mis_version.target);
|
||||||
fp_dbg ("Product: %d", self->mis_version.product);
|
fp_dbg ("Product: %d", self->mis_version.product);
|
||||||
|
|
||||||
|
synaptics_sensor_cmd (self, 0, BMKT_CMD_FPS_INIT, NULL, 0, prob_msg_cb);
|
||||||
/* 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);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1241,9 +1340,6 @@ dev_init (FpDevice *device)
|
|||||||
|
|
||||||
self->interrupt_cancellable = g_cancellable_new ();
|
self->interrupt_cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1309,4 +1405,6 @@ fpi_device_synaptics_class_init (FpiDeviceSynapticsClass *klass)
|
|||||||
dev_class->delete = delete_print;
|
dev_class->delete = delete_print;
|
||||||
dev_class->cancel = cancel;
|
dev_class->cancel = cancel;
|
||||||
dev_class->list = list;
|
dev_class->list = list;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ struct _FpiDeviceSynaptics
|
|||||||
FpiSsm *cmd_ssm;
|
FpiSsm *cmd_ssm;
|
||||||
FpiUsbTransfer *cmd_pending_transfer;
|
FpiUsbTransfer *cmd_pending_transfer;
|
||||||
gboolean cmd_complete_on_removal;
|
gboolean cmd_complete_on_removal;
|
||||||
|
guint8 id_idx;
|
||||||
|
|
||||||
bmkt_sensor_version_t mis_version;
|
bmkt_sensor_version_t mis_version;
|
||||||
|
|
||||||
|
|||||||
@@ -693,8 +693,6 @@ sm_read_reg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
fp_dbg ("read reg result = %02x", self->read_reg_result);
|
fp_dbg ("read reg result = %02x", self->read_reg_result);
|
||||||
fpi_ssm_next_state (transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (transfer->buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -731,7 +729,6 @@ sm_await_intr_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
g_free (transfer->buffer);
|
|
||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -739,7 +736,6 @@ sm_await_intr_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|||||||
fp_dbg ("interrupt received: %02x %02x %02x %02x",
|
fp_dbg ("interrupt received: %02x %02x %02x %02x",
|
||||||
transfer->buffer[0], transfer->buffer[1],
|
transfer->buffer[0], transfer->buffer[1],
|
||||||
transfer->buffer[2], transfer->buffer[3]);
|
transfer->buffer[2], transfer->buffer[3]);
|
||||||
g_free (transfer->buffer);
|
|
||||||
|
|
||||||
self->finger_state = FINGER_DETECTED;
|
self->finger_state = FINGER_DETECTED;
|
||||||
fpi_image_device_report_finger_status (dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define UPEKTC_CMD_LEN 0x40
|
#define UPEKTC_CMD_LEN 0x40
|
||||||
|
|||||||
@@ -527,15 +527,6 @@ initsm_read_msg_response_cb (FpiSsm *ssm,
|
|||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Unexpected response subcommand"));
|
"Unexpected response subcommand"));
|
||||||
}
|
}
|
||||||
else if (seq != upekdev->seq)
|
|
||||||
{
|
|
||||||
fp_err ("expected response to cmd seq=%02x, got response to %02x "
|
|
||||||
"in state %d", upekdev->seq, seq,
|
|
||||||
fpi_ssm_get_cur_state (ssm));
|
|
||||||
fpi_ssm_mark_failed (ssm,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Unexpected sequence number in response"));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_ssm_next_state (ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
@@ -1564,4 +1555,6 @@ fpi_device_upekts_class_init (FpiDeviceUpektsClass *klass)
|
|||||||
dev_class->verify = verify;
|
dev_class->verify = verify;
|
||||||
dev_class->enroll = enroll;
|
dev_class->enroll = enroll;
|
||||||
/* dev_class->cancel = cancel; */
|
/* dev_class->cancel = cancel; */
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-17
@@ -375,6 +375,10 @@ stop_irq_handler (FpImageDevice *dev, irqs_stopped_cb_fn cb)
|
|||||||
g_cancellable_cancel (self->irq_cancellable);
|
g_cancellable_cancel (self->irq_cancellable);
|
||||||
self->irqs_stopped_cb = cb;
|
self->irqs_stopped_cb = cb;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cb (dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** STATE CHANGING *****/
|
/***** STATE CHANGING *****/
|
||||||
@@ -412,18 +416,6 @@ dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
|||||||
{
|
{
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
|
|
||||||
self->activate_state = state;
|
self->activate_state = state;
|
||||||
if (self->img_transfer != NULL)
|
if (self->img_transfer != NULL)
|
||||||
return;
|
return;
|
||||||
@@ -663,7 +655,11 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
|||||||
case IMAGING_CAPTURE:
|
case IMAGING_CAPTURE:
|
||||||
self->img_lines_done = 0;
|
self->img_lines_done = 0;
|
||||||
self->img_block = 0;
|
self->img_block = 0;
|
||||||
fpi_usb_transfer_submit (self->img_transfer, 0, NULL, image_transfer_cb, NULL);
|
fpi_usb_transfer_submit (fpi_usb_transfer_ref (self->img_transfer),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
image_transfer_cb,
|
||||||
|
NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -799,8 +795,7 @@ imaging_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
if (error)
|
if (error)
|
||||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
|
||||||
|
|
||||||
/* Freed by callback or cancellation */
|
g_clear_pointer (&self->img_transfer, fpi_usb_transfer_unref);
|
||||||
self->img_transfer = NULL;
|
|
||||||
|
|
||||||
g_free (self->img_data);
|
g_free (self->img_data);
|
||||||
self->img_data = NULL;
|
self->img_data = NULL;
|
||||||
@@ -1182,7 +1177,10 @@ deactivate_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
|||||||
static void
|
static void
|
||||||
dev_deactivate (FpImageDevice *dev)
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
dev_change_state (dev, FPI_IMAGE_DEVICE_STATE_INACTIVE);
|
/* This is started/handled by execute_state_change in order to delay the
|
||||||
|
* action until after the image transfer has completed.
|
||||||
|
* We just need to override the function so that the complete handler is
|
||||||
|
* not called automatically. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1193,7 +1191,7 @@ execute_state_change (FpImageDevice *dev)
|
|||||||
|
|
||||||
switch (self->activate_state)
|
switch (self->activate_state)
|
||||||
{
|
{
|
||||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
case FPI_IMAGE_DEVICE_STATE_DEACTIVATING:
|
||||||
fp_dbg ("deactivating");
|
fp_dbg ("deactivating");
|
||||||
self->irq_cb = NULL;
|
self->irq_cb = NULL;
|
||||||
self->irq_cb_data = NULL;
|
self->irq_cb_data = NULL;
|
||||||
@@ -1248,6 +1246,12 @@ execute_state_change (FpImageDevice *dev)
|
|||||||
write_reg (dev, REG_MODE, MODE_AWAIT_FINGER_OFF,
|
write_reg (dev, REG_MODE, MODE_AWAIT_FINGER_OFF,
|
||||||
change_state_write_reg_cb, NULL);
|
change_state_write_reg_cb, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Ignored states */
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_ACTIVATING:
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-24
@@ -147,18 +147,6 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete loop sequential state machine */
|
|
||||||
static void
|
|
||||||
m_loop_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
g_warning ("State machine completed with an error: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
/* Free sequential state machine */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Exec init sequential state machine */
|
/* Exec init sequential state machine */
|
||||||
static void
|
static void
|
||||||
m_init_state (FpiSsm *ssm, FpDevice *_dev)
|
m_init_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
@@ -176,19 +164,7 @@ m_init_state (FpiSsm *ssm, FpDevice *_dev)
|
|||||||
static void
|
static void
|
||||||
m_init_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
m_init_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm_loop;
|
|
||||||
|
|
||||||
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
|
||||||
if (!error)
|
|
||||||
{
|
|
||||||
/* Notify activate complete */
|
|
||||||
|
|
||||||
/* Start loop ssm */
|
|
||||||
ssm_loop = fpi_ssm_new (dev, m_loop_state, M_LOOP_NUM_STATES);
|
|
||||||
fpi_ssm_start (ssm_loop, m_loop_complete);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free sequential state machine */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate device */
|
/* Activate device */
|
||||||
@@ -213,6 +189,19 @@ dev_deactivate (FpImageDevice *dev)
|
|||||||
fpi_image_device_deactivate_complete (dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
||||||
|
{
|
||||||
|
FpiSsm *ssm_loop;
|
||||||
|
|
||||||
|
if (state != FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Start a capture operation. */
|
||||||
|
ssm_loop = fpi_ssm_new (FP_DEVICE (dev), m_loop_state, M_LOOP_NUM_STATES);
|
||||||
|
fpi_ssm_start (ssm_loop, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_open (FpImageDevice *dev)
|
dev_open (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
@@ -273,6 +262,7 @@ fpi_device_vfs301_class_init (FpDeviceVfs301Class *klass)
|
|||||||
img_class->img_close = dev_close;
|
img_class->img_close = dev_close;
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
img_class->change_state = dev_change_state;
|
||||||
|
|
||||||
img_class->bz3_threshold = 24;
|
img_class->bz3_threshold = 24;
|
||||||
|
|
||||||
|
|||||||
@@ -213,11 +213,9 @@ vfs301_proto_generate (int type, int subtype, gssize *len)
|
|||||||
*len = 1;
|
*len = 1;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
return vfs301_proto_generate_0B (subtype, len);
|
return vfs301_proto_generate_0B (subtype, len);
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x02D0:
|
case 0x02D0:
|
||||||
{
|
{
|
||||||
@@ -233,22 +231,18 @@ vfs301_proto_generate (int type, int subtype, gssize *len)
|
|||||||
g_assert ((int) subtype <= G_N_ELEMENTS (dataLs));
|
g_assert ((int) subtype <= G_N_ELEMENTS (dataLs));
|
||||||
return translate_str (dataLs[subtype - 1], len);
|
return translate_str (dataLs[subtype - 1], len);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0220:
|
case 0x0220:
|
||||||
switch (subtype)
|
switch (subtype)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return translate_str (vfs301_0220_01, len);
|
return translate_str (vfs301_0220_01, len);
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return translate_str (vfs301_0220_02, len);
|
return translate_str (vfs301_0220_02, len);
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
return translate_str (vfs301_0220_03, len);
|
return translate_str (vfs301_0220_03, len);
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xFA00:
|
case 0xFA00:
|
||||||
case 0x2C01:
|
case 0x2C01:
|
||||||
@@ -271,7 +265,6 @@ vfs301_proto_generate (int type, int subtype, gssize *len)
|
|||||||
field[3] = field[1];
|
field[3] = field[1];
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* 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
|
/* There are many similar blocks in the data below, also the data are
|
||||||
* self-similar (looks like some config blocks? pokes like in vfs101?) */
|
* self-similar (looks like some config blocks? pokes like in vfs101?) */
|
||||||
|
|
||||||
|
|||||||
@@ -815,13 +815,11 @@ dev_close (FpImageDevice *dev)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011 (dev);
|
FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011 (dev);
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
|
|
||||||
g_free (self->capture_buffer);
|
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);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#define VFS5011_LINE_SIZE 240
|
#define VFS5011_LINE_SIZE 240
|
||||||
#define VFS5011_IMAGE_WIDTH 160
|
#define VFS5011_IMAGE_WIDTH 160
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 _FpiDeviceVirtualListener
|
||||||
|
{
|
||||||
|
GSocketListener parent_instance;
|
||||||
|
|
||||||
|
GSocketConnection *connection;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
guint cancellable_id;
|
||||||
|
|
||||||
|
FpiDeviceVirtualListenerConnectionCb ready_cb;
|
||||||
|
gpointer ready_cb_data;
|
||||||
|
|
||||||
|
gint socket_fd;
|
||||||
|
gint client_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FpiDeviceVirtualListener, fpi_device_virtual_listener, G_TYPE_SOCKET_LISTENER)
|
||||||
|
|
||||||
|
static void start_listen (FpiDeviceVirtualListener *self);
|
||||||
|
|
||||||
|
FpiDeviceVirtualListener *
|
||||||
|
fpi_device_virtual_listener_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (fpi_device_virtual_listener_get_type (), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_listener_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
FpiDeviceVirtualListener *self = FPI_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 (fpi_device_virtual_listener_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_listener_class_init (FpiDeviceVirtualListenerClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = fpi_device_virtual_listener_dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_listener_init (FpiDeviceVirtualListener *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
FpiDeviceVirtualListener *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 (FpiDeviceVirtualListener *self)
|
||||||
|
{
|
||||||
|
g_socket_listener_accept_async (G_SOCKET_LISTENER (self),
|
||||||
|
self->cancellable,
|
||||||
|
new_connection_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_cancelled (GCancellable *cancellable,
|
||||||
|
FpiDeviceVirtualListener *self)
|
||||||
|
{
|
||||||
|
fpi_device_virtual_listener_connection_close (self);
|
||||||
|
g_socket_listener_close (G_SOCKET_LISTENER (self));
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
self->ready_cb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fpi_device_virtual_listener_start (FpiDeviceVirtualListener *self,
|
||||||
|
const char *address,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
FpiDeviceVirtualListenerConnectionCb cb,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autoptr(GSocketAddress) addr = NULL;
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_return_val_if_fail (FPI_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
|
||||||
|
fpi_device_virtual_listener_connection_close (FpiDeviceVirtualListener *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (FPI_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;
|
||||||
|
FpiDeviceVirtualListener *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
|
||||||
|
fpi_device_virtual_listener_read (FpiDeviceVirtualListener *self,
|
||||||
|
gboolean all,
|
||||||
|
void *buffer,
|
||||||
|
gsize count,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = NULL;
|
||||||
|
GInputStream *stream;
|
||||||
|
|
||||||
|
g_return_if_fail (FPI_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
|
||||||
|
fpi_device_virtual_listener_read_finish (FpiDeviceVirtualListener *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
|
||||||
|
fpi_device_virtual_listener_write_sync (FpiDeviceVirtualListener *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);
|
||||||
|
}
|
||||||
@@ -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 (FpiDeviceVirtualListener, fpi_device_virtual_listener, FPI, DEVICE_VIRTUAL_LISTENER, GSocketListener)
|
||||||
|
|
||||||
|
typedef void (*FpiDeviceVirtualListenerConnectionCb) (FpiDeviceVirtualListener *listener,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
FpiDeviceVirtualListener * fpi_device_virtual_listener_new (void);
|
||||||
|
|
||||||
|
gboolean fpi_device_virtual_listener_start (FpiDeviceVirtualListener *listener,
|
||||||
|
const char *address,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
FpiDeviceVirtualListenerConnectionCb cb,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean fpi_device_virtual_listener_connection_close (FpiDeviceVirtualListener *listener);
|
||||||
|
|
||||||
|
void fpi_device_virtual_listener_read (FpiDeviceVirtualListener *listener,
|
||||||
|
gboolean all,
|
||||||
|
void *buffer,
|
||||||
|
gsize count,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
gsize fpi_device_virtual_listener_read_finish (FpiDeviceVirtualListener *listener,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean fpi_device_virtual_listener_write_sync (FpiDeviceVirtualListener *self,
|
||||||
|
const char *buffer,
|
||||||
|
gsize count,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
|
struct _FpDeviceVirtualDevice
|
||||||
|
{
|
||||||
|
FpDevice parent;
|
||||||
|
|
||||||
|
FpiDeviceVirtualListener *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);
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
|
dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,781 @@
|
|||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
FpiDeviceVirtualListener *listener = FPI_DEVICE_VIRTUAL_LISTENER (user_data);
|
||||||
|
|
||||||
|
if (!fpi_device_virtual_listener_write_sync (listener, key, strlen (key), NULL) ||
|
||||||
|
!fpi_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;
|
||||||
|
FpiDeviceVirtualListener *listener = FPI_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||||
|
gsize bytes;
|
||||||
|
|
||||||
|
bytes = fpi_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_device_virtual_listener_connection_close (listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_instruction (FpDeviceVirtualDevice *self)
|
||||||
|
{
|
||||||
|
fpi_device_virtual_listener_read (self->listener,
|
||||||
|
FALSE,
|
||||||
|
self->recv_buf,
|
||||||
|
sizeof (self->recv_buf),
|
||||||
|
recv_instruction_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_listener_connected (FpiDeviceVirtualListener *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(FpiDeviceVirtualListener) 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 = fpi_device_virtual_listener_new ();
|
||||||
|
cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
if (!fpi_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;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
|
}
|
||||||
@@ -29,25 +29,18 @@
|
|||||||
|
|
||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
|
|
||||||
|
#include "virtual-device-private.h"
|
||||||
|
|
||||||
#include "../fpi-image.h"
|
#include "../fpi-image.h"
|
||||||
#include "../fpi-image-device.h"
|
#include "../fpi-image-device.h"
|
||||||
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
#include <gio/gio.h>
|
|
||||||
#include <gio/gunixsocketaddress.h>
|
|
||||||
|
|
||||||
struct _FpDeviceVirtualImage
|
struct _FpDeviceVirtualImage
|
||||||
{
|
{
|
||||||
FpImageDevice parent;
|
FpImageDevice parent;
|
||||||
|
|
||||||
GSocketListener *listener;
|
FpiDeviceVirtualListener *listener;
|
||||||
GSocketConnection *connection;
|
|
||||||
GCancellable *listen_cancellable;
|
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
gint socket_fd;
|
|
||||||
gint client_fd;
|
|
||||||
|
|
||||||
gboolean automatic_finger;
|
gboolean automatic_finger;
|
||||||
FpImage *recv_img;
|
FpImage *recv_img;
|
||||||
gint recv_img_hdr[2];
|
gint recv_img_hdr[2];
|
||||||
@@ -56,9 +49,7 @@ struct _FpDeviceVirtualImage
|
|||||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FPI, DEVICE_VIRTUAL_IMAGE, FpImageDevice)
|
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)
|
G_DEFINE_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FP_TYPE_IMAGE_DEVICE)
|
||||||
|
|
||||||
static void start_listen (FpDeviceVirtualImage *dev);
|
static void recv_image (FpDeviceVirtualImage *self);
|
||||||
static void recv_image (FpDeviceVirtualImage *dev,
|
|
||||||
GInputStream *stream);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_image_img_recv_cb (GObject *source_object,
|
recv_image_img_recv_cb (GObject *source_object,
|
||||||
@@ -66,27 +57,16 @@ recv_image_img_recv_cb (GObject *source_object,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
FpiDeviceVirtualListener *listener = FPI_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||||
FpDeviceVirtualImage *self;
|
FpDeviceVirtualImage *self;
|
||||||
FpImageDevice *device;
|
FpImageDevice *device;
|
||||||
gboolean success;
|
gsize bytes;
|
||||||
gsize bytes = 0;
|
|
||||||
|
|
||||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
bytes = fpi_device_virtual_listener_read_finish (listener, res, &error);
|
||||||
|
|
||||||
if (!success || bytes == 0)
|
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))
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
||||||
return;
|
return;
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
|
||||||
g_clear_object (&self->connection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
device = FP_IMAGE_DEVICE (self);
|
device = FP_IMAGE_DEVICE (self);
|
||||||
@@ -98,7 +78,7 @@ recv_image_img_recv_cb (GObject *source_object,
|
|||||||
fpi_image_device_report_finger_status (device, FALSE);
|
fpi_image_device_report_finger_status (device, FALSE);
|
||||||
|
|
||||||
/* And, listen for more images from the same client. */
|
/* And, listen for more images from the same client. */
|
||||||
recv_image (self, G_INPUT_STREAM (source_object));
|
recv_image (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -108,33 +88,30 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
|||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
FpDeviceVirtualImage *self;
|
FpDeviceVirtualImage *self;
|
||||||
gboolean success;
|
FpiDeviceVirtualListener *listener = FPI_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||||
gsize bytes;
|
gsize bytes;
|
||||||
|
|
||||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
bytes = fpi_device_virtual_listener_read_finish (listener, res, &error);
|
||||||
|
|
||||||
if (!success || bytes == 0)
|
if (error)
|
||||||
{
|
|
||||||
if (!success)
|
|
||||||
{
|
{
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
||||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) ||
|
||||||
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
g_warning ("Error receiving header for image data: %s", error->message);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
if (!bytes)
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
|
||||||
g_clear_object (&self->connection);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000)
|
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_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
fpi_device_virtual_listener_connection_close (listener);
|
||||||
g_clear_object (&self->connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
|
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
|
||||||
@@ -163,153 +140,94 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
|||||||
!!self->recv_img_hdr[1]);
|
!!self->recv_img_hdr[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case -5:
|
||||||
|
/* -5 causes the device to disappear (no further data) */
|
||||||
|
fpi_device_remove (FP_DEVICE (self));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* disconnect client, it didn't play fair */
|
/* disconnect client, it didn't play fair */
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
fpi_device_virtual_listener_connection_close (listener);
|
||||||
g_clear_object (&self->connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And, listen for more images from the same client. */
|
/* And, listen for more images from the same client. */
|
||||||
recv_image (self, G_INPUT_STREAM (source_object));
|
recv_image (self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
|
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_debug ("image data: %p", self->recv_img->data);
|
||||||
g_input_stream_read_all_async (G_INPUT_STREAM (source_object),
|
fpi_device_virtual_listener_read (listener,
|
||||||
|
TRUE,
|
||||||
(guint8 *) self->recv_img->data,
|
(guint8 *) self->recv_img->data,
|
||||||
self->recv_img->width * self->recv_img->height,
|
self->recv_img->width * self->recv_img->height,
|
||||||
G_PRIORITY_DEFAULT,
|
|
||||||
self->cancellable,
|
|
||||||
recv_image_img_recv_cb,
|
recv_image_img_recv_cb,
|
||||||
self);
|
self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_image (FpDeviceVirtualImage *self, GInputStream *stream)
|
recv_image (FpDeviceVirtualImage *self)
|
||||||
{
|
{
|
||||||
FpiImageDeviceState state;
|
fpi_device_virtual_listener_read (self->listener,
|
||||||
|
TRUE,
|
||||||
g_object_get (self, "fpi-image-device-state", &state, NULL);
|
|
||||||
|
|
||||||
g_debug ("Starting image receive (if active), state is: %i", state);
|
|
||||||
|
|
||||||
/* Only register if the state is active. */
|
|
||||||
if (state != FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
|
||||||
{
|
|
||||||
g_input_stream_read_all_async (stream,
|
|
||||||
self->recv_img_hdr,
|
self->recv_img_hdr,
|
||||||
sizeof (self->recv_img_hdr),
|
sizeof (self->recv_img_hdr),
|
||||||
G_PRIORITY_DEFAULT,
|
|
||||||
self->cancellable,
|
|
||||||
recv_image_hdr_recv_cb,
|
recv_image_hdr_recv_cb,
|
||||||
self);
|
self);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
on_listener_connected (FpiDeviceVirtualListener *listener,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
GSocketConnection *connection;
|
FpiImageDeviceState state;
|
||||||
GInputStream *stream;
|
|
||||||
FpDeviceVirtualImage *dev = user_data;
|
|
||||||
|
|
||||||
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
self->automatic_finger = TRUE;
|
||||||
res,
|
|
||||||
NULL,
|
g_object_get (self,
|
||||||
&error);
|
"fpi-image-device-state", &state,
|
||||||
if (!connection)
|
NULL);
|
||||||
|
|
||||||
|
switch (state)
|
||||||
{
|
{
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
||||||
return;
|
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||||
|
recv_image (self);
|
||||||
|
|
||||||
g_warning ("Error accepting a new connection: %s", error->message);
|
default:
|
||||||
start_listen (dev);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. Double check here. */
|
|
||||||
g_input_stream_is_closed (g_io_stream_get_input_stream (G_IO_STREAM (dev->connection)));
|
|
||||||
|
|
||||||
g_io_stream_close (G_IO_STREAM (dev->connection), NULL, NULL);
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_init (FpImageDevice *dev)
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GSocketListener) listener = NULL;
|
g_autoptr(FpiDeviceVirtualListener) listener = NULL;
|
||||||
|
g_autoptr(GCancellable) cancellable = NULL;
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||||
const char *env;
|
|
||||||
|
|
||||||
g_autoptr(GSocketAddress) addr = NULL;
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->client_fd = -1;
|
listener = fpi_device_virtual_listener_new ();
|
||||||
|
cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
if (!fpi_device_virtual_listener_start (listener,
|
||||||
|
fpi_device_get_virtual_env (FP_DEVICE (self)),
|
||||||
listener = g_socket_listener_new ();
|
cancellable,
|
||||||
g_socket_listener_set_backlog (listener, 1);
|
on_listener_connected,
|
||||||
|
self,
|
||||||
/* 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))
|
&error))
|
||||||
{
|
{
|
||||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
fpi_image_device_open_complete (dev, g_steal_pointer (&error));
|
||||||
|
|
||||||
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->listener = g_steal_pointer (&listener);
|
self->listener = g_steal_pointer (&listener);
|
||||||
self->cancellable = g_cancellable_new ();
|
self->cancellable = g_steal_pointer (&cancellable);
|
||||||
self->listen_cancellable = g_cancellable_new ();
|
|
||||||
|
|
||||||
start_listen (self);
|
|
||||||
|
|
||||||
/* Delay result to open up the possibility of testing race conditions. */
|
/* 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);
|
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_open_complete, NULL, NULL);
|
||||||
@@ -323,11 +241,8 @@ dev_deinit (FpImageDevice *dev)
|
|||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
g_cancellable_cancel (self->cancellable);
|
g_cancellable_cancel (self->cancellable);
|
||||||
g_cancellable_cancel (self->listen_cancellable);
|
|
||||||
g_clear_object (&self->cancellable);
|
g_clear_object (&self->cancellable);
|
||||||
g_clear_object (&self->listen_cancellable);
|
|
||||||
g_clear_object (&self->listener);
|
g_clear_object (&self->listener);
|
||||||
g_clear_object (&self->connection);
|
|
||||||
|
|
||||||
/* Delay result to open up the possibility of testing race conditions. */
|
/* 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);
|
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_close_complete, NULL, NULL);
|
||||||
@@ -338,8 +253,8 @@ dev_activate (FpImageDevice *dev)
|
|||||||
{
|
{
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||||
|
|
||||||
if (self->connection)
|
/* Start reading (again). */
|
||||||
recv_image (self, g_io_stream_get_input_stream (G_IO_STREAM (self->connection)));
|
recv_image (self);
|
||||||
|
|
||||||
fpi_image_device_activate_complete (dev, NULL);
|
fpi_image_device_activate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
@@ -347,19 +262,39 @@ dev_activate (FpImageDevice *dev)
|
|||||||
static void
|
static void
|
||||||
dev_deactivate (FpImageDevice *dev)
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
g_cancellable_cancel (self->cancellable);
|
static void
|
||||||
g_clear_object (&self->cancellable);
|
dev_notify_removed_cb (FpDevice *dev)
|
||||||
self->cancellable = g_cancellable_new ();
|
{
|
||||||
|
FpiImageDeviceState state;
|
||||||
|
gboolean removed;
|
||||||
|
|
||||||
/* XXX: Need to wait for the operation to be cancelled. */
|
g_object_get (dev,
|
||||||
fpi_device_add_timeout (FP_DEVICE (dev), 10, (FpTimeoutFunc) fpi_image_device_deactivate_complete, NULL, NULL);
|
"fpi-image-device-state", &state,
|
||||||
|
"removed", &removed,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!removed || state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* This error will be converted to an FP_DEVICE_ERROR_REMOVED by the
|
||||||
|
* surrounding layers. */
|
||||||
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev),
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_device_virtual_image_init (FpDeviceVirtualImage *self)
|
fpi_device_virtual_image_init (FpDeviceVirtualImage *self)
|
||||||
{
|
{
|
||||||
|
/* NOTE: This is not nice, but we can generally rely on the underlying
|
||||||
|
* system to throw errors on the transport layer.
|
||||||
|
*/
|
||||||
|
g_signal_connect (self,
|
||||||
|
"notify::removed",
|
||||||
|
G_CALLBACK (dev_notify_removed_cb),
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry driver_ids[] = {
|
static const FpIdEntry driver_ids[] = {
|
||||||
|
|||||||
@@ -29,4 +29,5 @@
|
|||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
#include "fpi-print.h"
|
#include "fpi-print.h"
|
||||||
#include "fpi-usb-transfer.h"
|
#include "fpi-usb-transfer.h"
|
||||||
|
#include "fpi-spi-transfer.h"
|
||||||
#include "fpi-ssm.h"
|
#include "fpi-ssm.h"
|
||||||
|
|||||||
+171
-6
@@ -24,6 +24,18 @@
|
|||||||
#include "fpi-device.h"
|
#include "fpi-device.h"
|
||||||
#include <gusb.h>
|
#include <gusb.h>
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UDEV
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <linux/hidraw.h>
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION: fp-context
|
* SECTION: fp-context
|
||||||
* @title: FpContext
|
* @title: FpContext
|
||||||
@@ -86,6 +98,60 @@ is_driver_allowed (const gchar *driver)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FpContext *context;
|
||||||
|
FpDevice *device;
|
||||||
|
} RemoveDeviceData;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
remove_device_idle_cb (RemoveDeviceData *data)
|
||||||
|
{
|
||||||
|
FpContextPrivate *priv = fp_context_get_instance_private (data->context);
|
||||||
|
guint idx = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (g_ptr_array_find (priv->devices, data->device, &idx), G_SOURCE_REMOVE);
|
||||||
|
|
||||||
|
g_signal_emit (data->context, signals[DEVICE_REMOVED_SIGNAL], 0, data->device);
|
||||||
|
g_ptr_array_remove_index_fast (priv->devices, idx);
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_device (FpContext *context, FpDevice *device)
|
||||||
|
{
|
||||||
|
RemoveDeviceData *data;
|
||||||
|
|
||||||
|
data = g_new (RemoveDeviceData, 1);
|
||||||
|
data->context = context;
|
||||||
|
data->device = device;
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) remove_device_idle_cb, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_remove_on_notify_open_cb (FpContext *context, GParamSpec *pspec, FpDevice *device)
|
||||||
|
{
|
||||||
|
remove_device (context, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_removed_cb (FpContext *context, FpDevice *device)
|
||||||
|
{
|
||||||
|
gboolean open = FALSE;
|
||||||
|
|
||||||
|
g_object_get (device, "open", &open, NULL);
|
||||||
|
|
||||||
|
/* Wait for device close if the device is currently still open. */
|
||||||
|
if (open)
|
||||||
|
g_signal_connect_swapped (device, "notify::open", (GCallback) device_remove_on_notify_open_cb, context);
|
||||||
|
else
|
||||||
|
remove_device (context, device);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -110,6 +176,9 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_ptr_array_add (priv->devices, device);
|
g_ptr_array_add (priv->devices, device);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (device, "removed", (GCallback) device_removed_cb, context);
|
||||||
|
|
||||||
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
|
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +258,7 @@ usb_device_removed_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fpi_device_get_usb_device (dev) == device)
|
if (fpi_device_get_usb_device (dev) == device)
|
||||||
{
|
fpi_device_remove (dev);
|
||||||
g_signal_emit (self, signals[DEVICE_REMOVED_SIGNAL], 0, dev);
|
|
||||||
g_ptr_array_remove_index_fast (priv->devices, i);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +312,10 @@ fp_context_class_init (FpContextClass *klass)
|
|||||||
* @device: A #FpDevice
|
* @device: A #FpDevice
|
||||||
*
|
*
|
||||||
* This signal is emitted when a fingerprint reader is removed.
|
* This signal is emitted when a fingerprint reader is removed.
|
||||||
|
*
|
||||||
|
* It is guaranteed that the device has been closed before this signal
|
||||||
|
* is emitted. See the #FpDevice removed signal documentation for more
|
||||||
|
* information.
|
||||||
**/
|
**/
|
||||||
signals[DEVICE_REMOVED_SIGNAL] = g_signal_new ("device-removed",
|
signals[DEVICE_REMOVED_SIGNAL] = g_signal_new ("device-removed",
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
@@ -378,6 +446,103 @@ fp_context_enumerate (FpContext *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_UDEV
|
||||||
|
{
|
||||||
|
g_autoptr(GUdevClient) udev_client = g_udev_client_new (NULL);
|
||||||
|
|
||||||
|
/* This uses a very simple algorithm to allocate devices to drivers and assumes that no two drivers will want the same device. Future improvements
|
||||||
|
* could add a usb_discover style udev_discover that returns a score, however for internal devices the potential overlap should be very low between
|
||||||
|
* separate drivers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_autoptr(GList) spidev_devices = g_udev_client_query_by_subsystem (udev_client, "spidev");
|
||||||
|
g_autoptr(GList) hidraw_devices = g_udev_client_query_by_subsystem (udev_client, "hidraw");
|
||||||
|
|
||||||
|
/* for each potential driver, try to match all requested resources. */
|
||||||
|
for (i = 0; i < priv->drivers->len; i++)
|
||||||
|
{
|
||||||
|
GType driver = g_array_index (priv->drivers, GType, i);
|
||||||
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
|
const FpIdEntry *entry;
|
||||||
|
|
||||||
|
if (cls->type != FP_DEVICE_TYPE_UDEV)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (entry = cls->id_table; entry->udev_types; entry++)
|
||||||
|
{
|
||||||
|
GList *matched_spidev = NULL, *matched_hidraw = NULL;
|
||||||
|
|
||||||
|
if (entry->udev_types & FPI_DEVICE_UDEV_SUBTYPE_SPIDEV)
|
||||||
|
{
|
||||||
|
for (matched_spidev = spidev_devices; matched_spidev; matched_spidev = matched_spidev->next)
|
||||||
|
{
|
||||||
|
const gchar * sysfs = g_udev_device_get_sysfs_path (matched_spidev->data);
|
||||||
|
if (!sysfs)
|
||||||
|
continue;
|
||||||
|
if (strstr (sysfs, entry->spi_acpi_id))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If match was not found exit */
|
||||||
|
if (matched_spidev == NULL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (entry->udev_types & FPI_DEVICE_UDEV_SUBTYPE_HIDRAW)
|
||||||
|
{
|
||||||
|
for (matched_hidraw = hidraw_devices; matched_hidraw; matched_hidraw = matched_hidraw->next)
|
||||||
|
{
|
||||||
|
const gchar * devnode = g_udev_device_get_device_file (matched_hidraw->data);
|
||||||
|
int temp_hid = -1, res;
|
||||||
|
struct hidraw_devinfo info;
|
||||||
|
|
||||||
|
if (!devnode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
temp_hid = open (devnode, O_RDWR);
|
||||||
|
if (temp_hid < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
res = ioctl (temp_hid, HIDIOCGRAWINFO, &info);
|
||||||
|
close (temp_hid);
|
||||||
|
if (res < 0)
|
||||||
|
continue;
|
||||||
|
if (info.vendor == entry->hid_id.vid && info.product == entry->hid_id.pid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If match was not found exit */
|
||||||
|
if (matched_hidraw == NULL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
priv->pending_devices++;
|
||||||
|
g_async_initable_new_async (driver,
|
||||||
|
G_PRIORITY_LOW,
|
||||||
|
priv->cancellable,
|
||||||
|
async_device_init_done_cb,
|
||||||
|
context,
|
||||||
|
"fpi-driver-data", entry->driver_data,
|
||||||
|
"fpi-udev-data-spidev", (matched_spidev ? g_udev_device_get_device_file (matched_spidev->data) : NULL),
|
||||||
|
"fpi-udev-data-hidraw", (matched_hidraw ? g_udev_device_get_device_file (matched_hidraw->data) : NULL),
|
||||||
|
NULL);
|
||||||
|
/* remove entries from list to avoid conflicts */
|
||||||
|
if (matched_spidev)
|
||||||
|
{
|
||||||
|
g_object_unref (matched_spidev->data);
|
||||||
|
spidev_devices = g_list_delete_link (spidev_devices, matched_spidev);
|
||||||
|
}
|
||||||
|
if (matched_hidraw)
|
||||||
|
{
|
||||||
|
g_object_unref (matched_hidraw->data);
|
||||||
|
hidraw_devices = g_list_delete_link (hidraw_devices, matched_hidraw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free all unused elemnts in both lists */
|
||||||
|
g_list_foreach (spidev_devices, (GFunc) g_object_unref, NULL);
|
||||||
|
g_list_foreach (hidraw_devices, (GFunc) g_object_unref, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (priv->pending_devices)
|
while (priv->pending_devices)
|
||||||
g_main_context_iteration (NULL, TRUE);
|
g_main_context_iteration (NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,13 @@ typedef struct
|
|||||||
|
|
||||||
GUsbDevice *usb_device;
|
GUsbDevice *usb_device;
|
||||||
const gchar *virtual_env;
|
const gchar *virtual_env;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
gchar *spidev_path;
|
||||||
|
gchar *hidraw_path;
|
||||||
|
} udev_data;
|
||||||
|
|
||||||
|
gboolean is_removed;
|
||||||
gboolean is_open;
|
gboolean is_open;
|
||||||
|
|
||||||
gchar *device_id;
|
gchar *device_id;
|
||||||
@@ -50,6 +56,7 @@ typedef struct
|
|||||||
|
|
||||||
/* State for tasks */
|
/* State for tasks */
|
||||||
gboolean wait_for_finger;
|
gboolean wait_for_finger;
|
||||||
|
FpFingerStatusFlags finger_status;
|
||||||
} FpDevicePrivate;
|
} FpDevicePrivate;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+177
-14
@@ -44,16 +44,27 @@ enum {
|
|||||||
PROP_DEVICE_ID,
|
PROP_DEVICE_ID,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
PROP_OPEN,
|
PROP_OPEN,
|
||||||
|
PROP_REMOVED,
|
||||||
PROP_NR_ENROLL_STAGES,
|
PROP_NR_ENROLL_STAGES,
|
||||||
PROP_SCAN_TYPE,
|
PROP_SCAN_TYPE,
|
||||||
|
PROP_FINGER_STATUS,
|
||||||
PROP_FPI_ENVIRON,
|
PROP_FPI_ENVIRON,
|
||||||
PROP_FPI_USB_DEVICE,
|
PROP_FPI_USB_DEVICE,
|
||||||
|
PROP_FPI_UDEV_DATA_SPIDEV,
|
||||||
|
PROP_FPI_UDEV_DATA_HIDRAW,
|
||||||
PROP_FPI_DRIVER_DATA,
|
PROP_FPI_DRIVER_DATA,
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
static GParamSpec *properties[N_PROPS];
|
static GParamSpec *properties[N_PROPS];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
REMOVED_SIGNAL,
|
||||||
|
N_SIGNALS
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[N_SIGNALS] = { 0, };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_device_retry_quark:
|
* fp_device_retry_quark:
|
||||||
*
|
*
|
||||||
@@ -84,6 +95,8 @@ fp_device_cancel_in_idle_cb (gpointer user_data)
|
|||||||
|
|
||||||
cls->cancel (self);
|
cls->cancel (self);
|
||||||
|
|
||||||
|
fpi_device_report_finger_status (self, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +140,8 @@ fp_device_constructed (GObject *object)
|
|||||||
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (self);
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (self);
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (self);
|
FpDevicePrivate *priv = fp_device_get_instance_private (self);
|
||||||
|
|
||||||
|
g_assert (cls->features != FPI_DEVICE_FEATURE_NONE);
|
||||||
|
|
||||||
priv->type = cls->type;
|
priv->type = cls->type;
|
||||||
if (cls->nr_enroll_stages)
|
if (cls->nr_enroll_stages)
|
||||||
priv->nr_enroll_stages = cls->nr_enroll_stages;
|
priv->nr_enroll_stages = cls->nr_enroll_stages;
|
||||||
@@ -158,6 +173,8 @@ fp_device_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_object (&priv->usb_device);
|
g_clear_object (&priv->usb_device);
|
||||||
g_clear_pointer (&priv->virtual_env, g_free);
|
g_clear_pointer (&priv->virtual_env, g_free);
|
||||||
|
g_clear_pointer (&priv->udev_data.spidev_path, g_free);
|
||||||
|
g_clear_pointer (&priv->udev_data.hidraw_path, g_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (fp_device_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fp_device_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -174,15 +191,19 @@ fp_device_get_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_NR_ENROLL_STAGES:
|
case PROP_NR_ENROLL_STAGES:
|
||||||
g_value_set_int (value, priv->nr_enroll_stages);
|
g_value_set_uint (value, priv->nr_enroll_stages);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SCAN_TYPE:
|
case PROP_SCAN_TYPE:
|
||||||
g_value_set_enum (value, priv->scan_type);
|
g_value_set_enum (value, priv->scan_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_FINGER_STATUS:
|
||||||
|
g_value_set_flags (value, priv->finger_status);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_DRIVER:
|
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;
|
break;
|
||||||
|
|
||||||
case PROP_DEVICE_ID:
|
case PROP_DEVICE_ID:
|
||||||
@@ -197,6 +218,10 @@ fp_device_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, priv->is_open);
|
g_value_set_boolean (value, priv->is_open);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_REMOVED:
|
||||||
|
g_value_set_boolean (value, priv->is_removed);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
@@ -229,6 +254,20 @@ fp_device_set_property (GObject *object,
|
|||||||
g_assert (g_value_get_object (value) == NULL);
|
g_assert (g_value_get_object (value) == NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_FPI_UDEV_DATA_SPIDEV:
|
||||||
|
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||||
|
priv->udev_data.spidev_path = g_value_dup_string (value);
|
||||||
|
else
|
||||||
|
g_assert (g_value_get_string (value) == NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_FPI_UDEV_DATA_HIDRAW:
|
||||||
|
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||||
|
priv->udev_data.hidraw_path = g_value_dup_string (value);
|
||||||
|
else
|
||||||
|
g_assert (g_value_get_string (value) == NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_FPI_DRIVER_DATA:
|
case PROP_FPI_DRIVER_DATA:
|
||||||
priv->driver_data = g_value_get_uint64 (value);
|
priv->driver_data = g_value_get_uint64 (value);
|
||||||
break;
|
break;
|
||||||
@@ -310,6 +349,13 @@ fp_device_class_init (FpDeviceClass *klass)
|
|||||||
FP_TYPE_SCAN_TYPE, FP_SCAN_TYPE_SWIPE,
|
FP_TYPE_SCAN_TYPE, FP_SCAN_TYPE_SWIPE,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||||
|
|
||||||
|
properties[PROP_FINGER_STATUS] =
|
||||||
|
g_param_spec_flags ("finger-status",
|
||||||
|
"FingerStatus",
|
||||||
|
"The status of the finger",
|
||||||
|
FP_TYPE_FINGER_STATUS_FLAGS, FP_FINGER_STATUS_NONE,
|
||||||
|
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||||
|
|
||||||
properties[PROP_DRIVER] =
|
properties[PROP_DRIVER] =
|
||||||
g_param_spec_string ("driver",
|
g_param_spec_string ("driver",
|
||||||
"Driver",
|
"Driver",
|
||||||
@@ -337,6 +383,41 @@ fp_device_class_init (FpDeviceClass *klass)
|
|||||||
"Whether the device is open or not", FALSE,
|
"Whether the device is open or not", FALSE,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||||
|
|
||||||
|
properties[PROP_REMOVED] =
|
||||||
|
g_param_spec_boolean ("removed",
|
||||||
|
"Removed",
|
||||||
|
"Whether the device has been removed from the system", FALSE,
|
||||||
|
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpDevice::removed:
|
||||||
|
* @device: the #FpDevice instance that emitted the signal
|
||||||
|
*
|
||||||
|
* This signal is emitted after the device has been removed and no operation
|
||||||
|
* is pending anymore.
|
||||||
|
*
|
||||||
|
* The API user is still required to close a removed device. The above
|
||||||
|
* guarantee means that the call to close the device can be made immediately
|
||||||
|
* from the signal handler.
|
||||||
|
*
|
||||||
|
* The close operation will return FP_DEVICE_ERROR_REMOVED, but the device
|
||||||
|
* will still be considered closed afterwards.
|
||||||
|
*
|
||||||
|
* The device will only be removed from the #FpContext after it has been
|
||||||
|
* closed by the API user.
|
||||||
|
**/
|
||||||
|
signals[REMOVED_SIGNAL] = g_signal_new ("removed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* Private properties */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpDevice::fpi-environ: (skip)
|
* FpDevice::fpi-environ: (skip)
|
||||||
*
|
*
|
||||||
@@ -364,6 +445,32 @@ fp_device_class_init (FpDeviceClass *klass)
|
|||||||
"Private: The USB device for the device",
|
"Private: The USB device for the device",
|
||||||
G_USB_TYPE_DEVICE,
|
G_USB_TYPE_DEVICE,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
/**
|
||||||
|
* FpDevice::fpi-udev-data-spidev: (skip)
|
||||||
|
*
|
||||||
|
* This property is only for internal purposes.
|
||||||
|
*
|
||||||
|
* Stability: private
|
||||||
|
*/
|
||||||
|
properties[PROP_FPI_UDEV_DATA_SPIDEV] =
|
||||||
|
g_param_spec_string ("fpi-udev-data-spidev",
|
||||||
|
"Udev data: spidev path",
|
||||||
|
"Private: The path to /dev/spidevN.M",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
/**
|
||||||
|
* FpDevice::fpi-udev-data-hidraw: (skip)
|
||||||
|
*
|
||||||
|
* This property is only for internal purposes.
|
||||||
|
*
|
||||||
|
* Stability: private
|
||||||
|
*/
|
||||||
|
properties[PROP_FPI_UDEV_DATA_HIDRAW] =
|
||||||
|
g_param_spec_string ("fpi-udev-data-hidraw",
|
||||||
|
"Udev data: hidraw path",
|
||||||
|
"Private: The path to /dev/hidrawN",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpDevice::fpi-driver-data: (skip)
|
* FpDevice::fpi-driver-data: (skip)
|
||||||
@@ -469,6 +576,26 @@ fp_device_get_scan_type (FpDevice *device)
|
|||||||
return priv->scan_type;
|
return priv->scan_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fp_device_get_finger_status:
|
||||||
|
* @device: A #FpDevice
|
||||||
|
*
|
||||||
|
* Retrieves the finger status flags for the device.
|
||||||
|
* This can be used by the UI to present the relevant feedback, although it
|
||||||
|
* is not guaranteed to be a relevant value when not performing any action.
|
||||||
|
*
|
||||||
|
* Returns: The current #FpFingerStatusFlags
|
||||||
|
*/
|
||||||
|
FpFingerStatusFlags
|
||||||
|
fp_device_get_finger_status (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
|
g_return_val_if_fail (FP_IS_DEVICE (device), FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
|
return priv->finger_status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_device_get_nr_enroll_stages:
|
* fp_device_get_nr_enroll_stages:
|
||||||
* @device: A #FpDevice
|
* @device: A #FpDevice
|
||||||
@@ -502,7 +629,7 @@ fp_device_supports_identify (FpDevice *device)
|
|||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return cls->identify != NULL;
|
return cls->identify && !!(cls->features & FPI_DEVICE_FEATURE_IDENTIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -520,7 +647,7 @@ fp_device_supports_capture (FpDevice *device)
|
|||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return cls->capture != NULL;
|
return cls->capture && !!(cls->features & FPI_DEVICE_FEATURE_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -539,7 +666,7 @@ fp_device_has_storage (FpDevice *device)
|
|||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return cls->list != NULL;
|
return !!(cls->features & FPI_DEVICE_FEATURE_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -592,6 +719,7 @@ fp_device_open (FpDevice *device,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TYPE_VIRTUAL:
|
case FP_DEVICE_TYPE_VIRTUAL:
|
||||||
|
case FP_DEVICE_TYPE_UDEV:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -603,6 +731,7 @@ fp_device_open (FpDevice *device,
|
|||||||
priv->current_action = FPI_DEVICE_ACTION_OPEN;
|
priv->current_action = FPI_DEVICE_ACTION_OPEN;
|
||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->open (device);
|
FP_DEVICE_GET_CLASS (device)->open (device);
|
||||||
}
|
}
|
||||||
@@ -710,7 +839,7 @@ fp_device_close_finish (FpDevice *device,
|
|||||||
* in. The driver may make use of this metadata, when e.g. storing the print on
|
* 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
|
* 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
|
* and returned, or whether the driver will return a newly created print after
|
||||||
* enrollment successed.
|
* enrollment succeeded.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fp_device_enroll (FpDevice *device,
|
fp_device_enroll (FpDevice *device,
|
||||||
@@ -826,6 +955,7 @@ fp_device_verify (FpDevice *device,
|
|||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
||||||
FpMatchData *data;
|
FpMatchData *data;
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
@@ -846,6 +976,14 @@ fp_device_verify (FpDevice *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cls->verify || !(cls->features & FPI_DEVICE_FEATURE_VERIFY))
|
||||||
|
{
|
||||||
|
g_task_return_error (task,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
"Device has no verification support"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_VERIFY;
|
priv->current_action = FPI_DEVICE_ACTION_VERIFY;
|
||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
@@ -859,7 +997,7 @@ fp_device_verify (FpDevice *device,
|
|||||||
// Attach the match data as task data so that it is destroyed
|
// Attach the match data as task data so that it is destroyed
|
||||||
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
|
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->verify (device);
|
cls->verify (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -897,7 +1035,7 @@ fp_device_verify_finish (FpDevice *device,
|
|||||||
|
|
||||||
data = g_task_get_task_data (G_TASK (result));
|
data = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
*print = data->print;
|
*print = data ? data->print : NULL;
|
||||||
if (*print)
|
if (*print)
|
||||||
g_object_ref (*print);
|
g_object_ref (*print);
|
||||||
}
|
}
|
||||||
@@ -936,6 +1074,7 @@ fp_device_identify (FpDevice *device,
|
|||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
FpMatchData *data;
|
FpMatchData *data;
|
||||||
|
int i;
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
@@ -955,12 +1094,26 @@ fp_device_identify (FpDevice *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fp_device_supports_identify (device))
|
||||||
|
{
|
||||||
|
g_task_return_error (task,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
"Device has not identification support"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_IDENTIFY;
|
priv->current_action = FPI_DEVICE_ACTION_IDENTIFY;
|
||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
|
|
||||||
data = g_new0 (FpMatchData, 1);
|
data = g_new0 (FpMatchData, 1);
|
||||||
data->gallery = g_ptr_array_ref (prints);
|
/* We cannot store the gallery directly, because the ptr array may not own
|
||||||
|
* a reference to each print. Also, the caller could in principle modify the
|
||||||
|
* GPtrArray afterwards.
|
||||||
|
*/
|
||||||
|
data->gallery = g_ptr_array_new_full (prints->len, g_object_unref);
|
||||||
|
for (i = 0; i < prints->len; i++)
|
||||||
|
g_ptr_array_add (data->gallery, g_object_ref (g_ptr_array_index (prints, i)));
|
||||||
data->match_cb = match_cb;
|
data->match_cb = match_cb;
|
||||||
data->match_data = match_data;
|
data->match_data = match_data;
|
||||||
data->match_destroy = match_destroy;
|
data->match_destroy = match_destroy;
|
||||||
@@ -1003,13 +1156,13 @@ fp_device_identify_finish (FpDevice *device,
|
|||||||
|
|
||||||
if (print)
|
if (print)
|
||||||
{
|
{
|
||||||
*print = data->print;
|
*print = data ? data->print : NULL;
|
||||||
if (*print)
|
if (*print)
|
||||||
g_object_ref (*print);
|
g_object_ref (*print);
|
||||||
}
|
}
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
*match = data->match;
|
*match = data ? data->match : NULL;
|
||||||
if (*match)
|
if (*match)
|
||||||
g_object_ref (*match);
|
g_object_ref (*match);
|
||||||
}
|
}
|
||||||
@@ -1038,6 +1191,7 @@ fp_device_capture (FpDevice *device,
|
|||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
@@ -1057,13 +1211,21 @@ fp_device_capture (FpDevice *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cls->capture || !(cls->features & FPI_DEVICE_FEATURE_CAPTURE))
|
||||||
|
{
|
||||||
|
g_task_return_error (task,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
"Device has no verification support"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_CAPTURE;
|
priv->current_action = FPI_DEVICE_ACTION_CAPTURE;
|
||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
|
|
||||||
priv->wait_for_finger = wait_for_finger;
|
priv->wait_for_finger = wait_for_finger;
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->capture (device);
|
cls->capture (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1112,6 +1274,7 @@ fp_device_delete_print (FpDevice *device,
|
|||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
@@ -1132,7 +1295,7 @@ fp_device_delete_print (FpDevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Succeed immediately if delete is not implemented. */
|
/* Succeed immediately if delete is not implemented. */
|
||||||
if (!FP_DEVICE_GET_CLASS (device)->delete)
|
if (!cls->delete || !(cls->features & FPI_DEVICE_FEATURE_STORAGE_DELETE))
|
||||||
{
|
{
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (task, TRUE);
|
||||||
return;
|
return;
|
||||||
@@ -1146,7 +1309,7 @@ fp_device_delete_print (FpDevice *device,
|
|||||||
g_object_ref (enrolled_print),
|
g_object_ref (enrolled_print),
|
||||||
g_object_unref);
|
g_object_unref);
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->delete (device);
|
cls->delete (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,10 +38,12 @@ G_DECLARE_DERIVABLE_TYPE (FpDevice, fp_device, FP, DEVICE, GObject)
|
|||||||
/**
|
/**
|
||||||
* FpDeviceType:
|
* FpDeviceType:
|
||||||
* @FP_DEVICE_TYPE_VIRTUAL: The device is a virtual device
|
* @FP_DEVICE_TYPE_VIRTUAL: The device is a virtual device
|
||||||
|
* @FP_DEVICE_TYPE_UDEV: The device is a udev device
|
||||||
* @FP_DEVICE_TYPE_USB: The device is a USB device
|
* @FP_DEVICE_TYPE_USB: The device is a USB device
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FP_DEVICE_TYPE_VIRTUAL,
|
FP_DEVICE_TYPE_VIRTUAL,
|
||||||
|
FP_DEVICE_TYPE_UDEV,
|
||||||
FP_DEVICE_TYPE_USB,
|
FP_DEVICE_TYPE_USB,
|
||||||
} FpDeviceType;
|
} FpDeviceType;
|
||||||
|
|
||||||
@@ -91,6 +93,7 @@ typedef enum {
|
|||||||
* @FP_DEVICE_ERROR_DATA_NOT_FOUND: Requested print was not found on device
|
* @FP_DEVICE_ERROR_DATA_NOT_FOUND: Requested print was not found on device
|
||||||
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
|
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
|
||||||
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
|
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
|
||||||
|
* @FP_DEVICE_ERROR_REMOVED: The device has been removed.
|
||||||
*
|
*
|
||||||
* Error codes for device operations. More specific errors from other domains
|
* 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.
|
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
|
||||||
@@ -106,6 +109,8 @@ typedef enum {
|
|||||||
FP_DEVICE_ERROR_DATA_NOT_FOUND,
|
FP_DEVICE_ERROR_DATA_NOT_FOUND,
|
||||||
FP_DEVICE_ERROR_DATA_FULL,
|
FP_DEVICE_ERROR_DATA_FULL,
|
||||||
FP_DEVICE_ERROR_DATA_DUPLICATE,
|
FP_DEVICE_ERROR_DATA_DUPLICATE,
|
||||||
|
/* Leave some room to add more DATA related errors */
|
||||||
|
FP_DEVICE_ERROR_REMOVED = 0x100,
|
||||||
} FpDeviceError;
|
} FpDeviceError;
|
||||||
|
|
||||||
GQuark fp_device_retry_quark (void);
|
GQuark fp_device_retry_quark (void);
|
||||||
@@ -170,6 +175,7 @@ const gchar *fp_device_get_device_id (FpDevice *device);
|
|||||||
const gchar *fp_device_get_name (FpDevice *device);
|
const gchar *fp_device_get_name (FpDevice *device);
|
||||||
gboolean fp_device_is_open (FpDevice *device);
|
gboolean fp_device_is_open (FpDevice *device);
|
||||||
FpScanType fp_device_get_scan_type (FpDevice *device);
|
FpScanType fp_device_get_scan_type (FpDevice *device);
|
||||||
|
FpFingerStatusFlags fp_device_get_finger_status (FpDevice *device);
|
||||||
gint fp_device_get_nr_enroll_stages (FpDevice *device);
|
gint fp_device_get_nr_enroll_stages (FpDevice *device);
|
||||||
|
|
||||||
gboolean fp_device_supports_identify (FpDevice *device);
|
gboolean fp_device_supports_identify (FpDevice *device);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
FpiImageDeviceState state;
|
FpiImageDeviceState state;
|
||||||
gboolean active;
|
gboolean active;
|
||||||
gboolean cancelling;
|
|
||||||
|
|
||||||
gboolean finger_present;
|
gboolean finger_present;
|
||||||
|
|
||||||
@@ -42,4 +41,5 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
void fpi_image_device_activate (FpImageDevice *image_device);
|
void fpi_image_device_activate (FpImageDevice *image_device);
|
||||||
void fpi_image_device_deactivate (FpImageDevice *image_device);
|
void fpi_image_device_deactivate (FpImageDevice *image_device,
|
||||||
|
gboolean cancelling);
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ static void
|
|||||||
fp_image_device_cancel_action (FpDevice *device)
|
fp_image_device_cancel_action (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpImageDevice *self = FP_IMAGE_DEVICE (device);
|
FpImageDevice *self = FP_IMAGE_DEVICE (device);
|
||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
|
||||||
FpiDeviceAction action;
|
FpiDeviceAction action;
|
||||||
|
|
||||||
action = fpi_device_get_current_action (device);
|
action = fpi_device_get_current_action (device);
|
||||||
@@ -93,11 +92,7 @@ fp_image_device_cancel_action (FpDevice *device)
|
|||||||
action == FPI_DEVICE_ACTION_VERIFY ||
|
action == FPI_DEVICE_ACTION_VERIFY ||
|
||||||
action == FPI_DEVICE_ACTION_IDENTIFY ||
|
action == FPI_DEVICE_ACTION_IDENTIFY ||
|
||||||
action == FPI_DEVICE_ACTION_CAPTURE)
|
action == FPI_DEVICE_ACTION_CAPTURE)
|
||||||
{
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
priv->cancelling = TRUE;
|
|
||||||
fpi_image_device_deactivate (self);
|
|
||||||
priv->cancelling = FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -195,9 +190,7 @@ fp_image_device_constructed (GObject *obj)
|
|||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
|
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
|
||||||
|
|
||||||
/* Set default values. */
|
/* Set default threshold. */
|
||||||
fpi_device_set_nr_enroll_stages (FP_DEVICE (self), IMG_ENROLL_STAGES);
|
|
||||||
|
|
||||||
priv->bz3_threshold = BOZORTH3_DEFAULT_THRESHOLD;
|
priv->bz3_threshold = BOZORTH3_DEFAULT_THRESHOLD;
|
||||||
if (cls->bz3_threshold > 0)
|
if (cls->bz3_threshold > 0)
|
||||||
priv->bz3_threshold = cls->bz3_threshold;
|
priv->bz3_threshold = cls->bz3_threshold;
|
||||||
@@ -215,6 +208,9 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
|
|||||||
object_class->get_property = fp_image_device_get_property;
|
object_class->get_property = fp_image_device_get_property;
|
||||||
object_class->constructed = fp_image_device_constructed;
|
object_class->constructed = fp_image_device_constructed;
|
||||||
|
|
||||||
|
/* Set default enroll stage count. */
|
||||||
|
fp_device_class->nr_enroll_stages = IMG_ENROLL_STAGES;
|
||||||
|
|
||||||
fp_device_class->open = fp_image_device_open;
|
fp_device_class->open = fp_image_device_open;
|
||||||
fp_device_class->close = fp_image_device_close;
|
fp_device_class->close = fp_image_device_close;
|
||||||
fp_device_class->enroll = fp_image_device_start_capture_action;
|
fp_device_class->enroll = fp_image_device_start_capture_action;
|
||||||
@@ -224,6 +220,8 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
|
|||||||
|
|
||||||
fp_device_class->cancel = fp_image_device_cancel_action;
|
fp_device_class->cancel = fp_image_device_cancel_action;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (fp_device_class);
|
||||||
|
|
||||||
/* Default implementations */
|
/* Default implementations */
|
||||||
klass->activate = fp_image_device_default_activate;
|
klass->activate = fp_image_device_default_activate;
|
||||||
klass->deactivate = fp_image_device_default_deactivate;
|
klass->deactivate = fp_image_device_default_deactivate;
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
|||||||
gint map_w, map_h;
|
gint map_w, map_h;
|
||||||
gint bw, bh, bd;
|
gint bw, bh, bd;
|
||||||
gint r;
|
gint r;
|
||||||
g_autofree LFSPARMS *lfsparms;
|
g_autofree LFSPARMS *lfsparms = NULL;
|
||||||
|
|
||||||
/* Normalize the image first */
|
/* Normalize the image first */
|
||||||
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
||||||
|
|||||||
+10
-20
@@ -667,36 +667,25 @@ fp_print_serialize (FpPrint *print,
|
|||||||
for (i = 0; i < print->prints->len; i++)
|
for (i = 0; i < print->prints->len; i++)
|
||||||
{
|
{
|
||||||
struct xyt_struct *xyt = g_ptr_array_index (print->prints, i);
|
struct xyt_struct *xyt = g_ptr_array_index (print->prints, i);
|
||||||
gint j;
|
|
||||||
gint32 *col = g_new (gint32, xyt->nrows);
|
|
||||||
|
|
||||||
g_variant_builder_open (&nested, G_VARIANT_TYPE ("(aiaiai)"));
|
g_variant_builder_open (&nested, G_VARIANT_TYPE ("(aiaiai)"));
|
||||||
|
|
||||||
for (j = 0; j < xyt->nrows; j++)
|
|
||||||
col[j] = GINT32_TO_LE (xyt->xcol[j]);
|
|
||||||
g_variant_builder_add_value (&nested,
|
g_variant_builder_add_value (&nested,
|
||||||
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
||||||
col,
|
xyt->xcol,
|
||||||
xyt->nrows,
|
xyt->nrows,
|
||||||
sizeof (col[0])));
|
sizeof (xyt->xcol[0])));
|
||||||
|
|
||||||
for (j = 0; j < xyt->nrows; j++)
|
|
||||||
col[j] = GINT32_TO_LE (xyt->ycol[j]);
|
|
||||||
g_variant_builder_add_value (&nested,
|
g_variant_builder_add_value (&nested,
|
||||||
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
||||||
col,
|
xyt->ycol,
|
||||||
xyt->nrows,
|
xyt->nrows,
|
||||||
sizeof (col[0])));
|
sizeof (xyt->ycol[0])));
|
||||||
|
|
||||||
for (j = 0; j < xyt->nrows; j++)
|
|
||||||
col[j] = GINT32_TO_LE (xyt->thetacol[j]);
|
|
||||||
g_variant_builder_add_value (&nested,
|
g_variant_builder_add_value (&nested,
|
||||||
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
|
||||||
col,
|
xyt->thetacol,
|
||||||
xyt->nrows,
|
xyt->nrows,
|
||||||
sizeof (col[0])));
|
sizeof (xyt->thetacol[0])));
|
||||||
g_variant_builder_close (&nested);
|
g_variant_builder_close (&nested);
|
||||||
g_free (col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_variant_builder_close (&nested);
|
g_variant_builder_close (&nested);
|
||||||
@@ -819,6 +808,7 @@ fp_print_deserialize (const guchar *data,
|
|||||||
"device-id", device_id,
|
"device-id", device_id,
|
||||||
"device-stored", device_stored,
|
"device-stored", device_stored,
|
||||||
NULL);
|
NULL);
|
||||||
|
g_object_ref_sink (result);
|
||||||
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
||||||
for (i = 0; i < g_variant_n_children (prints); i++)
|
for (i = 0; i < g_variant_n_children (prints); i++)
|
||||||
{
|
{
|
||||||
@@ -868,6 +858,7 @@ fp_print_deserialize (const guchar *data,
|
|||||||
"device-stored", device_stored,
|
"device-stored", device_stored,
|
||||||
"fpi-data", fp_data,
|
"fpi-data", fp_data,
|
||||||
NULL);
|
NULL);
|
||||||
|
g_object_ref_sink (result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -886,8 +877,7 @@ fp_print_deserialize (const guchar *data,
|
|||||||
return g_steal_pointer (&result);
|
return g_steal_pointer (&result);
|
||||||
|
|
||||||
invalid_format:
|
invalid_format:
|
||||||
*error = g_error_new_literal (G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
||||||
G_IO_ERROR_INVALID_DATA,
|
|
||||||
"Data could not be parsed");
|
"Data could not be parsed");
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-5
@@ -66,12 +66,19 @@ typedef enum {
|
|||||||
FP_FINGER_LAST = FP_FINGER_RIGHT_LITTLE,
|
FP_FINGER_LAST = FP_FINGER_RIGHT_LITTLE,
|
||||||
} FpFinger;
|
} FpFinger;
|
||||||
|
|
||||||
FpPrint *fp_print_new (FpDevice *device);
|
/**
|
||||||
|
* FpFingerStatusFlags:
|
||||||
|
* @FP_FINGER_STATUS_NONE: Sensor has not the finger on it, nor requires it
|
||||||
|
* @FP_FINGER_STATUS_NEEDED: Sensor waits for the finger
|
||||||
|
* @FP_FINGER_STATUS_PRESENT: Sensor has the finger on it
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
FP_FINGER_STATUS_NONE = 0,
|
||||||
|
FP_FINGER_STATUS_NEEDED = 1 << 0,
|
||||||
|
FP_FINGER_STATUS_PRESENT = 1 << 1,
|
||||||
|
} FpFingerStatusFlags;
|
||||||
|
|
||||||
FpPrint *fp_print_new_from_data (guchar *data,
|
FpPrint *fp_print_new (FpDevice *device);
|
||||||
gsize length);
|
|
||||||
gboolean fp_print_to_data (guchar **data,
|
|
||||||
gsize length);
|
|
||||||
|
|
||||||
const gchar *fp_print_get_driver (FpPrint *print);
|
const gchar *fp_print_get_driver (FpPrint *print);
|
||||||
const gchar *fp_print_get_device_id (FpPrint *print);
|
const gchar *fp_print_get_device_id (FpPrint *print);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fprint.h>
|
#include "fp-image.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_frame:
|
* fpi_frame:
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#if !GLIB_CHECK_VERSION (2, 57, 0)
|
#if !GLIB_CHECK_VERSION (2, 57, 0)
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GTypeClass, g_type_class_unref);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GTypeClass, g_type_class_unref);
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GFlagsClass, g_type_class_unref);
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref);
|
||||||
#else
|
#else
|
||||||
/* Re-define G_SOURCE_FUNC as we are technically not allowed to use it with
|
/* Re-define G_SOURCE_FUNC as we are technically not allowed to use it with
|
||||||
|
|||||||
+244
-16
@@ -46,6 +46,40 @@ fp_device_get_instance_private (FpDevice *self)
|
|||||||
g_type_class_get_instance_private_offset (dev_class));
|
g_type_class_get_instance_private_offset (dev_class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_class_auto_initialize_features:
|
||||||
|
*
|
||||||
|
* Initializes the #FpDeviceClass @features flags checking what device vfuncs
|
||||||
|
* are implemented.
|
||||||
|
* Drivers should call this at the end of the class initialization.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_device_class_auto_initialize_features (FpDeviceClass *device_class)
|
||||||
|
{
|
||||||
|
g_return_if_fail (FP_IS_DEVICE_CLASS (device_class));
|
||||||
|
|
||||||
|
if (device_class->capture)
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_CAPTURE;
|
||||||
|
|
||||||
|
if (device_class->verify)
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_VERIFY;
|
||||||
|
|
||||||
|
if (device_class->identify)
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_IDENTIFY;
|
||||||
|
|
||||||
|
if (device_class->list)
|
||||||
|
{
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_STORAGE;
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_STORAGE_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_class->delete)
|
||||||
|
{
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_STORAGE;
|
||||||
|
device_class->features |= FPI_DEVICE_FEATURE_STORAGE_DELETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_retry_new:
|
* fpi_device_retry_new:
|
||||||
* @error: The #FpDeviceRetry error value describing the issue
|
* @error: The #FpDeviceRetry error value describing the issue
|
||||||
@@ -139,6 +173,10 @@ fpi_device_error_new (FpDeviceError error)
|
|||||||
msg = "This finger has already enrolled, please try a different finger";
|
msg = "This finger has already enrolled, please try a different finger";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FP_DEVICE_ERROR_REMOVED:
|
||||||
|
msg = "This device has been removed from the system.";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warning ("Unsupported error, returning general error instead!");
|
g_warning ("Unsupported error, returning general error instead!");
|
||||||
error = FP_DEVICE_ERROR_GENERAL;
|
error = FP_DEVICE_ERROR_GENERAL;
|
||||||
@@ -212,6 +250,7 @@ fpi_device_set_nr_enroll_stages (FpDevice *device,
|
|||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
g_return_if_fail (enroll_stages > 0);
|
||||||
|
|
||||||
priv->nr_enroll_stages = enroll_stages;
|
priv->nr_enroll_stages = enroll_stages;
|
||||||
g_object_notify (G_OBJECT (device), "nr-enroll-stages");
|
g_object_notify (G_OBJECT (device), "nr-enroll-stages");
|
||||||
@@ -330,6 +369,38 @@ fpi_device_get_usb_device (FpDevice *device)
|
|||||||
return priv->usb_device;
|
return priv->usb_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_get_udev_data:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @subtype: Which subtype to get information about
|
||||||
|
*
|
||||||
|
* Get a subtype-specific hardware resource for this #FpDevice. Only permissible to call if the
|
||||||
|
* #FpDevice is of type %FP_DEVICE_TYPE_UDEV.
|
||||||
|
*
|
||||||
|
* Returns: Depends on @subtype; for SPIDEV/HIDRAW returns a path to the relevant device.
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
fpi_device_get_udev_data (FpDevice *device, FpiDeviceUdevSubtypeFlags subtype)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
|
g_return_val_if_fail (FP_IS_DEVICE (device), NULL);
|
||||||
|
g_return_val_if_fail (priv->type == FP_DEVICE_TYPE_UDEV, NULL);
|
||||||
|
|
||||||
|
switch (subtype)
|
||||||
|
{
|
||||||
|
case FPI_DEVICE_UDEV_SUBTYPE_HIDRAW:
|
||||||
|
return priv->udev_data.hidraw_path;
|
||||||
|
|
||||||
|
case FPI_DEVICE_UDEV_SUBTYPE_SPIDEV:
|
||||||
|
return priv->udev_data.spidev_path;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_return_val_if_reached (NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_get_virtual_env:
|
* fpi_device_get_virtual_env:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
@@ -576,6 +647,49 @@ fpi_device_get_cancellable (FpDevice *device)
|
|||||||
return g_task_get_cancellable (priv->current_task);
|
return g_task_get_cancellable (priv->current_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_removed_on_task_completed (FpDevice *device)
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (device, "removed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_remove:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
*
|
||||||
|
* Called to signal to the #FpDevice that it has been unplugged (physically
|
||||||
|
* removed from the system).
|
||||||
|
*
|
||||||
|
* For USB devices, this API is called automatically by #FpContext.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_device_remove (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
g_return_if_fail (!priv->is_removed);
|
||||||
|
|
||||||
|
priv->is_removed = TRUE;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (device), "removed");
|
||||||
|
|
||||||
|
/* If there is a pending action, we wait for it to fail, otherwise we
|
||||||
|
* immediately emit the "removed" signal. */
|
||||||
|
if (priv->current_task)
|
||||||
|
{
|
||||||
|
g_signal_connect_object (priv->current_task,
|
||||||
|
"notify::completed",
|
||||||
|
(GCallback) emit_removed_on_task_completed,
|
||||||
|
device,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_signal_emit_by_name (device, "removed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_action_error:
|
* fpi_device_action_error:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
@@ -691,6 +805,7 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
|||||||
FpDeviceTaskReturnData *data = user_data;
|
FpDeviceTaskReturnData *data = user_data;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (data->device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (data->device);
|
||||||
g_autofree char *action_str = NULL;
|
g_autofree char *action_str = NULL;
|
||||||
|
FpiDeviceAction action;
|
||||||
|
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
|
|
||||||
@@ -699,9 +814,39 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
|||||||
g_debug ("Completing action %s in idle!", action_str);
|
g_debug ("Completing action %s in idle!", action_str);
|
||||||
|
|
||||||
task = g_steal_pointer (&priv->current_task);
|
task = g_steal_pointer (&priv->current_task);
|
||||||
|
action = priv->current_action;
|
||||||
priv->current_action = FPI_DEVICE_ACTION_NONE;
|
priv->current_action = FPI_DEVICE_ACTION_NONE;
|
||||||
priv->current_task_idle_return_source = NULL;
|
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 &&
|
||||||
|
((action != FPI_DEVICE_ACTION_OPEN) ||
|
||||||
|
(action == FPI_DEVICE_ACTION_OPEN && data->type == FP_DEVICE_TASK_RETURN_ERROR)))
|
||||||
|
{
|
||||||
|
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 necessary. */
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (data->type)
|
switch (data->type)
|
||||||
{
|
{
|
||||||
case FP_DEVICE_TASK_RETURN_INT:
|
case FP_DEVICE_TASK_RETURN_INT:
|
||||||
@@ -713,16 +858,17 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_OBJECT:
|
case FP_DEVICE_TASK_RETURN_OBJECT:
|
||||||
g_task_return_pointer (task, data->result, g_object_unref);
|
g_task_return_pointer (task, g_steal_pointer (&data->result),
|
||||||
|
g_object_unref);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
||||||
g_task_return_pointer (task, data->result,
|
g_task_return_pointer (task, g_steal_pointer (&data->result),
|
||||||
(GDestroyNotify) g_ptr_array_unref);
|
(GDestroyNotify) g_ptr_array_unref);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_ERROR:
|
case FP_DEVICE_TASK_RETURN_ERROR:
|
||||||
g_task_return_error (task, data->result);
|
g_task_return_error (task, g_steal_pointer (&data->result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -735,6 +881,30 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
fpi_device_task_return_data_free (FpDeviceTaskReturnData *data)
|
fpi_device_task_return_data_free (FpDeviceTaskReturnData *data)
|
||||||
{
|
{
|
||||||
|
if (data->result)
|
||||||
|
{
|
||||||
|
switch (data->type)
|
||||||
|
{
|
||||||
|
case FP_DEVICE_TASK_RETURN_INT:
|
||||||
|
case FP_DEVICE_TASK_RETURN_BOOL:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FP_DEVICE_TASK_RETURN_OBJECT:
|
||||||
|
g_clear_object ((GObject **) &data->result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
||||||
|
g_clear_pointer ((GPtrArray **) &data->result, g_ptr_array_unref);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FP_DEVICE_TASK_RETURN_ERROR:
|
||||||
|
g_clear_error ((GError **) &data->result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
g_object_unref (data->device);
|
g_object_unref (data->device);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
@@ -787,6 +957,7 @@ fpi_device_probe_complete (FpDevice *device,
|
|||||||
g_debug ("Device reported probe completion");
|
g_debug ("Device reported probe completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@@ -829,12 +1000,7 @@ fpi_device_open_complete (FpDevice *device, GError *error)
|
|||||||
g_debug ("Device reported open completion");
|
g_debug ("Device reported open completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
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)
|
if (!error)
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||||
@@ -862,6 +1028,7 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
|||||||
g_debug ("Device reported close completion");
|
g_debug ("Device reported close completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
switch (priv->type)
|
switch (priv->type)
|
||||||
{
|
{
|
||||||
@@ -876,6 +1043,7 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TYPE_VIRTUAL:
|
case FP_DEVICE_TYPE_VIRTUAL:
|
||||||
|
case FP_DEVICE_TYPE_UDEV:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -886,16 +1054,10 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
|
||||||
priv->is_open = FALSE;
|
|
||||||
g_object_notify (G_OBJECT (device), "open");
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||||
GUINT_TO_POINTER (TRUE));
|
GUINT_TO_POINTER (TRUE));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -918,12 +1080,14 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
|||||||
g_debug ("Device reported enroll completion");
|
g_debug ("Device reported enroll completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
if (FP_IS_PRINT (print))
|
if (FP_IS_PRINT (print))
|
||||||
{
|
{
|
||||||
FpiPrintType print_type;
|
FpiPrintType print_type;
|
||||||
|
g_autofree char *finger_str = NULL;
|
||||||
|
|
||||||
g_object_get (print, "fpi-type", &print_type, NULL);
|
g_object_get (print, "fpi-type", &print_type, NULL);
|
||||||
if (print_type == FPI_PRINT_UNDEFINED)
|
if (print_type == FPI_PRINT_UNDEFINED)
|
||||||
@@ -937,6 +1101,9 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finger_str = g_enum_to_string (FP_TYPE_FINGER, fp_print_get_finger (print));
|
||||||
|
g_debug ("Print for finger %s enrolled", finger_str);
|
||||||
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -985,6 +1152,7 @@ fpi_device_verify_complete (FpDevice *device,
|
|||||||
data = g_task_get_task_data (priv->current_task);
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@@ -1044,6 +1212,7 @@ fpi_device_identify_complete (FpDevice *device,
|
|||||||
data = g_task_get_task_data (priv->current_task);
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@@ -1059,7 +1228,7 @@ fpi_device_identify_complete (FpDevice *device,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT, GINT_TO_POINTER (TRUE));
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL, GUINT_TO_POINTER (TRUE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1100,6 +1269,7 @@ fpi_device_capture_complete (FpDevice *device,
|
|||||||
g_debug ("Device reported capture completion");
|
g_debug ("Device reported capture completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@@ -1145,6 +1315,7 @@ fpi_device_delete_complete (FpDevice *device,
|
|||||||
g_debug ("Device reported deletion completion");
|
g_debug ("Device reported deletion completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||||
@@ -1179,6 +1350,7 @@ fpi_device_list_complete (FpDevice *device,
|
|||||||
g_debug ("Device reported listing completion");
|
g_debug ("Device reported listing completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
if (prints && error)
|
if (prints && error)
|
||||||
{
|
{
|
||||||
@@ -1394,3 +1566,59 @@ fpi_device_identify_report (FpDevice *device,
|
|||||||
if (call_cb && data->match_cb)
|
if (call_cb && data->match_cb)
|
||||||
data->match_cb (device, data->match, data->print, data->match_data, data->error);
|
data->match_cb (device, data->match, data->print, data->match_data, data->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_report_finger_status:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @finger_status: The current #FpFingerStatusFlags to report
|
||||||
|
*
|
||||||
|
* Report the finger status for the @device.
|
||||||
|
* This can be used by UI to give a feedback
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if changed
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
fpi_device_report_finger_status (FpDevice *device,
|
||||||
|
FpFingerStatusFlags finger_status)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
g_autofree char *status_string = NULL;
|
||||||
|
|
||||||
|
if (priv->finger_status == finger_status)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
status_string = g_flags_to_string (FP_TYPE_FINGER_STATUS_FLAGS, finger_status);
|
||||||
|
fp_dbg ("Device reported finger status change: %s", status_string);
|
||||||
|
|
||||||
|
priv->finger_status = finger_status;
|
||||||
|
g_object_notify (G_OBJECT (device), "finger-status");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_report_finger_status_changes:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @added_status: The #FpFingerStatusFlags to add
|
||||||
|
* @removed_status: The #FpFingerStatusFlags to remove
|
||||||
|
*
|
||||||
|
* Report the finger status for the @device adding the @added_status flags
|
||||||
|
* and removing the @removed_status flags.
|
||||||
|
*
|
||||||
|
* This can be used by UI to give a feedback
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if changed
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
fpi_device_report_finger_status_changes (FpDevice *device,
|
||||||
|
FpFingerStatusFlags added_status,
|
||||||
|
FpFingerStatusFlags removed_status)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpFingerStatusFlags finger_status = priv->finger_status;
|
||||||
|
|
||||||
|
finger_status |= added_status;
|
||||||
|
finger_status &= ~removed_status;
|
||||||
|
|
||||||
|
return fpi_device_report_finger_status (device, finger_status);
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,18 @@
|
|||||||
#include "fp-image.h"
|
#include "fp-image.h"
|
||||||
#include "fpi-print.h"
|
#include "fpi-print.h"
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpiDeviceUdevSubtype:
|
||||||
|
* @FPI_DEVICE_UDEV_SUBTYPE_SPIDEV: The device requires an spidev node
|
||||||
|
* @FPI_DEVICE_UDEV_SUBTYPE_HIDRAW: The device requires a hidraw node
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
FPI_DEVICE_UDEV_SUBTYPE_SPIDEV = 1 << 0,
|
||||||
|
FPI_DEVICE_UDEV_SUBTYPE_HIDRAW = 1 << 1,
|
||||||
|
} FpiDeviceUdevSubtypeFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpIdEntry:
|
* FpIdEntry:
|
||||||
*
|
*
|
||||||
@@ -43,10 +55,44 @@ struct _FpIdEntry
|
|||||||
guint vid;
|
guint vid;
|
||||||
};
|
};
|
||||||
const gchar *virtual_envvar;
|
const gchar *virtual_envvar;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FpiDeviceUdevSubtypeFlags udev_types;
|
||||||
|
const gchar *spi_acpi_id;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
guint pid;
|
||||||
|
guint vid;
|
||||||
|
} hid_id;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
guint64 driver_data;
|
guint64 driver_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpiDeviceFeature:
|
||||||
|
* @FPI_DEVICE_FEATURE_NONE: Device does not support any feature
|
||||||
|
* @FPI_DEVICE_FEATURE_CAPTURE: Supports image capture
|
||||||
|
* @FPI_DEVICE_FEATURE_IDENTIFY: Supports finger identification
|
||||||
|
* @FPI_DEVICE_FEATURE_VERIFY: Supports finger verification
|
||||||
|
* @FPI_DEVICE_FEATURE_STORAGE: Device has a persistent storage
|
||||||
|
* @FPI_DEVICE_FEATURE_STORAGE_LIST: Supports listing the storage templates
|
||||||
|
* @FPI_DEVICE_FEATURE_STORAGE_DELETE: Supports deleting stored templates
|
||||||
|
* @FPI_DEVICE_FEATURE_STORAGE_CLEAR: Supports clearing the whole storage
|
||||||
|
* @FPI_DEVICE_FEATURE_DUPLICATES_CHECK: Natively supports duplicates detection
|
||||||
|
*/
|
||||||
|
typedef enum /*< flags >*/ {
|
||||||
|
FPI_DEVICE_FEATURE_NONE = 0,
|
||||||
|
FPI_DEVICE_FEATURE_CAPTURE = 1 << 0,
|
||||||
|
FPI_DEVICE_FEATURE_IDENTIFY = 1 << 1,
|
||||||
|
FPI_DEVICE_FEATURE_VERIFY = 1 << 2,
|
||||||
|
FPI_DEVICE_FEATURE_STORAGE = 1 << 3,
|
||||||
|
FPI_DEVICE_FEATURE_STORAGE_LIST = 1 << 4,
|
||||||
|
FPI_DEVICE_FEATURE_STORAGE_DELETE = 1 << 5,
|
||||||
|
FPI_DEVICE_FEATURE_STORAGE_CLEAR = 1 << 6,
|
||||||
|
FPI_DEVICE_FEATURE_DUPLICATES_CHECK = 1 << 7,
|
||||||
|
} FpiDeviceFeature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpDeviceClass:
|
* FpDeviceClass:
|
||||||
* @id: ID string for the driver. Should be a valid C identifier and should
|
* @id: ID string for the driver. Should be a valid C identifier and should
|
||||||
@@ -54,6 +100,8 @@ struct _FpIdEntry
|
|||||||
* @full_name: Human readable description of the driver
|
* @full_name: Human readable description of the driver
|
||||||
* @type: The type of driver
|
* @type: The type of driver
|
||||||
* @id_table: The table of IDs to bind the driver to
|
* @id_table: The table of IDs to bind the driver to
|
||||||
|
* @features: The features the device supports, it can be initialized using
|
||||||
|
* fpi_device_class_auto_initialize_features() on @class_init.
|
||||||
* @nr_enroll_stages: The number of enroll stages supported devices need; use
|
* @nr_enroll_stages: The number of enroll stages supported devices need; use
|
||||||
* fpi_device_set_nr_enroll_stages() from @probe if this is dynamic.
|
* fpi_device_set_nr_enroll_stages() from @probe if this is dynamic.
|
||||||
* @scan_type: The scan type of supported devices; use
|
* @scan_type: The scan type of supported devices; use
|
||||||
@@ -111,6 +159,7 @@ struct _FpDeviceClass
|
|||||||
const gchar *full_name;
|
const gchar *full_name;
|
||||||
FpDeviceType type;
|
FpDeviceType type;
|
||||||
const FpIdEntry *id_table;
|
const FpIdEntry *id_table;
|
||||||
|
FpiDeviceFeature features;
|
||||||
|
|
||||||
/* Defaults for device properties */
|
/* Defaults for device properties */
|
||||||
gint nr_enroll_stages;
|
gint nr_enroll_stages;
|
||||||
@@ -131,6 +180,8 @@ struct _FpDeviceClass
|
|||||||
void (*cancel) (FpDevice *device);
|
void (*cancel) (FpDevice *device);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void fpi_device_class_auto_initialize_features (FpDeviceClass *device_class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpTimeoutFunc:
|
* FpTimeoutFunc:
|
||||||
* @device: The #FpDevice passed to fpi_device_add_timeout()
|
* @device: The #FpDevice passed to fpi_device_add_timeout()
|
||||||
@@ -171,6 +222,8 @@ typedef enum {
|
|||||||
|
|
||||||
GUsbDevice *fpi_device_get_usb_device (FpDevice *device);
|
GUsbDevice *fpi_device_get_usb_device (FpDevice *device);
|
||||||
const gchar *fpi_device_get_virtual_env (FpDevice *device);
|
const gchar *fpi_device_get_virtual_env (FpDevice *device);
|
||||||
|
gpointer fpi_device_get_udev_data (FpDevice *device,
|
||||||
|
FpiDeviceUdevSubtypeFlags subtype);
|
||||||
//const gchar *fpi_device_get_spi_dev (FpDevice *device);
|
//const gchar *fpi_device_get_spi_dev (FpDevice *device);
|
||||||
|
|
||||||
|
|
||||||
@@ -202,6 +255,7 @@ void fpi_device_get_delete_data (FpDevice *device,
|
|||||||
FpPrint **print);
|
FpPrint **print);
|
||||||
GCancellable *fpi_device_get_cancellable (FpDevice *device);
|
GCancellable *fpi_device_get_cancellable (FpDevice *device);
|
||||||
|
|
||||||
|
void fpi_device_remove (FpDevice *device);
|
||||||
|
|
||||||
GSource * fpi_device_add_timeout (FpDevice *device,
|
GSource * fpi_device_add_timeout (FpDevice *device,
|
||||||
gint interval,
|
gint interval,
|
||||||
@@ -255,4 +309,10 @@ void fpi_device_identify_report (FpDevice *device,
|
|||||||
FpPrint *print,
|
FpPrint *print,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
|
||||||
|
gboolean fpi_device_report_finger_status (FpDevice *device,
|
||||||
|
FpFingerStatusFlags finger_status);
|
||||||
|
gboolean fpi_device_report_finger_status_changes (FpDevice *device,
|
||||||
|
FpFingerStatusFlags added_status,
|
||||||
|
FpFingerStatusFlags removed_status);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ fp_image_device_get_instance_private (FpImageDevice *self)
|
|||||||
g_type_class_get_instance_private_offset (img_class));
|
g_type_class_get_instance_private_offset (img_class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fp_image_device_change_state (FpImageDevice *self,
|
||||||
|
FpiImageDeviceState state);
|
||||||
|
|
||||||
/* Private shared functions */
|
/* Private shared functions */
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -51,59 +54,105 @@ fpi_image_device_activate (FpImageDevice *self)
|
|||||||
|
|
||||||
g_assert (!priv->active);
|
g_assert (!priv->active);
|
||||||
|
|
||||||
/* We don't have a neutral ACTIVE state, but we always will
|
|
||||||
* go into WAIT_FINGER_ON afterwards. */
|
|
||||||
priv->state = FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
|
|
||||||
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
|
||||||
|
|
||||||
fp_dbg ("Activating image device");
|
fp_dbg ("Activating image device");
|
||||||
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_ACTIVATING);
|
||||||
cls->activate (self);
|
cls->activate (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fpi_image_device_deactivate (FpImageDevice *self)
|
fpi_image_device_deactivate (FpImageDevice *self, gboolean cancelling)
|
||||||
{
|
{
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (device);
|
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (device);
|
||||||
|
|
||||||
if (!priv->active || priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
if (!priv->active || priv->state == FPI_IMAGE_DEVICE_STATE_DEACTIVATING)
|
||||||
{
|
{
|
||||||
/* XXX: We currently deactivate both from minutiae scan result
|
/* XXX: We currently deactivate both from minutiae scan result
|
||||||
* and finger off report. */
|
* and finger off report. */
|
||||||
fp_dbg ("Already deactivated, ignoring request.");
|
fp_dbg ("Already deactivated, ignoring request.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!priv->cancelling && priv->state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
if (!cancelling && priv->state != FPI_IMAGE_DEVICE_STATE_IDLE)
|
||||||
g_warning ("Deactivating image device while waiting for finger, this should not happen.");
|
g_warning ("Deactivating image device while it is not idle, this should not happen.");
|
||||||
|
|
||||||
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
|
||||||
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
|
||||||
|
|
||||||
fp_dbg ("Deactivating image device");
|
fp_dbg ("Deactivating image device");
|
||||||
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_DEACTIVATING);
|
||||||
cls->deactivate (self);
|
cls->deactivate (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Static helper functions */
|
/* Static helper functions */
|
||||||
|
|
||||||
|
/* This should not be called directly to activate/deactivate the device! */
|
||||||
static void
|
static void
|
||||||
fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
|
fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
|
||||||
{
|
{
|
||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
g_autofree char *prev_state_str = NULL;
|
g_autofree char *prev_state_str = NULL;
|
||||||
g_autofree char *state_str = NULL;
|
g_autofree char *state_str = NULL;
|
||||||
|
gboolean transition_is_valid = FALSE;
|
||||||
|
gint i;
|
||||||
|
|
||||||
/* Cannot change to inactive using this function. */
|
struct
|
||||||
g_assert (state != FPI_IMAGE_DEVICE_STATE_INACTIVE);
|
{
|
||||||
|
FpiImageDeviceState from;
|
||||||
|
FpiImageDeviceState to;
|
||||||
|
} valid_transitions[] = {
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_INACTIVE, FPI_IMAGE_DEVICE_STATE_ACTIVATING },
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_ACTIVATING, FPI_IMAGE_DEVICE_STATE_IDLE },
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_ACTIVATING, FPI_IMAGE_DEVICE_STATE_INACTIVE },
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_IDLE, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON },
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_IDLE, FPI_IMAGE_DEVICE_STATE_CAPTURE }, /* raw mode -- currently not supported */
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_IDLE, FPI_IMAGE_DEVICE_STATE_DEACTIVATING },
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON, FPI_IMAGE_DEVICE_STATE_CAPTURE },
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON, FPI_IMAGE_DEVICE_STATE_DEACTIVATING }, /* cancellation */
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_CAPTURE, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF },
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_CAPTURE, FPI_IMAGE_DEVICE_STATE_IDLE }, /* raw mode -- currently not supported */
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_CAPTURE, FPI_IMAGE_DEVICE_STATE_DEACTIVATING }, /* cancellation */
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF, FPI_IMAGE_DEVICE_STATE_IDLE },
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF, FPI_IMAGE_DEVICE_STATE_DEACTIVATING }, /* cancellation */
|
||||||
|
|
||||||
|
{ FPI_IMAGE_DEVICE_STATE_DEACTIVATING, FPI_IMAGE_DEVICE_STATE_INACTIVE },
|
||||||
|
};
|
||||||
|
|
||||||
prev_state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, priv->state);
|
prev_state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, priv->state);
|
||||||
state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, state);
|
state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, state);
|
||||||
fp_dbg ("Image device internal state change from %s to %s",
|
fp_dbg ("Image device internal state change from %s to %s",
|
||||||
prev_state_str, state_str);
|
prev_state_str, state_str);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (valid_transitions); i++)
|
||||||
|
{
|
||||||
|
if (valid_transitions[i].from == priv->state && valid_transitions[i].to == state)
|
||||||
|
{
|
||||||
|
transition_is_valid = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!transition_is_valid)
|
||||||
|
g_warning ("Internal state machine issue: transition from %s to %s should not happen!",
|
||||||
|
prev_state_str, state_str);
|
||||||
|
|
||||||
priv->state = state;
|
priv->state = state;
|
||||||
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
||||||
g_signal_emit_by_name (self, "fpi-image-device-state-changed", priv->state);
|
g_signal_emit_by_name (self, "fpi-image-device-state-changed", priv->state);
|
||||||
|
|
||||||
|
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
||||||
|
{
|
||||||
|
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||||
|
FP_FINGER_STATUS_NEEDED,
|
||||||
|
FP_FINGER_STATUS_NONE);
|
||||||
|
}
|
||||||
|
else if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
|
||||||
|
{
|
||||||
|
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||||
|
FP_FINGER_STATUS_NONE,
|
||||||
|
FP_FINGER_STATUS_NEEDED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -132,7 +181,7 @@ fp_image_device_maybe_complete_action (FpImageDevice *self, GError *error)
|
|||||||
if (priv->action_error && !(priv->action_error->domain == FP_DEVICE_RETRY))
|
if (priv->action_error && !(priv->action_error->domain == FP_DEVICE_RETRY))
|
||||||
{
|
{
|
||||||
g_warning ("Will complete with first error, new error was: %s", error->message);
|
g_warning ("Will complete with first error, new error was: %s", error->message);
|
||||||
g_free (error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -204,7 +253,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
|||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
{
|
{
|
||||||
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +285,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
|||||||
{
|
{
|
||||||
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
||||||
/* We might not yet be deactivating, if we are enrolling. */
|
/* We might not yet be deactivating, if we are enrolling. */
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,10 +306,10 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
|||||||
g_steal_pointer (&print), error);
|
g_steal_pointer (&print), error);
|
||||||
|
|
||||||
/* Start another scan or deactivate. */
|
/* Start another scan or deactivate. */
|
||||||
if (priv->enroll_stage == IMG_ENROLL_STAGES)
|
if (priv->enroll_stage == fp_device_get_nr_enroll_stages (device))
|
||||||
{
|
{
|
||||||
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
fp_image_device_maybe_complete_action (self, g_steal_pointer (&error));
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -359,6 +408,19 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
|
|||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
FpiDeviceAction action;
|
FpiDeviceAction action;
|
||||||
|
|
||||||
|
if (present)
|
||||||
|
{
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_PRESENT,
|
||||||
|
FP_FINGER_STATUS_NONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_report_finger_status_changes (device,
|
||||||
|
FP_FINGER_STATUS_NONE,
|
||||||
|
FP_FINGER_STATUS_PRESENT);
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
||||||
{
|
{
|
||||||
/* Do we really want to always ignore such reports? We could
|
/* Do we really want to always ignore such reports? We could
|
||||||
@@ -390,8 +452,10 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
|
|||||||
* In the enroll case, the decision can only be made after minutiae
|
* In the enroll case, the decision can only be made after minutiae
|
||||||
* detection has finished.
|
* detection has finished.
|
||||||
*/
|
*/
|
||||||
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_IDLE);
|
||||||
|
|
||||||
if (action != FPI_DEVICE_ACTION_ENROLL)
|
if (action != FPI_DEVICE_ACTION_ENROLL)
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self, FALSE);
|
||||||
else
|
else
|
||||||
fp_image_device_enroll_maybe_await_finger_on (self);
|
fp_image_device_enroll_maybe_await_finger_on (self);
|
||||||
}
|
}
|
||||||
@@ -437,6 +501,7 @@ fpi_image_device_image_captured (FpImageDevice *self, FpImage *image)
|
|||||||
fpi_image_device_minutiae_detected,
|
fpi_image_device_minutiae_detected,
|
||||||
self);
|
self);
|
||||||
|
|
||||||
|
/* XXX: This is wrong if we add support for raw capture mode. */
|
||||||
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,27 +544,21 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
|
|||||||
{
|
{
|
||||||
fpi_device_verify_report (FP_DEVICE (self), FPI_MATCH_ERROR, NULL, error);
|
fpi_device_verify_report (FP_DEVICE (self), FPI_MATCH_ERROR, NULL, error);
|
||||||
fp_image_device_maybe_complete_action (self, NULL);
|
fp_image_device_maybe_complete_action (self, NULL);
|
||||||
priv->cancelling = TRUE;
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
fpi_image_device_deactivate (self);
|
|
||||||
priv->cancelling = FALSE;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
|
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
|
||||||
{
|
{
|
||||||
fpi_device_identify_report (FP_DEVICE (self), NULL, NULL, error);
|
fpi_device_identify_report (FP_DEVICE (self), NULL, NULL, error);
|
||||||
fp_image_device_maybe_complete_action (self, NULL);
|
fp_image_device_maybe_complete_action (self, NULL);
|
||||||
priv->cancelling = TRUE;
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
fpi_image_device_deactivate (self);
|
|
||||||
priv->cancelling = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The capture case where there is no early reporting. */
|
/* The capture case where there is no early reporting. */
|
||||||
g_debug ("Abort current operation due to retry (no early-reporting)");
|
g_debug ("Abort current operation due to retry (no early-reporting)");
|
||||||
fp_image_device_maybe_complete_action (self, error);
|
fp_image_device_maybe_complete_action (self, error);
|
||||||
priv->cancelling = TRUE;
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
fpi_image_device_deactivate (self);
|
|
||||||
priv->cancelling = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,10 +617,8 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
|||||||
if (error->domain == FP_DEVICE_RETRY)
|
if (error->domain == FP_DEVICE_RETRY)
|
||||||
g_warning ("Driver should report retries using fpi_image_device_retry_scan!");
|
g_warning ("Driver should report retries using fpi_image_device_retry_scan!");
|
||||||
|
|
||||||
priv->cancelling = TRUE;
|
|
||||||
fp_image_device_maybe_complete_action (self, error);
|
fp_image_device_maybe_complete_action (self, error);
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self, TRUE);
|
||||||
priv->cancelling = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -580,6 +637,7 @@ fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
|
|||||||
action = fpi_device_get_current_action (FP_DEVICE (self));
|
action = fpi_device_get_current_action (FP_DEVICE (self));
|
||||||
|
|
||||||
g_return_if_fail (priv->active == FALSE);
|
g_return_if_fail (priv->active == FALSE);
|
||||||
|
g_return_if_fail (priv->state == FPI_IMAGE_DEVICE_STATE_ACTIVATING);
|
||||||
g_return_if_fail (action == FPI_DEVICE_ACTION_ENROLL ||
|
g_return_if_fail (action == FPI_DEVICE_ACTION_ENROLL ||
|
||||||
action == FPI_DEVICE_ACTION_VERIFY ||
|
action == FPI_DEVICE_ACTION_VERIFY ||
|
||||||
action == FPI_DEVICE_ACTION_IDENTIFY ||
|
action == FPI_DEVICE_ACTION_IDENTIFY ||
|
||||||
@@ -598,6 +656,7 @@ fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
|
|||||||
|
|
||||||
/* We always want to capture at this point, move to AWAIT_FINGER
|
/* We always want to capture at this point, move to AWAIT_FINGER
|
||||||
* state. */
|
* state. */
|
||||||
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_IDLE);
|
||||||
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +673,7 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
|
|||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
|
|
||||||
g_return_if_fail (priv->active == TRUE);
|
g_return_if_fail (priv->active == TRUE);
|
||||||
g_return_if_fail (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE);
|
g_return_if_fail (priv->state == FPI_IMAGE_DEVICE_STATE_DEACTIVATING);
|
||||||
|
|
||||||
g_debug ("Image device deactivation completed");
|
g_debug ("Image device deactivation completed");
|
||||||
|
|
||||||
@@ -623,6 +682,8 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
|
|||||||
/* Assume finger was removed. */
|
/* Assume finger was removed. */
|
||||||
priv->finger_present = FALSE;
|
priv->finger_present = FALSE;
|
||||||
|
|
||||||
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_INACTIVE);
|
||||||
|
|
||||||
fp_image_device_maybe_complete_action (self, error);
|
fp_image_device_maybe_complete_action (self, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,6 +710,8 @@ fpi_image_device_open_complete (FpImageDevice *self, GError *error)
|
|||||||
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
|
||||||
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
|
||||||
|
|
||||||
|
fpi_device_report_finger_status (FP_DEVICE (self), FP_FINGER_STATUS_NONE);
|
||||||
|
|
||||||
fpi_device_open_complete (FP_DEVICE (self), error);
|
fpi_device_open_complete (FP_DEVICE (self), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
/**
|
/**
|
||||||
* FpiImageDeviceState:
|
* FpiImageDeviceState:
|
||||||
* @FPI_IMAGE_DEVICE_STATE_INACTIVE: inactive
|
* @FPI_IMAGE_DEVICE_STATE_INACTIVE: inactive
|
||||||
|
* @FPI_IMAGE_DEVICE_STATE_ACTIVATING: State during activate callback
|
||||||
|
* @FPI_IMAGE_DEVICE_STATE_IDLE: Activated but idle
|
||||||
|
* @FPI_IMAGE_DEVICE_STATE_DEACTIVATING: State during deactivate callback
|
||||||
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
|
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
|
||||||
* @FPI_IMAGE_DEVICE_STATE_CAPTURE: capturing an image
|
* @FPI_IMAGE_DEVICE_STATE_CAPTURE: capturing an image
|
||||||
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
|
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
|
||||||
@@ -35,9 +38,33 @@
|
|||||||
* The driver needs to call fpi_image_device_report_finger_status() to move
|
* The driver needs to call fpi_image_device_report_finger_status() to move
|
||||||
* between the different states. Note that the capture state might be entered
|
* between the different states. Note that the capture state might be entered
|
||||||
* unconditionally if the device supports raw capturing.
|
* unconditionally if the device supports raw capturing.
|
||||||
|
*
|
||||||
|
* A usual run would look like:
|
||||||
|
* - inactive -> activating: activate vfunc is called
|
||||||
|
* - activating -> idle: fpi_image_device_activate_complete()
|
||||||
|
* - idle -> await-finger-on
|
||||||
|
* - await-finger-on -> capture: fpi_image_device_report_finger_status()
|
||||||
|
* - capture -> await-finger-off: fpi_image_device_image_captured()
|
||||||
|
* - await-finger-off -> idle: fpi_image_device_report_finger_status()
|
||||||
|
* - idle -> deactivating: deactivate vfunc is called
|
||||||
|
* - deactivating -> inactive: fpi_image_device_deactivate_complete()
|
||||||
|
*
|
||||||
|
* Raw mode is currently not supported (not waiting for finger), but in that
|
||||||
|
* case the following transitions are valid:
|
||||||
|
* - idle -> capture
|
||||||
|
* - capture -> idle
|
||||||
|
*
|
||||||
|
* Also valid are these transitions in case of errors or cancellations:
|
||||||
|
* - activating -> inactive: fpi_image_device_activate_complete()
|
||||||
|
* - await-finger-on -> deactivating: deactivate vfunc is called
|
||||||
|
* - capture -> deactivating: deactivate vfunc is called
|
||||||
|
* - await-finger-off -> deactivating: deactivate vfunc is called
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FPI_IMAGE_DEVICE_STATE_INACTIVE,
|
FPI_IMAGE_DEVICE_STATE_INACTIVE,
|
||||||
|
FPI_IMAGE_DEVICE_STATE_ACTIVATING,
|
||||||
|
FPI_IMAGE_DEVICE_STATE_DEACTIVATING,
|
||||||
|
FPI_IMAGE_DEVICE_STATE_IDLE,
|
||||||
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON,
|
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON,
|
||||||
FPI_IMAGE_DEVICE_STATE_CAPTURE,
|
FPI_IMAGE_DEVICE_STATE_CAPTURE,
|
||||||
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF,
|
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF,
|
||||||
@@ -58,11 +85,6 @@ typedef enum {
|
|||||||
* finger or image capture). Implementing this is optional, it can e.g. be
|
* finger or image capture). Implementing this is optional, it can e.g. be
|
||||||
* used to flash an LED when waiting for a finger.
|
* used to flash an LED when waiting for a finger.
|
||||||
*
|
*
|
||||||
* These are the main entry points for image based drivers. For all but the
|
|
||||||
* change_state vfunc, implementations *must* eventually call the corresponding
|
|
||||||
* function to finish the operation. It is also acceptable to call the generic
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* These are the main entry points for drivers to implement. Drivers may not
|
* These are the main entry points for drivers to implement. Drivers may not
|
||||||
* implement all of these entry points if they do not support the operation
|
* implement all of these entry points if they do not support the operation
|
||||||
* (or a default implementation is sufficient).
|
* (or a default implementation is sufficient).
|
||||||
|
|||||||
@@ -0,0 +1,432 @@
|
|||||||
|
/*
|
||||||
|
* FPrint SPI transfer handling
|
||||||
|
* Copyright (C) 2019-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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fpi-spi-transfer.h"
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/spi/spidev.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:fpi-spi-transfer
|
||||||
|
* @title: SPI transfer helpers
|
||||||
|
* @short_description: Helpers to ease SPI transfers
|
||||||
|
*
|
||||||
|
* #FpiSpiTransfer is a structure to simplify the SPI transfer handling
|
||||||
|
* for the linux spidev device. The main goal are to ease memory management
|
||||||
|
* and provide a usable asynchronous API to libfprint drivers.
|
||||||
|
*
|
||||||
|
* Currently only transfers with a write and subsequent read are supported.
|
||||||
|
*
|
||||||
|
* Drivers should always use this API rather than calling read/write/ioctl on
|
||||||
|
* the spidev device.
|
||||||
|
*
|
||||||
|
* Setting G_MESSAGES_DEBUG and FP_DEBUG_TRANSFER will result in the message
|
||||||
|
* content to be dumped.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
G_DEFINE_BOXED_TYPE (FpiSpiTransfer, fpi_spi_transfer, fpi_spi_transfer_ref, fpi_spi_transfer_unref)
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_buffer (guchar *buf, gssize dump_len)
|
||||||
|
{
|
||||||
|
g_autoptr(GString) line = NULL;
|
||||||
|
|
||||||
|
line = g_string_new ("");
|
||||||
|
/* Dump the buffer. */
|
||||||
|
for (gssize i = 0; i < dump_len; i++)
|
||||||
|
{
|
||||||
|
g_string_append_printf (line, "%02x ", buf[i]);
|
||||||
|
if ((i + 1) % 16 == 0)
|
||||||
|
{
|
||||||
|
g_debug ("%s", line->str);
|
||||||
|
g_string_set_size (line, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line->len)
|
||||||
|
g_debug ("%s", line->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_transfer (FpiSpiTransfer *transfer, gboolean submit, GError *error)
|
||||||
|
{
|
||||||
|
if (g_getenv ("FP_DEBUG_TRANSFER"))
|
||||||
|
{
|
||||||
|
if (submit)
|
||||||
|
{
|
||||||
|
g_debug ("Transfer %p submitted, write length %zd, read length %zd",
|
||||||
|
transfer,
|
||||||
|
transfer->length_wr,
|
||||||
|
transfer->length_rd);
|
||||||
|
|
||||||
|
if (transfer->buffer_wr)
|
||||||
|
dump_buffer (transfer->buffer_wr, transfer->length_wr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_autofree gchar *error_str = NULL;
|
||||||
|
if (error)
|
||||||
|
error_str = g_strdup_printf ("with error (%s)", error->message);
|
||||||
|
else
|
||||||
|
error_str = g_strdup ("successfully");
|
||||||
|
|
||||||
|
g_debug ("Transfer %p completed %s, write length %zd, read length %zd",
|
||||||
|
transfer,
|
||||||
|
error_str,
|
||||||
|
transfer->length_wr,
|
||||||
|
transfer->length_rd);
|
||||||
|
if (transfer->buffer_rd)
|
||||||
|
dump_buffer (transfer->buffer_rd, transfer->length_rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_new:
|
||||||
|
* @device: The #FpDevice the transfer is for
|
||||||
|
* @spidev_fd: The file descriptor for the spidev device
|
||||||
|
*
|
||||||
|
* Creates a new #FpiSpiTransfer.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A newly created #FpiSpiTransfer
|
||||||
|
*/
|
||||||
|
FpiSpiTransfer *
|
||||||
|
fpi_spi_transfer_new (FpDevice * device, int spidev_fd)
|
||||||
|
{
|
||||||
|
FpiSpiTransfer *self;
|
||||||
|
|
||||||
|
g_assert (FP_IS_DEVICE (device));
|
||||||
|
|
||||||
|
self = g_slice_new0 (FpiSpiTransfer);
|
||||||
|
self->ref_count = 1;
|
||||||
|
|
||||||
|
/* Purely to enhance the debug log output. */
|
||||||
|
self->length_wr = -1;
|
||||||
|
self->length_rd = -1;
|
||||||
|
|
||||||
|
self->device = device;
|
||||||
|
self->spidev_fd = spidev_fd;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_spi_transfer_free (FpiSpiTransfer *self)
|
||||||
|
{
|
||||||
|
g_assert (self);
|
||||||
|
g_assert_cmpint (self->ref_count, ==, 0);
|
||||||
|
|
||||||
|
if (self->free_buffer_wr && self->buffer_wr)
|
||||||
|
self->free_buffer_wr (self->buffer_wr);
|
||||||
|
if (self->free_buffer_rd && self->buffer_rd)
|
||||||
|
self->free_buffer_rd (self->buffer_rd);
|
||||||
|
self->buffer_wr = NULL;
|
||||||
|
self->buffer_rd = NULL;
|
||||||
|
|
||||||
|
g_slice_free (FpiSpiTransfer, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_ref:
|
||||||
|
* @self: A #FpiSpiTransfer
|
||||||
|
*
|
||||||
|
* Increments the reference count of @self by one.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): @self
|
||||||
|
*/
|
||||||
|
FpiSpiTransfer *
|
||||||
|
fpi_spi_transfer_ref (FpiSpiTransfer *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self, NULL);
|
||||||
|
g_return_val_if_fail (self->ref_count, NULL);
|
||||||
|
|
||||||
|
g_atomic_int_inc (&self->ref_count);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_unref:
|
||||||
|
* @self: A #FpiSpiTransfer
|
||||||
|
*
|
||||||
|
* Decrements the reference count of @self by one, freeing the structure when
|
||||||
|
* the reference count reaches zero.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_unref (FpiSpiTransfer *self)
|
||||||
|
{
|
||||||
|
g_return_if_fail (self);
|
||||||
|
g_return_if_fail (self->ref_count);
|
||||||
|
|
||||||
|
if (g_atomic_int_dec_and_test (&self->ref_count))
|
||||||
|
fpi_spi_transfer_free (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_write:
|
||||||
|
* @transfer: The #FpiSpiTransfer
|
||||||
|
* @length: The buffer size to allocate
|
||||||
|
*
|
||||||
|
* Prepare the write part of an SPI transfer allocating a new buffer
|
||||||
|
* internally that will be free'ed automatically.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_write (FpiSpiTransfer *transfer,
|
||||||
|
gsize length)
|
||||||
|
{
|
||||||
|
fpi_spi_transfer_write_full (transfer,
|
||||||
|
g_malloc0 (length),
|
||||||
|
length,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_write_full:
|
||||||
|
* @transfer: The #FpiSpiTransfer
|
||||||
|
* @buffer: The data to write.
|
||||||
|
* @length: The size of @buffer
|
||||||
|
* @free_func: (destroy buffer): Destroy notify for @buffer
|
||||||
|
*
|
||||||
|
* Prepare the write part of an SPI transfer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_write_full (FpiSpiTransfer *transfer,
|
||||||
|
guint8 *buffer,
|
||||||
|
gsize length,
|
||||||
|
GDestroyNotify free_func)
|
||||||
|
{
|
||||||
|
g_assert (buffer != NULL);
|
||||||
|
g_return_if_fail (transfer);
|
||||||
|
|
||||||
|
/* Write is always before read, so ensure both are NULL. */
|
||||||
|
g_return_if_fail (transfer->buffer_wr == NULL);
|
||||||
|
g_return_if_fail (transfer->buffer_rd == NULL);
|
||||||
|
|
||||||
|
transfer->buffer_wr = buffer;
|
||||||
|
transfer->length_wr = length;
|
||||||
|
transfer->free_buffer_wr = free_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_read:
|
||||||
|
* @transfer: The #FpiSpiTransfer
|
||||||
|
* @length: The buffer size to allocate
|
||||||
|
*
|
||||||
|
* Prepare the read part of an SPI transfer allocating a new buffer
|
||||||
|
* internally that will be free'ed automatically.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_read (FpiSpiTransfer *transfer,
|
||||||
|
gsize length)
|
||||||
|
{
|
||||||
|
fpi_spi_transfer_read_full (transfer,
|
||||||
|
g_malloc0 (length),
|
||||||
|
length,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_read_full:
|
||||||
|
* @transfer: The #FpiSpiTransfer
|
||||||
|
* @buffer: Buffer to read data into.
|
||||||
|
* @length: The size of @buffer
|
||||||
|
* @free_func: (destroy buffer): Destroy notify for @buffer
|
||||||
|
*
|
||||||
|
* Prepare the read part of an SPI transfer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_read_full (FpiSpiTransfer *transfer,
|
||||||
|
guint8 *buffer,
|
||||||
|
gsize length,
|
||||||
|
GDestroyNotify free_func)
|
||||||
|
{
|
||||||
|
g_assert (buffer != NULL);
|
||||||
|
g_return_if_fail (transfer);
|
||||||
|
g_return_if_fail (transfer->buffer_rd == NULL);
|
||||||
|
|
||||||
|
transfer->buffer_rd = buffer;
|
||||||
|
transfer->length_rd = length;
|
||||||
|
transfer->free_buffer_rd = free_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task = G_TASK (res);
|
||||||
|
FpiSpiTransfer *transfer = g_task_get_task_data (task);
|
||||||
|
GError *error = NULL;
|
||||||
|
FpiSpiTransferCallback callback;
|
||||||
|
|
||||||
|
g_task_propagate_boolean (task, &error);
|
||||||
|
|
||||||
|
log_transfer (transfer, FALSE, error);
|
||||||
|
|
||||||
|
callback = transfer->callback;
|
||||||
|
transfer->callback = NULL;
|
||||||
|
callback (transfer, transfer->device, transfer->user_data, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
transfer_thread_func (GTask *task,
|
||||||
|
gpointer source_object,
|
||||||
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
FpiSpiTransfer *transfer = (FpiSpiTransfer *) task_data;
|
||||||
|
struct spi_ioc_transfer xfer[2];
|
||||||
|
int transfers = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (transfer->buffer_wr == NULL && transfer->buffer_rd == NULL)
|
||||||
|
{
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
|
"Transfer with neither write or read!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (xfer, 0, sizeof (xfer));
|
||||||
|
|
||||||
|
if (transfer->buffer_wr)
|
||||||
|
{
|
||||||
|
xfer[transfers].tx_buf = (guint64) transfer->buffer_wr;
|
||||||
|
xfer[transfers].len = transfer->length_wr;
|
||||||
|
|
||||||
|
transfers += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transfer->buffer_rd)
|
||||||
|
{
|
||||||
|
xfer[transfers].rx_buf = (guint64) transfer->buffer_rd;
|
||||||
|
xfer[transfers].len = transfer->length_rd;
|
||||||
|
|
||||||
|
transfers += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This ioctl cannot be interrupted. */
|
||||||
|
status = ioctl (transfer->spidev_fd, SPI_IOC_MESSAGE (transfers), xfer);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
G_IO_ERROR,
|
||||||
|
g_io_error_from_errno (errno),
|
||||||
|
"Error invoking ioctl for SPI transfer (%d)",
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_submit:
|
||||||
|
* @transfer: (transfer full): The transfer to submit, must have been filled.
|
||||||
|
* @cancellable: Cancellable to use, e.g. fpi_device_get_cancellable()
|
||||||
|
* @callback: Callback on completion or error
|
||||||
|
* @user_data: Data to pass to callback
|
||||||
|
*
|
||||||
|
* Submit an SPI transfer with a specific timeout and callback functions.
|
||||||
|
*
|
||||||
|
* The underlying transfer cannot be cancelled. The current implementation
|
||||||
|
* will only call @callback after the transfer has been completed.
|
||||||
|
*
|
||||||
|
* Note that #FpiSpiTransfer will be stolen when this function is called.
|
||||||
|
* So that all associated data will be free'ed automatically, after the
|
||||||
|
* callback ran unless fpi_usb_transfer_ref() is explicitly called.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_spi_transfer_submit (FpiSpiTransfer *transfer,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
FpiSpiTransferCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (transfer);
|
||||||
|
g_return_if_fail (callback);
|
||||||
|
|
||||||
|
/* Recycling is allowed, but not two at the same time. */
|
||||||
|
g_return_if_fail (transfer->callback == NULL);
|
||||||
|
|
||||||
|
transfer->callback = callback;
|
||||||
|
transfer->user_data = user_data;
|
||||||
|
|
||||||
|
log_transfer (transfer, TRUE, NULL);
|
||||||
|
|
||||||
|
task = g_task_new (transfer->device,
|
||||||
|
cancellable,
|
||||||
|
transfer_finish_cb,
|
||||||
|
NULL);
|
||||||
|
g_task_set_task_data (task,
|
||||||
|
g_steal_pointer (&transfer),
|
||||||
|
(GDestroyNotify) fpi_spi_transfer_unref);
|
||||||
|
|
||||||
|
g_task_run_in_thread (task, transfer_thread_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_spi_transfer_submit_sync:
|
||||||
|
* @transfer: The transfer to submit, must have been filled.
|
||||||
|
* @error: Location to store #GError to
|
||||||
|
*
|
||||||
|
* Synchronously submit an SPI transfer. Use of this function is discouraged
|
||||||
|
* as it will block all other operations in the application.
|
||||||
|
*
|
||||||
|
* Note that you still need to fpi_spi_transfer_unref() the
|
||||||
|
* #FpiSpiTransfer afterwards.
|
||||||
|
*
|
||||||
|
* Returns: #TRUE on success, otherwise #FALSE and @error will be set
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
fpi_spi_transfer_submit_sync (FpiSpiTransfer *transfer,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = NULL;
|
||||||
|
GError *err = NULL;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
g_return_val_if_fail (transfer, FALSE);
|
||||||
|
|
||||||
|
/* Recycling is allowed, but not two at the same time. */
|
||||||
|
g_return_val_if_fail (transfer->callback == NULL, FALSE);
|
||||||
|
|
||||||
|
log_transfer (transfer, TRUE, NULL);
|
||||||
|
|
||||||
|
task = g_task_new (transfer->device,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
g_task_set_task_data (task,
|
||||||
|
fpi_spi_transfer_ref (transfer),
|
||||||
|
(GDestroyNotify) fpi_spi_transfer_unref);
|
||||||
|
|
||||||
|
g_task_run_in_thread_sync (task, transfer_thread_func);
|
||||||
|
|
||||||
|
res = g_task_propagate_boolean (task, &err);
|
||||||
|
|
||||||
|
log_transfer (transfer, FALSE, err);
|
||||||
|
|
||||||
|
g_propagate_error (error, err);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* FPrint spidev transfer handling
|
||||||
|
* Copyright (C) 2019-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-compat.h"
|
||||||
|
#include "fpi-device.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define FPI_TYPE_SPI_TRANSFER (fpi_spi_transfer_get_type ())
|
||||||
|
|
||||||
|
typedef struct _FpiSpiTransfer FpiSpiTransfer;
|
||||||
|
typedef struct _FpiSsm FpiSsm;
|
||||||
|
|
||||||
|
typedef void (*FpiSpiTransferCallback)(FpiSpiTransfer *transfer,
|
||||||
|
FpDevice *dev,
|
||||||
|
gpointer user_data,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpiSpiTransfer:
|
||||||
|
* @device: The #FpDevice that the transfer belongs to.
|
||||||
|
* @ssm: Storage slot to associate the transfer with a state machine.
|
||||||
|
* Used by fpi_ssm_spi_transfer_cb() to modify the given state machine.
|
||||||
|
* @length_wr: The length of the write buffer
|
||||||
|
* @length_rd: The length of the read buffer
|
||||||
|
* @buffer_wr: The write buffer.
|
||||||
|
* @buffer_rd: The read buffer.
|
||||||
|
*
|
||||||
|
* Helper for handling SPI transfers. Currently transfers can either be pure
|
||||||
|
* write/read transfers or a write followed by a read (full duplex support
|
||||||
|
* can easily be added if desired).
|
||||||
|
*/
|
||||||
|
struct _FpiSpiTransfer
|
||||||
|
{
|
||||||
|
/*< public >*/
|
||||||
|
FpDevice *device;
|
||||||
|
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
gssize length_wr;
|
||||||
|
gssize length_rd;
|
||||||
|
|
||||||
|
guchar *buffer_wr;
|
||||||
|
guchar *buffer_rd;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
guint ref_count;
|
||||||
|
|
||||||
|
int spidev_fd;
|
||||||
|
|
||||||
|
/* Callbacks */
|
||||||
|
gpointer user_data;
|
||||||
|
FpiSpiTransferCallback callback;
|
||||||
|
|
||||||
|
/* Data free function */
|
||||||
|
GDestroyNotify free_buffer_wr;
|
||||||
|
GDestroyNotify free_buffer_rd;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType fpi_spi_transfer_get_type (void) G_GNUC_CONST;
|
||||||
|
FpiSpiTransfer *fpi_spi_transfer_new (FpDevice *device,
|
||||||
|
int spidev_fd);
|
||||||
|
FpiSpiTransfer *fpi_spi_transfer_ref (FpiSpiTransfer *self);
|
||||||
|
void fpi_spi_transfer_unref (FpiSpiTransfer *self);
|
||||||
|
|
||||||
|
void fpi_spi_transfer_write (FpiSpiTransfer *transfer,
|
||||||
|
gsize length);
|
||||||
|
|
||||||
|
FP_GNUC_ACCESS (read_only, 2, 3)
|
||||||
|
void fpi_spi_transfer_write_full (FpiSpiTransfer *transfer,
|
||||||
|
guint8 *buffer,
|
||||||
|
gsize length,
|
||||||
|
GDestroyNotify free_func);
|
||||||
|
|
||||||
|
void fpi_spi_transfer_read (FpiSpiTransfer *transfer,
|
||||||
|
gsize length);
|
||||||
|
|
||||||
|
FP_GNUC_ACCESS (write_only, 2, 3)
|
||||||
|
void fpi_spi_transfer_read_full (FpiSpiTransfer *transfer,
|
||||||
|
guint8 *buffer,
|
||||||
|
gsize length,
|
||||||
|
GDestroyNotify free_func);
|
||||||
|
|
||||||
|
void fpi_spi_transfer_submit (FpiSpiTransfer *transfer,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
FpiSpiTransferCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
gboolean fpi_spi_transfer_submit_sync (FpiSpiTransfer *transfer,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSpiTransfer, fpi_spi_transfer_unref)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
+95
-1
@@ -74,7 +74,7 @@
|
|||||||
* upon success (or fails).
|
* upon success (or fails).
|
||||||
*
|
*
|
||||||
* Your completion callback should examine the return value of
|
* 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.
|
* failed. An error code of zero indicates successful completion.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -130,6 +130,7 @@ fpi_ssm_new_full (FpDevice *dev,
|
|||||||
{
|
{
|
||||||
FpiSsm *machine;
|
FpiSsm *machine;
|
||||||
|
|
||||||
|
BUG_ON (dev == NULL);
|
||||||
BUG_ON (nr_states < 1);
|
BUG_ON (nr_states < 1);
|
||||||
BUG_ON (handler == NULL);
|
BUG_ON (handler == NULL);
|
||||||
|
|
||||||
@@ -155,6 +156,8 @@ fpi_ssm_set_data (FpiSsm *machine,
|
|||||||
gpointer ssm_data,
|
gpointer ssm_data,
|
||||||
GDestroyNotify ssm_data_destroy)
|
GDestroyNotify ssm_data_destroy)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine);
|
||||||
|
|
||||||
if (machine->ssm_data_destroy && machine->ssm_data)
|
if (machine->ssm_data_destroy && machine->ssm_data)
|
||||||
machine->ssm_data_destroy (machine->ssm_data);
|
machine->ssm_data_destroy (machine->ssm_data);
|
||||||
|
|
||||||
@@ -173,12 +176,32 @@ fpi_ssm_set_data (FpiSsm *machine,
|
|||||||
void *
|
void *
|
||||||
fpi_ssm_get_data (FpiSsm *machine)
|
fpi_ssm_get_data (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (machine, NULL);
|
||||||
|
|
||||||
return machine->ssm_data;
|
return machine->ssm_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_ssm_get_device:
|
||||||
|
* @machine: an #FpiSsm state machine
|
||||||
|
*
|
||||||
|
* Retrieve the device that the SSM is for.
|
||||||
|
*
|
||||||
|
* Returns: #FpDevice
|
||||||
|
*/
|
||||||
|
FpDevice *
|
||||||
|
fpi_ssm_get_device (FpiSsm *machine)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (machine, NULL);
|
||||||
|
|
||||||
|
return machine->dev;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_ssm_clear_delayed_action (FpiSsm *machine)
|
fpi_ssm_clear_delayed_action (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine);
|
||||||
|
|
||||||
if (machine->cancellable_id)
|
if (machine->cancellable_id)
|
||||||
{
|
{
|
||||||
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
|
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
|
||||||
@@ -235,6 +258,8 @@ fpi_ssm_set_delayed_action_timeout (FpiSsm *machine,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify destroy_func)
|
GDestroyNotify destroy_func)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine);
|
||||||
|
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
@@ -302,6 +327,8 @@ __ssm_call_handler (FpiSsm *machine)
|
|||||||
void
|
void
|
||||||
fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
|
fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (ssm != NULL);
|
||||||
|
|
||||||
BUG_ON (!ssm->completed);
|
BUG_ON (!ssm->completed);
|
||||||
ssm->callback = callback;
|
ssm->callback = callback;
|
||||||
ssm->cur_state = 0;
|
ssm->cur_state = 0;
|
||||||
@@ -336,6 +363,9 @@ __subsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|||||||
void
|
void
|
||||||
fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
|
fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (parent != NULL);
|
||||||
|
g_return_if_fail (child != NULL);
|
||||||
|
|
||||||
BUG_ON (parent->timeout);
|
BUG_ON (parent->timeout);
|
||||||
child->parentsm = parent;
|
child->parentsm = parent;
|
||||||
|
|
||||||
@@ -355,6 +385,8 @@ fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
|
|||||||
void
|
void
|
||||||
fpi_ssm_mark_completed (FpiSsm *machine)
|
fpi_ssm_mark_completed (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine != NULL);
|
||||||
|
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
@@ -427,6 +459,7 @@ fpi_ssm_mark_completed_delayed (FpiSsm *machine,
|
|||||||
void
|
void
|
||||||
fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
|
fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine != NULL);
|
||||||
g_assert (error);
|
g_assert (error);
|
||||||
if (machine->error)
|
if (machine->error)
|
||||||
{
|
{
|
||||||
@@ -534,6 +567,8 @@ fpi_ssm_next_state_delayed (FpiSsm *machine,
|
|||||||
void
|
void
|
||||||
fpi_ssm_jump_to_state (FpiSsm *machine, int state)
|
fpi_ssm_jump_to_state (FpiSsm *machine, int state)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail (machine != NULL);
|
||||||
|
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (state < 0 || state >= machine->nr_states);
|
BUG_ON (state < 0 || state >= machine->nr_states);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
@@ -610,6 +645,8 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
|||||||
int
|
int
|
||||||
fpi_ssm_get_cur_state (FpiSsm *machine)
|
fpi_ssm_get_cur_state (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (machine != NULL, 0);
|
||||||
|
|
||||||
return machine->cur_state;
|
return machine->cur_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,6 +661,8 @@ fpi_ssm_get_cur_state (FpiSsm *machine)
|
|||||||
GError *
|
GError *
|
||||||
fpi_ssm_get_error (FpiSsm *machine)
|
fpi_ssm_get_error (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (machine != NULL, NULL);
|
||||||
|
|
||||||
return machine->error;
|
return machine->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,6 +677,8 @@ fpi_ssm_get_error (FpiSsm *machine)
|
|||||||
GError *
|
GError *
|
||||||
fpi_ssm_dup_error (FpiSsm *machine)
|
fpi_ssm_dup_error (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (machine != NULL, NULL);
|
||||||
|
|
||||||
if (machine->error)
|
if (machine->error)
|
||||||
return g_error_copy (machine->error);
|
return g_error_copy (machine->error);
|
||||||
|
|
||||||
@@ -696,3 +737,56 @@ fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
|
|||||||
|
|
||||||
fpi_ssm_usb_transfer_cb (transfer, device, weak_ptr, error);
|
fpi_ssm_usb_transfer_cb (transfer, device, weak_ptr, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_ssm_spi_transfer_cb:
|
||||||
|
* @transfer: a #FpiSpiTransfer
|
||||||
|
* @device: a #FpDevice
|
||||||
|
* @unused_data: User data (unused)
|
||||||
|
* @error: The #GError or %NULL
|
||||||
|
*
|
||||||
|
* Can be used in as a #FpiSpiTransfer callback handler to automatically
|
||||||
|
* advance or fail a statemachine on transfer completion.
|
||||||
|
*
|
||||||
|
* Make sure to set the #FpiSsm on the transfer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_ssm_spi_transfer_cb (FpiSpiTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer unused_data, GError *error)
|
||||||
|
{
|
||||||
|
g_return_if_fail (transfer->ssm);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
else
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_ssm_spi_transfer_with_weak_pointer_cb:
|
||||||
|
* @transfer: a #FpiSpiTransfer
|
||||||
|
* @device: a #FpDevice
|
||||||
|
* @weak_ptr: A #gpointer pointer to nullify. You can pass a pointer to any
|
||||||
|
* #gpointer to nullify when the callback is completed. I.e a
|
||||||
|
* pointer to the current #FpiSpiTransfer.
|
||||||
|
* @error: The #GError or %NULL
|
||||||
|
*
|
||||||
|
* Can be used in as a #FpiSpiTransfer callback handler to automatically
|
||||||
|
* advance or fail a statemachine on transfer completion.
|
||||||
|
* Passing a #gpointer* as @weak_ptr permits to nullify it once we're done
|
||||||
|
* with the transfer.
|
||||||
|
*
|
||||||
|
* Make sure to set the #FpiSsm on the transfer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_ssm_spi_transfer_with_weak_pointer_cb (FpiSpiTransfer *transfer,
|
||||||
|
FpDevice *device, gpointer weak_ptr,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
g_return_if_fail (transfer->ssm);
|
||||||
|
|
||||||
|
if (weak_ptr)
|
||||||
|
g_nullify_pointer ((gpointer *) weak_ptr);
|
||||||
|
|
||||||
|
fpi_ssm_spi_transfer_cb (transfer, device, weak_ptr, error);
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ void fpi_ssm_set_data (FpiSsm *machine,
|
|||||||
gpointer ssm_data,
|
gpointer ssm_data,
|
||||||
GDestroyNotify ssm_data_destroy);
|
GDestroyNotify ssm_data_destroy);
|
||||||
gpointer fpi_ssm_get_data (FpiSsm *machine);
|
gpointer fpi_ssm_get_data (FpiSsm *machine);
|
||||||
|
FpDevice * fpi_ssm_get_device (FpiSsm *machine);
|
||||||
GError * fpi_ssm_get_error (FpiSsm *machine);
|
GError * fpi_ssm_get_error (FpiSsm *machine);
|
||||||
GError * fpi_ssm_dup_error (FpiSsm *machine);
|
GError * fpi_ssm_dup_error (FpiSsm *machine);
|
||||||
int fpi_ssm_get_cur_state (FpiSsm *machine);
|
int fpi_ssm_get_cur_state (FpiSsm *machine);
|
||||||
@@ -111,4 +112,15 @@ void fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
|
|||||||
gpointer weak_ptr,
|
gpointer weak_ptr,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
|
||||||
|
typedef struct _FpiSpiTransfer FpiSpiTransfer;
|
||||||
|
|
||||||
|
void fpi_ssm_spi_transfer_cb (FpiSpiTransfer *transfer,
|
||||||
|
FpDevice *device,
|
||||||
|
gpointer unused_data,
|
||||||
|
GError *error);
|
||||||
|
void fpi_ssm_spi_transfer_with_weak_pointer_cb (FpiSpiTransfer *transfer,
|
||||||
|
FpDevice *device,
|
||||||
|
gpointer weak_ptr,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSsm, fpi_ssm_free)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSsm, fpi_ssm_free)
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ fpi_usb_transfer_fill_bulk (FpiUsbTransfer *transfer,
|
|||||||
* fpi_usb_transfer_fill_bulk_full:
|
* fpi_usb_transfer_fill_bulk_full:
|
||||||
* @transfer: The #FpiUsbTransfer
|
* @transfer: The #FpiUsbTransfer
|
||||||
* @endpoint: The endpoint to send the transfer to
|
* @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
|
* @length: The size of @buffer
|
||||||
* @free_func: (destroy buffer): Destroy notify for @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:
|
* fpi_usb_transfer_fill_interrupt_full:
|
||||||
* @transfer: The #FpiUsbTransfer
|
* @transfer: The #FpiUsbTransfer
|
||||||
* @endpoint: The endpoint to send the transfer to
|
* @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
|
* @length: The size of @buffer
|
||||||
* @free_func: (destroy buffer): Destroy notify for @buffer
|
* @free_func: (destroy buffer): Destroy notify for @buffer
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
|
||||||
|
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
||||||
|
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
|
||||||
|
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "fpi-context.h"
|
||||||
|
#include "fpi-device.h"
|
||||||
|
|
||||||
|
static const FpIdEntry whitelist_id_table[] = {
|
||||||
|
/* Currently known and unsupported devices.
|
||||||
|
* You can generate this list from the wiki page using e.g.:
|
||||||
|
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
|
||||||
|
*/
|
||||||
|
{ .vid = 0x04f3, .pid = 0x036b },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c00 },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c4b },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c4c },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c4f },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c57 },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c5e },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x2706 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x0081 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x0088 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x008a },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x009a },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x009b },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00a2 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00b7 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00bb },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00be },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00c4 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00cb },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00d8 },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00da },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5801 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5805 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5834 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5840 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5841 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5842 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5843 },
|
||||||
|
{ .vid = 0x0a5c, .pid = 0x5845 },
|
||||||
|
{ .vid = 0x10a5, .pid = 0x0007 },
|
||||||
|
{ .vid = 0x1188, .pid = 0x9545 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x0007 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x003a },
|
||||||
|
{ .vid = 0x138a, .pid = 0x003c },
|
||||||
|
{ .vid = 0x138a, .pid = 0x003d },
|
||||||
|
{ .vid = 0x138a, .pid = 0x003f },
|
||||||
|
{ .vid = 0x138a, .pid = 0x0090 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x0092 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x0094 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x0097 },
|
||||||
|
{ .vid = 0x138a, .pid = 0x009d },
|
||||||
|
{ .vid = 0x138a, .pid = 0x00ab },
|
||||||
|
{ .vid = 0x147e, .pid = 0x1002 },
|
||||||
|
{ .vid = 0x1491, .pid = 0x0088 },
|
||||||
|
{ .vid = 0x16d1, .pid = 0x1027 },
|
||||||
|
{ .vid = 0x1c7a, .pid = 0x0300 },
|
||||||
|
{ .vid = 0x1c7a, .pid = 0x0570 },
|
||||||
|
{ .vid = 0x1c7a, .pid = 0x0575 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5042 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5110 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5117 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5201 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x521d },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5301 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x530c },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x532d },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x533c },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5381 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5385 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x538c },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x538d },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5395 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5584 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x55a2 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x55a4 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x55b4 },
|
||||||
|
{ .vid = 0x27c6, .pid = 0x5740 },
|
||||||
|
{ .vid = 0x2808, .pid = 0x9338 },
|
||||||
|
{ .vid = 0x298d, .pid = 0x2033 },
|
||||||
|
{ .vid = 0x3538, .pid = 0x0930 },
|
||||||
|
{ .vid = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const FpIdEntry blacklist_id_table[] = {
|
||||||
|
{ .vid = 0x0483, .pid = 0x2016 },
|
||||||
|
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
||||||
|
{ .vid = 0x045e, .pid = 0x00bb },
|
||||||
|
{ .vid = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const FpDeviceClass whitelist = {
|
||||||
|
.type = FP_DEVICE_TYPE_USB,
|
||||||
|
.id_table = whitelist_id_table,
|
||||||
|
.id = "whitelist",
|
||||||
|
.full_name = "Hardcoded whitelist"
|
||||||
|
};
|
||||||
|
|
||||||
|
GHashTable *printed = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_driver (const FpDeviceClass *cls)
|
||||||
|
{
|
||||||
|
const FpIdEntry *entry;
|
||||||
|
gint num_printed = 0;
|
||||||
|
|
||||||
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (entry = cls->id_table; entry->vid != 0; entry++)
|
||||||
|
{
|
||||||
|
const FpIdEntry *bl_entry;
|
||||||
|
char *key;
|
||||||
|
|
||||||
|
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++)
|
||||||
|
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (bl_entry->vid != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
||||||
|
|
||||||
|
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, (void *) cls->id);
|
||||||
|
|
||||||
|
if (num_printed == 0)
|
||||||
|
{
|
||||||
|
if (cls != &whitelist)
|
||||||
|
g_print ("\n# Supported by libfprint driver %s\n", cls->id);
|
||||||
|
else
|
||||||
|
g_print ("\n# Known unsupported devices\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("usb:v%04Xp%04X*\n",
|
||||||
|
entry->vid, entry->pid);
|
||||||
|
num_printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_printed > 0)
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
GType driver = g_array_index (drivers, GType, i);
|
||||||
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
|
|
||||||
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
print_driver (cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_driver (&whitelist);
|
||||||
|
|
||||||
|
g_hash_table_destroy (printed);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
|
|
||||||
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
|
||||||
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
|
|
||||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "fpi-context.h"
|
|
||||||
#include "fpi-device.h"
|
|
||||||
|
|
||||||
static const FpIdEntry whitelist_id_table[] = {
|
|
||||||
/* Unsupported (for now) Validity Sensors finger print readers */
|
|
||||||
{ .vid = 0x138a, .pid = 0x0090 }, /* Found on e.g. Lenovo T460s */
|
|
||||||
{ .vid = 0x138a, .pid = 0x0091 },
|
|
||||||
{ .vid = 0x138a, .pid = 0x0094 },
|
|
||||||
{ .vid = 0x138a, .pid = 0x0097 }, /* Found on e.g. Lenovo T470s */
|
|
||||||
{ .vid = 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FpIdEntry blacklist_id_table[] = {
|
|
||||||
{ .vid = 0x0483, .pid = 0x2016 },
|
|
||||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
|
||||||
{ .vid = 0x045e, .pid = 0x00bb },
|
|
||||||
{ .vid = 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const FpDeviceClass whitelist = {
|
|
||||||
.type = FP_DEVICE_TYPE_USB,
|
|
||||||
.id_table = whitelist_id_table,
|
|
||||||
.full_name = "Hardcoded whitelist"
|
|
||||||
};
|
|
||||||
|
|
||||||
GHashTable *printed = NULL;
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_driver (const FpDeviceClass *cls)
|
|
||||||
{
|
|
||||||
const FpIdEntry *entry;
|
|
||||||
gint num_printed = 0;
|
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (entry = cls->id_table; entry->vid != 0; entry++)
|
|
||||||
{
|
|
||||||
const FpIdEntry *bl_entry;
|
|
||||||
char *key;
|
|
||||||
|
|
||||||
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++)
|
|
||||||
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (bl_entry->vid != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
|
||||||
|
|
||||||
if (g_hash_table_lookup (printed, key) != NULL)
|
|
||||||
{
|
|
||||||
g_free (key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
|
||||||
|
|
||||||
if (num_printed == 0)
|
|
||||||
g_print ("# %s\n", cls->full_name);
|
|
||||||
|
|
||||||
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\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");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
g_autoptr(GArray) drivers = fpi_get_driver_types ();
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < drivers->len; i++)
|
|
||||||
{
|
|
||||||
GType driver = g_array_index (drivers, GType, i);
|
|
||||||
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
print_driver (cls);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_driver (&whitelist);
|
|
||||||
|
|
||||||
g_hash_table_destroy (printed);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+42
-10
@@ -16,6 +16,7 @@ libfprint_private_sources = [
|
|||||||
'fpi-print.c',
|
'fpi-print.c',
|
||||||
'fpi-ssm.c',
|
'fpi-ssm.c',
|
||||||
'fpi-usb-transfer.c',
|
'fpi-usb-transfer.c',
|
||||||
|
'fpi-spi-transfer.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
libfprint_public_headers = [
|
libfprint_public_headers = [
|
||||||
@@ -40,6 +41,7 @@ libfprint_private_headers = [
|
|||||||
'fpi-minutiae.h',
|
'fpi-minutiae.h',
|
||||||
'fpi-print.h',
|
'fpi-print.h',
|
||||||
'fpi-usb-transfer.h',
|
'fpi-usb-transfer.h',
|
||||||
|
'fpi-spi-transfer.h',
|
||||||
'fpi-ssm.h',
|
'fpi-ssm.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -140,6 +142,9 @@ foreach driver: drivers
|
|||||||
if driver == 'vfs5011'
|
if driver == 'vfs5011'
|
||||||
drivers_sources += [ 'drivers/vfs5011.c' ]
|
drivers_sources += [ 'drivers/vfs5011.c' ]
|
||||||
endif
|
endif
|
||||||
|
if driver == 'vfs7552'
|
||||||
|
drivers_sources += [ 'drivers/vfs7552.c' ]
|
||||||
|
endif
|
||||||
if driver == 'upektc_img'
|
if driver == 'upektc_img'
|
||||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
|
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
|
||||||
endif
|
endif
|
||||||
@@ -155,6 +160,15 @@ foreach driver: drivers
|
|||||||
if driver == 'virtual_image'
|
if driver == 'virtual_image'
|
||||||
drivers_sources += [ 'drivers/virtual-image.c' ]
|
drivers_sources += [ 'drivers/virtual-image.c' ]
|
||||||
endif
|
endif
|
||||||
|
if driver == 'virtual_device'
|
||||||
|
drivers_sources += [ 'drivers/virtual-device.c' ]
|
||||||
|
endif
|
||||||
|
if driver == 'virtual_device_storage'
|
||||||
|
drivers_sources += [ 'drivers/virtual-device-storage.c' ]
|
||||||
|
endif
|
||||||
|
if driver.startswith('virtual_')
|
||||||
|
drivers_sources += [ 'drivers/virtual-device-listener.c' ]
|
||||||
|
endif
|
||||||
if driver == 'synaptics'
|
if driver == 'synaptics'
|
||||||
drivers_sources += [
|
drivers_sources += [
|
||||||
'drivers/synaptics/synaptics.c',
|
'drivers/synaptics/synaptics.c',
|
||||||
@@ -167,6 +181,11 @@ foreach driver: drivers
|
|||||||
'drivers/goodixmoc/goodix_proto.c',
|
'drivers/goodixmoc/goodix_proto.c',
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
if driver == 'nb1010'
|
||||||
|
drivers_sources += [
|
||||||
|
'drivers/nb1010.c',
|
||||||
|
]
|
||||||
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
if aeslib
|
if aeslib
|
||||||
@@ -212,6 +231,7 @@ deps = [
|
|||||||
glib_dep,
|
glib_dep,
|
||||||
gobject_dep,
|
gobject_dep,
|
||||||
gusb_dep,
|
gusb_dep,
|
||||||
|
gudev_dep,
|
||||||
imaging_dep,
|
imaging_dep,
|
||||||
mathlib_dep,
|
mathlib_dep,
|
||||||
nss_dep,
|
nss_dep,
|
||||||
@@ -234,6 +254,8 @@ libnbis = static_library('nbis',
|
|||||||
'-Wno-error=redundant-decls',
|
'-Wno-error=redundant-decls',
|
||||||
'-Wno-redundant-decls',
|
'-Wno-redundant-decls',
|
||||||
'-Wno-discarded-qualifiers',
|
'-Wno-discarded-qualifiers',
|
||||||
|
'-Wno-array-bounds',
|
||||||
|
'-Wno-array-parameter',
|
||||||
]),
|
]),
|
||||||
install: false)
|
install: false)
|
||||||
|
|
||||||
@@ -256,7 +278,7 @@ libfprint_drivers = static_library('fprint-drivers',
|
|||||||
mapfile = files('libfprint.ver')
|
mapfile = files('libfprint.ver')
|
||||||
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
|
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: [
|
sources: [
|
||||||
fp_enums,
|
fp_enums,
|
||||||
libfprint_sources,
|
libfprint_sources,
|
||||||
@@ -293,20 +315,30 @@ libfprint_private_dep = declare_dependency(
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
udev_rules = executable('fprint-list-udev-rules',
|
udev_hwdb = executable('fprint-list-udev-hwdb',
|
||||||
'fprint-list-udev-rules.c',
|
'fprint-list-udev-hwdb.c',
|
||||||
dependencies: libfprint_private_dep,
|
dependencies: libfprint_private_dep,
|
||||||
link_with: libfprint_drivers,
|
link_with: libfprint_drivers,
|
||||||
install: false)
|
install: false)
|
||||||
|
|
||||||
if get_option('udev_rules')
|
udev_hwdb_generator = custom_target('udev-hwdb',
|
||||||
custom_target('udev-rules',
|
output: 'autosuspend.hwdb',
|
||||||
output: '60-@0@-autosuspend.rules'.format(versioned_libname),
|
depend_files: drivers_sources,
|
||||||
capture: true,
|
capture: true,
|
||||||
command: [ udev_rules ],
|
command: [ udev_hwdb ],
|
||||||
install: true,
|
install: false,
|
||||||
install_dir: udev_rules_dir)
|
)
|
||||||
endif
|
|
||||||
|
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',
|
supported_devices = executable('fprint-list-supported-devices',
|
||||||
'fprint-list-supported-devices.c',
|
'fprint-list-supported-devices.c',
|
||||||
|
|||||||
+77
-10
@@ -1,5 +1,5 @@
|
|||||||
project('libfprint', [ 'c', 'cpp' ],
|
project('libfprint', [ 'c', 'cpp' ],
|
||||||
version: '1.90.3',
|
version: '1.90.7',
|
||||||
license: 'LGPLv2.1+',
|
license: 'LGPLv2.1+',
|
||||||
default_options: [
|
default_options: [
|
||||||
'buildtype=debugoptimized',
|
'buildtype=debugoptimized',
|
||||||
@@ -88,10 +88,19 @@ cairo_dep = dependency('cairo', required: false)
|
|||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
drivers = get_option('drivers').split(',')
|
drivers = get_option('drivers').split(',')
|
||||||
virtual_drivers = [ 'virtual_image' ]
|
virtual_drivers = [
|
||||||
|
'virtual_image',
|
||||||
|
'virtual_device',
|
||||||
|
'virtual_device_storage',
|
||||||
|
]
|
||||||
|
|
||||||
|
udev_drivers = [
|
||||||
|
]
|
||||||
|
|
||||||
default_drivers = [
|
default_drivers = [
|
||||||
'upektc_img',
|
'upektc_img',
|
||||||
'vfs5011',
|
'vfs5011',
|
||||||
|
'vfs7552',
|
||||||
'aes3500',
|
'aes3500',
|
||||||
'aes4000',
|
'aes4000',
|
||||||
'aes1610',
|
'aes1610',
|
||||||
@@ -111,9 +120,17 @@ default_drivers = [
|
|||||||
'upeksonly',
|
'upeksonly',
|
||||||
'upekts',
|
'upekts',
|
||||||
'goodixmoc',
|
'goodixmoc',
|
||||||
|
'nb1010'
|
||||||
]
|
]
|
||||||
|
|
||||||
all_drivers = default_drivers + virtual_drivers
|
# 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 + udev_drivers
|
||||||
|
|
||||||
if drivers == [ 'all' ]
|
if drivers == [ 'all' ]
|
||||||
drivers = all_drivers
|
drivers = all_drivers
|
||||||
@@ -127,8 +144,21 @@ if drivers.length() == 0 or drivers[0] == ''
|
|||||||
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
|
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
nss_dep = dependency('', required: false)
|
nss_dep = dependency('', required: false)
|
||||||
imaging_dep = dependency('', required: false)
|
imaging_dep = dependency('', required: false)
|
||||||
|
gudev_dep = dependency('', required: false)
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', false)
|
libfprint_conf.set10('HAVE_PIXMAN', false)
|
||||||
foreach driver: drivers
|
foreach driver: drivers
|
||||||
if driver == 'uru4000'
|
if driver == 'uru4000'
|
||||||
@@ -145,11 +175,33 @@ foreach driver: drivers
|
|||||||
|
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||||
endif
|
endif
|
||||||
|
if udev_drivers.contains(driver)
|
||||||
|
gudev_dep = dependency('gudev-1.0', required: false)
|
||||||
|
if not gudev_dep.found()
|
||||||
|
error('udev is required for SPI support')
|
||||||
|
endif
|
||||||
|
|
||||||
|
libfprint_conf.set10('HAVE_UDEV', true)
|
||||||
|
endif
|
||||||
if not all_drivers.contains(driver)
|
if not all_drivers.contains(driver)
|
||||||
error('Invalid driver \'' + driver + '\'')
|
error('Invalid driver \'' + driver + '\'')
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if default_drivers_are_enabled and supported_drivers != drivers
|
||||||
|
default_drivers_are_enabled = false
|
||||||
|
endif
|
||||||
|
|
||||||
# Export the drivers' types to the core code
|
# Export the drivers' types to the core code
|
||||||
drivers_type_list = []
|
drivers_type_list = []
|
||||||
drivers_type_func = []
|
drivers_type_func = []
|
||||||
@@ -162,7 +214,7 @@ drivers_type_func += '{'
|
|||||||
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
||||||
drivers_type_func += ' GType t;'
|
drivers_type_func += ' GType t;'
|
||||||
drivers_type_func += ''
|
drivers_type_func += ''
|
||||||
foreach driver: drivers
|
foreach driver: supported_drivers
|
||||||
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
||||||
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
||||||
drivers_type_func += ' g_array_append_val (drivers, t);'
|
drivers_type_func += ' g_array_append_val (drivers, t);'
|
||||||
@@ -174,13 +226,27 @@ drivers_type_func += '}'
|
|||||||
|
|
||||||
root_inc = include_directories('.')
|
root_inc = include_directories('.')
|
||||||
|
|
||||||
if get_option('udev_rules')
|
udev_hwdb = get_option('udev_hwdb')
|
||||||
udev_rules_dir = get_option('udev_rules_dir')
|
if not udev_hwdb.disabled()
|
||||||
|
# systemd v248 includes our autosuspend rules
|
||||||
if udev_rules_dir == 'auto'
|
udev_versioned_dep = dependency('udev', version: '>= 248', required: false)
|
||||||
udev_dep = dependency('udev')
|
udev_hwdb_dir = get_option('udev_hwdb_dir')
|
||||||
udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/rules.d'
|
if udev_hwdb.auto()
|
||||||
|
if udev_versioned_dep.found()
|
||||||
|
udev_hwdb_dir = ''
|
||||||
endif
|
endif
|
||||||
|
else
|
||||||
|
if udev_versioned_dep.found()
|
||||||
|
warning('udev hwdb will be installed by both systemd and libfprint')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if udev_hwdb_dir == 'auto'
|
||||||
|
udev_dep = dependency('udev')
|
||||||
|
udev_hwdb_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/hwdb.d'
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
udev_hwdb_dir = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('gtk-examples')
|
if get_option('gtk-examples')
|
||||||
@@ -204,6 +270,7 @@ if get_option('gtk-examples')
|
|||||||
subdir('demo')
|
subdir('demo')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
subdir('data')
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
|
|
||||||
pkgconfig = import('pkgconfig')
|
pkgconfig = import('pkgconfig')
|
||||||
|
|||||||
+6
-6
@@ -6,12 +6,12 @@ option('introspection',
|
|||||||
description: 'Build GObject Introspection repository',
|
description: 'Build GObject Introspection repository',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true)
|
value: true)
|
||||||
option('udev_rules',
|
option('udev_hwdb',
|
||||||
description: 'Whether to create a udev rules file',
|
description: 'Whether to create a udev hwdb',
|
||||||
type: 'boolean',
|
type: 'feature',
|
||||||
value: true)
|
value: 'auto')
|
||||||
option('udev_rules_dir',
|
option('udev_hwdb_dir',
|
||||||
description: 'Installation path for udev rules',
|
description: 'Installation path for udev hwdb',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
value: 'auto')
|
value: 'auto')
|
||||||
option('gtk-examples',
|
option('gtk-examples',
|
||||||
|
|||||||
+6
-1
@@ -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 LD_PRELOAD=<meson-build-dir>/libfprint/libfprint-2.so`
|
||||||
- `export GI_TYPELIB_PATH=<meson-build-dir>/libfprint`
|
- `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).
|
(mainly if it uses random numbers, see `synaptics.c` for an example).
|
||||||
Set the following environment variable to enable this adaptation:
|
Set the following environment variable to enable this adaptation:
|
||||||
- `export FP_DEVICE_EMULATION=1`
|
- `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:
|
The following USB device is used in the example above:
|
||||||
`/dev/bus/usb/001/005`.
|
`/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:
|
4. Record information about this device:
|
||||||
|
|
||||||
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`
|
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0000
|
A: bcdDevice=0000
|
||||||
A: bmAttributes=80
|
A: bmAttributes=80
|
||||||
A: busnum=3
|
A: busnum=3\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
|
H: descriptors=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
|
||||||
A: dev=189:259
|
A: dev=189:259
|
||||||
A: devnum=4
|
A: devnum=4\n
|
||||||
A: devpath=1.1.3
|
A: devpath=1.1.3
|
||||||
L: driver=../../../../../../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=5731
|
A: idProduct=5731
|
||||||
@@ -106,11 +106,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=9100
|
A: bcdDevice=9100
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=3
|
A: busnum=3\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
||||||
A: dev=189:258
|
A: dev=189:258
|
||||||
A: devnum=3
|
A: devnum=3\n
|
||||||
A: devpath=1.1
|
A: devpath=1.1
|
||||||
L: driver=../../../../../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0006
|
A: idProduct=0006
|
||||||
@@ -186,11 +186,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=9100
|
A: bcdDevice=9100
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=3
|
A: busnum=3\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
||||||
A: dev=189:257
|
A: dev=189:257
|
||||||
A: devnum=2
|
A: devnum=2\n
|
||||||
A: devpath=1
|
A: devpath=1
|
||||||
L: driver=../../../../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0006
|
A: idProduct=0006
|
||||||
@@ -270,11 +270,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0415
|
A: bcdDevice=0415
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=3
|
A: busnum=3\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
|
H: descriptors=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
|
||||||
A: dev=189:256
|
A: dev=189:256
|
||||||
A: devnum=1
|
A: devnum=1\n
|
||||||
A: devpath=0
|
A: devpath=0
|
||||||
L: driver=../../../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0002
|
A: idProduct=0002
|
||||||
|
|||||||
+6
-6
@@ -36,11 +36,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0140
|
A: bcdDevice=0140
|
||||||
A: bmAttributes=80
|
A: bmAttributes=80
|
||||||
A: busnum=1
|
A: busnum=1\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
|
H: descriptors=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
|
||||||
A: dev=189:93
|
A: dev=189:93
|
||||||
A: devnum=94
|
A: devnum=94\n
|
||||||
A: devpath=4.4
|
A: devpath=4.4
|
||||||
L: driver=../../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0c26
|
A: idProduct=0c26
|
||||||
@@ -107,11 +107,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=5284
|
A: bcdDevice=5284
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=1
|
A: busnum=1\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
|
H: descriptors=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
|
||||||
A: dev=189:82
|
A: dev=189:82
|
||||||
A: devnum=83
|
A: devnum=83\n
|
||||||
A: devpath=4
|
A: devpath=4
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=1018
|
A: idProduct=1018
|
||||||
@@ -189,11 +189,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0503
|
A: bcdDevice=0503
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=1
|
A: busnum=1\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
|
H: descriptors=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
|
||||||
A: dev=189:0
|
A: dev=189:0
|
||||||
A: devnum=1
|
A: devnum=1\n
|
||||||
A: devpath=0
|
A: devpath=0
|
||||||
L: driver=../../../../bus/usb/drivers/usb
|
L: driver=../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0002
|
A: idProduct=0002
|
||||||
|
|||||||
+128
-218
@@ -1,307 +1,217 @@
|
|||||||
@DEV /dev/bus/usb/001/003
|
@DEV /dev/bus/usb/003/008
|
||||||
USBDEVFS_GET_CAPABILITIES 0 FD010000
|
USBDEVFS_GET_CAPABILITIES 0 FD010000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 D00000000500BA4500611A297F
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980001FE415050000000000030313030303232384C454E4F564F0000474D3138384230004746333230360000312E30322E30310055534200000000005642530000000000303030303030303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051239DE6303030303033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980002FE4150500000000000303130303032343744454C4C00000000474D3138384230004746353238380000312E30342E30352E31302E3530000000000000000000000000000000000000005553420000000000564253000000000030303030303030330000000000000000000000000000000000000000000000000000000000003B5CB43C000000000000555342000000000056425300000000003030303030303033000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F410C0A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F3EB36C6A
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030500FB040093B3ED01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030700D12E0014140342C8AE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000002050049B600C27E4B39
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000050600609F000094D6C40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E0010005080054AB00141441240D0ECF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000030700AC53000F411A349263
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A2000007070007F8005564FA6B157100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000070600B64900007A6860130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000042400F40B000000000000000000000000000000000000000000000000000000000000000095D4A28A
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A50000090500DE2103D6515435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000090C00BC430054640027004D0084CD5EED0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A10000050500807F007BE269C4
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000B250002FD00B786B17D6A044D24C1651C2B1A76F6396D790639F58CA6D62DDDB8E179A9BD4A6C5C6C9200000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A500000B050008F703C6DBFA26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000607006C93000F41A33C2AB4
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000D0700807F0059643EDA283F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000D25007F8000D7843025CC713EA1543DF81EBAAF6BE244543EB9F4BC6FA74E8F246A711CD8C3EA54665F00000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000007070055AA016450891085EC
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000000F070004FB000000E0109A2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000F0C00C13E003E620027005900101FD1980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200080500629D004A354747
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200114500A15E008E0091009E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000988D37C39E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001107008A7500000002FCFB4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000907002BD4000F41D2CA1A81
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001307000EF1004B640F46BD2D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001345007788008A009C009400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D000000000000000000BEDDBBB29400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000A0700C43B016450398D1A9E
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000015070021DE0000007BC22C5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000150C00E41B004E640027004F00755632510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000B0500DF200052FA3E5D
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200174500DC23008200A200AA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000F1B14CECAA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000170700F708000000BAA9831600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000C0700EB14000F416BC2A256
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001907008976005664DBD4593000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200194500F00F008C009C009600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C000000000000000000E3A1F2A19600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000D0700D22D01645041EE0D0E
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001B07000DF2000000CA0273AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001B0C00C8370048640027005A00021B15CE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000E05001FE000EF2AA657
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001D45005BA400A8009100AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C000000000000000000000000008A57E0B3AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001D0700708F003A000B89A2D100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000F070056A9000F416A9F62DF
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001F0700F40B005A625A6BF72B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001F45008D720008009900920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D00000000000000000069C4E77C920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000100700E11E016450A25FACED
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002107006B94002900A6F807F200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000210C00AE510048640027005500DD002B870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200110500FA0500438F0629
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200234500966900870088008800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D0000000000000000000000000074CA825A8800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000230700BD420000008C0CEEF100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000120700659A000F41892EC33C
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000250700926D00556427B73E5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200254500EB14008D00A100900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C0000000000000000000F8D1061900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001307005CA3016450A3026C64
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000027070016E90058265460564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000270C00D32C0057640027004E0017D2351D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001405003AC500FE5F9E23
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020029450011EE007B00950097006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D000000000000000000000000007AB44F7697006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002907003AC500000044F2661300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000150700738C000F41F14DD4AC
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002B0700BE4100566455244C8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002B4500C7380089009C00920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D000000000000000000A0269EE8920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001607009C630164501A0AD4B3
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002D0700916E005F2DD3D14D7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002D0C0054AB004A64002700590057B20D220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200170500877800E690E739
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002F45006C9300A80083008A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000DD3369188A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002F070047B8004C4C4EAAB86E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000180700E21D000F4141D04BDE
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003107009B6400586440DB796400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200314500E21D00080008000800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C000000000000000000E0BA753D0800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000190700DB240164506BFCE486
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003307001FE072635FE0E8A18200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000330C00DA25005464002700500088A694DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001A050016E900A4EAF211
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020035450049B6007D00920094008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000000000000000000000520A47F394008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000350700629D0000006775A83E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001B07005FA0000F41408D8B57
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000370700E619005964B9BF1A2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003745009F600008000800080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C000000000000000000F054EC42080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001C07001BE4016450D2F45C51
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003907009867725F526A136B6D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000390C005DA2004A640027004F005D569D1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001D050000FF0009B0C408
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003B4500659A0084007D008B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000BAEEF1FA8B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003B07004EB1000000D6B5F7C500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001E07009F60000F41F9853380
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003D0700619E005864307089D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A300003D0500629D009DDA98C4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001F0700A659016450D3A99CD8
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003F0700E51A0063324BE2275A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A400003F05006B940099962233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200200500708F00DCB5EECB
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200414500857A0078006F0074009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C0000000000000000000000000079DB6FC674009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000004108001BE400000000315A099D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000021070039C6000F41C7E8B94B
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004307002AD5005A647427533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 A60000436C00EC130001640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900FA60A49A000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000220700D6290164502CAFB954
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000045070005FA0061447F5F4C1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E00100450800D22D000000002B1189D3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200230500CD3200C47A97D1
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200474500F807009500860087008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C0000000000000000000000000074D7CC3787008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000470C0016E9004C640027004D005C10F4310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000240700F906000F417EE0019C
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000490700AD52005764F1A7756700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000499200D22D004C642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50C82BB7E8C2D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000250700C03F01645054CCAEC4
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000004B070029D60041281F96933800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000004B08009C63004C642A9C8BFEAB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002605000DF20079AA0FDB
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002004D45007F80009E008E008E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000D393E7738E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E001004D0800837C004C642ACB9D5A09000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB000F417FBDC115
|
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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004E080037C800A20001A1744041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0700D02F005964C7DF8EA700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0C0047B80052640027004D00E19CE96F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000028070051AE016450E45131B6
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005107000CF300624F1EC75A2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A5000051920021DE0052642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50CCC7D08E82D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002905004AB5002B5AB4E0
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200534500F10E0077007A00720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000000000000000000000C5190965720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000005308006F900052642AB5A4CC36000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002A0700D52A000F41CF205E67
|
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 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 0 0
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000550700F50A0058641D3C23CD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000055050052AD00C5D5FE86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
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
|
|
||||||
|
|||||||
@@ -20,11 +20,21 @@ d.open_sync()
|
|||||||
template = FPrint.Print.new(d)
|
template = FPrint.Print.new(d)
|
||||||
|
|
||||||
def enroll_progress(*args):
|
def enroll_progress(*args):
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
|
||||||
print('enroll progress: ' + str(args))
|
print('enroll progress: ' + str(args))
|
||||||
|
|
||||||
|
def identify_done(dev, res):
|
||||||
|
global identified
|
||||||
|
identified = True
|
||||||
|
identify_match, identify_print = dev.identify_finish(res)
|
||||||
|
print('indentification_done: ', identify_match, identify_print)
|
||||||
|
assert identify_match.equal(identify_print)
|
||||||
|
|
||||||
# List, enroll, list, verify, identify, delete
|
# List, enroll, list, verify, identify, delete
|
||||||
print("enrolling")
|
print("enrolling")
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
p = d.enroll_sync(template, None, enroll_progress, None)
|
p = d.enroll_sync(template, None, enroll_progress, None)
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
print("enroll done")
|
print("enroll done")
|
||||||
|
|
||||||
print("listing")
|
print("listing")
|
||||||
@@ -33,17 +43,31 @@ print("listing done")
|
|||||||
assert len(stored) == 1
|
assert len(stored) == 1
|
||||||
assert stored[0].equal(p)
|
assert stored[0].equal(p)
|
||||||
print("verifying")
|
print("verifying")
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
verify_res, verify_print = d.verify_sync(p)
|
verify_res, verify_print = d.verify_sync(p)
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
print("verify done")
|
print("verify done")
|
||||||
|
del p
|
||||||
assert verify_res == True
|
assert verify_res == True
|
||||||
print("identifying")
|
|
||||||
identify_match, identify_print = d.identify_sync(stored)
|
identified = False
|
||||||
print("identify done")
|
deserialized_prints = []
|
||||||
assert identify_match.equal(identify_print)
|
for p in stored:
|
||||||
|
deserialized_prints.append(FPrint.Print.deserialize(p.serialize()))
|
||||||
|
assert deserialized_prints[-1].equal(p)
|
||||||
|
del stored
|
||||||
|
|
||||||
|
print('async identifying')
|
||||||
|
d.identify(deserialized_prints, callback=identify_done)
|
||||||
|
del deserialized_prints
|
||||||
|
|
||||||
|
while not identified:
|
||||||
|
ctx.iteration(True)
|
||||||
|
|
||||||
print("deleting")
|
print("deleting")
|
||||||
d.delete_print_sync(p)
|
d.delete_print_sync(p)
|
||||||
print("delete done")
|
print("delete done")
|
||||||
|
|
||||||
d.close_sync()
|
d.close_sync()
|
||||||
|
|
||||||
del d
|
del d
|
||||||
|
|||||||
+54
-51
@@ -1,30 +1,30 @@
|
|||||||
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8
|
P: /devices/pci0000:00/0000:00:14.0/usb3/3-2
|
||||||
N: bus/usb/001/003=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
N: bus/usb/003/008=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||||
E: DEVNAME=/dev/bus/usb/001/003
|
E: DEVNAME=/dev/bus/usb/003/008
|
||||||
E: DEVTYPE=usb_device
|
E: DEVTYPE=usb_device
|
||||||
E: DRIVER=usb
|
E: DRIVER=usb
|
||||||
E: PRODUCT=27c6/60a2/100
|
E: PRODUCT=27c6/5840/100
|
||||||
E: TYPE=239/0/0
|
E: TYPE=239/0/0
|
||||||
E: BUSNUM=001
|
E: BUSNUM=003
|
||||||
E: DEVNUM=003
|
E: DEVNUM=008
|
||||||
E: MAJOR=189
|
E: MAJOR=189
|
||||||
E: MINOR=2
|
E: MINOR=263
|
||||||
E: SUBSYSTEM=usb
|
E: SUBSYSTEM=usb
|
||||||
E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
|
E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
|
||||||
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
|
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
|
||||||
E: ID_VENDOR_ID=27c6
|
E: ID_VENDOR_ID=27c6
|
||||||
E: ID_MODEL=Goodix_USB2.0_MISC
|
E: ID_MODEL=Goodix_USB2.0_MISC
|
||||||
E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC
|
E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC
|
||||||
E: ID_MODEL_ID=60a2
|
E: ID_MODEL_ID=5840
|
||||||
E: ID_REVISION=0100
|
E: ID_REVISION=0100
|
||||||
E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDCBEE4D7B_XXXX_MOC_B0
|
E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDE1AD5CBA_XXXX_MOC_B0
|
||||||
E: ID_SERIAL_SHORT=UIDCBEE4D7B_XXXX_MOC_B0
|
E: ID_SERIAL_SHORT=UIDE1AD5CBA_XXXX_MOC_B0
|
||||||
E: ID_BUS=usb
|
E: ID_BUS=usb
|
||||||
E: ID_USB_INTERFACES=:ff0000:
|
E: ID_USB_INTERFACES=:ff0000:
|
||||||
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
|
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
|
||||||
E: ID_PATH=pci-0000:00:14.0-usb-0:8
|
E: ID_PATH=pci-0000:00:14.0-usb-0:2
|
||||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8
|
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2
|
||||||
E: LIBFPRINT_DRIVER=AuthenTec AES1610
|
E: LIBFPRINT_DRIVER=Goodix MOC Fingerprint Sensor
|
||||||
A: authorized=1
|
A: authorized=1
|
||||||
A: avoid_reset_quirk=0
|
A: avoid_reset_quirk=0
|
||||||
A: bConfigurationValue=1
|
A: bConfigurationValue=1
|
||||||
@@ -37,32 +37,32 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0100
|
A: bcdDevice=0100
|
||||||
A: bmAttributes=a0
|
A: bmAttributes=a0
|
||||||
A: busnum=1
|
A: busnum=3\n
|
||||||
A: configuration=UIDCBEE4D7B_XXXX_MOC_B0
|
A: configuration=UIDE1AD5CBA_XXXX_MOC_B0
|
||||||
H: descriptors=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
H: descriptors=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||||
A: dev=189:2
|
A: dev=189:263
|
||||||
A: devnum=3
|
A: devnum=8\n
|
||||||
A: devpath=8
|
A: devpath=2
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=60a2
|
A: idProduct=5840
|
||||||
A: idVendor=27c6
|
A: idVendor=27c6
|
||||||
A: ltm_capable=no
|
A: ltm_capable=no
|
||||||
A: manufacturer=Goodix Technology Co., Ltd.
|
A: manufacturer=Goodix Technology Co., Ltd.
|
||||||
A: maxchild=0
|
A: maxchild=0
|
||||||
L: port=../1-0:1.0/usb1-port8
|
L: port=../3-0:1.0/usb3-port2
|
||||||
A: power/active_duration=324448
|
A: power/active_duration=2684
|
||||||
A: power/async=enabled
|
A: power/async=enabled
|
||||||
A: power/autosuspend=2
|
A: power/autosuspend=2
|
||||||
A: power/autosuspend_delay_ms=2000
|
A: power/autosuspend_delay_ms=2000
|
||||||
A: power/connected_duration=5916532
|
A: power/connected_duration=54348
|
||||||
A: power/control=auto
|
A: power/control=auto
|
||||||
A: power/level=auto
|
A: power/level=auto
|
||||||
A: power/persist=1
|
A: power/persist=1
|
||||||
A: power/runtime_active_kids=0
|
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_enabled=enabled
|
||||||
A: power/runtime_status=active
|
A: power/runtime_status=active
|
||||||
A: power/runtime_suspended_time=5588987
|
A: power/runtime_suspended_time=51550
|
||||||
A: power/runtime_usage=0
|
A: power/runtime_usage=0
|
||||||
A: power/wakeup=disabled
|
A: power/wakeup=disabled
|
||||||
A: power/wakeup_abort_count=
|
A: power/wakeup_abort_count=
|
||||||
@@ -75,38 +75,39 @@ A: power/wakeup_max_time_ms=
|
|||||||
A: power/wakeup_total_time_ms=
|
A: power/wakeup_total_time_ms=
|
||||||
A: product=Goodix USB2.0 MISC
|
A: product=Goodix USB2.0 MISC
|
||||||
A: quirks=0x0
|
A: quirks=0x0
|
||||||
A: removable=fixed
|
A: removable=removable
|
||||||
A: rx_lanes=1
|
A: rx_lanes=1
|
||||||
A: serial=UIDCBEE4D7B_XXXX_MOC_B0
|
A: serial=UIDE1AD5CBA_XXXX_MOC_B0
|
||||||
A: speed=12
|
A: speed=12
|
||||||
A: tx_lanes=1
|
A: tx_lanes=1
|
||||||
A: urbnum=2180
|
A: urbnum=15
|
||||||
A: version= 2.00
|
A: version= 2.00
|
||||||
|
|
||||||
P: /devices/pci0000:00/0000:00:14.0/usb1
|
P: /devices/pci0000:00/0000:00:14.0/usb3
|
||||||
N: bus/usb/001/001=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
N: bus/usb/003/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||||
E: DEVNAME=/dev/bus/usb/001/001
|
E: DEVNAME=/dev/bus/usb/003/001
|
||||||
E: DEVTYPE=usb_device
|
E: DEVTYPE=usb_device
|
||||||
E: DRIVER=usb
|
E: DRIVER=usb
|
||||||
E: PRODUCT=1d6b/2/504
|
E: PRODUCT=1d6b/2/508
|
||||||
E: TYPE=9/0/1
|
E: TYPE=9/0/1
|
||||||
E: BUSNUM=001
|
E: BUSNUM=003
|
||||||
E: DEVNUM=001
|
E: DEVNUM=001
|
||||||
E: MAJOR=189
|
E: MAJOR=189
|
||||||
E: MINOR=0
|
E: MINOR=256
|
||||||
E: SUBSYSTEM=usb
|
E: SUBSYSTEM=usb
|
||||||
E: ID_VENDOR=Linux_5.4.0-29-generic_xhci-hcd
|
E: ID_VENDOR=Linux_5.8.0-38-generic_xhci-hcd
|
||||||
E: ID_VENDOR_ENC=Linux\x205.4.0-29-generic\x20xhci-hcd
|
E: ID_VENDOR_ENC=Linux\x205.8.0-38-generic\x20xhci-hcd
|
||||||
E: ID_VENDOR_ID=1d6b
|
E: ID_VENDOR_ID=1d6b
|
||||||
E: ID_MODEL=xHCI_Host_Controller
|
E: ID_MODEL=xHCI_Host_Controller
|
||||||
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||||
E: ID_MODEL_ID=0002
|
E: ID_MODEL_ID=0002
|
||||||
E: ID_REVISION=0504
|
E: ID_REVISION=0508
|
||||||
E: ID_SERIAL=Linux_5.4.0-29-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
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_SERIAL_SHORT=0000:00:14.0
|
||||||
E: ID_BUS=usb
|
E: ID_BUS=usb
|
||||||
E: ID_USB_INTERFACES=:090000:
|
E: ID_USB_INTERFACES=:090000:
|
||||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||||
|
E: ID_AUTOSUSPEND=1
|
||||||
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||||
E: ID_PATH=pci-0000:00:14.0
|
E: ID_PATH=pci-0000:00:14.0
|
||||||
E: ID_PATH_TAG=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: bMaxPower=0mA
|
||||||
A: bNumConfigurations=1
|
A: bNumConfigurations=1
|
||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0504
|
A: bcdDevice=0508
|
||||||
A: bmAttributes=e0
|
A: bmAttributes=e0
|
||||||
A: busnum=1
|
A: busnum=3\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||||
A: dev=189:0
|
A: dev=189:256
|
||||||
A: devnum=1
|
A: devnum=1\n
|
||||||
A: devpath=0
|
A: devpath=0
|
||||||
L: driver=../../../../bus/usb/drivers/usb
|
L: driver=../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0002
|
A: idProduct=0002
|
||||||
A: idVendor=1d6b
|
A: idVendor=1d6b
|
||||||
A: interface_authorized_default=1
|
A: interface_authorized_default=1
|
||||||
A: ltm_capable=no
|
A: ltm_capable=no
|
||||||
A: manufacturer=Linux 5.4.0-29-generic xhci-hcd
|
A: manufacturer=Linux 5.8.0-38-generic xhci-hcd
|
||||||
A: maxchild=12
|
A: maxchild=4
|
||||||
A: power/active_duration=5879432
|
A: power/active_duration=2790916
|
||||||
A: power/async=enabled
|
A: power/async=enabled
|
||||||
A: power/autosuspend=0
|
A: power/autosuspend=0
|
||||||
A: power/autosuspend_delay_ms=0
|
A: power/autosuspend_delay_ms=0
|
||||||
A: power/connected_duration=5916912
|
A: power/connected_duration=15607832
|
||||||
A: power/control=auto
|
A: power/control=auto
|
||||||
A: power/level=auto
|
A: power/level=auto
|
||||||
A: power/runtime_active_kids=2
|
A: power/runtime_active_kids=1
|
||||||
A: power/runtime_active_time=5879430
|
A: power/runtime_active_time=2790874
|
||||||
A: power/runtime_enabled=enabled
|
A: power/runtime_enabled=enabled
|
||||||
A: power/runtime_status=active
|
A: power/runtime_status=active
|
||||||
A: power/runtime_suspended_time=37481
|
A: power/runtime_suspended_time=12816956
|
||||||
A: power/runtime_usage=0
|
A: power/runtime_usage=0
|
||||||
A: power/wakeup=disabled
|
A: power/wakeup=disabled
|
||||||
A: power/wakeup_abort_count=
|
A: power/wakeup_abort_count=
|
||||||
@@ -167,5 +168,7 @@ A: rx_lanes=1
|
|||||||
A: serial=0000:00:14.0
|
A: serial=0000:00:14.0
|
||||||
A: speed=480
|
A: speed=480
|
||||||
A: tx_lanes=1
|
A: tx_lanes=1
|
||||||
A: urbnum=1319
|
A: urbnum=584
|
||||||
A: version= 2.00
|
A: version= 2.00
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Executable
+54
@@ -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)
|
||||||
+35
-10
@@ -5,6 +5,7 @@ envs.set('G_MESSAGES_DEBUG', 'all')
|
|||||||
|
|
||||||
# Setup paths
|
# Setup paths
|
||||||
envs.set('MESON_SOURCE_ROOT', meson.source_root())
|
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'))
|
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
|
# Set FP_DEVICE_EMULATION so that drivers can adapt (e.g. to use fixed
|
||||||
@@ -12,7 +13,11 @@ envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
|
|||||||
envs.set('FP_DEVICE_EMULATION', '1')
|
envs.set('FP_DEVICE_EMULATION', '1')
|
||||||
|
|
||||||
# Set a colon-separated list of native drivers we enable in tests
|
# 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')
|
envs.set('NO_AT_BRIDGE', '1')
|
||||||
|
|
||||||
@@ -21,26 +26,36 @@ drivers_tests = [
|
|||||||
'elan',
|
'elan',
|
||||||
'synaptics',
|
'synaptics',
|
||||||
'vfs0050',
|
'vfs0050',
|
||||||
|
'vfs301',
|
||||||
'vfs5011',
|
'vfs5011',
|
||||||
|
'vfs7552',
|
||||||
'goodixmoc',
|
'goodixmoc',
|
||||||
|
'nb1010',
|
||||||
]
|
]
|
||||||
|
|
||||||
if get_option('introspection')
|
if get_option('introspection')
|
||||||
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
|
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
|
||||||
|
virtual_devices_tests = [
|
||||||
|
'virtual-image',
|
||||||
|
'virtual-device',
|
||||||
|
]
|
||||||
|
|
||||||
if 'virtual_image' in drivers
|
|
||||||
python3 = find_program('python3')
|
|
||||||
unittest_inspector = find_program('unittest_inspector.py')
|
unittest_inspector = find_program('unittest_inspector.py')
|
||||||
base_args = files('virtual-image.py')
|
|
||||||
suite = []
|
|
||||||
|
|
||||||
r = run_command(unittest_inspector, files('virtual-image.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')
|
unit_tests = r.stdout().strip().split('\n')
|
||||||
|
|
||||||
if r.returncode() == 0 and unit_tests.length() > 0
|
if r.returncode() == 0 and unit_tests.length() > 0
|
||||||
suite += 'virtual-image'
|
suite += vdtest
|
||||||
else
|
else
|
||||||
unit_tests = ['virtual-image']
|
unit_tests = [vdtest]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
foreach ut: unit_tests
|
foreach ut: unit_tests
|
||||||
@@ -59,17 +74,19 @@ if get_option('introspection')
|
|||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
else
|
else
|
||||||
test('virtual-image',
|
test(vdtest,
|
||||||
find_program('sh'),
|
find_program('sh'),
|
||||||
args: ['-c', 'exit 77']
|
args: ['-c', 'exit 77']
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
foreach driver_test: drivers_tests
|
foreach driver_test: drivers_tests
|
||||||
driver_envs = envs
|
driver_envs = envs
|
||||||
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
|
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,
|
test(driver_test,
|
||||||
find_program('umockdev-test.py'),
|
find_program('umockdev-test.py'),
|
||||||
args: join_paths(meson.current_source_dir(), driver_test),
|
args: join_paths(meson.current_source_dir(), driver_test),
|
||||||
@@ -167,6 +184,13 @@ foreach test_name: unit_tests
|
|||||||
)
|
)
|
||||||
endforeach
|
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)
|
gdb = find_program('gdb', required: false)
|
||||||
if gdb.found()
|
if gdb.found()
|
||||||
add_test_setup('gdb',
|
add_test_setup('gdb',
|
||||||
@@ -187,6 +211,7 @@ if valgrind.found()
|
|||||||
timeout_multiplier: 10,
|
timeout_multiplier: 10,
|
||||||
env: [
|
env: [
|
||||||
'G_SLICE=always-malloc',
|
'G_SLICE=always-malloc',
|
||||||
|
'UNDER_VALGRIND=1',
|
||||||
('LIBFPRINT_TEST_WRAPPER=@0@ --tool=memcheck --leak-check=full ' +
|
('LIBFPRINT_TEST_WRAPPER=@0@ --tool=memcheck --leak-check=full ' +
|
||||||
'--suppressions=@1@ --suppressions=@2@').format(
|
'--suppressions=@1@ --suppressions=@2@').format(
|
||||||
valgrind.path(), glib_suppressions, python_suppressions)
|
valgrind.path(), glib_suppressions, python_suppressions)
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
@DEV /dev/bus/usb/001/003
|
||||||
|
USBDEVFS_GET_CAPABILITIES 0 FD010000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 2 0 0 8 8 0 8038010008000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 16 16 0 803701001000000000000000F7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 2 0 0 12 12 0 800D03000C00000000040000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 16 16 0 80200300100000000000000000000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 2 0 0 32 32 0 8012040020000000020000000000000000000000000000000000000020000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 16 16 0 80200400100000000000000003000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000010000000001000001E5E5E5E5E5E4E4E4E5E5E5E4E6E7E6E6BEE6E4E5E4E3E5E6E3E4E4E3E5E6E4E5E6E5E5E5E4E4E5E5E3E3E2E3E3E4E4E4E4E5E5E5E2E2E3C9E2E4E3E4E3E3E4E4E8E8E7E8E5E5E3E4E5E3E4E5E3E4E5E3E4E4E5E5E3E4E4E4E4E5E5E5E3E3E2E3E4E3E3E3E2E3E3E3E3E5E5E5E5E5E4E5E3E4E4E3E5E66AE3E4E5E4E5E5E4E4E5E4E2E2E3E6E5E5E4E4E3E5E3E6E6E7E6E4E4E3E2E5E5E5E6E4E6E5E2E2E3E2E3E4E3E3E4E5E3E5E5E5E3E4E4E6E4E5E5E4E3E4E2E3E5E4E4E5E6E4E5E2E3E2E3E2E3E4E4E5E4E3E3E5E6E6E6E4E4E3E3E6E5E5E6E5E5E5E6E5E5E5E5E5E4E0E4E4E3E2E3E3E3E2E4E3E4E4E5E5E4E5E6E2E3E3E2E4E4E4E3E4E2E4E6E4E5E4E4E6E6E7E7E6E7E6E7E8E6E7E7E8E8E8E8E7E6E7E6E7E5E7E7E7E7E7E6E6E4E4E6E3E4E3E4E4E3E3E4E2E3E4E3E4E3E4E5E3E5E4E5E4E4E3E2E5E5E5E4E5E6E7E6E4E5E4E5E6E7E7E8E2E3E4E4E7E5E7E6E6E3E4E5E7E7E7E8E6E5E6E6E6E5E5E6E6E5E6E4E4E5E4E4E7E7E5E5E5E6E4E7E7E6E5E6E4E4E6E6E6E6E5E5E5E5E5E5E5E4E5E6E4E5E6E6E4E4E5E4E4E6E6E6E6E6E6E5E6E7E7E6E5E7E5E5E7E6E5E7E5E5E7E5E6E4E5E6E7E6E5E7E4E5E5E5E8E6E7E0E6E6E7E7E8E8E9E9E3E5E5E4E6E5E6E7E6E5E5E6E6E5E5E6E5E4E4E3E6E6E6E6E5E4E3E4E6E7E6E5E6E7E5E5E6E6E7E7E7E7E8E6E7E5E7E5E7E6E7E8E6E6E7E5E5E5E5E5E5E2E6E5E7E6E7E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000030000000001000001E7E7E7E7E6E6E6E6E7E7E7E8E8E8E6E8E9E7E8E9E0E4E5E4E8E7E8E7E5E4E4E5E6E1E5E5E7E6E6E6E6E5E4E4E5E4E3E5E5E6E4E5E4E5E5E5E2E6E4E3E5E5E5E6E6E6E5E5E6E5E6E6E7E6E6E7E5E4E5E5E4E5E5E7E7E7E7E7E5E4E4E4E4E3E3E3E5E5E6E5E6E6E5E5E4E4E4E2E6E6E4E5E6E6E8E6E7E6E5E8E6E6E4E5E6E6E7E6E6E6E6E6E6E6E6E5E5E7E5E5E5E6E6E7E5E6E5E5E5E5E5E4E6E6E8E6E0E6E6E7E7E7E8E8E6E6E7E6E7E6E8E6E6E5E6E6E7E6E6E5E5E6E4E5E6E5E6E6E6E4E6E5E7E6E6E6E2E6E7E6E6E5E5E6E7E7E6E5E5E5E6E5E7E7E6E6E5E3E5E3DEE5E6E5E4E5E2E5E6E5E4E5E6E4E5E5E5E5E4E4E6E6E7E7E6E7E6E5E6E4E6E5E4E5E3E4E8E6E7E6E8E7E7E9E7E5E7E9E6E6E5E7E8E7E7E7E7E6E6E6E7E6E7E5E3E4E6E5E4E4E4E6E4E5E3E7DDE5E6E5E6E5E5E7E3E4E5E4E4E5E4E5E3E3DCE4E6E5E6E7E4E4E4E6E5E4E7E7E4E4E3E5E6E6E7E7E5E4E6E5E4E4E5E5E6E5E5E5E6E6E5E6E3E6E5E6E4E2E2E4E5E6E4E4E4E5E4E5E9E9E8E7E6E6E7E7E8E7E7E7E5E4E5E3E6E8E7E7E5E5E3E4E4E5E3E4E5E5E5E5E6E5E4E5E6E7E7E7E5E7E6E6E4E6E6E6E5E4E094E5E6E6E6E7E5E6E5E7E6E7E6E5E6E6E7E7E6E6E6E6E7E8E7E7E5E5E6E6E6E8E6E6E5E5E7E7E7E6E7E5E7E5E5E8E8E7E7E7E5E7E4E6E5E4E6E5E7E4E5E7E6E6E6E7E5E6E6E6E4E6E6E5E7E6E6E5E5E3E6E8E7E6E7E4E2E4E4E6E6E7E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000050000000001000001E6E6E6E6E8E7E7E7E8E6E7E8E9E8E8E8E8E8E8E9E7E6E6E9E6E7E4E6E5E5E6E5E5E6E7E6E6E5E6E6E4E5E4E4E3E5E2E4E5E4E4E5DDE3E4B5E5E7E6E5E5E6E5E1E6E7E7E7E5E6E7E5E5E5E5E5E6E5D6E5A1E4E6E6E4E5E4E3E4E4E4E5E4E5E4E5E6E6E6E6E7E7E6E7E4E4E5E4E6E5E4E6E47AE5E5E7E7E6E7E4E4E5E3E6E4E5E5E4E4E2E3E6E7E7E4E5E6E7E6E6E7E6E7E5E6E6E4E6E7E6E5D4E7E8E7E3E4E5E4E6E6E5E7E5E4E5E3E3E5E7E6E4E3E4E6E6E7E7E7E4E4E5E4E6E7E6E8E7E6E6E7E9E8E9E9E7E6E6E6E4E6E5E4E6E6E7E4E6E6E7E6E7E6E6E5E4E4E5E5E6E5E6E4E6E6E5E6E6E4E5E5E5E6E5E7E6E6E6E7E5E6E5E5E7E6E8E6E4E4E5E5E5E6E5E5E8E8E7E7E6E6E6E6E8E6E8EAE7E9E8E8E8E8E8E9E6E6E7E6E4E5E6E4E5E4E3E5E5E5E5E5E4E5E48B80E4E5E0E7E5E8E6E4E5E5E5E6E2D2E6E7E6E5E6E2E3E5E3E6E8E417D4E3E6E6E6E4E5E5E6E4E6E6E5E6E5E5E7E7E6E7E6E5E4E5E4E5E4E6E7E6E7E7E5E4E6E3E6E4E5E780E6E5E6E4E4E3E4E4E5E6E4E5E5E5E4E7E7E7E6E4E5E4E5E6E1E8E8E6E7E7E8E7E5E5E6E0E5E5D0E4E4E3E4E7E4E6E5E3E4E4E5E5E6E5E6E5E4E3E3DEE2E6E6E5E5E5E4E2E4E6E692E7E6E6E4E6E5E5E3E5E5E6E4E4E4E5E4E5E5E6E6E4E5E6E7E5E5E6E5E5E5E5E6E5E5E5E7E5E7E7E6E6E6E6E6E6E5E6E4E4E5E4E5E6E4E4E6E5E5E6E6E7E7E5E4E5E4E5E6E3E5E5E3E5E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000070000000001000001E5E5E5E5E7E7E8E7E4E8E8E9E9E7E8E8E9E8E9E8E6E8E7E659E5E5E578E5E5E4E5E4E5E5E3AFE4E2E4E0E3E5E0E3E5E5E6E6E7E6E3CDE4E3E6E400E1E3E4E6E3E8E7E6E7E4E3E5E4E5E5E5E5E5E6E5E6E6E6E5E7E4E5E4E5E5E5E4E1D8E6E719E5E7E7E6E5E5E4E6E5E4E4E5E0E7E7E7E7E7E678E6E7E7E5E4E6E6E5E6E6E5E6E4E5E4E4E6E3E6E1E5E6E5E6E4E7E6E6E6E4E5E6E7E6E5E6E7E2E6E7E4E6E6E6E7E7E5E6E6E5E7E6E6E8E7E6E5E5E3E2E4E4E5E6E6E7E4E6E6A6E4E6E5E6E5E5E7E5E6E4E4E3E4E4E7E5E5E4E4E3E5E6E7E6E5E7E4E5E5E5E6E6E6E6E4E4E5E5E7E6E5E7E3E4E3E4E8E7E6E7E5E6E4E5E4E6E5E5E6E5E4E4E7E5E7E6E4E3E5E5E6E6E7E7E7E7E7E7E8E8E8EAE8E8E7E8E9E8E8E9E9E8D8E8E7E6E6E789E3E1E4E3E390E4E5E6E5E6E4E4E5E2E6E5E7E6E7E5E5E5E1E3E5030CE1000019E4E3E3E4E5E3E5E7E5E6E6E6E7E7E6E6E6E6E5E7E6E6E5E5E6E5E7E5E69BE4E7E6E6E5E5E4E4E4E7E7E6E7E4E4E4E5E7E7E7E6E5E5E7E7E6E5E6E6E4E4E4E5E6E7E7E7E5E7E6E5E5E4E6E6E5E4E4E4D8E6E6E5E5E6E6E6E4E5E3E2E6E3E6E7E3E3E4E3E6E6E6E6E5E6E7E7E4E5E6E6E6E7E5E3E5E5E6E7E4E5E4E4E7E7BCE5E5E4E5E6E6E7E7E6D6E4E6E4E7E6DDE5E7E6E7E6E5E631E4E8E7E7E6E7E6E6E7E8E7E6E7E7E5E5E5E5E4E0E6E7E6E6E6E7E5E5E5E7E7E8E7E8E7E6E5E7E7E6E7E5E4E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000090000000001000001E5E5E6E5E5BEE1E6EAE6E8E9E7E7E6E6EAE6E9E7E6E7E6E7E5E7E3E7E4E3E2E5E5E4D8E4E4E5E4E5E4E4E44599E3E5E6E3E2E1E3E5E4E03100E100000078E5E5E4E4E5E5E6E6E5E5E3E4E5E4E6E7E4E6E7E5E4E4E5E3E3E4E42B0000D6E5E4E6E6E6E5E5E5E3E3E4E5E4E4E6E4E5E4E4E8E6E7E8E6E6E6E6E7E6E6E7E5E6E5E6E5E5E6E5E5E6E6E4E6E6E6E4E3E2E5E6E6E5B7E5E3E5E5E5E5E6E5E6E5E4E5E6E585E4E5E6E5E7E6E4E3E6E5E4E5E5E5E6E4E4E6E6E5E7E6E5E5E4E3E5E5E5E5E4E5E5E4E4E5E5E4E5E4E4E5E6E6E6E5E5E5E6E5E4E4E0E1E3E4E4E59BE3E5E5E4B5BEE5E6E5D6E5E5E6E5E4E5E6E4E6E4E5E6E5E6E5E4E7E5E5E5E5E5E4E5E2E7E6E7E6E8E7E7E8E7E6E7E7E8E9E8E8E8E7E8E7E8D2E7E7E6E5E4E6E6DDE6E22DE3E4E7E9E6E5E7E2E2E3A62278E4E7E4E4E5E4E6E7E078E08B0000001B249DB3E4E0E3E6E5E7E7E6E6E8E4E6E4E8E6E4E5E4E4E4E4E2E6E6851D00009BE4E4E6E5E6E5E5E4E3E5E8E7E7E8E6E5E6E500B7E6E5E6E5B33628E4E5E7E6E5E5E5E7E5E6E2E5E5E5E4E6E5E3E3E6E6E4E5E8E7E8E7E6E5E5E5E6E1E6E5E6E5E5E4CBE6E6E7E8E7E7E6E5E5E4E5E5E6E7E8E6E3E4E4E8E8E7E7E5E4E6E3E5E6E5E6E6E5E5E5E7E3E6E7E7E7E7E7E6E7E5E6E5E6E7E7E4E5E3E4E6E5E6E7E5E4E5E5E7E5E5E5E6E6E5E5E7E7E5E7E8E8E6E7E8E5E5E7E5E7E6E7E4E5E5E5E6E5E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000000B0000000001000001E3E4E4E4E6E7E6E6E8E6E8E7E9E2E8E8E9E9E9E8E6E7E1E6E5E4E5E5E4E5E2E47300E3E4E3E4E3E3E4E3D6E1432B0043E6E7E7E5E5E5E5DFE3E0000026000024E5E6E5E4E5E2E4E5E5E4E0E34141E3E4E4E3E3E3E6E4E4E5E4E3000000B3E5E5E5E6E5E6E8E610E4E4E5E5E5E7E8905F001D83E2E5E2E4E3E2E1A600E4E6E7E5E3E5E4E3E4E5E7E6E8E5E4E4E5E4E5E5E6E5E6E5E4E4E4E4E4E3E4E4E4E4E2E3E6E7E6E6E5E4E3E2E6E5E7E5E4E2E5E3E7E5E5E5E5E4E5E7E7E6E6E6E5E4E3E3E3E5E7E5E5E5E5E4E6E6E5E5E6E5E6E6E6E3E5E4E6E6E4E5E6E4E4E5E5E5E4E3E3E4E4E3E4E5E6E3E4E4E5E4E7E6E5E5E7E5E6E6E7E4E6E6E6E5E6E6E4E5E5E2E7E7E7E7E7E6E7E8E6E7E7E8EBEAE9E9E4E7E8E7E8E7E9E8E7E3C0E7E5E6E6E324242B89C7E5E6E5E2E473E4E5050012E5E5E2E6E59BE5E6E589000000520100D0E6E5D4E4E3E5E4E5E4E5A6031B0092E5E3E4E4E2E4E5E3E4E50022000017E3E6E7E6E6E3E10057E3E5E5E6E4E30000039F0CE3E4E4E3E3E6E05B2D05E7E6E7E6E5E5E4E9E7E6E9E1E4E4E3E6E5E5E5E6E6E6E7E6E4E5E7E6E4E6E5E6E4E4E4E7E6E7E8E5E6E4E5E7E7E8E8E6E6E4E5E6E4E6E5E4E5E5E6E7E6E6E6E7E5E6E7E7E6E6E7E5E2E6E6E6E7E6E7E7E8E7E7E97EE7E7E6E6E6E5E6E5E5E5E5E5E5E6E7E6E6E7E6E6E7E7E6E5E6E6E6E5E6E5E6E6E8E7E6E7E5AAE7E8E8E7E6E5E5E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000000D0000000001000001E3E3E3E2E6E6E7E6E8E6E6E7E6E7E7E7E3E4E4E1E5E0E0E5E6E6CBE5DEE4E1E07E002B0000DBE2E1E5E4E4E5E300001243E40001E2E1D0E0006A000024000000E5E6E7E8E4E3E3E4E2E3E3E300380000E6E4E6E5E3E2E3E2E3E30000000000E2E485E4E5E00599000EDBE3E4E4E4E3B100000000E4E6E5E5E3E400D2317AE4E1E2E1E3E3E5E4E5E5E7E6E6E5A4222BE2E1E5E4E4E600E6E6DCE4E5E4E0E3E3E3E4E5E4E3E3E1E4E3E5E4E6E6E3E3E2E3E4E5E4E4E2E2E3E2E694E5E4E2E2E3C9E6E8E6E7E5E6E4E4E3E4E5E4E5E5E4E5E4E5E5E4E4E4E2E4E4E2E2CBE5E5E7E5E5E5E5E4E5E6DDE5E5E5E2E4E3E6E4E5E3E3E4E4E6E5E6E6E4E4E5E4E4E5E5E5E7E7E6E7E7E5E6E7E6E6E7E7E9EAE9E8E8E8E8E9E5E3E0E6E3E4E3DFE1E2E2E3BC476D831720191080E4E5E5E27300260000152DE2E3E0E29FE30000007800009BE4E4E4E5E5E4E3E5E4E36F00000010DEE3E4E5E517E2E3E5E50000000083E3D0E7E4E4E2789400AF83E4E5E6E6E5E40000330041E4E4E4E3E5712FE20CE4E4E4E4E3E3E5E4E6E5E6E6E6E3CB5FE5E3E5E6E5E4E7E5E7E5E5E3E3E5E5E6E4E4E5E5E5E5E4E5E4E2E5E4E7E5E4E3E4E2E4E5E5E4B3E6E4E6E8E5E7E7E3E4E5A6E6E7E6E6E4E4E2DFE5E5E4E5E6E5E6E5E4E5E6E4E6E3E6E3E6E6E5E4E6E6E7E6E4E5DDE5E6E7E6E6E3E5E0E7E5E6E7E5E6E4E4E5E8E7E6E0E2E5E5E4E4E3E4E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000000F0000000001000001E5E4E5E5E6E6E6E6E7E7E8E8E9E7E8E6E8E090E8E6E6E5E4E5E5E3E5E5E4E5E5E2E4050001000094E1E2E3E2E3D00E4300150064E105B1DDE4DC5D0000000000E0E5E3E2E7E5E5E3E2E3E2DB2200001B01E2E2E3E4E37CE1E3E4E3240000000049E3E5E4E6CBE4BA9B459BE5E4E3E2C90020410000E7E6E5E6E03600B55BE4E5E6E3E4E3E6B1E4A8E5E5E5E4E58B3A33E3E5E5E5E5E5E4E3DFE4E4E4E6E6E5E4E4E5E6AFE2E4E4E3E5E5E5E4E6E6E5E6006AE3E7E0E4E3E3E6E5E4E4E3E4E4E3E6E6E6E7E5E5E347E2E4E4E4E4E5E7E4E4E3E5E4E6E6E4C9E3E6E6E4E5E5E5E7E6E5E5E5E5E4E5E3E4E4E2E6E2E6E7E7E7E675E4E6E8E5E8E6E5E6E3E5E4E4E4E7E7E7E7E6D8E6E5E8E8E8E8E7E6E4E5E9E9EBEAE4E5E59D1D0C266FE1E2E1E1E61B000003000C6F6DE4E5E4E0E1CB0000000C0EDF7E01E1E1E6E5D80000000000E3E4E5E4E4E4E3E4E5E1E1A6DB830E00E5E4E4E4E3E2E3E3E0E2E3870028000096E4E6DE8E00451B0C68E4E5E3E5A80000000000E3E7E4E43A003E0038E4E3E5E5E5E4E449DE4E00C9E6E5E6E0B1B7E7E5E6E7E7E6E673220000E5BAE5E6E7E5E4E0E3E46FE4E5E7E4E4E5E7E7E6E700E3E3E3E5E6E5E5E5991BC5E2E5E7E7E6E5E6E7E7E5E35F20E5E5E6E5E4E3E4E5E6E6E6E5E5E4E5DBE6E6E7E4E4E4E4E8E6E6E6E4E4E5E4E6E7E5E2E3E5E5E4E0E571E4E7E6E7E7E7E6E2E6E5E5E7E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000110000000001000001E4E4E5E2E8E7E7E9E6E6E7E8E6E7E8E4E5E7E6E6E4E4E378E29600C9E1E2E3E2B1E2000000DC003EACB5E0E3E21BE00000C20000D2E08315E3E3E3191000002B00E2E5E3E4E4E3E4E0E5E4BCE2E528004C0500E4E4E3E3B3920AE2E3E400002600BCE1E1E30500735D000000E6E5E3E7D800000066E7E7E6E4E300001968E5E4E2E3E4B5DDAC83730E03E3E3E4E3626DE5E4E4E5E5E4E3E3E2000000E3E3E2E4E3E28900E3E4E3E3D6E4E4E3E4E4E4E20CE0E0E3E5E4E2E52F07004331A8E3E3E3E3E5E3E4E4C7AFD4E3E2E4E6E4E5E6E4E4E2E1E5E4E5D4E6E0E4E6E5E4E4E5E6E6E5E4E4E5E5E5E4E3E3DCE3E5E6E5E6E3E4E7E4E5E4E6E4E4E5E6E4E4E4E4E7E6E6E8E7E6E8E7E8E7E3E7E6E7E5E7E7E7E8E7E5E37A43000000789FE3E3E3E1E44C0E000000129D0C99E3E3E1E31000000000209FDFE4E5E4E2C9003A000036E4E4E5E5E5E6BC22070A75E54E4C0E0000001DE3E4E2E3E6E6E6E60E225DB50099E3E3E68500000000000000E5E3E5E61B31007AE5E4E4E6E4260000BEE3C24EE6E8E13E80A82D01D600E5E4E319AFE8E7E5E7E5E6E6E6855900E519E0E4E4E5E6E3E3BAE4E5E5E7E6E6E6E400009D00E3E5E5E6E7E5E564A1D20A00D8E5E6E6E5E6E1CDE6E4E4E6E7E7E5E6E6E6E4E5E4E4E5E7E6E6E6E5E5E6E6E6E6E6E7E6E4E7E6E7E7E6E7E4E4E1E5E8E6EAE9E7E6E7E5DFE7E7E6E6E5E5E6E6E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000130000000001000001E5E5E4E5E1E6E6E6E7E7E7E7E6E6E6E7E7E7E6E6E5E5E5E51D001543DD89ACE3E59DE1E30000007E493885E1E4E5E3B30A0C004E004CE3E2E3E34CE2A40000032DE3E6E7E4E4E12F0038362BE2E3E43C00002B0059E5E6E6E6E6E5E24C000000003638E1E3E4000000079B6800E3E6E7E5E496000A1700C9E5E60000C0E4000000E2E5E650000007000000E3E5E4E1BEE72DE541C0E5E6E56A00E3E5DBB7E4E4E4E4E5E5E2D6E5E5E3E5E6E4BA00000050E5E5E3E4E5E5E4008500000012E4E4E3E5E4E4B5E4E6E6E5E5E6E4E3E5E50003E4E4E3E5E5E4E6E6E4E5E4E4E6E5E6E7E7E6E6E5E5E5E3E4E3E4E6E7E6E6E6E6E6E6E7E6E0E5E4E7E5E6E5E4E4E4E4E7E7E6E7E8CBE8E7E8E7E6E6E7E5E8E8E9E7E7E8E8E8E7E6E6993E129DE13ADCE7E4E3E35D4E000000000AB7E4E4E4E2570000000000008BDBE11BD25D07170CAFE3E3E3E6E5E007012B001028E5E638001000154EE3E4E4E5E4E2E2E2173A00000E1741E3E10110000A4CBC00A4E4E4E5E5E6000000050AE4E62D0100E4000020E6E7E7E1E2008568200C05E2E6E7E6E3E6E6000CBEE7E5E400E5E33AE4E4E6E7E5E6E6E2E2E4E3E5E6E6E5AC000000E3E6E4E5E4E6E6E5758B8050AF33E4E5E7E6E7E68BB3E4E6E5E2E5E5E6E503D2002DE2E6E6E3E6E5E7E6E8E7E6E6E5E4E6E6E5E7E6E5E5E6E5E5E5E5E5E6E6E7E5E7E6E5B7E6E6E7E6E7E6E7E5E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000150000000001000001E4E5E5E5E7E6E7E7E8E2E8DDE7E8E6E700CBE7E8E7E6E6E7E5E33307004E002DE4E4E4A1AC312F9DE071059BB5E4E3E2E5435D0700000028E4E3E2E4DD19000000DFE5E4E6E36F0A0000992F00E0E4E000003C0C20E1E4E2E4E3E5E2E1AFE0000115AF89E5E62B47001B00003654E4E5E1E2E2100A00126DE4E7E5E4DE000000002DD2E5E4E100000C1D9D0C43E3E6E5E6E7732207A4E4E4E39BE252A10028E4E5E4E6E3E3E1E47EE4E4E4E4E3DB3643E4E5E4E6E4E5E5E590E5E27E7EE4E4E5E4525DE5E7E6E7E7E7E3E5E4E38B000000E1E4E4E5E4E5E6E5E4E4E5E6E6E5E5E5E5E4E4E8E8E6E6E3E3E6E4E5E6E7E5E5E4C9E4E5E5E5E7E6E6E4E5E4E3E5E4E7E7E7E6E6E7E2E1EAE8E8E8E9E7DCE89DE8E8E7E6E5E6E6E4E300201B0000004728E4E4E3DD000000A1439DC0C7E5DFE6E40E000000001573E2E4E5E3125D1B00E4E3E6E6E3E42B000000000020E2CDE2201B12003ACDE1E2E3E2E4E2E4E00A00000015D6E6E322003615197C50E0E3E5E2E5010000000AE2E3E4E5E63A000C00E4E6E6E4C9014500000300DBE7E6E8E3E5E61549E2E4E5E5E5E6E600E3730AE6E4E6E08EE4920AE5E5E5E3000EBE475FE5E6E4E6E4E5DFDEE6E2E6E5E4E5E6E673E5E7E5E4E4E4E6E1E6E4000C007528E5E5E5E4E6E6E7E5E6E6E6E7E4E4E5E6E6E7E6E6E6E7E6E1E4E5E5E4E4E5E4E6E6E5E6E6E1BA07E6E7E6E5E4E5E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000170000000001000001E6E7E6E5E7E6E7E7E8E8E7E9E7E9EAE8E7E7E6E6E6E7E7E7E4E3E2070010000000B7E2E2D8DCC7590000CDE1D4E0E4E2E2E483000000002B0AE3E2DCE0450E05058BE2E150E4E3520105050320C5E2E1940107000043DCE2E4E5E5E4E3E4E320105B2094D2E4E2E0E2011252000071E3E5E6E43100000000E5E4E4E7E4E22815031D00E4E2E4D8AF002B4100E5E6D6E6E5E1E5E30E3600E5E5E3E4780A120300E3E6E7E5DDE2389DE5E4E5E00000963A2DE1E4E4E2E4DF68DC077EE5E4E4E1E43850E3E5E5E4E4E4E5E6E5E6E426DDA60AE3E4E4E1E4E6E4E5E5E478E5E5E4E6E6E5E5E5E7E6E7E6E4E4E5E6E6E4E4E5E4E5E5E4E5E4E1E5E1E4E6E4E5E5E5E6E7E7E7E7E6E7E7E6E8E8E7E8E7E8E8E8E8E992E9E7E6E7E8E4E0E5050007E33E6DE1E3DDE289E4E32F00282FE1E3E2E3E3DBE41B000000010085E5C289780000A6E2E14717B3E443490A00000064B5E5E20E003100003ADFE5E3E4E6E37E623E3C4307B3E5DEE4E00E00120C4C0CDEE5E2E1E500000E0043E3E2E4E4E5BA002B00190057E5E4E6E4000000002FDCE6E5E6E5E6E700000071E4E6E57510070152E7E8E8E8BC3AE2D2E6E5E4E60000E2AFACD0E4E2E5E2E66F3C5FE1E4E0E6E3E3666A9B339BE6E5E4E6E4E4E4E49D901BE2E4E2E3E6E7E5E7E5E2E5E2E1E4E4E4E6E7E6E7E7E6E6E7E6E6E6E7E6E6E6E5E7E7E6E7E5E5E5E6E7E7E8E7E4E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000190000000001000001E4E4E5E4E6E6E6E5CBE5E7E6E7E7E7E6E7E56DE6E4E6E6E5E4E3E2830C007C1564DC24E2E5E4E3E357000E01030A20E0C789B7E2C54300071BE0E0E383E324006FE4C5597E00A48500000033000085E326E30000000528996FE2E4E4A4E1E26F00100700177EE5E5E16A0000000A4E625FE2E00000000000E3E5E6E6E54C00000000001BE3E5E3E2002B012F50E1E3E4E5E0E20073000000E2E2E5E25728CD31E5E4E4E54CDFE400E3E4E4E100000A3CD8E5E3E6E4E05B5B000CE3E5E3E4E31278A4C0B3BEA8E5E7E4E4E4E2E38B3807E1E4E4E4E6E4E5E5C7BCE5E6E3E4E5E4C7E4E5E6E4E2E4E4E5E4E4E5E6E5E6E5E5E4E5E4E5E4E6E4E3E4E4E5E3D4E4E5E7E7E7E8E8E7E7E7E8E7E0E8E6E5E6E5E5BE2BE7E2E4E4E3E4E3E50020000000382062A4E2E2E1A48500050E000A0A22E3E4BE451D20D60A05E0C9E2D09D6DDC7CE1E207152B94E1315F1D261952E4E1C5D2362F0307057AE2E4E5E6E2E2E3541D0533240010DBE6E5000001001700E0E3E6E55F0C1010E57E8590E6E473240000000000E3E5E5E6E459431DBCE1E8E0E6AC570000000000E4E5E5E178943C17E2E3E5E0B1E40000E5E4E55B50E0594978E5E6E6E1904EB77300D6E6E5E3E42001A6949FE5E5E5E7E5E6E5E5E4E2789BE4E4E5E5E4E5E5B1DE8EE2E4E5E5E4E4E7E5E6E5E6E7E6E7E6E5E4E6E5E6E5E6E3E4E5E4E6E8E6E1DDE7E6E5E3E2E3E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000001B0000000001000001E5E5E5E6E8E7E7E7E5E6E7E6E8E7E9E8E7E2E4E5BCDB33C2E3E2E0E22D00000001287C9FCBE1BE940000000000016431E1E3965B00171724E2C7E0D8E0D6E14CE1E1E16A000762E233002200000CCDE1E1DF07000000000064A6E0E1E4E3E12B10280000ACE3B7E4E2000000003C0119E3DFE2680031901900000064E2E3E2AF00000052E3E3E4E1A43A070100A6C7E3E3DC228B0000000000E2E5E3E278000083E5E5E4E5E5730085E4E3E100895FAFC5E4E3E3E2457852AF28C7E4E4E2E310002641C2E5E4E4E3E296E3E3E5E4E5E2E3E3E2E4E5E0B1AC4CE3E3B1D6E6E5E5E4E2E5E4E5E5E4E3E6E5E5E5E5E5E6E5E3E6E3E5E5E3E3E4E4E4E5E3E2E3E5E3E7E7E8E8E7E6E7E7E7E5E6E6E7E7E9E8E8E8E5E400360C1749E1E4E1DF0000BA2001055252C2E44E000000002B0022685BB5D2A8102F3622C2E0E2E3E49657E5E3E4E1C0430547E4E0855D00000028E2E2E46F3E0000E20033E575E5E5E4E4E2432F1D00006D0578E11B000000190071C5E5E7CBE0E2000000000068E6E6E4C00012002D26E4E5E6E50300E4E3E6E58BE6E2C0E6E10A5D3C0000E1E5E5E6002B7A41E5E6E4E6E03E87E5E6E4E2E3E4E3E4E1E4E44159E26D5BE0E6E6E3E3E1DBE5B74E59E5E6E6E3E01DAAE3E6E5E5E5E6E5E4E6E6E592C9DC9FACE4E6E5E5E5E6E7E6E7E6E6E5E5E6E6E6E8E7E6E7E5E6E6E8E7E5E5E5E5E7E7E7E6E0E4E0E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000001D0000000001000001E5E5E5E5E6E6E6E2E8E6E7E7E6E7E7E8E8E7E6E40000000CE1E3E3E1E20E2B00052652432D31E2A6E00700006600382DE1E1E5E3002F7A00004E4536E2E35DE5E6E3876F000005AAE3E01200003A2FC9E2E5D015000000001DE46AE3E2E4D8E22F000000003A0003E4780000004E3100AAE5E4E4E4E4000000050000DDE53E00000043220026E5E6E5470045C2E2E6BE6DE4D8E2E76622E10075E2E4E5E4DBE400E2E2E5E5E4E4E5E2E3E4E2032F36E4E5E4E6E0E34EE3DEE3E4E6E5E2DB0E015D7512E5E6E6E5E6E2207AE5E4E5E5E4E6E4E5E5E4DFC0AAD845B5E3E6E6E6E5E5E3E2E5E4E5E5E3E5E4E6E6E8E7E7E7E7E5E7E7E5E4E5E6E6E5E4E6E5E5E5E4E7E7E8E6E5E6E6E6E7E7E6E615E7E7E8E6E7E60000000000AFE3E3E5E4E35F01002600150001D0E3D83A000000000C49E0E0E3D600000000001B0552E1E3E2E5E4E0150300000000E3E34300A83300D6E1E3C05D2000000000AADBE5E3E49F6FE50C00E200000C194728017A003A0000737EE4E4E3E400000000000000E7D0380049000000003AE4E4E4000500E30E00A4E4E6E5E400689D000CAFE5E20022001BE2E3E4E6E4E2E5E5E4E6E60E5900E1E6E5E4E4E5E3E4E4E1E4E5E5E6E347B54C0A83E7E6E6E7E59207E0DBE6E6E1E6E3E5E4E1E46F50DEB5E3E5E4E6E5E5E5E6E6E6E6E6E6E7E7E5E6E7E8E6E5E6E6E6E6E4E5E6E7E7E6E5E5E4E3E4E5E6E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000001F0000000001000001E3E4E4E5E7E6E5E6E7E7DFE5E7E8E7E7E9E9E5E200000000E1E2E2E0E3E3730C0015000C052DC2A67EE03C0700000C2B6820E3E4DC1922000000000162E4E5E4E0E25D0000000000B5E43E00120A36E4B3E3E3E3C90E152F7812BAE2E4A6E3D2E3100000000331E3E2E1E37A4303003600ACE3E3E8E6E400000000CDE6E6E5E700B72D94000E909DE7E38919E2E0050000C9E4E4E3874C0000B5E2E7E2D005E3DCE5E4E0E2C236103CE4E5E5E2007868E6E6E494003E0596E2E5E5E5E3E3E3E492E3E4E3E5E7E4E0545FC533BAE5E4E5E5E5E4E6E5E7E5E5E1E4E4E4E6E6E5E4E3E3E5E4E6E6E4E6E5E0E4E6E7E5E6E6E8E5E5E6E7E6E6E8E6E5E3E4E5E2E5E5E6E6E6E6E7E6E7E7E7E5E6E7E8E8E6E7E6E6E8E7D40000000000E3E3E4E0E53C001031000AB7E3E4E3E3B1920038222654A8E3E32B6F31000000000017E2E3E3E549E1450000000000E462000012AFE3E1E1E3E1E30C260A683AE1E0E3E3E4E3D6E1014E0001002212D8CD2FE10100010500E3E5E6A6E6A1280017030094E1E189E410002B00B1D2C5E5B145E2E4030000A4E4DD00E20000001DE5E5E5E5E4337AE5E7E5E67ADB4500DCE5E5000000E3E3E6E4503E9B49A8E4E4E0E30000008EE5E5E6E4E5E552E264E4E39DE5E5E6E6E5E6E5E5E2E6E7E6E7E6E6E6E5E5E5E5E7E6E8E7E5E5E6E5E7E7DEE4E6E6E6E3E6E6E6E6E5E4E5E5E0E5E5E3A6E5E4E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000210000000001000001E5E6E6E4E8E6E7DDE7E7E7E5E6E8E8E7E7E6E8E8E4E3E05F001280E6E3E4E390382419004CB5E2E392E080780C1D000A2D75E3DFE3BA2020013E000000E3E3E3E5DD1D000000000000BCE347006D260057E0E5C95B5F0022000000C2AAE1E3E4E6220A170C20360A00E1E4E6002F00E10000E5E5E322E4220000032250C2E0D8E4E5000000B375623EE4E5E0E5E000000003E4E4E30700C9000543E3E4E215196659E4E3E57E2D0C5BE3E44700000092E4E6E36A0015E3E1E2E4E33300A80000E4E6E4E5E3E4E6E3D675E2E0E3E3E5E5E5E6E4E4E4E3E6E5E6E4E5E6E4E5E5E5E4E4E4E4E4E7E5E6E5E6E6E7E5E7B3E5E6E5E5E5E6E6E6E5B7E445E8E4E0E2E3E7E7E7E7E7E6E7E7E8E8E7E7EAE9E9E9E7E6E6E6E7E6E5711DE2E3D2E3E5E4D4A4240E54032224E1D8E46887BE2B00071B00D8E2AFD82F00890000003AE2E4E1E1BE5D2FBE710E0031ACE49F547115070E54E5E6E249050500000000E2E0E4E4A83E00052010001D0E68E5E4E30000E000105DE6E6DEE6E6360015000001E3CDE4E41D0049310AE1E5E6E6E5E6E50000001DDEE6E50A000500260059E3D4228E508E59E7E4E5005FE2E5E520170000DCE6E6E603C74799E6E5E5E30003000000BEE7E7E4E5E22DA1E2E0E3E3E6E6E7E6E7E6E5E6E5E5E6E6E7E7E6E8E5E5E4E5E7E7E6E5E5E5E4E6E6E6E6E4E7E7E7E9E8E6E7E6E7E5E7E7E6E6E6E6E0E3E5E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000230000000001000001E4E4E5E5E7E6E5E6E8CBE8E8E9E8E7E8E8E9E9E8E7E4E4A67CC062E2E4E2E4E3E34731000019076AE0E2C964122B100000001BE1E2D264000000079FE2E2E2E3E203E1E39D00000000C0DEE2200C0015BCE4DEE4E5900A0000001000C094E4E4E3990000007A0000B7E2E4E466000300000ADEC5E6E5E6E50000003C0007E0E4E4E2DE017C57008E24E2E4E3E4E500002FE4E5E494E4B500003E0110DF470031A4000E99E287001D87E0E568220AE2E5E5E3E4E5E21099E0E6E5B7DBC5505BE2E5E5E6E4E1CD8BAA89C2E6E5E4E5E6E4786AE3E4E3E4E3E4E6E6E6E7E5E5E5E4E5E1E5E3E6E5E6E6E8E6E3E6E5E7E5E6E6E6E6E5E5E5E5E5E4E4E1E6E5E5E5E4E7E7E8E7E7E1E6E6E5E6E7E6E6E7E5E6E6E7E7E7E7BC52416FE4E296B5BEE3E0E3DC0C010000013ABEE4BC6F0000001900008589E4713601001933BCE4E4E49FE4E3C552412F1B030033E3E49600000A002FC7E6B5415949000000170E38E6E6E6BC000000000022752628E2E30C0033120564966FE5E6E32F0E000C000092E4E6E7E8331D24052DAAE5E5E4E4E4D07C0031E2E5E6E5193C2845000CDEE500E3E50578C0E345003A00E4E5570050E4E4E5E5E6A854472DE5E6E6E4E341070071E6E5E5E220C7A6DDE3B7E5E5E4E4E5E3E2C759925FE4E3E1E6E7E7E5E4E5E4E6E5E6E7E6E5E5E5C5E6E6E6E5E7E7E6E759E5CDE6E6E6CBE6E5E07A7AE5E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000250000000001000001E4E5C9E5E7E7E8E7E8E6E7E6E9E7E5E9E4E6E6E6E3786D57001BE1E1E2A1C2E2E1E400000000000000E0E3942600000000158026BEE2CD4500419062D0E0E18EE4E3E4DE667C0000000ADBE0E20C000000008EE4E34C92152415281D0700E1E2E5E500000000000000594EE2E224003C006603527AE2E4BE570A00102D47E3E4E5E5E562001D072054E2E1E3E4B7A817001983E4E3E54599A85BCD0C9DE422DB005D7CE4E40E280C002FE4E4D805E0E4E4E4DE7AE1E3C7E5E4E592646F318EE5E6E5E5E5D89FC09DE2E3E4E3E4E4E5BE64E3AC5F7AE4E4E4E3E3E4E3E4E3E4E4E5E5E5AFE4E5E4E6E6E6E6E6E5E5E5E6E5E5E5E6E6E4E4E5E3E4E5E6E3E4E4E3E7E7E8E7E7E6E7E4E6E6E5E5E5E7E3E7E6E5E5E4E5E0E20A0031001DD2E5E4E4E4E1AA4E000000000071E3DB622F000A36000E0CDCE0B5A63E12B3E2E3E4E2E3E6E6E6B3C73C00001536A8E36A4500100E00ACE3E4E42D3E002F000E22D4E3E4E5E4E2E37A45000000220389D099809F0017000A0EC0E4E41B010000010ACD8B00E2E5E2151B00E3E5E5E6E6E30AA67EBC572290E4E4412403750000E2E3E38B000028E5E347151231B1E4E4E5E5E6E5E3E4E58EC766C9E5E4E23E33C754E4E4E4E3E3CD1BE443BEE5E5E4E7E4E4E44EE6E0DDE4E7E6E5E5E6E4E8E7E5E3E5BCE5E6E5E7E4E4E5E3E7E7E6E8E5E1E6E5E6E6E6E7E7E6E4E6E4E3BCE6E5E5E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000270000000001000001E3E5E5E5E7E6E6E6E7E7E6E6E8E8E8E7E5E6E4E5E4E4E4AF00000000996AB5E1E1E1DE0000000101103ED6E2E14300000000031538DDE24C03003CE0CDA1579BDEE3E1A6E187070E4EE3E3E4E2E36600001952B1E2E4D40700120000017CE5B7C7E3E1E419000000000328DBE390E13E6D0000000054E6E4E42600280528000001C7E357018E0141E6E6E7E4E478002FA42D073CE3E5E000224C2800A8E5E5E47826DCE5E46D0385AF71E4E4E5E4E5E4E3E39F2B2600BEE2E5AF3826E545E5E3E5E4E69D120750AFE4E4E6E4E4E200B32FE245E1E4E5E4E0E3E2E2E2E4E4E3E2E3E4E3E4E6E6E4E5E5E6E5E5E4E3E4E5E5E4E6E5E5E5E4E6E5E6E4E1E2E4E5E1E6E7E6E7E6E6E6E6E6E6E6E6E5E6C5E5E5E6E5E7E56FE45200191D38929BB1E2E2E3686F000A000E3A4C62E4E25200000C364E00173CA178BA20009DE2102022E0E4E2E5E6527ADF17E1E2BAE4E0DE500005E1E2CBE6AC261000752400ACCDE2E3E3E49B7128261703281294E3E2E3E3A60E030000248EE4E2750000005707002217E3590A47E52FE5E3E1E4E3E222CD3C3600571DE6E31900A62057E4E4E5E27EE2E2E3E4E4E2E00071E5E5E3E5E5E4E6E36F2B0057E5E6E4E08B006A41E1E4E7E6E3E2D01DE3E4E6E6E6E6E2DC00E32B9243E6E5E4E4E5E2D0E2E3E0E3E3E3E3E2E3E4E5E3E6E6E2E5E4E6E6E6E3E5E4E6E6E7E7E6E6E5E7E7E7E8E3E5E0E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000290000000001000001E3E4E4E4E7E8E7E7E7E8E6E4E9E6E8E6E3E5E6E6E6E5E4E4E00A17000054DD9487E58BDD00002BB7202694E3D4E1360000122B00197EBCDDE27A009F520031005BD8E3CDE04E4E310020E2E5E5E1C29D0010992B5DE3E280010C0000005DD8E3D0E4E3E2E27A192D001D45B5A4E5E0BAC717007A000068E3E4500000000000000031E3C9BC000000E5E53CE3E2009B190315032F2666E3C70005668BE3E4DC0003001DE1E2E4E4E4E4E4E5E2E5E4E4E5E4E4E23E526A78E4E5E29DB100CBE5E4E5DB1089E16DE3E6E6E4E4E5E4474517E1E4E5E4E3E4D6BCE380E4E0E2E2E3E3E5E4E6E4E4E6E6E4E3E5E5E4E6E5E4E4E3E5E6E4E8E6B5E6E794E7E6E5E4E4E4E6E7E7E6E6E6E7E6E7E7E7E6E6E6E6E7C2285BE6E7E6E1E5C9380000000C5B9BE2E4E2E30A051983DBDD8BE2E371D2360000002B0054DCE2D86AE266005B2D0775E4E4E5E383BA1D0007E0E3E3E4E3AC0000003E75DBE3E3E02401051003E0E4E2E5E4E4B5AC3349000010A4E483D050201500241B0112BAC7E119123C0A000000E1E5E475380341E4E289E3E3DCE10A03226D00B3E5E3E3E5E5E6E5E55078490571E1E5E5E6E5E6E52443E4E5E5E5E4E6E7E6E59F874EB1E5E54E59B1E4E4E4E26A6464E2C7E5E6E5E4E4E483E5E04E33E5E5E7E7E5E7E5C7E3E5E6E8E4E6E5E4E5E4E4E5E6E5E4E4E3E5E6E8E6E7E5E2E1E5E5E8E6E6E6E6E5E6E0E5E6E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000002B0000000001000001E3E3E4E4E7E7E7E7E8E6E8E8E6E8E8E568101BE7E7E6E6E5AA3300002F0017E1CDE1E4E3E143003633D8A8E5B1E1A69F120105150319A8B3E56AE5450CE36419128BE2E5E47C9678000C2F7EDEE3BA620E36001033D4D2E2785D7300052D5DA1E1CDE4E4E2E026121728871750C2B7BA20001200002405413CC21D00660000003600E5E7170EE0D2E5C2E2E4E2E3E10000E3310020B5C0E2E5E5E7E5E49626E1005DA1E5E5E4E5E5DB9D8B36A8E3E3E4E4E6E2E3E5E387E1E5E6E4E2E3E4E4E4DDD80E0CE1E2E5E5E5E5E4E3B5E0E27A94E4E4E5E4E4E6E3E1C7D4E0E4E5E5E3E1E4E2E4E6E5E4E3E4E5E5E4E5E5E4E4E3E4E6E6E6E5E5E5E4E2E4E2E0E3E4E3E5E6E6E6E7E5E7E6E8E6E6E6E6E8E7E40E0119E7E6E5E3E32B943600000000E4E2E3E3B76D240019033154B7E3E1E4E0453E0A0E001003E3DDE2E2E138010024C7E1C5E3E5E1D84900000059E4E5541B0500381210127EE4E22BB13C0E071000B7E5E5E5C7CB244C00A60A004900C0E8000047006400000317E2E2E0E50E0E001220DEE5E4E3E6E728573ADCE5E5AC5F0000410C07E5C9E3E1E2E3E4E5E2009200ACE4E5E5E4E1AF03244333DBE5E6E4E3E4E5E2E5E4E6E5E4E5E3E5E1E5DFE4E30590014EE5E5E5E7E5E4E6D8E4BE3AE4E6E7E7E8E6E7C000070CDFE7E6E5E5E4E3D8E5E6E7E6E6E7E5E5E6E7E7E7E7E6E6E4E7E5E6E5E6E6E3E6E6DEE1E5E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000002D0000000001000001E3E2E4E4E6E6E5E6E7E6E7E6E8E8E8E6AFE3E5E4E4E6E190E2E19000001589C0A887D8C9920000000012478315E2E2C58926004300330087E2E4C9E1E05200003A6DE0E3E2E0D80000E100C5C7E3B72D00032F05000000E3E5E200100007000028E5E4E7E1ACE4364E2619000083ACE30A000000AF2D6D3C2FE1E4E5E6DFC7520000E4E7E6E2E5E092E185E4E645C20A4E05030700A8E443E3E5E0E4E66A94310043E5E5E4E3E3E5AC751722E6E5E4E5E4E352CDE3E0E3E5E3E5E5E2E6E4E4D2E05438AFE3E4E3E3E4E2E4C0854185A1DCE7E4E6E4E4E2660124E4E4E4E4E3E2E4E5E2E4E6E5E6E5E4E5E5E4E6E6E6E5E3E4E5E4E6E6E5E3E5E4E5E699E4E5E6E5E8E7E7E7E7E7E7E9DBE8E8EAE8E8E300050A5BE0E6BC4CE5E5D06D103A1296E16F38E2C5AF000000000080D8E4E1E3B10100000020D0E1E3E5E3B1381533261D5743DFE3E4DB0000000341D2E4E3E2121500C5002B00E4E7E34345000E00000022AFE3E5E2E1E3E2412800856880E6E2E10C00001200050EE4E5E5E3E40000000064E3E6E4CDA4E2E4DCE5E4E4E152891241500054E8E5E3E6E4E5D61B0073203EE2E5E4E4410EC7E23107E4E5E4E4E3E52D832D75E5E5E5E5E5E3E5E5BE8038C0C0E5E5E6E5E6E6E5E4E0E44562C9E6E6E4E5E2E2E19928006DE6E6E5E5E5E5E4E6D4E5E5E6E5E6E6E5E6E7E5E6E6E5E4E2E4E5E6E7E6E6E6E6E2E2E4E4E1000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000002F0000000001000001E1E5E5E4E7E7E6E6E7E6E5E5E9E7E62D00E57A12D0E0E6E6E45F00DF00190001058780E4AC1B0000000000319BE0E0E3E1010C0000432BB1E4E3E490542D0000002438E27CE1B55F0000001BE5E1E3E45D100022000000DBE3E2C2360300002D000026E4E5E3E2E3B51D3600005DE2C7E3B10300000100100022E5E4E3E0001500000041E5E59212E3E438E1E4E2DF5D45240C125D002DE5E4E6E4B1170057004373E2E4E2E2E001E0990085E6E4E2E4E4E43A6AA49BE0E4E3E4E4E4E5E5E3C215418BE3E5E4E5E6BE6D59E46433E5E6E2E6E5E1B5E3E2E2D066E2E6E4E3E5E4E5E4E5E6E5E5E5E6E5E5E5E4E3E5E4E4E6E6E6E7E2E5E4E3E6E6E7E68EE5E5E4E5E6E6D2E7E6E6E6E8E8E8E8E7E6E8332200050305E6E5E6E4DE03120000AA00001B00A8E29F20000000001B9F31E3E390E226033157E1D2E5E4E4C045052400005D38E1D4E2BE50BE2D31208EE4E3E3E15D000C0003529DD8E3E3DB17000000002DA6AFE4E396E15F5F2220EBE5E0E3E39F2F491915056415E27554E3E50500000000D2E3E46200E6E12F8EE5E5E3A8E7E600100C0700E6E2E3E4E3002D8928527AE1E2E7E778D2BE240E33C5E4E5E5E4E3DB59E0711BE0E3E5E5E5E2E3E4E4B39DE6E6E6E5E5E5E6D6E559E5E5E5E5E5E5E4E1BECBE3E2CDE5E3E5E2E3E5E3E5E4E3E4D0E690E6E6E5E5E6E7E4E6E5E6E5E4E6E7E6E8E7E4E3E5E4E2DEE4E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000310000000001000001E2E4E4E4E7E5E5E6E6E3E5E5E6E7E70000003CDD3A966DD2E2E2C90000010000001924E2E2960A0000000000003180E226E173030700CDE1E2DBAFE49B7E03000000105DDCDBAC7C3E36000C005BD0E2E77107000022007AC5B762D4D40000520000BC7CE0E2E1E0E1E07A0003E77EE2BAD65B9D00003801263C01CDE0751500002415E1E4E3E399E0E14E6FA8E6E5E6E501001B001D1043E4E5E1A6750000004C2D36E4E3E21073501B00B7E3E2E2E3E5E41228E2DBE0E1E5B7E5E4E0E2E3C0C026E2E3E4E2E4E31066E59468E3E4E3E3E1D800B18EE4ACE1E2E3E2E4E3E4E3E5E5E6E6E4E3E5E4E6E6E5E4E4E2E3E5E2E4E5E3DDE4E5E4E5E4E5E2E5CDE4E4E4E7E8E6E7E7E7E7E7E6E6E7E6E6E8000036E2B5E2E0E3E5E5E3E4E20A000000597E99E0D094C23600007107000AE05FE3B3BC00282407DCBE8936E1AF6A3100000003037EE1E5E05F200000000CC2EBEAB1030000101D5B92EA9F28D6363E000000105D2D9D7C68A6411712458EE254E3E2544E0000122B2899DF9FC5AAA61B380015E09BE3E5E5E5E3003320AFDFE4495959832649055FE2E5E3E4546410000317E4E2E4E5E4E50C0715C9E2E4E4E5E6DD317C54175DE6E5E4E0E7E0DFBAE4DFCBE5E3E0E5E5E42D6A62E2E2E4E6E4E6E389DBE5E4E0E4CDE5E4E7E3E4E3E594E4E4E4E1E3E5E5E4E5E6E5E4E4E3E4E7E6E6E6E4E4E4E4E5E5E4E7E5DEE6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000330000000001000001E2E4E3E4E7E7E6D8E5E7E6E6E6E6E61903389994E1E1CB36E068E2A11500317A1D1573E3A8DBDE33000C0000002426D2E1C9E0000000009971152D99E19B620000120C262BBCDDC0E1E6003A000EBEE5EA5D7CC900000000E5E8E9890066122D000000265DDBE0E6E478004C001500DB83E3E1BA5401005941A6E2E012E2E4870001122BE2E4E3E5E3E324E09BE1E3E4E5A800100A203C22E1E4E4E4E149030700A8E2E4E4E4E40000000068DFE3E2E3E37507472DE0E2E4E3E3E4E48E66E4E3E6E5E4E6E3E4E41B263E8ED0E3E1E3E5E4E268039FE4E2E3E3E4E4E4E3E3E4E4E3E4E3E2E3E4E4E6E4E5E4E6E5E6E6E4E5E4E5E4E4E5E4E5E6E4E7E5E4A1E4E4E5E7E7E7E6E6E5E6E7E7E8E6E0E7E8E3000000E1E4E3E0E3E3E1E1E0E07E2B01000000AF36C2DE7C0000000000000AE1D88E0043000026000000007AE00A120000000000D0E4A1E6DBE200000000D6E1E9EBE79400000000D6EAE1E580364C000000010017E6E8EBE3E215005B2D000CA4E2E3E24500002BE022000041DB90120024000043E3E5E5E4E5B5C0E6E6E6E4E5E501576F179901E4E3E4E4E33E260007CDE5E5E19F00000001E2E4E3E3E4E457000080E1D8E2E4E4E4E5E5E4923ACBE6E5E5E5E4E4E159E010C7E3E5E3E5E3E3E4E3520049E4E4E4E5E4E5E6E4E4E2E2E4E4E4E6E4E4E5E5E5E6E5E3E2E4E3E5E6E5E6E3E2E3E5E7E7E7E6E0E4E1E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000350000000001000001E1E4E4E5E7E6E7E8E7E6E3E6EAE9E7BE00070000334EBAA4DDE2E0E2C99BE11D28000052E0E29F2B00000020000000001DE2E0B7800A28150000646FE1E25B000000000000E5E1E1E2BCD800000022E2EBEBE8640E2412036F9080E7E37A00050000000028C5E094CBD499000000170089E1DCE1150000000A28962DC503430A000305006AE2E6E5E6830019E1E3E5E4E4E12B2B00000012E5E4E3E4E21200410047E5E4E2730000AC2200E1E4E4E55F0007260AE3E3E4E4E4E33EE0E1003AC0E5E5E4E4E6E55400E1E4CDC0E5E4E5E5E5E2E3E4E450E5E7E4E3E5E4E7E4C5E0E1E3E4E5E4E3E3E4E3E3E4E3E6E6E3E3E1E4E4E4E6E6E4E4E5E5E5E5E4E2E2E5E4E7E8E7E8E6E7E7E8E7E7E7E9E7AAE9E07505710057D815C9E2E3E5E4E0E2AF280E0C9D2FE47CE20700000E0000001200E4E35296E08B00001500126FE368DD00120000000059B7E0E2577E1B003871E1E8C773070A000007544E7CE48747240000000000501BDEDEE8E0000000504CBECBE2E5E96624002F1B1B433EE2E101004C000EA1E3E4E2E04E4507006ABAE6B70710156A4131004CE6E7E4520A000000E4E2E3E3000043000000E6E6E6E7E5311B0022E2E5E5E3E6DC00332400B1E4E6E7E6E4E7E51BE10007AFC9E6E5E4E5E4E38EE026E6E7E6E5E6E7E552668EE6E6E7E7E6E6E4E5E6E6E5E7E7E5E396E3E6E6E3E5E6E6E4E4E7E7E8E6E1E5E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000370000000001000001E3E5E5E5E7E7E7E6E8E8E7E5E5E8E6E8E500000010006D246F9FA4E3E3E4E3C0E33E005F1DE3E05092000000000A0373A4E3E2577AE0E10007AC000000E1CB2F6D00BA00000001C7E3DCDE661D1759DBE5E3E89900000001006FE1E1E4E4E2C7335F3A00000000198EA6A8281500284100BAE4E5EBEA62001726000017DBDB000000000015E3E5E3D05D26006AE5E1E6E4E30000000A0000E4E1E3E4E21D150000C2E0E4E4A42F002D009450E5E5E4E3002F1B4307E4E3E4E4E3E412E4E500E4E4E4E4E5E6E5E5E4003CCBE4E4E4E6E5E3E4E0664EE5E0E4E4E6E5E42BE2E1E2E2E3E6E4E4E5E5E5E4E6E5E5E6E6E7E5E6E3E4E4E6E5E5E4E6E3E6E7E3E6E0E5E5E7E7E7E5E5E6E5E6E6E5E5269FE7E7E9E4150E0A71E09678E2E1A65BCBE0E16D330C0A008BA47105000000001001004CE3E0D49BD89F0000002D1200B5E3E212000019170005E1E4E0BE1B000005B7BADBE5CD00002D000147E0E6E6E4D8243A1B73D2000000E0EB9FD052384700000041B1E5EBE99289B5000000003CC50000E5000000E0E6E5AF781759E7E6E6E7E6E5DB01002200226FE3E1E5E5A6382043E4E1E2E3E4E54147859B64E3E3E3E4CDE09DE4E4E5E4E5E6E5E6C2000000E3E6E7E3E5E8E6E5E6E6E4E5E48EE4E6E65DAC225FE4E5E5E6E6E6E5E59BE7E3E6E6E3E6E5E5E6E4E5E3E5E6E7E4E6E5E6E6E5E6E4E6E7E6E6E6E6E7E7E6E4E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000390000000001000001E0E5E3E4E4E2E7E7E6E7E9E7E5E8E7E6E7E503150000A100050085D0C9E2E2C2E180D6545DA4E2DCD02B0E0000000000008ED694E3E30001000000000E1BE0E205003112002494EBEAE03A000000000043E2E9E500000000002D15E77EE36D281507000000034389E6E5E1E3E3751D00000C4CE2CBE2AF9F781B1003781B7C000000001D2FC5E4CB070C5B643AE3E6E5E6E5E8E50096009612E5E4E45D833A246F15ACE4E5CD1017450045E4E3E2E4DF3C8E3E1BD4E4E3E6E6E6E138410738E2E6E6E6E5E685E3E4E4E4E4E3E4E2E1BA38D0857CE4E1E2E49DE5E5E2E2E4DED0E6E5E5E5E6E6E7E4E4E2E3E5E5E5E4E5E5E3E4E6E4E4E4E3E4E5E5E6E4E5E7E6E3E6E7E6E7E7E6E6E7E8E9E7000015E8E7E79F1700190100000041E3DE8E667E9FE1AC193892BA9FE17C030000000000006F24E3E5E56A680E2B22070A7EE5C2525D360A005041E2EBE0BE0000E10301E4E7E75400000028386200DF15E4E31700150000473838B3E1DBB3E3BA9F0020000092D2E7BEEAAFDCE3942633003E96004C453822E4E5E3313A283A66E4DF054C2B223E002D00332880E3E48E0000229405E7E5E6E6498B0E4105E1E3E5E5E478E0872B57E4E4E4E5E37A472D49E5E5E7E5E6C03A0307DBE6E6E6E8E5E5E5E2433C36E2E6E6E7E7E7E5E1E3CD94E4E5E5E3E2E4E6E4E6E7E5E2E5E6E8E6E7E8E6E6E6E5E7E7E6E8E6E7E5E7E5E5E4E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000003B0000000001000001E3E5E6E6E3E5E6E6E6E6E7E5000000C0E7E7E70000033EE500006FE1E48BE24E2D80C26FB3C24CDB5DD42800BE0012C70096E1E3D4E5E00005000000000E7ACBC71200002B0A17E0E6B5E0190000001D64E9EBBA000000000007758362EAE5DB00000000001564474CE56F1DDF0E008000000059E6E2EBC0DEE1803C004100E10A450054E2E3E459500E54DBE3E30000005D002F00E000333EE4E3E457363C00005DE2E4E5E6E5330031E0E4E5E6E5E63AC00028E5E7E6E7E2E4478B003CE3E4E6E5E46205E3AA01E3E5E6E3E5E5E2E6E37EDDE7E6E3E5E4E4E42D00B5E3E1E5E5E5E5E4E5E5E4E4E7E5E2E6E4E3E4E6E5E4E3E4E3E4E6E5E6E5E7E5E4E4E6E4E4E7E7E7E7E6E7E7E3E5E6E65B000083E6E8E8A10003001500202D8EE080E25F0585E2E3A8E15DE2DC54E2190001001B264EBCE3E3787A1900000000000517E3E390000064070C33E1A8E3E1000000009BE7E4E3050010000028504E75E9E79B242D030000121D0000D878DBE2000000150020A6E9E4E2CDE01B000036310022E400006AE1DDE4E4E29F7C38ACE300E4472247260E9D001D4CC0E3E1E20003B3000054E3E4E412000050E6E6E7E6E45743E4DE3AE3E5E5E4E2E219000041E1E5E7E6DF945D8E0C8EC9E6E5E8E5E6E6E5E6E4E5E6E4E4E3E45400E3E55FE3E3E3E5E6E4E5E4E4E5E4E6E6E6E5E5E4E4E7E7E3E6E5E4E4E6E7E5E4E4E3E5E5E5E2000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000003D0000000001000001E1E3E4E4E6E6E7E6E6E7E6E600000000E2E0E5C2593600003E288041E2C2D0A84E90877EBEE1DDE1BEE199E10000003328E1B1E2E0E0800000002400000052C2E4A68000000000005B62E4E3330000D0E2C0E4CBB5AC22E3000000000C85E7C2928017070057000000B5E58592D2000000009B68E5E3E2DBE200107CC20000E2E56A26E7E3D0E0E4E41B00E0E4E626D07A262083002B000083D4E1E1DE0000E400001DE3E4CB00A44E0A43E4E5E0E2126F3A0A0AE4E5E6E6E27868BC003EE2E2E2E1E22B28E3E1AFDEE6E6E5E5E4E6E5E2E4E5E6E6E5E3E00A12E03350E2E2E0E5E1E4E3E4E4E6E5E4E4E5E4E6E4E5E5E5E4E4E5E3E4E2E7E4E5E4E3E5E522DBE3E6E6E6E7E6E7E6E7E6E6E417006F1980E4E3E443190000000E6D718BBAE119191D660CD8E2E2E3DEE092640038663C80DBE2E4DCD8101B000000002D003E6ADC712220000000000E50E9E7E171151D0010CBE2E2991500010A00000000E1E38B332400380000000022851DDC9F170000000A8083EBE2D0E2E31B22006A1285E1E2E3EAE7E2E3E1D028283EE2E8C9070A20DBC954753C1000E5E4E5DC22226800002DE6E5C70105003349E5E4E6E5E54C2431E5E3E4E3E2E3685B6D24E1E3E3E6E5E47E5F595728E7E6E5E6E73EE1E5E5E4E5E5E5E5E5E4E0D4E317E0E5E4E5E7E5E6E6E5E6E5E6E6E7E7E6E4E3E3E4E7E5E5E5E5E4E5E5E6E6E6E6E4E4E3E0000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000003F0000000001000001E2E5E5E4E6E6E6E6E7E7E7E8E400177EDBAAE4E7ACA6000000000012C0E2E30000380E0150BC6DDBE2B3685924381D9017E2E2E5C0E0E394DD57001000000C01CBE27A5F008B380024E2E1EBE95900000000387C2B9466000010000000E1A6E4E4E300000000710000104185BCD0781000200092EBE1E3E0E0E26A000000992026C2EBC0BE49DD6D942FACD6EAE6B1E3E343E4000073288B3EE3E3E3BC3AAC00220A41E2E7E25417002BB3C2E5E5E4E08E5B17E4E4E2E5E4E5E092E5E4E4E2E4E5E5E1E226945922E0E6E7E666B1BCDEE3E4E5E4E5E5E4E3E5E3E2E4E4E5E4E6E5E5E5E5E7E6E8E5E6E6E4E7E6E4E5E4E4E4E5E5E1E5E5E5E5E4E4E5BCE4E5E5E3E4E7E6E7E7E6E7E9E8E8E8E74778E5E4C7CBE3E33E00000015000017E2C2150007008B034E204178E185E1E13E2FAC077C7EE1DCE4DDE5E1E13E00005D1768D6895931000E01246292E1EBB35D0000002B1B00456F9654071719000100BEE4E5E50E000000000000000000B1E8E245001792DCEBA8E0DFC5E28000000C909D28B3C9EBEBE2E4E5A83AC57C64E2C2AFE6C200001B00000096C9E5E4E2BAE3BA000545E7E4902062E5E43CE4E5E3E5175D1092E4E3E4E2E3E31010C2E6E5E5E6E6E7E7E5E3544CE4E6E5E4E4E2E666E4E4E5E6E6E6E6E6E5E2E5E4E4E5E5E5E4E6E6E6E3E6E6E5E6E6E6E7E8E5E5E4E5E6E6E5E6E8E1E5E5E8E7E7E77EE371E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000410000000001000001E3E4E5E5E6E6E4E4E8E9E8E9E77E00000041E3E7E30503000000000C00C9E3641B241B00000C104E89DE5971125D07120EE26F079DE4E4E4D0B7002B0000000036E1DF891900000005AAE5E90019000000190003E57385730075000033000000E3EB544900000000000000000087E13A000019C7E5E345E0BAE2EB64001500E2E4E0CBE0E5E1E3E2DC0EE05FE2BABE0C38120A0059593E009FDEE5E4E3E2E0E30024C0E4E5E30571C57350E7E4E3410100642F71E3E5E3D29B99CB5DE4E4E3E6E5E35D5B0EE4E5E5E4E1E2E073960E85BEE4E3E3E5E4E4E5E5E3E4E4E4E3E3E3E3E4E5E2E6E5E5E6E3E5E4E5E5E6E3E3E6E6E7E7E5E5E4DFE6E5E5E6E3E3E4B7E5E7E7E7E5E6E6E2E8E8E7E7E900000A00D0DFB7E5E1070000000000A1E2E0E200000005120C0059CDE0CBC989521003DFE1121BA12D94E4E200000005330000008EE3E2450E010000BAE2E4DE2F000000430000E8199B2D3A00000000000000E2E6E55D00000700000500229228E1A6003C00E31B45159FD8E396870003000CE4E3EBEBE8E6E4E568890ECBEAE2E4E3000000000000001B80E2E4E3E4E4E5BE171536E4E5AF100EBE2489E4E4E50E0EC0206496E4E5E6E5A817003CE4E2E4E4E6E399D6E5E6E4E5E6E5E4B766D038285DE4E3E5E4E3E2E4E7E2DEE4E1E4E5E5E5E5E4E4E4E3E6E4E5E4E6E4E5E6E5E7E4E5E4E6E6E7E4E5E5E6E5E6B1E5E2E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000430000000001000001E2E4E4E4E7E7E7E7E8E7E8EAE1B100000000BEE09B2F00000000005B9FBA2B57050000003841000062C5E2E3D07E9D196F891D00000036E2E27500000062000000E1E28BE1B5008E1722C7E3D4BA9F5F003A3E008B7C3671B5000000003C0000A1E8E93300000000AA411B00006AE17A1BE6D6E7003E49A6DBE3E792AA00000024E5E9EBEBE6E4E500001000170EA8E3E4D6360E001233C9E4E3E3E4E3E2E3E320CDE4E2A47810500C20C5E6E3E33A470000E1E6E4E5C73300AA0092E4E3E4E4E47347E2E4E56AE5E4E4E494E5E54C8BBEE3E4E2E3C50050E2E3E2D2E1E2E4E6E3E6E4E2E4E3E4E5E3E6E6E689E7E5E7E6E6E7E7E5E4E3E2E5E5E5E5E2E2E2E3E5E7E7E5E6E6E7E2E9E8E8E8E9E80503E059206AE547012B0000002D3875B54ED033000000000019005BE3E157E0E07EBE0A0015310E00CDE19D000000000003E2E1E2E2E1012600000036E1E03A9B31007A64500E28B168E500000000170000BC0001E900000000000000000096E26A001D9226190112AFD6E5E86F6F3C003305EBE1EBEBE4E3E3E3010000004390DFE3E3E50028C9E6E1E6E4E6E2E4E3E4544C7CE6E4E5E436DB3600E5E6E6E1D685159FE5E6E6E4E2960000008EE5E4E6E3E23E94AFE4E5E5E3E5E4AAC2ACAAE0D4E4E5E3E4E068E4E112DDE2E5E3E2E2E3E6E5E4E4E2E4E4E3E3E5E6E5E4E5E6E4E6E7E7E9E5E5E6E4E6E6E5E7E5E3E3E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000450000000001000001E2E5E5E5E5E5E5E5E4E5E5E6E7E5E7E8E03A1524E3E43A68000012100047D8E100075200000000000E8EE1E28BE185E4A8AF4CB55D002F9BA4E119000003001B3373C7E4E319006F000375DCE0C7E1102BC54920000000C0E00000000C000000030096E40000000000000000007EDBE1923EEB3819623371E0E4EBEA1B00126D0000D4EBE8E4E3E1E0101D00052B3817E4E457312F454CE4E5E6E6E2E5E7E6E7E3E2E4DFE4E3E3E0E200E3E3E5E5E5E1E5E5E4E4E6E5E6E4200001E2E5E5E46D1B0000C7E4E5E4E3E3E3E4E3E58971E4E5E5E4E2E152DC6A00D6E4E3E2E2E3E2E3E5E5E2E3E4E3E2E2E2E3E3E6E5E2E6E2E5E5E6E5E5E5E5E2E7E6E5E7E6E6E3E4E6E6E6E7E6E6E6E7E7E7E7E7E8E8E8E77E0C41E2E5E68B00030A05009D71C90A38680041000A0000AA57BCE5E4E3E5E16FE33A0C2BA1E3E0E2E2520005005F009DE3E29D1900000000E4E0E5DEE1AA6F0E050A00003AE8E6DE5B1D0000009D501BE6E9000000004107AA224C24E0E5809B3A410012000003E4EAE82B2F0000001DE3E5E3E5E7E9E5E5E000007C572BE1E29F073617009BE554E4E4E3E4E40C00339FE5E6E5E34347E4E3E4E5E3E6E6AFE3E3E2E7E7E6E70520A6E4E3E5E5A622E32807E2E5E5E6E6E685E4E45438E6E5E6E4E4E1AAE11733E2E3E3E2E48594E5E5E5E4E5E4E5E3E4E4E4E5E7E6E7E8E6E6E8E6E7E6E6E5E4E6E6E6E5E4E2E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000470000000001000001E2E4E5E5E7E7E7E6E8E7E8E7E5E6E7E7E8E7ACE6E4E6E5DE85000000002D50C000CB47002012333C490E002D7EE3C0E5E2E1105F100005E3E1D4DE41000000470000E3D4E1D40007002645E3E2E0E0E2158524DF0005A4E2E5E1360E1B00000071D4E1E94E2B20050E000A0C4C506AE2E2E5D8E74E000000E5E3E450E3E1000A00A89BE3E2E3E380E20043900026E0E3E0755B5252120C00B1D6E1E2B7E43100DB0050E3E6E7D05700AFE5E4E4E3317C20E2E5E5E3E4E69D1919E6E7E3E4E4122817520012E4E4E4E6E559902857E4E5E5E5E475AAE2DE38A4E3E5E5E4E2D896E4E5E4E5E5E4E4E3E4E4E5E4E6E5E6E6E4E5E4E5E7E4E5E6E5E5E4E5E6E4DFE5E4E6E7E7E6E7E6E6E8E7E7E7E7E7E7E7E6E4E1E0E3DFE3E4AF1700000012284592DC663E000E0000001B927AE1E4E4E4E5E1A65B0000002D52E4E46A171000000000E1E3E3800E66244771AFE2E0DDE83E503A220087E0E3E7E3E22B000100243A59C5E775AF9F313E2000000073D4AFE8E8E6DF05000003EAEBE6EBE1C0802F002B523A71E4E2660000E22F00003A6690E3B520001D0000005980E7E5E6A13EBC1771E3E5E55F45339024E5E4DC33264966E3E4E5E5E59D1D57E6E6E7A4E6E1380C7350E2E4E4E5E7E580E0D092E4E5E8E5E6E5E1E4D6E1E6E2E6E4E5E4E4E2E4E6E4E5E3E4E3E3E4E4E5E4E5E5E6E5E7E6E5E6E7E7E8E8E4E7E7E7E7E5D6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000490000000001000001E3E6E5E6E6E7E6E6E7E8E5E7E6E7E7E8E6E4E7E7E3D4E3E3DE45003C000E6A22BEE1B1010A0000870054A8B5CDE5E5E689B7E1360000000A0EBAE3DF750007001B1B05CBE2E2E0457C471D2B1285D8E7D0410031BCE1C9E5EBE4E233000000244C9D5FAF92E0BE0328000000000057E7E7EB3E000C000000CDE9EBEBB5C968107E2F38009DE5E7730028003E001900A4A6E3E3220312E6920000E1E1E2DF57A68E3328E4E4E48771E2E25DD4E6E48B785DE3E5E4E2E3030C1536E3E5E3E4E4AF9FC94783E4E5E6E6CBE0E6B5E3E4E6E5E6E6E5E689D054E2E5E5E5E4E4E4AFE3E6E3E5E6E3E5E4E5E3E5E3E4E6E6E6E6E6E5E4E4E4E7E6E6E8E5E4E5E5E4E5E6E5E7E7E7E7E7E6E7E2E5E7E6E7DBE8E803E5E7E1E1E5E4E3E3E1411B005B719DE1E0D4C91D000000001D174CE3E2E6E5CD5B5700006200001278E1E473830C0510203194D8E25BC9150E00150062E0E2AC83154E78D4E4E5EBEAE5E2E4E03600361B19AFE357890A000C0000000007E5EBE45B0ED00A0A2F26E2E8E6E2E1E1009F52102BDFE1E5C9101700193103E49F85E52836000C5B12001792E1E4E16D337E3C17DBE4E5E6BEE6E16894E2E65F1794E3E5E5E5A10000006AE1E4E5E4E33CBA5FACE2E5E6E6E4A42857BA85E5E5E5E6E6E7AFE58533E1E1E5E5E3E6BAE4D2E5E4E3E4E5E5E4E6E4E4E3E4E6E6E6E7E5E6E4E3E5E6E6E6E6E6E7E7E6E6E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000004B0000000001000001E1E5E5E5E7E7E7E6E7E1E7E6E6E6E6E6E5E5E4E29FDE49E2E1E3E1E28075B1E2E4E3E43322001200005B0068D8E3E1E2E4E319000000000000D0E2E39BB50C0100280C1252E1D4E28900000019BA96E0E2CB450300D4A6E4E5E6E6E5E0E3E08B9F190C3CC2D06D1B00000000005447E2E8E4D8000000000038E0E4E3D8E2E10C000026C9C0E2E41964000001001700E4E2E5E04100000701000A4154E1E4D06F730180E2E28BE4E3E5E52B2BE3E4E3B7E3E5E6E4E4010031004C52E3E4E4DB00310000E4E4E5E5E5899DE44EE5E6E7E8E5E4640EE3D2E2E4E3E3E4E3E2E1E0E2E2E3E3E4E3E3E3E4E6E6E4E5E5E6E5E6E7E8E6E6E4E4E6E6E6E7E6E5E6E5E5E6E3E7E7E7E8E7E5E6E7E3E7E6E7E7E7E8E557385219A628DBE2836F49A12B789675E1E03A5B12002F73AFA4E1E2E0E2E3E2E16D9400002800001D948EC7E17CA1000000173368E3E4990000850015D0E3E2AF15000C0001E0E4E0E4E5E441B1E3E20728E2E3E1E39D000041000022504CE2E531150C0300003864C9E1E5E55D524E641064DEE6E7E3122D0007E500001DE3E27AE200BE8EAC002BCBE4E6C0E57322B7E5E2E3E5E5E4E3E47300E1E4E4D6E4E4E4E5E45B00000092E2E5E6E6E40ADF3E28E1E7E6E7E2E4E79D6DE3E5E6E5E7E6E7DF5700E5E6E3E4E4E4E3E3E4E3E3E4E4E5E6DCE5E5E3E4E1E6E3E5E5E7E7E5E6E6E6E5E3E6E7E6E8E6E5E3E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000004D0000000001000001E2E6E6E6E6E5E7E6CBE6E62BE6E5E7E7E34531192003DFDED8E1BE000000102803AA5038002F00190049B189E3E3E1ACE1E3CD3C00050010001B3EBCDDB7A42F012DD236007AE2E2E03A000000013C73E1C7C222200A006250E1D0E4E3C70C1700B580E3DBD0B5E4D8000000A622C7E073D2E1A843001B28177CE2E1E3E5D6A1174741A694DBD89DE5E20000000A171592B5E1E4E2E13600A6477EE3E54CB57C201BCBE6E5E4E4E4E2E4A6171599E4E3E6E0E5E3E5DE00003AE3E4E3E5E696103A0089E3E4E2E4E0E0E5A457E5E5E5E5E6E49999E3E4E5E4E6E5E5E5E3E3E5E4E3E4E4E3E4E4E3E4E2E1E1E2E4E5E5E6E6E5E5E5E6E4E4E6E4E4E5E4E7E5E6DBE5E6E6E6E7E7E7BAE6E7E6C9E5E7E6E9E5BC004C000071E078DF50000000000A00D2A801000C003A0059629BCBDEBC73DEE3E3E32F2600000000008B45E2E09D0038E3310743DDE0DB6A000A12052443A8E26F5F0000000028E1BCDCE37C0000000000DFE6DFE0E3E0CBDB1924B7DBE5E36DE58515AC1000151B24B7E1E399C06F2620D29DE3E4E3E4D20C570010157AE7C0DCE6E3E3E3DCE2000EE4E2D85007006866E2E3E1E4E5E5C91D3115E0E3E5E5E5E6E5E43C2B542D17E4E5E3E2335F0036B3E2E3E1E6C58968D483E5E5E4E5E6E200CBA1E2E3E3E3E5E3E3BA525DE5E3E4E4E3E5E6E4E5E4E5E3E5E3E4E5E5E4E6E6E6E6E6E4E7E6E5E6E4E4E4E4E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000004F0000000001000001E3E5E7E6E7E8E7E7E3E7E5E4E6E4E7E7E3E500172B00385DE2E3411D0000002D43D8DF001038002D0E68E0C9E14C730E416AE2C7E25412000000005DE2E1835B8000000019AADEE2DEAAAA22151700E392E138000000920038E2E4E15D361500470000948BE1E1E1E1DFE1E3C2E0E2E4D87EE4E3AC170000001DC54EC0E4E3DDA133077A7CE2E4E3DD7A0A2B1D5000001BDC64E3E4E4E4E22B0041E147E43845000000AFE4DBE4E3E5E44C001DC9D0E5E3E4E4E5E5D2C7E1D4E4E6E2E4E4E1BA785068E4E3E32D640024E3E3E2E4E5E4E5E4E2E06AE0E2E4E5E4CDE3E2D2E2E2E6E3E4E6E4E0E3E3E3E2E1E4E3E3E3E5E6E6E6E7E3E5E4E6E7E6E4E5E5E5E5E4E5E7E7E7E8E7E4E7E8E8E8E6E652E6E8E8E4001500000022DEAADE0000BA570059A1E4E4265F0000009FE1E3C9782B3615C0E2E3A41D000000A10094E19BBCE3430E000000473AD089CB2F0000000E71E3DD6600000000005778E5E25D120017B7170000005FD4E4642F80E2E5E2E5E3E3E2E4E4E300260000173C03E3E4E6E550494C1B243EE5E2E28B150C00123E010EC752E5E2E5E0EA2B0000D0E57A5B1B002B01BEE4E4E2E0628B5D0038E5E5E2E3E4E5E3E5E5E5E3E4E4E3E4E6E2E3DB807CE5E5E6E5A8BC9F0033E4E4E4E3E24926008B24E3E3E5E4E322C7BEE4E5E6E5E5E5E4E4E1E3E5E4E4E4E2E5E5E6E5E5E5E4E0E8E6E6E7E7E6E5E5E6E5E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000510000000001000001E1E4E4E5E5E6E7E7E6E7E7E7E03307E7E8E8E0220000002D90E3E18B00000000003CC96D57190047ACE1DDDC9F41000E004E59E4E42800000000006AD4E1E2DB3A280000000000E380DFD0006F005422DFE27500030000005452D6E554751B000000000000338096893E00E266E1E3E1E0AC66E36200006200000A9BE4E4A4C9BC055726009DE6E5DC52013C000000006FE0E1E2D000787E830000B79BE33C5B891745E3E5E5E4783A0E012D0EAFE3E3E2E3E3E2E6E4C55FE3E4E3E4E3E4E4E1E1E4E5E4E4E35D12DC0143E3E4E4E5E5DD8EE35089E6E6E6E5E3E2B1E4E4E4E5E4E3E3E2E3E2E2D2E1E4E3E4E4E4E6E5E5E5E5E5E5E4E5E5E6E5E5E5E5E3E4E5E5E5E5E6E8E8E7E7E7E8E7E7E63E03E6E8E5E717002205667AB7E3E1000C00AFE1DEE389264C2D716F3675E1787822005D7E36E2E3AA000000000100B5E1E2E4E11B33000000363CE2E3AC5724050A9DE2E359E35F00221D4C68E0E4E18771070000960000229BE199000075786DE2E3A49B2DDBE1260000000000D0E4E6E65D8500001B38857CE3E38E00000105000C31E0E4E5E1200000000A7517E2E29DE0946619E5E0E5E1B38000AC9900E4E3E3E2E3E4E36F5F59C5E5E5E5E4E7E5E6E1E5E6E1E6E4E5D071DD17C5E4E5E5E5E37CE3E5D8D8E5E6E3E5E5E399E2E3E4E4E6E4E6E5E2E3E4E3E5E5E4E3E4E6E4E5E4E5E3E4E6E6E6E4E6E5E6E4E6E4E4E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000530000000001000001E5E7E6E6E8E7E8E7E8E8DCE6E8B1BAE6E7E6E72D002F3C1D0CE0E1E47822003C0059E4D29F994522000024E0E1475712121BACDBE2E0B5030000010A6F3AE4E178262D0100031728C073E068005B3A057ED489E3A4190C1200B3E249E6C2311500000000263C0CE05B00006A75E2ACBCE56AD6E2E0CD2B0000010012D2E4E5B3BA0A12000012A8E3E4AA003300C2000020E5E4E28B2D0000006F7A00DDE478AC68203EA8E4E3E1E3C5E33A0500E4CBE1E4E6E5C03A7538A6E6E6E6E6B5003E15E4E8E5E6E4E3E4E2E5E5E4E6E5E4E3C7DEE3E4E5E6E7E8E7E4E3E5E4E4E3E5E3E5E7E4E3E3E2E1E3E3E1E2E2E5E6E6E5E6E4E6E6E6E7E7E7E7E7E6E8E3E4E4E5E5E7E7E7E7E6E7E6E9E7E8E2E7E7C985E8E7E4E207051B1533E6E4E35D1703220E5792E06FA44100002F1B2DE28E2F2F00073E9DE2BCC0B30A00005D243671E1E08EAF030000331B00E1E5DB89E0261226E3E3E3E09462002D2F78D0DEE45B07000005000017B1DFE2071D053EE34C00E0DEE3E5E41519000000003689E5E5360500200000269BE4E5BE941D00100005E3E0E0B100410047310000E28EE6E47305124596E4E5E3E4E3E371472FE5E0E1D4E4E32F000028E287E4E4A60000001DE3E6E6E6E5E6E7E5E6E5E4E7E7E6E2E0E3E0C2E5E3E4E5E6E5E5E3E6E6E4E6E4E4E7E7E3E6E4E3E4E1E3E3E5E4E5E5E6E5E5E5E5E4E5E7E6E6E6E6E7E6E5E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000550000000001000001E4E6E5E5E6E6E7E5E7E7E7E7E605003C5BE1E2D0318900000033DEE2D050152B0533AFE3D85D153A2F0C1717C7BE522D410E3E36D6E2E2940000005900033ED6E49496380E310A3E529BE1E1B12424030159E3B39B94170000006ABCE1E4A1900500002B001712A668E27C0043337A1B2F8BE1D6E3E1E0000000001B41B1E3E2430090000017E2C5E5E310680050200A26E3E7E1A4E1000E000000E2E6E5E2C5B33AB71BDEE5E5E2E1529D26031D90E5E5E6E633006D0E9DE4E5E6E60AE10C85E6E4E5E6E68E49D4E5E6E5E6E7E4E4D092E4E5E7E5E4E4E5E3E3E3E4E3E3E4E4E5E6E5E3E6E4E4E5E5E2E3E4E6E6E5E7E5E6E4E6E6E7E5E7E6E6E6E5E6E6E6E6E5E6E6E6E8E6E7E7E7E7E6E6E300001920E2E3E2E1D000000000DFA87A0741360A1B38E3E39B00311B904E07318752220A100A7E94E1E3AF4300002B000712BAE3E12801002B3319A1BA87E0DE50001000C5E3E380A80000B7000094ACE3E0572D502824000100D00790381BD8000000002447E2E1E3E100000000000033E3E2D65000010007AFE3D0E46A0A5441170E00DFE4E5DE240500001200AAE3E4E3E23A41544703E4E3527E0312E50054D2E3E6E6E69D3E3E66E3E4E7E6E700575F015DE4E5E5E445921DA4E2E5E7E4E4E3E4BEE3E4E6E6E5E6E5E4E3E3E3E0E3E5E3E5E6E5E6E3E3E2E2E4E3E5E4E5E4E4E5DFE6E5E4E6E6E6E6E6E7E6E7E6E5E5E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000570000000001000001E5E8E7E5E2E7E8E6E8E4E5E57C00000E78C0E5E6E12F000100009BCDA40A017100003CAFE3BA0C070054000036E33A4717000015C7C0E5E12B6200032028009FE1E36F579B010E7822BE80E4CD2015E30007CBE2E2E124000000002B80D6E1A63A190000000000AAA1B3E2E3E0D000E10000001DC55BE336000000247A6285DBDBA40000000057665DE4E4C0D8000500571BBAE5E194012424490EE0C0E3E3E22400000059E1C29417500126DE80E2E3E6E6E6E6DF49E4E5E5E6E5E4E5504C01DEE4E3E45D5F5924E0E3E5E5E3E5E41B9FE5E6E5E6E7E4E5E4E5E4E5E4E4E2E3E5E5E4E4E3E1E2E1E3E5E5E5E4E3E5E4E7E6E6E2E4E6E6E7E6E6E5E5E5E5E6E5E4E7E7E6E7E6E7E4E7E5E6E500E1000000E2E4E3E100000000005BE2C5000064000524E0E3E21045000000241DB147000092000047E0E2A8A4850C1D00009BDBA4E0C5DB9F170115000C43E3E00000000000DFE1C959C90700001DC0A6E2E2D8C7AC00015D0000C9E0E1E0E1000000D0001000D0D8E2E1E3E4E2002D78B7E2E3E490151900053AA6E2E49478261505008B0185E6EA66D633336F4700CDE5E5E7E38320001BE2E2AF6F5073D287DDE3E0E1E2E53C547CDEE3E6E7E7E8E6D2A47CE3E4E4E56D201000A8E5E5E3E6E4CD68E03EE2E4E8E6E5E5E5E2E4E4E4E5E1E5E4E4E3E3E4E3E5E2E4E4E5E4E5E4E4E4E5E5E4E3E5E5E6E5E6E6E7E6E6E5E6E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000590000000001000001E1E5E4E1E7E6E6E6E7E7E7E7E3050010B5C783E5BC960003000A0052E14C003C00A60024D2E1DBA4C700002007475F00000000006FBC75E2E1DF26331700491BA4E1DEE000660000000071E1E03E000000334CDFB3C9801D00001D3600DD68E11B33000000003EE0E1C9E2E0D405003800000022C9E0E0E3E3E283192B50DFE2E2B11D710043005D73E3B12B000700E20003DDE7EBC257734C5062629BE2E4DF3E717A5B7CDCE2E3503E87E405E4E2E2DDE1DD33D257E5E5E3E4E3E4E4E5B57AE4E4E4E6A4311900E1E5E5E2E16AAFE3E043DDE3E4E5E4E3E2E3E5E5E3E5E4E3E3E5E5E4E5E4E3E4E3E4E5E5E4E5E5E4E5E5E5E4E3E4E5E5E5E6E5E5E6E6E7E6E4E6E8E7E7E8E8E8E7E6E6E3E7E2E76A125B4EE5B57A0000005B006FD09038000503002BE0E39D94A42B07011D75DDC9282F12002BD2E0E2DB1BB3620000001D002FE2C5AA380000410A01E1E3E03C00000117E0E3E1E1A600330C365DCDE2E1E0A105000000036ABADDC2E0E15B0031012B009673E3E1E3DEE1BC004E3EDDE2E0BC0000000300BC50AAE30A173E3CE56603E1E2E9EADCE5E2DDDCE3D8E4AF3807CB000028D4E1C007DE9D8B96E6E4E5E5E6E894AF5FE3E4E1E2E4E4E06AE5E4E5E5E5E6DBD6DB00E6E4E5E468A8E3E4E3E3E4E6E5E4E3E3E4E3E2E2E6E5E6E6E4E5E2E5E3E4E6E3E3E2E3E3E6E5E6E7E6E5E5E5E5E6E4E6E7E7E7E7E6E3E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000005B0000000001000001E3E5E4E5E6E6E5E6E6E7E5E5E8AF9F000000C9E4E5E3150000050000D8CD4E4E96123EDDE3E37131000000000075E1C07838AC0005B5B7E4E3C70E0000000000006DE0E3E3B52D00000C24E1E0D2E22B2D19129DE3BCE0E00C1B0038C5D8E1E1E15B1D0000000A1D4ECBE0E0D800002F00001959E2D0339D00003ED400009FE2E2E12F96000000200062E39D220000E4BA0047E2E6E87524A4E2E0E2DBE3D6E1E3E3E2E3E4E6E4E2E059C250383EBAE1E3E436383CCD52E2E3E4E3E4437383E3E3E5E3C0A4E3496AE4E5E5E4E7E4E5E3E2DDE5E3E3E3E3E1E2E3E2E3E4E3E4E5E4E4E2E3E2E3E4E1E6E3E4E4E4E5E5E5E5E6E4E5E6E3E4E5E4E4E6E6E4E5E4E5E5E6E7E7E7E7E6E7E7E5E5E5E9E7AC0E8E000CE0E190E25D00000000A8874C38105B31E0D0E152070E03000A008EE0E2924141100050B5E1E1E1AC07005000244141E2E5E2D62B032417073CE8DFE19600282633E1E2B3005003030A28283AE0E26D2F00000000014171E6E3A6000000000038A6737EDD280C0000E1B59B85E2E2E3E11D00001D018075E3DF3805016D0003D4E3C7D23E0C0E2249DFE0E4E6E5E4E4E4E3E5E6E6E400E0E31924E0E4E2E5B30E1700AFB5E4E5E6E519193333E1E6E6E5E13126A868E4E4E4E4E2E5E5C954E1E2E3E6E5E5E0E4E3E4E6E6E5E5E7E6E5E4E4E1E4E5E4E5E5E3E4E6E6E6E6E7E7E7E7E9E6E3E7E8E6E9E7E6E6E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000005D0000000001000001E4E685E5E7E7E7E7E8E7E7E6E9E5E53C43010A22B5E4D2780085000087E4000A01E2E0E2B3641B0054050500005233E4E36A361900008EE4E4E4D08B101B003A07A6C9C5E4891736005F2283E1E33A0000000199DBE29BB7A6050000001B0080C9DED65F0007000E2490E3E2E0DDC003000107385DE3E39F00011210E2DCE1E1E3E4E5000068800028D0E6E4DE011200730075DFE2AC0C1D0015284CE0E4E5AAE1E3E6E4E4E5E4E5E2E3001983D8E4E5E43354D62226E6E5E5E4BE00003610E4E5E5E5E4DE9F009BE6E7E0E4E59DE6E5E3E3E4E4E6E6E5E7E3E3E3E4E6E5E4E5E5E5E6E6E4E4E5E4E6E4E4E3E5E4E4E5E7E6E6E6E5E5E4E5E6E5E7E7E6E5E6E2E5E5A4E5E7E7E7E1E6E7E7E7E6E9E8310020030E17E2E3DB0500000001D200003164D6E0E0646D00000A05002B59DEE48E7A6600000017A1DCE1E252202233000052AABEE5E30E000054053A64E4DB00640000E3DDE3E1E49F17000E000CAFC0C7C21200000020DB00E37CE2E1E2A8903600003A24ACB1360000000092E2E3E1E1E4E4E30000000001C7E2E4DE26C533E1D44331C7DCA4C910A10045BEE3DC503A7EE3E4C7E3E4E5E6E5E12243E2E4E2E2E1C5000010E5E5E5E3A10A80412FE4E5E5E5629BE2A810E6E4E5E2AA6F00E1E4E3E5E5E6E5E4E4E4E2E6E4E5E4E5E5E5E5E4E4E6E7E6E5E5E6E5E3E7E5E5E7E7E5E5E5E5E6E5E5E5E5E7E7E5E2E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000005F0000000001000001E483E594E7E4E6E7E6E4E6E6E9E9E9E600203E0066E2E3E2C707000000E220265DC5E0E18389E0A605002010458BE3E3E2E1750000287C5FBECB80CD73E05D0A001B2F03D8E3625B00000000BED89B00000000D8CBE4C7968B2F000000000036D2805400001B000000BADC68B380CDDFC20000000589C7240043000000C771E3E3E2E2E3BC241000005950E3E1B3DFE1E3E41D3ECDDEC72B360000BCE3D012072D52CDBAE2E0E3E5E3E5453CB5ACE3E3E0680CE52819E3E4E3E3262400B7E0E5E4E1E3E30A12002DE6E4E3E27EA4E447E4E3E3E4E7E4E5E4E6E3E5E4E4E4E4E4E6E5E3E6E5E4E3E4E2E4E3E4E4E3E6E4E5E6E4E5E4E7E7E5E6E5E5E7E5E6E4E6E6E7C7E7E7E7E7E6E8E8E8E6E6E4E6E17319152D1DE1E396AA5F00336DA120330045E1CBC77EE4DD75000A00006FAFE4E3DB170A0000196F68DCC5E2A4BE52010019016475C9734E0E07000000E2852F0C001D1B20E1E3C0DE960007000C3ABAE0E1A41B032B2FDB31E10033A1E354E3710005000000E0CD00010C0000009971E5E5E6E5E5D80E001787E1E3E37CE1E3E1E09BC95FE3E183545920E2E2960059A6A82D71E4E4E5E3E5E3E26843D4E3E2B38BE0B14E78E6E6E4E5572283BA57E5E8E5E4907CC987E3E5E6E3E2E5B3E5E1E4E6E4E4E5E4E5E3E5E4E5E4E4E4E3E3E5E4E4E5E3E3E3E3E4E6E6E6E4E6E5E6E7E6E5E4E6E7E7E7E4E5E6E7E6E5E5E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000610000000001000001E6E6E6E6E6E1E3E5E6E7E6E6E7E5E5E4E4D60000010000C9E2E1E268DDE12D001DBE2403624CE3E1E2A63C7A208390DCE2D88000781D0036DEDCE1C0E1E1C0AF280000000000E09F1200000012CDE600004E0100D2C0E0C9A49F0000000000010000DC7A8E263AC9E194B3DFBCDC0000E10000E2000000CBAA0E01000322193EDFE2DE87000000E2007CE3DDE2DCE2E3E2E19D7A8750DBDEE3E2E2C7C75B000E000038E3E2E3E1E5E7E5E5E4E1E2CBE3E6D6411B855289E4E3E3E5416AD2E4E4E3E4E2E3E2A6E5E5E4E0A1D4E4E3E4E4E4E4E5E2E4E3E6E6E5E5E5E4E3E3E4E4E4E6E3E4E3E4E3E4E4E4E5E4E4E5E4E3E8E6E6E7E6E5E6E7E4E5E7E5E5E5E5E5E6E8E8E8E5E5E7E6E8E8E8E8E3E5E4E2E1E1000000001719BAE0E0E2E2D65D5054903C280000E2DFE1B36F2424240E24E0DBD62B00000087493CDEBCD8E49092000000A4002696E0DC0A0000009BE9E1B5000000ACA1E3B7E201000000000000004EBAE0BEE3E1DF99A4CB6800000005174E000000000087E23E590A00000A00A8BEBCB73A0E000000385FE1E4D0E5E4E43C005915AC6AC2E1E4E4E2E30515360071E3D2E2CBE8E4E3E3DEE3E3E2E4E4E6E038E49000E4E3DBE4E500009BE4E5E3E6E1E2AFC0E6E6E5E5E5E3E487E4E6E6E5E6E5E5E4B1E5E5E3E3E2E5E4E4E5E4E5E5E4E2E5E1E4E4E4E3E4E5E5E5E6E5E6E6E4E5E7E7E7E5E5E6E7E5E4E6E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000630000000001000001E3E4E5E4E7E8E7E7E8E7E6E5E6E6E4E6E400000000000049A694E17392E23A45B7470A1D714EE2E0E09F570E0010003AD8E39F0E000C0C9B90D6E1C26DE3E073000000000092E2E2D2D05B0010DFE7E72F000000002F62E0C54E00000043000000150AE00052BAE1DEBEB53A4C0000008764000000000110A805000000000000DDD2E18B9F4E2D00498EDBE1E4DBE3E5E3E34C15416DCDE338E2E17C6A6433665B80E4E1E3E6E4E4E4C2E1E4E4E5E4E9E4E2E09F8092E0E3E5E56607A110AFE1E2E6BCA8E2A4E0E3E6E7E8E5E2E2E0E3E5E4E5E4E3E3E0E2E2E2E2E2E2E2E1E0E5E6E5E5E6E6E4E4E3E5E5E5E5E5E4E5E5E5E5E4E5E3E5E5E5E5E4E5E6E4E6E5E5E7E6E7E9E7E7E7E6E7E4E522E2E5E4E2D6280C000010001538E3A6CDE3E2E0E4D010260E1B26BEE3D06D0789C700015BDEE3C5280E241B43DEE1030E7EE2835015243E284350E1E0E0E5E2E1E6E6E52000000000C201E0E3E2A10000000300000075E2C778E4E3E3E2E2A6645F000000002D6D00150024E1E205005900003C59E5E4C728001900E1E3E3DFE0E5E4E1B57A0E0012B7E3E4E3E5DED2E2E4CB6DB5DFE1E1E4E8E5E88545DDE3E5E5E2E3E6E6E6E500E0E3E4E5E454AFB515E1E0E7E6E5E4C7E4E5E7E4E5E4E2E4E5E3E6E3E5E5E5E3E2E2E4E5E4E5E2E4E1E3E3E4E5E6E5E5E5E6E6E4E7E6E6E5E4E5E4E5E6E6E6E6E6E4E8E6E6E5E4E6E4E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000650000000001000001E4E5E5E4E7E7E7E8E6E6E5E6E05FE2E9E1E4D850000000000012E1E15496E1E2E3E324010000004EE2D0000000330005A1B3E1C966380AA48B5DE1544C20E1E39B0C71003E2D0A90E1AFDFDEA875E5E2AA00000000206DE1BED2E1C0000000000712005B57DFE4E5E2E341A6DC000000009FDF380E000075E1E200000000011000E0E159D06F9D3143E4E5E5E3E4E2E29BE1E1576ABCC5D6E3E2E3B3CBB1227C7ED4E512E3E5E3E5A46F000089E4E4E3E3E1E2E4E4E3E5E1E4E4C543190EC9E4E5E4E5DBE1E1E1E3E6E5E26AE1E2E0E3E4E0E6E5E3E4E2E5E1E5E4E4E4E2E2E4E2E4E5E4E4E4E4E6E4E6E4E5E3E4E3E3E4E4E5E5E6E6E4E4E3E5E6E6E3E4E3E6E6E7E7E7E8E6E5E7E9E6E8E9E6E4E6E3E3E100DB1907E00A0036C0C9C9C9E4E3E2201B0000005DE1E3E23C00000500123AE2E3E2451B0020A6E1E0590000B3E2E10015006A201D2D6A3E2FE2E2E2E0D0A4000003103366E3E2CD269400000A120000498BACE1E2E2E2E396001B00000015D0D60E000A00B7D8E32F030700000031E3E2CBE5C91D4C73E3E3E4E7E6E4E2E3CB5250891DE0BAE1E4E3E443C06880E4E4AAD2EAE4E6E5E5D8050000DFE3E4E4E4E5E5E7E7E6E5E6E58E8747C0B1E4E6E6E5E1D057E1E4E6E6E6DBE4E1E4E3E4E5E5E5E4E1E3E4E5E6E5E6E5E3E4E2E2E5E4E6E4E5E6E5E6E7E7E6E5E4E6E5E5E5E6E5E0E5E5E5E6E6E8E6E3E3E3E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000670000000001000001E7E7E7E7E7E6E6E6E7E7E6E7E32BE4E6E4E2E03A00008700007CE0E2B3E1E3DCE2E141000000332BE3E3964E001B201252B3E1DF38240E332BE1BC5B001000DDE5C9A12D0C245B4E004CE2E19FE2E2D29B00001B005B5B71E2E18EA45B00000A5200000047E3E4E2E2E3E08B2803000020E3E2DE283A3C17DFE1AF2D00000000001DE3E0E27E31314326E4E3E5E0E0E4E4AA593C87876D31A8E3E8E3E3E3E296E1E5D4E0E6E2E3E4E11D262241E5EBE2E4E2E4E7E4E5E5E4E3E3E1A18BB3E2E4D6E0E07A49A4E4E7E6E6E5E3E3E1E6E4E3E4E6E6E6E0E1E3E2E6E6E5E3E2E3E4E6E5E6E3E3DCE5E4E4E5E5E4E5E7E5E5E3E5E5E5E6E5E6E7E6E7E8E7E6E4E5E5E7E8E6E7E6E2E6E0E8E7E9E7E4E1BAD0E6E2E4AC1D0100000033AC5BE2E3E2E1E2AA26000083005B96E2AAA612681B0E0312E4E4800AB30028E3521900000000E1E2504E000A00000000A1E17AE2E5DB41000000363C47AF68E30AAF0E00000749004C0019B3E2E2E5E3E16600681B0300E1E4E32F871B01BAE1E262002D500010A6E0E0E24500000005C2E4E4E4E2E3E2E2E20000387C2271D8E09B7AE28EDFDEE1E2E3E3E3E0E224A150DE1BE2E6E2E4E3E4E7E6E6E5E3E5E7E48BDBE2E2E2E5CB68E6E226E3E5E5E4E0CDE5E0E5E4E2E5E4E5E6E2E4E3E6E4E5E6E4E4E5E5E4E5E5E5E3E2E2E2E3E4E4E4E5E5E5E3E5E6E5E4E7E6E5E6E5E5E5E7E4E5E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000690000000001000001E5E6E5E6E6E6E5E7E6E5E6E5E645471080E4E1E4E1333E000020003ADCC7E3D68BE32800000A0078E3E2D0E09B43002B002DC2E3E107000001E42D0050800000A6E4E1434E000062000022929DDDE2C900570000000E662B49C2E0A66D3C0087000000151DE1E2E3E5E2E17C003C100C207CA4A48B3C38246FE2E40100000000007EDEE29603007100009DE3E1D8E2E3E3E3AF00A110E3D8CDD66645E02F28E3E3B1E3E3E4E2E38907B1E1B766E0E1E0E1C507E2E4E5E4E4E3E4E5E4E5C2E1E0E1E420AFE200DEE4E3E6E0E290E4E4E5E2E4E4E5E2E4E3E3E5E5E3E4E3E2E3E2E6E5E5E5E4E1E2E3E2E5E5E6E4E0E2E3E3E5E3E5E5E4E3E4E2E4E5E5E4E5E5E5E6E6E6E7E8E6E7E4E8E8E2E8E2263E28B1E2E6E4DC5D003617BC6252E0E1E062E2757C1D541962CBE3DCE4E2E4E16A050062B3E1E3B34C506FE219030000001203E2E3E2526400000000037AE0E4E2E02B38000000105D00B3D0E1CB66B10700003C20001B78E3E596E4E138152812173ADEE0DDE0C28BE2E4EBE69B000000000047E3E2E20000000000E1220CA4E4E3E5E5E441001549D280E0A4E0C7C059DCE26690E3E6E5E3E23A64E5E15DE4E4E4E29D5BC9E4E7E3E5E2E4E5E5E5E4E2E3E3E56ADB5B5DE4E3E4E13CE3E3E6E3E4E3E2E4E4E6E6E5E6E4E4E5E2E3E4E2E4E2E3E6E6E5E0E3E5E5E6E5E6E6E1E5E5E5E6E6E7E6E5E6E5E6E5E6E7E6E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000006B0000000001000001E7E7E8E7E7E7E3E8E4E7E6E7E58B331033ACD2E2E4E1A6D8002F0CE2E336D0E19BE3E25F0C07283E10E0DEE2E2E2C000000017E1E5D6751566E09B3C000500000ECDE1D2E028170E007E5BDDE1D6DFE08524056A000000B7D071DEE1261038000000001700E0E3E3E4E47E621700000089E1E3E375623C664CE4EBBC00002D00000089E5E2CB2F0017C9470078E0E5E4E6E6E6E50A1724319BE4E3CBAC9401E2E200AFE3E6E6EAEBBC00002D45E5E5E6E4C2C233D4E5E8E5E2E4E5E4E4E5E6E5E2E5E4E1D8AFE3E3E5E5E699E5E4E4E3E6E6E7E5E6E4E4E5E5E6E6E4E6E4E3E4E3E5E6E6E3E3E5E4E5E6E5E5E7E1E4E4E6E5E6E5E8E4E6E6E6E6E5E7E6E4E6DCE6E7E7E6E6E2E6E3E6E6E8E7E8E600000017C7E0E2E3E21500D000D626E2E2E2E1B3E2660001000105A6C5E31DC01900000000009BE1E0A4E3E1B550003E00100059E0E0E2DD62281B0C032BE3E5E2E2E2B700000000319F00961BE07AE0DE0000001B2600C5E2E0E3B51245000000000AAFE2E0BE0A00153187EBE017001533004C0ADCE5CBDFBAE6E1C07A66E5E3E2E1AFDBE7E3E02D59E0E5E4E389E1E1E0E36231E5E4E3E0B100732B1BE8E4E5E4E2C7000731E5E5E5E3E5E5E5E1E2E3E3E7E6E8E5C7B3E2E4E5E2E6E5E5E1E3E6E4E5E5E4E5E5E2E2E0E5E4E4E4E4DDE3E3E2E5E6E5E2E4E4E5E5E6E6E8E6E6E6E6E8E7E7E7E6E5E5E6E8E7E7E2E4E2E3000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000006D0000000001000001E4E4E4E5E7E6E6E6E7E7E6E5E7E67500000000E2E1E3E1280019DFDE000094C96A877E3C2417077CE1E262E16FC01700E138000100E1E2E0E3E2B7D25F1973001D0EC5E11DCDCB710026004EE2E2E3E0E3A8310000172F00001D50C28E0010000000E3E100B1E3E038AAB5592F0000330043D6DFD466A43E1BE1E9E2E4000000000010BED8E2E071DCE4B1C7E6C2E4DFE2783EAFE4E338226FAAE25B80E3E8E2030E54DBE4E4E9E017382000E8E3E3E4E6B1497A92E4E6E5E5E4E5E1E4E4E5E5E2E3E2E4E4E3D2E3E4E4E4E3E7E6E5E4E3E3E4E2E4E4E1E4E4E4E3E4E4E3E1E3E4E4E5E5E5E2E1E4E4E3E5E5E3E2E4E3E3E5E5E3E8E6E6E7E4E4E5E4E5E4E4E49FE8E8E7E6E6E5E2E7E7E7E6E4E6E500800052AF12E19BC003202800000085E08368B70000000022A8E254E2E4DF4C00000000001BE0E18BE5DFD610000003642466DCE3878E0000000000013AE1E2E1E06A71413805C9C70050CDA4E2BA52BE310A01000085E4E10031E2AFC764000E7E2BDBDBB587C96422E0EAE38B17003C002080DCD2DDE4E7E9E2E26DB568E4E2E3AA3A33E4E8E2837EAAE4DFE4E9E6AF173E54DEDFE6DEB303C5594ED0E4E5E4DDB1D2E317E6E5E6E6E5E4E4E4E5E5E5E4E4E5E5E6E6E0E1E6E5E5E6E4E5E5E3E6E4E4E4E5E5E4E4E4E4E3E7E5E5E3E1E3E4E3E6E2E2E1E3E3E5E6E5E6E2E4E5E4E5E6E7E8E5E6E4E6E6E6E8E4E4E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000006F0000000001000001E6E6E6E5E7E7E6E7E9E8E7E7E8E5E7200000005BC2E380E1852D9B0043593371E4E5E14100994100003A6A71E3E16A156400010003A6E3A1E3E3C5C503032B12001DDDDBE5E2BE410000000017C9E0E3E2E2B7CD261D28075BDEBEE2E2E0E06D2800000010E4E5E22043E1E2E224000000C0DDE3DE687A590068E3EBE4C2C510000103A6C7E14726E9E5E1949BE1E2E2E5E3E3E447B1666D52A8E290E7E5E4E47110035489E2E1C026B5BA1DE2E3E39DC9C9AC4E10E3E7E5E2E664AFE4E3E3E4E5E3E5E5E5E5E5E6E4E4E5E6E7E6E6E5E4E3E4E2E5E6E4E4E2E4E5E2E2E3DDE2E5E5E6E6E4C2E4E4E5E5E6E6E1E4E4E7E6E4E4E5E6E5E4E4E6E5E6E7E8E6E6E7E5E6E5E5E7E8E7E8E8E7E8E6E6E5E8E6E507001B2FB383E3A6B7E152000A1D836DE1D03800280E0020314CE4E0E2E0E15D240C0015D6E457E1E3E4E1C7540300001B73E2D850E3DD3A20000012E2DCE1E2E392A8313A00121B224CE1E3E20C3A0000000000BEE200008700E14E628926038EE3E5E38B002D223CE37ADBEB908E2800DFE2EBEBBA45E1CBC0000E5DBEAAE29FB30A0ACB00E4DEE2E4E487E4E3E100008EE6E6E4E5E4E46DB39DD2E4E4E4D6102478A48EE5E7E4E496E4E0E1E3E3E5E2E6E3E6E6E4E7E5E4E5E6E5E6E4E5E6E7E7E7E6E4E2E4E2E5E4E6E4E387E3E5E3E6E6E7E1CDE6E5E5E6E6E6E5E5E6E3E5E6E6E6E5E4E3E5E3E5E1E5E3E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000710000000001000001E6E7E5E5E5E6E7DDE6E6E5E5E6E6E6E6E3DD0052002F5BE1E1E4E3A42610207E80ACE2832600000A89A8227CE4E1D8D2520E003E000AE08EE3E3E1C25F120078000062E3D8E192893E001528265FA8A68EE0C7AFDE05000503479F10E0E192A6002200009BE310010087C5DB92330C00001BE3E5E2AC0C3C432BE2E2EAE871280000E2E4E9EBEBE3E4E3E21985C7E0E4E4C2661B0EE4DE4EE4E4E2E3E4E4E27C001931C5E6E4E4E2E57AD22883E3E7E5A83E49E36DE6E7E7E3E55DE3E5E4E5E6E5E4E4E3E5E2E6E8E5E6E459E6E5E4E2E4E5E6E5E5E6E4E3E5E5E5E5E3E4E4E2E7E5E6E6E4E2E0E2E6E5E8E7E6E2E5E7E3E5E5E6E6E69FE6E6E6E7E6E6ACE0E5E7E7E7E7B5E6E9E7E7E7E6E7E6E7E1E6E2E01503102DE0E0E2E3E4E0001919717333E5A61B36412B001D3807E2E4E4E33C121B1900286DE3E2D2E3E34500000CD6004CAFE5E2AFA6E1682401001264D6DFA8E0450017017C151D87E1E5E5E0AFDE0E002BACE324000000E0E3E26A26190071E0E3E3E2E01D0C4CB3E5E6A1660000000549E6EAE4E4E1E2621D5045D4E5E0C26D056401017EE3E3E3E5E6E5BE1B000500B549E5E7C7CB2DE4121DE1E3E4D8E5E5E4E3E3E4E7E5E6E5E2E4E1E4E3E6E6E4E5DDE2E5E5E4E5E4E5E6E4E6E4E3E6E4E6E5E7E5E5E3E5E5E4E4E4E2E0E4E5E7E4E6E5DCE0E3E7E7E6E5E6E4E4E4E4E7E7E7E6E4E6E7E8E7E8E4E5E5E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000730000000001000001E5E5E6E6E7E6E6E7E5E4E5E5E7E7E7CB94E326000059A1E2E2E1E2E20A000C002638E2DB382B265000120ADF87E3D2E0E22F000000002DE180BEE18E6449000100070319E3E0E03AE08B2400000A0049E0E0E3E18B80030000008BCB0CE4E2B30C20A1007AE100001701808BE4D41D15000096E3E4E2DD4E2466C9C0EBE4A40000000000DDE3E2E5E1190100001BE0E0E2D6AF223A07CDE4E3E5E2E3E3E5E2D8524C5B33E5E2E2D271714900AAE4E4E1E4E520E20047E3E4E2E4E3C5E3E3E3E5E5E2E4E3E6E0E4E7E5E4E5E6E6E4E3E4E3E4E5E5E5E4E3E2E4E6E5E5E3E4E2E1E5E7E5E5E2E5E3E3E5E4E3E4E4E4E4E3E3E5E5E4E6E6E4E6E3E5E6E6E6E4E6E7E7E7E7E7E6E5E6E7E7E7E8E6E6E2E8E6E464005022B5A1E2E0E3C03C00000005263852E3A8E17E2200002226923896E3E4620000E2000531C949E5D4D2D010002B2400007EE2C5D2C9176200000100335DE0E4E3E3E16F220000008722D0E3E045284178E350001068227AE5E28B24000031387AE9EBE33A28016D85E9E12D00E517016D9BE8E9EB501B43C90033E4E1E3E1E15B1971E2E3E4E3E4E2E6E6E6E5A194AC54E3E4E4E4D8B785E6E3E4E4E6E6E5E3D2E2A4E7E9E6E5E3DEDFD4E5E6E5E56FE4E3E6E8E6E7E5E4E6E5E5E8E7E4E6E4E6E5E2E2E3E4E5E7E6E4E5E1E4E5E7E6E7E5E5E4E5E5E4E6E6E6E6E3E6E6E6E8E7E7E6E5E5E5E5E6E6E5E5CBDF000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000750000000001000001E7E7E7E7E6E7E6E6E8E7E7E7E7E7E7E6E4645BE24101D2E2E4E2E4000000000000156DE2E4453C1710000C0E3C28E3E4BEE252000000364CAC17B7E25FC924121B2D0343E0E3E5C0A4543824002400003638E2E2E15B3C0000000000002BD6E3E19626BCB1E2000C1B1D5BE2E1E1C70003000033E6E6E0001B100019D0E3312F150A92459BE5E9B75B0E00000038E0E3E5E6E5B73CD2D4DFE4E3E3E3E6A1E3E3C72887E2E4E5E4E3E0E1E0E4E5E5E5E3E2E2E5E5E07EE4E5E5E4E5E3E1E1E4E3E7E6E5E5E2E4E6E6E7E7E4E8E6E3E5E7E4E5E5E6E6E1E1E4E3E2E3E4E5E4E2E4E4E5E4E6E4E4E6E6E4E6E7E8E4E4E4E3E5E5E6E6E5E5E5E5E7E5E7E7E5E6E5E7E7E7E6E7E7E7E2E7E6E6E7E6E9E7E8E9E4E400380145E3E5DFE1E164000000000054E0E3B3E380450024004E0592E2C99FDDA6001D100045B3E271E3E4E2E18500000E3E28DFE4E15D9F2B3300000E9F5033E3D2E3E12F00030000006AE2E2E2E53E0589E4288BE300003696E4E3BE5700000000E0DDE2570015000028E09417E2D8B3D2E1E6E6E0AF7826000015DDD2E4E349C9BAE5155BE3E3E4E3E5E0E0E8E4E37EE4E5E6E2E3E1A6CBE2E6E6E5E4E5E6E5E5E4E4E4E7E5E236E5E2E3E3E4E4E4E5E5E6E7E6E7E5E4E5E6E4E4E5E5E3E5E4E6E6E6E5E3E4E4E6E6E5E4E3E5E2E6E5E7E5E5E6E7E6E5E7E5E5E6E5E5E4E5E4E6E6E5E5E5E4E4E5E5E3E4E4E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000770000000001000001E5E6E5E6E6E7E6E4E7E7E7E6E8E4E4E7E78E073100E1DFE3E0E2E32D15000C0000002BA8E3BE8038010E20280003E2E2E2E3D426000000001D8BBEE2D0E1837C001B004E0036D4E4E299683E0A364141AADCE3E2E1E12B00000C0000005BD6D2E1E289BE5D0E1000000036B7E0A46600002F000089E4E30E0100000196DFE275505450E2DEE4E4E0AC315B00455FE6E1E0E25764E2CB03C9E4E2E4E4E6E0E1E4E5E6E3E7E6E7DDE2E3C783CDE5E5E3E4E59FE3E4E0E3E5E6E6E6D0E1E2E4E3E4E6E7E5E6E6E6E6E4E4E4E5E6E5E5E4E4E2E4E4E4E3E1E1E4E4E4E5E6E3E0E3E3E2E4E5E4E4E4E4E0E4E6E3E4E5E5E2E1E4E6E6E7E5C9E5E6E6E7E7E7E5E5E4E5E6E7E7E7E6E6E6E7E8E7E7E8E5C5DDE6E4E4592426C0E2E1E5D0D0A8BE2600070E2F4E9DD4C2733C493600280A75E5E3E2E1D22D0700031B2B5B599DE0CBA873000000000047E0E4E3E3E25705DE00753A5066E3E4E385750045001D17127359DEBEE3E3E42F4500003E0054D8E545220000190000E4E0E42D28000001E1E6D63A662B22BAE3E3E0922015000CE1E3E2E5E3E6E4D4007CC741D2E1E4E5E0E2E3E4E3E6E3E4E4E4E4D064D0E0E4E6E3E4E5E5E6E2E3E4E5E6E5E4E5E1E5E4E5DEE7E7E5E4E2E4E5E5E5E3E5E8E6E5E5E6E6E6E7E6E4E1E2E4E5E5E4E4E49DE4E3E5E5E5E5E5E5E6E5E5E6E5E5E6E6DBE3E3E5E5E5E7E5E5E4E6E8E8E7E4E3E5E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000790000000001000001E4E5E5E5E8E8E6E7E8E7E7E7001780E1E2E1AF100EE32DDFE1E3E2E2C79B68001541806AE06AE1002600150000055FA6E2E1DE33200A242DD62F99DFE3E3E0A143005D00002D80DFE1BE2D0C050A001D003AE2D4E1DE9F965D929D1B0043280054E4E2E2E4E23300000E00E0E2E3A49D0000170A89E4E4E13A5B28005285D6E3A1E2E6E0E4E1E1E1E2330A221983E3B5E6E5E4E1E1B1CD2D28A8E2E35FDFD400E38BE4E5E5E6E6E4E2BEE55BE6E4E0E2E4E4E3E3E2E3E2E4E6E5E5E4E2E3E5E7E5E5E5E2E3E6E7E7E5E4E5E5E1E6E5E7E3E4E4E3E6E5E3E3E3E5E6E5E4E2E4E3E5E5E4E6E5E4E6E4E5E5E5E5E6E6E5E6E5E4E5E6E5E6E5E5E5E5E5E6E4E3E5E1E7E7E7E6E7E7E6E6E8E7E7E7000726E0E3E4E371E2E31D0000E0E1E0E1E17A1B000141503183DD006F0E541200430EA64CDEE1CB01200012000E2FC7E1E3E4DD6F00000003B52DAFE3E10A001200780000AAE08EE273E1E02D6F1715002B3126C2E2E4E3E3E1752000010054E0E2DD3E22000000B5E4E6DF6A6D9403260094E3E5E5CBE2E3E3E5E3E23A002F0064E2E4E3E4E4E10000330094E59BE2E4E0362B0000E0E5E5E4E3E5E3E3E536E2E5CBE5E3E6E45BE2E4E5E7E7E2E3E7E4E4E6E5E7E6E6E3E3E4E6E5E7E5E6E5E3E6E8E4E4E3E6E4E6E5E5E4E3E3E5E3E2E2BCE1E6E6E5E6E5E5E6E5E6E6E7E8E5E6E3E4E3E3E6E5E7E7E6E6E7E6E5E7E6E5E785000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000007B0000000001000001E6E7E7E7E7E7E8E7E8E8E8E80038990000E3B59DE36607E30115E0A4E5E2A417001B1D22D0D2E4E46F000001000C00196FE4E683942F10071B19003347E29BE2570E00003E1268B7E3E2C0E2800000240083A8BAC2E389C0332200B5031B0000CBE4E4E4E4ACA1260000283EA6E4E3E34500100A1DE2E1D0B7850045286DE1E3E1DDE3D0E5E2E3E300006800267CE2E5E8E6E1E40000850068E4E2E4DBE2680AE200E3E4E5E2E6E5E412E5A6E5E1E1E5E3E5E3E40EE3E5E7E5E3D8E4E3E4E5E5E8E6E8E2E2E5E4E5E6E5E6E4E6E6E5E6E6E5E6E6E4E5E5E2E4E4E5E3E5E5E1E5E6E6E6E6E5E5E6E7E1E3E5E4E7E7E5E6E5E5E6E5E6E6E6E5E3E5E7E6E5D2E4E4E7E8E8E8E8CBE7E8E8E8E8E700001B000000E4E56DB10012000CA6AA47DCB39B0A0000153A83B3E7520A0E003A0E102B3A75E4E3E0430000BE0C0045E1E2DEC0AC0E000300384EE1E5DBBE83150003001DAC5DB7E2E4A4BA9090380000260000E3E0E2E2E13A00000024000099D6A64C03200019008E47E1E2872B0000005D43E1D0E3E4E6E4E6E48000001219D8E3E4E3E4DF5400002B0000E1E4E4E3E4E000002654E3E0E4E5E4E4E5E7E4E7E6E3E6E4E4E2E7E5D0E6DDE4E2E4E6E6E5E7E7E6E0E4E6E3E7E4E6E4E5E4E3E7E6E6D0E4E6E4E4E5E6E2E4E6E5E7E6E4B5E4E7E4E5E5E5E8E6E6E6E4E6E6E7E6E7E7E7E5E6E7E8E5E5E5E6E6E5E6E7E4E3E4DD000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000007D0000000001000001E4E5E6E5E7E4E7E7E7E7E7E8E7C900010000E5E5E3E40007001D906DE0E0A8B70020000A0024AFE38726001D000000000399E2E3C5E10305E483125F07E3E4A69B264C00000015DED8DDE0711B0C0064000199E0DEE3E296E1DD7133DE005F00D8E0E3E4D6E100008019000000D0E100200000000043B3A6E380C200006D030089E3DDE6E5E2E3E3E1DBD0E0E4E5E5E1E7E5E5E2BE780E0005E3E0E0E2E2E3000A00E4E2E1E4D2E3E6E3E8E7E5E1E3E4E4E4E3E3E4E2E3E1E2E5E6E5E5E5E6E5E6E5E0E3E6E6E7E7E3E3E1E3E4E4E5E7E4E6E4E5E5E4E4E6E5E4E5E0E2E4E1E4E5E6E7E5E5E4E2E3E5E6E5E5E6E4E6E7E5E6E5E7E7E6E7E7E4E7E6E7E6E5E6E5E7E8E7E7E8E7E7E7EAEAE4E9E600000000C9E4E4E2E23600003143E1D8E0E2D8000A1DAF2489A1E1E32D2F0380071905389685E3ACE083380500010A92E1AFA180BE2D000000001DE38BE3E1A496621900CDA671E2E2E4E3E8A4381D0059E9DFE0A8E3E5E0DD0000000000416A92E3000012B7000064D6DFE0D46A1B28150010E154E2E4E6E5E57E28688B41E4E3E6E5E3E6E5E371851B24DEE5E2E3E5E39D2DBAC2BCE6E4E4E7E5E4E5E7E7DDE4E6E3E0E3E4E6E7E4E5D4E6E5E3E4E2E3E6E5E6E5E7E3E5E5E5E5E7E7E5E6E5E5E3E3E5E6E6E5E4E4E6E5E6E5E5E4E5E4E6E5E6E6E5E5E7E5E5E5E5E5E6E6E7E6E7E6E6E8E8E8E8E7E7E7E5E6E6E7E7E5E7E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000007F0000000001000001E4E5E5E6E6E4E7E6E9E9E9E8DC00000000B3E4E3E3E2A8260E24006283E0E347895033E2662D5FE0E1C21B050015012D5B66B5E3E2A883192819010778B3E3E1E0DF6400669B002431E0E2A19FD0924E000000195DE3E0B3E254C53800106DE2D0E3D8E3E2D0830A000012C53C00E1E20007000000432DE4E2E3592896171957DEE0E2E5E5E2D4240000001500AFE3E3E4E4E6E5E6E0685B3CE1E3E4E2E3D66428B7C2E3E1E2E4E4E4E5E7E6E3E4E2E4E2E5E4E2E4E5E0E4E3E4E4E4E4E4E5E4E8E7E4E6E4E4E5E6E7E6E3E5E5E4E4E2E4E3E3E1E5E4E5E6E6E5E0E5E3E7E6E6E6E6E6E4E4E5E4E4E3E4E4E6DEE2E5E4E6E7E7E7E5E5E4E4E5E5E5E6E3E4E4E1E5E6E5E6E8E7E6E8E7E7E8E8E900000000E3E4E4E2E1E3A4430E2B2F47E1E1A82819D0D6E35F4141E3E147875D45192D006689D4E1E199070001000000E0E3E1E3E4470000E3000031C0E1E4E2B50000005B000015A4DFE1D69FE22003B7AAE3BEE2E1E2E59DBA940E280003BAC510AF334E0C00000E0EB3E3BA9B450E260000A4E3E3E3E5E3DC9D9201240CA6492BE6E4E01D7C7805002643E1E2E5E5E5E0CDA8E2E3E7E6E4E6E47854E4E5E4E5E4E4E5E5E5E5E6E6E6E6E6E6E5E6E5E5E5E5E6E5E4E7E5E5E6E5E5E5E2E1E6E8E2E7E4E6E4E4E4E1E6E5E4E3E3E3E1E3E3E3E5E5E5E5E1E5E6E5E5E4E6E5E5E5E0E1E4E4E4E4E5E5E6E4E7E5E8E7E6E5E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000810000000001000001E6E7E7E5E7E7E8E8E6E7E5E7E5DB000007E3B1BCE1E1DC752D0000011D94E0E39200265BC9E0E27166E29F9996170059003399E0E5B5DC19000100000031E0AFE4E4DD100000007E0E2DCDE4E1D86F00008E0000170C6FE19D78803A0A7E87E0DEEBE0DCE1E2E2E39F12000ED2C7E1E2BE6D000C000C00D2E2DD1BA6BC1B00000000E4D2E4E5E3D02817B1E40026C5ACE4E445BE7A00D0D200C5E1E4E6E4E1E4B3E3D8E6E5E3E5E59B0CE2E6E5E6E3E5E5E5E5E6E4E5E1E3E6E6E5E5E3E4E3E5E7E7E8E6E6E6E7E6E6E6E5E6E5E5E6E5E6E5E4E7E5E3E7E5E5E5E4E1E4E5E5E6E5E3E5E5E4E4E5E3E3E5E5E7E8E4E6E6E7E6E7E7E7E6E8E5E5E3E6E4E6E5E6E6E5E8E7E5E9E6E7E9E8E8E8EAE6E6E7E5E5E417BA90E0E1E03C00A82000C58BB7E0B5246A6DE2E5A666E0E1E4785B00310017AA2FBEE4DBCB26009200000E00A8E466E480476A2B5247E0E3E4E27C9F73002F285747E3E1C0C7E592B10A45B5204CE8DE80E3E4E5DB000000000EC7C7E1DEC7052F000000A8E3E1AAE1E26F5D0000E100E2E5E1E0B7002801262443DCE2E2E55D9B5422E31B00AAE3E3E5E4E2E08585A4E5E4E6E5E4E4D2E1E3E6E5E7E6E3E4E6E6E6E6E4E5E6E4E6E5E5E6E6E6E6E5E6E4E4E5E7E6E5E4E5E3E5E6E5E6E6E6E6E6E6E4E5E5E6E5E6E5E4E5E4E5E5E5E5E7E6E2E3E3E4E4E5E4E7E6E3E6E4E4E5E5E7E6E5E6E3E4E6E6E7E4E694000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000830000000001000001E6E7E7E8E7E7E8E0E9EAE9E8E6E7E8E9E3CD0C99E1E3E3E000000100001B9092E3E33E0E000062E0C5E5E3E08E7A05000010002450E1E2E27E311D0000649D83C5D8E3E32D1B05E3E2A457E1E5D2E2993C7E157C36E3E2E4EAEBE8A83126E36FC7D4DD5FE0E3E4E000008B00E2DBE0E1DE7C543126000066C2E3E2E25B4C000000C50AD0E6E3E2E0262B0033504757E4E0E6E3B74900000020E2E4E4E4E4E3CDD0C7E3E7E6E5E6E4E2E2E199E3E5E5E4E5E6E6E5E6E5E6E4E5E4E5E5E3E4E6E3E4E5E6E5E5E7E7E7E5E3E6E4E8E7E9E8E5E4E2E5E6E7E7E3E5E5E7E2E5E5E5E4E4E5E4E5E6E6E7E6E7E5E6E6E6E6E5E4E5E4E6E7E7E6E5E6E7E7E6E6E7ACE6E4E5E4DCE6E6E7E6E7E8E8E8E9E8E6E8E6E51B89E32DE2E1E3E2B1013C2219649BE2D8E0170E000390E2BAE4E3E0A84100006D0A0785B3E3E4A4963100002FC7E1E1E6C7E2D66D4C267EE3E1E2E3E4E5E4DE4E6A7A36C2E1E5EBEBEBE2178EDF90DE00008071E3E5E531000E000073E5E3E5E2E23E1931287AE2E2E3E400310000121D0C5FE4E1E05F784778D000B1E4E2E2E583E1E4543A0A0C85E6E4E5E4E4E171AFD8E5E6E3E5BEE431E5E4E6E6E5E4E7E5E6E7E5E4E4E5E8E6E6E6E2E4E5E6E6E6E7E5E7E7E8E7E6E6E6E6E5E6E8E6E6E4E5E6E8E6E4E7E6E3E5E5E5E5E6E4E7E7E5E5E8E6E6E5E5E6E5E5E5E6E6E6E6E5E6E8E6E5E6E5E6E7E7E8E7C0E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000850000000001000001E6E6E5E7E7E7E6E6E8E8E8E7E4E3E5E2E33C49E2BCE1E2A6E00A00333CD8E0D2E3E0B57100A4200AB5E2DBE2E2CD4E5B0300005771E1BEE3D6C5070C01153190B5E2E2E3457C24102F1BE2C9E4E4E4E2B77C4E28209D66E2E4EBE9EBE4E0C019009B414543E1E5E59F5B100000288BE5E5E4CB0000000071E4E5E2E3B7D615003892A6E2E4E3E1850C8B0712005FE3E2E4E4DF9FE1C7E141A8CBE4E7E1E4E3E3E4E5E3E5E3E3E4E2E4DEC7E5E6E4E4E4E3E485E4E3E4E4E7E6E6E7E5E5E4E6E5E5E2E6E8E4E5E4E6E6E4E5E6E7E5E6E5E6E6E6E7E5E4E6E5E5E5E3E6E6E5E6E5E4E5E5E5E5E5E5E5E2E3E4E4E8E5E7E5E3E6E5E6E7E5E6E5E7E6E6E7E4E5E5E5E5E6E6E6E0E5E5E0E7E7E6E8E2E4E6E6E4B34CE2E0E4E4E1DF0E220000059B54B7E0E0949903001B129BE2E2E2E2E1B524831B220A2D5DE3E371262B032D8EE0E1E3E1D8DD663E0000008080E2E5DCCB226F9D4C00E078E1E0E9EBE33C6400AF00E1E047D075E3DF006D00470000E0C06AE366000A100000E3ACE3E2E3E252031724A883E2E2E59F9B380A57004EE5E5E6E5E3E2E47C2FA1E2E3E1E5E5E5E7E580E3E2E5E6E5E7E3E6E2E3E5E6E6E4E4E3E5E4E4E3E4E6E6E2E2E6E6E4E5E6E7E6E7E6E6E5E4E5E1E6E5E6E6E7E6E5E6E2E6E4E5E6E6E6E5E6E5E5E6E7E6E6E6E5E4E4E6E8E6E6E6E5E1E6E4E6E5E5E5E5E2E6C9E6E6E6E7E6E5E6E6E3E5E4E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000870000000001000001E4E6E6E6E7E7E7E7E7E6E7E7E7E7E6E4E47C00544EE1E2E2E3890012000015CB80D6E08B31104E0000384EE4E4E0E1E2495F19001BD4C9E3E2E0640087B764D6D6E5E4E2E3E136005F2B0078ACE2E2C0BEA1050000478BDDE2EBEBE2C26A1B12E133903AA1E0E2DBD0E71D0000000000E1E0E3430026003CE0CBE2E3E1070C0C1092E2E2DCE2E0AA9FE000000C12C7E1E4E3E3E3E33336C2E5E4E5E3E5E6E5E589E3E0E6E5E5E4E2E5E3E4E4E6E4E4E4E5E7E6E6E6E4E7E6E4E6E6E6E3E4E4E4E7E5E5E6E5E4E5E7E3E4E4E6E8E6E5E6E5E6E4E5E5E1E5E4E5E5E4E5E4E4E4E4E4E4E3E6E4E3E4E2E6E5E6E6E6E5E5E6E4E4E4E6E6E6E5E5E7E6E5E6E4E4E4E2E4E6E7E6E7E7E3E7E7E7E8E7E7E6E3E5E200007A1BB1E3E3E34E52220C4C2059BE96E2E2BEBC593C005D2066E6E5E266E0470C5F1BB3E5D2E5E37C509B2D73C9E3D4E4E4C0D6D63C000087E28BE4E4E0E39F0000802B89AF2DE0EAE645DEE5E1E4E9B71010E1E2E2EBC79900E40000E0E2E6E08B002200171DE5E4E4BC0000E20033DEE4E1E4E6E3E2E317473643E1D0E4E4E4E4E571B30AE6E5E5E7E5E4E4E4E164E4E5E4E3E3E0E4E4E5E5E5E6E4E3E2E6E6E6E6E7E7E7E3E3E4E4E5E6E5E5E8E5E6E7E7E6E5E5E6E6E7E6E7E6E6E5E6E5E7E7E6E6E4E6E5E6E6E4E5E4E3E5E6E5E0E6E5E4E5E4E8E7E6E7E6E5E7E6E6E7E7E7E6E696E7E8E7E7E7E5E6E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000890000000001000001E2E7E7E4E8E8E6E8E8E7E7E7E7E6E8E6E1BE4C542F50DEE3B5D8640024E171419DC2E3E092DB3673282F3C9FE0E4E371005D99360057BEE0E4E278E4D81959AFC7E2E4E5E2E0CB6F00006AAFE2D2E3E2E18E8E034E0000599689E7E45D73E5E5E4E4789D00336AE2EAD0EB000000006AE2E15D1B2022E02036E3E4E6E21B00000049E0E1E3E2E1E5E58B8B2415AFE4E2E6E4E6E6E43C000ED4E3E4E6E4E4E3E3E3E2E3E3E6E5E5E4E3E5E7E6E9E7E6E6E4E5E4E4E6E6E6E894E7E8E7E5AAE5E5E7E6E7E8E6E4E5E5E6E5E5E6E6E6E2E7E7E6E6E6E6E7DDE5E3E6E6E7E6E4E4E4E6E7E7E7E7E7E7E6E6E6E7E7E8E6E5E6E5E6E6E6E6E6E6E4E6E5E7E8E6E6E6E5E5E8E8E7E7E7E7E7E9E9E7E8E7E6E6E7E1E1014112ACE1E3E2E05996D847572073E352E0E3DEA67A542F1B4EE3E6E5E4331D5422000515DFE5E1CBE3960A411DE375E3E3E5E2E1365B6FAF12E1B3E1E6C7E378100124000078DBAFD4DE9283E4E4BE5B1D0017ACE4E9EBE98700001BD6E6E5E149009680199268E6E38E714122711D31E5E5E4E6E6E4E4A11B24E5E7E4E6E3E6E6E252C512E4E6E7E6E3E4E3E4E79FE3E7E7E3E4E4E2E4E5E4E7E4E5E2E4E5E4E5E6E6E8E7E6E4E7E6DFE6E6E5E7E6E6E9E8E6E6E6E7E7E8E7E7E6E6E6E6E7E7E5E6E6E4E6E5E5E7E5E6E4E6E4E6E5E6E5E4E5E4E4E6E6E5E8E7E6E4E5E7E7E7E7E7E8E5E7E5E6E5E7E7E5E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000008B0000000001000001E1E5E6E5E7E3E6E6E8E8E7E8E5E5E6E6E3E20E17832675E2E4E147E3E16A280054E1E180E5E5E05D3A500E4178BAE4E57C07892B0A590000E6E1E1544C3C5283498BE3AFE6E3DCAA0112E05B49E0B5E1E1E43C000000000028E396DDE2E2E4E4E65990000000E3E5E4EBEB80002FDEE2E5E9E4E0496D0E1B2DE1E3E3E3E2007A2D3815C7E6E3E5E5E6E750010000E3E2E3E4E5E4E2E0E3ACE5E4E6E6E5E0E2E3E3E319E4E6E4E3E5E3E5E5E5E5E4E6E6E5E4E3E2E6E5E5E7E6E4E6E6E7E5E6E4E5E5E6E5E6E6E1E7E8E8E7E7E9E6E7E9E5E5E6E5E6E6E6E5E4E5E6E5E7E5E2E5E5E5E6E6E7E7E4E5E5E6E7E7E6E0E5E5E6E7E7E7E7E6E7E8E7E7E7E7E7E7E6E7E4E7E7E4E7E7E6E7E8E8E8E8E8E9E8EAE2DB280A1243DC8EE2E2E2E3E2E14C3C01B3A4E3E5D6E37831DF6F1B28E1E2E2E3504C1531E20015E1E4E3DF8745A82F45338EDEDFE4E383D2492F50A4A1BAE4E5E894E00000000C3175BAE2E4E4E5E5E4240000004949E2E4E4E5D207A1D6E5E0E4DDE4C92222000EE2E5E5E4E58B5F005210E4E4E5E4E4E7AA9F19000003E1E5E5E5E6D0E3E2E3E4CDE4E4E5E5E5E566E215E6E5E4E4E5E6E6E6E5E7E7E7E6E7E7E7E6E6E7E5E6E6E4E3E7E8E6E5E5E7E7E7E7E6E6E5E7E6E6E5E6E6E5E5E6E8E8E7E7E5E7E5E6E5E6E6E5E4DDE4E4E4E6E5E6E6E5E6E6E5E6E5E7E7E6E6E7E6E6E5E6E6E7E6E6E7E7E7E5E7E6E64C000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000008D0000000001000001E3E6E6E5E8E9E5E8E7E7E6E7E8E8E9E8E5E5C70A1DE1E2E4E3E55BE4E1DE80124322E0ACE2E2AA8B9B2B3C1920DFE4E4E2C0BC000C0033001BE5E1E5E2E173BE244E3378DEE5E4E3BE17243300E0AFE1E3E5E0D8BE712020542F41E7E2DCE3E3E46D6A00640A85E4E4E619000000E1E5E3E4E5E3E00C78E364C2E3E5E471014E00E5E3E5E4E4E5E4E4360700E3001DE5E6E4E8E1ACC7E08EE6E7E4E4E5E4E4641DE0B3E5E4E5E5E4E4E5E6E6E7E6E6E7E6E4E5E6E6E6E5E6E4E3E5E6E6E6E4E5E6E6E7E6E7E0E5E5E6E5E6E7E6E3E5E6E5E5E5E4E8E5E6E4E5E6E6E6E5E3E4E4E3E5E5E6E6E5E5E5E6E6E5E6E6E4E5E5E7E7E7E7E4E5E6E6E8E7E8E7E2E6CBE7E4E5E6E6E7E4C7E7E9E9E9E8E8E9E8E9E6E415940000A8DFE2E26D78E2E27E0131289FDDA6E5E4E3000000000136AAE2DEE4E34E07389BAA45E3E3DDE1DEE1B312002F7EBEE4E5E4544C26001B43DD64E5E4E3851DAA5F547CE031A6C0E3E4E3E6E37E173A1728E0E6E40000000028E3E4E7E2E2E003E5E743A6E3E3E45D451D00E3E4E4E5E5E4E4E5E3C205000083E4E6E6E5E6E1D8E1DCE2E6E5E6E6E4E6DD3CE5E5E5E3E5E4E2E6E4E6E5E3E4E3E4E6E7E5E6E7E6E7E6E6E7E9E8E2E3E4E5E6E7E6E8E5E6E6E6E7E6E6E6E6E4E6E6E7E7E6E6E8E7E5E7E7E6E5E7E4E3E5E5E7E6E6E8E5E3E4E5E8E8E8E9E7E6E7E5E6E6E4E6E4E6E6E8D8E7E6E6E6E5E5E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000008F0000000001000001E5E7E7E6E6E3E6E7E8E8E8E3B5E4E2E6E4E3249FB70019DF6FE2E5BAE2E2DD9B92001D3C3650E2E10C19004E0000529FE5E0E2CB785D05CDE0E1E4E4CD9BC9000000310078E4E5E1CBBEBA0000033EAFE3E3E6E49643734E3AE3E4E4E0E6E6E0E7E4D40700006AE3E6E60019E3006DD4E5E6E3E0157A7CE200B3E1E3E2C9222B0185E5E5E6E4E3E5E6E7E631004CE3E5E8E5E8E6E3E3E3E1E6E7ACE8E6E4E5E5AAE6E5E6E6E5E6E5E5E4E6E5E5E5E5E6E6E6E5E6E8E7E7E7E8E7E6E7E5E5E5E5E7E7E6E7E4E3E4E5E7E7E7E6E6E7E6E7E6E7E6E5E6E7E4E6E5E7E5E6E3E4E5E6E6E5E6E6E6E5E7E7E7E6E5E7E6E5E7E6E2E5E6E7E4E4E6E8E5E6E6E7E8E7E7E8E5E6E7E6E7E7E8E7E8E8E8E8E9E8E8E6E4E3E200001D26E18BE2E5E3DBE4E1B700E300945FDEE0D2AA57000000001547C2DCE0E52D0C1BAFAFE185E5E1CBD69D7A246F49E1E2E4E3E0E217000031906D89E3DDE3E3D2E27131CDA1C9E3E3E4E3D4E20707000E00E1E6E6000000009DE2E4E7DCE39F4538284CE6E6E6E5C57C94E4DEE4E4E7E6E6E5E5E1E3DDE7E6E7E7E6E4E6E6E4E4E36AE4E3E4E4E4E4E4E4E4E5E6E8E6E5E4E6E7E6E7E6E5E4E5E5E7E6E6E5E6E2E4AFE6E6E7E6E7E3E6E7E7E7E7E8E4E6ACE5E7E5E6E6E6E6E6E6E6E5E7E7E7E5E6E6E6E8E7E6E4E4E4E3E6E6E6E4E5E3E4E5E6E6E7E5E7E6E6E8E6E5E5E5E5E4E6E5E5E6E6E7E6E4E5E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000910000000001000001E5E6E6E6E7E8E7E7E7E5E6E6E5E4E4E4E2E3E07A430EC7E1E1E2E4E3E0B5E1C9002854386A87E1DBE349000000000028E0E2E4E0101B9B6D2FAAE3E2DCE0D62B47640AC2E3D4E2DFE7E57500000AC983E3E4E4DEE4E4E0004C9DB380E4E4E6E5DE380C00000007E2E4E6E10000107AE3E1E5DFE0E3E5AF22DBE4E5E59BE11522E4E6E7E6E6E6E5E5E5E6B7E1E4E4E6E6E4E6E5E5E2E3B17AE3E5E5E1E4E4E3E2E5E5E6E7E5E6E5E5E5E5E5E6E4E4E5E6E4E5E5E4E5E8E5E6E4E7E5E3E5C2E4E6E6E5E4E6E3E4E4E6E7E6E7E7E3E6E6E4E5E4E5E5E4E6E2E4E5E5E6E6E6E6E7E7E6E6E5E4E6E6E4E6E7E5E7E5E6CBE5E6E8E6E6B1E5E7E5E7E6E5E7E6E7E6E5E6E5E6E5E7E7E7E7E6E9E8E8E9E5E6E4E4E3E3E3E23C2087E3DEE0E2E2E2E3E4DF052D053C33A8E3E57E7E00001700000A45E0E2575F012D330CE1E5E4E3E0E1943E99242DBCE3E4E3E3D8E2A8E375B1DCDFE1E5E4E3E1E3D26492E1E0DEE2DEE4E2E31901360E5B57E6E5E5527E1B0773E4E5E5E4E1E3E51994E5E6E4E5E59236E5E5E5E6E7E7E5E5E4E4D290684CE6E6E6E6E6E5E4E4E3E5E2E3E6E5E7E5E5E6E6E6E3E8E8E7E6E8E6E5E6E5E7E6E7E9E6E5E6E5E4E5E7E7E6E6E5E5E6E5E4E6E6E7E5E4E5E3E5E6E6E6E7E7E6E6E2E7E6E5E5E7E6E6E5E5E4E4E4E4E6E5E5E6E5E5E6E6E5E4E4E6E6E5E6E6E5E5E6E7E5E5E5E5EAE6E7E8E7E7E9E7E5E5E3E4000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000930000000001000001E4E6E6E6E6E6E6E7E6E7E7E7E3E3E3E2E2E0E2E0800000808E80E0E1DCE1E2E0AC477A54263C87E39FC5470000001B2B4EAAE3E1DFE2474E19DDE2E4E0E2E14C153E3E0000648BE3E3DCE3DB7580DEE2DEE4E4E4E6E5E44719100794BAD2DBE4E4E0D047074719E3E3E5E2E02B244322BCE3E4E2E3E0000012C5E3E4E4E443DBD0E587CBE7E6E5E4E6E5DBB75750C2E5E6E6E7E6E4E3E4E2E5E5E3E4E2E3E2E3E2E4E2E2E5E5E6E6E5E4E3E2E3E3E5E6E5E5E3C9E5E6E5E6E7E7E7E6E6E5E5E6E6E5E6E7E4E4E5E4E4E2E2E3E5E3E5E6E2E5E4E3E5E6E6E8E4E4E5E3E4E4E4E4E6E5E6E6E5E5E5E5E7E8E5E8E4E3E4E4E5E4E2E4E6E4E6E7A6E5E696E5E6E7E7E7E7E7E8E7E7E8E7E8E9E7E8E7E6E2E6E2E2E1DC20A8005BE0C9E3E1E39FE4E3E352D46D2641C59DB5E36A173C125B4C5DE0E4E5BEE1BE1041158EC0D8E3E0E19B2B0E000000ACE2E4E2BCDBAC83D4E2E3E3BEE3E4E1437AE4E400E0E1E4E3E4E5E5E2BC00415BDFE2E3E4E10024CBE5E4E4E4E2E4E40500006FE4E5E2E2E4E3E5E468E5E5C7E6E6E6E5C0B5E0E5E5E6E5E5E5E5E4E5E5E3E5E6E6E7E4E4E4E4E6E5E6E4E5E5E4E7E6E6E6E5E8E6E8E8E5E6E5E3E5E5E5E6E7E4E4E5E6E5E5E6E7E7E6E7E6E3E5E6E4E5E5E6E3E3E6E5E5E5E4E4E5E5E6E5E3E5E6E5E3E4E4E4E6E7E7E9E6E6E5E6E6E5E6E6E7E6E3E7E7E7E5E5BEE8E0E7E3E7E7E8E8E6E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000950000000001000001E5E7E7E2E7E8E4E7E8E8E7E8E7E7E8E7E3E2E3E26DDE246FE2DEE4E4AC2FE3E3E2E2C0C05F2DC971BEBEE4B58E4E2F991599E5E7E2E5804500057AB3E1E3E3E29BB1071B1B1568BAE6E3E3E2E12F33B5D0D2E4E5E3E02F10523C05E4E3E09DDEE8E5453619005BE4E2E5E4E1000019DEE4E3E5E5E4B500E500BCE5E6E4E4E5E4E3451049E4E4E6E4E4E5E6E6C9E5E5E6E6E6E6E7E6E7E7E6E3E6E6E5E6E6E5E5E4E5E5E5E5E4E6E7E7E6E5E6E6E5E5E5E6E7E6E6E5E6E5E5E6E6E6E6E3E4E5E5E5E6E6E6E4E5E5E5E6E5E5E5E7E2E7E8E6E5E8E6E6E7E6CDE6E7E5E6E2E4E3E3E7E6E6E7E3E4E4E4E6E6E0E7E6E7E7E8E7E5E6E5E6E4E8E77CE7E6E6E7E6E7E5E5E7E7E7E7E6E7E6E7E7E8E7E6E4E6E5E2DBE2E2E58B3301E0E0E5DC311290E3E6E5E3E38EB3999FDDE3E4E3434C473310A1E1E1E6D6E2B5009B4789DCE5E4E0E2C53A00000122CBE3E0E3E2BCA80C50B1B1D8E5E5E3D4DF57361DE3E3E496E3E5BC47E4010000E4E6E6E6DC00000000A4E4E4E5E4E4100000E1E5E5E5E5E5E4E33C0090E6E3E6E3E5E6E6E5C0E4E6E6E8E8E6E8E6E7E6E7E4E5E4E5E4E4E4E4B7E5E6E7E5E6E7E7E6E6E6E3E5E5E7E6E5E3E4E5E6E6E7E5E9E6E6E8E5E6E4E7E5E6E6E5E4E6E4E5E5E4E5E4E6E6E8E7E4E6E6E5E6E5E6E6E6E5E6E7E1E5E4E6E7E5E5E6E5E4E7E6E7E7E8E7E6E6E6E7E4CD6FE4E8C9E8E7E5E6E8E7E7E5E7E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000970000000001000001E4E6E6E6E6E6E7E6E8E9EAE8E3E6E6E7E3C7E2E3E3D8BE1703BAE1E238174EDEE3E5E4E3E04EE3E2E4E4E3E55BAA5F3E014968B7E2E1BA5F7C8022DC92E3E3E3E5E03C68000022AFE4E3E1E4E38E83B352E1D0E2E6E3E2C97CE2E4E4E27E8796E0E387E0003C0073E4E5E5E400004700E4E4E4E4E26803000052E4E3E5E5E5E4003C0003E6E8E9E7E3E5E4E2C752E4E5E6E5E5E4E5E5E5E4E6E5E6E7E3E5E4E4E6E5E3E4E3E4E5E6E7E7E5E6E6E5E5E4E6E6E6E5E6E7E5E5E6E4E4E4E2E6E5E5E6E5E4E4E4E5E5E5E4E6E5E6E4E0E4E4E7E6E6E7E5E4E3E5E5E4E6E4E4E4E3E6E6E3E6E5E7E6E6E6E5E4E2E4E6E5E7E6E4E4E4E6E5E3E6E7E8E6E7E7E6E550E3E7E8E2E8E7E8E7E8E1E7E8E6E7E6E8E4E1E0E2E1E2E178195094E3E5523AE1CBE0E3E2DF417343DCE2E3E1E3E273995D224EBCE0E4E5E6D0385B286AC794E0E2E290DCE13A0C78E1E4E5E5E3E462265D3AD6E2E1E3E4DF22A4E6E5E6E36D9FDFE5E6E4E2000000E3E6CDE4E4000C0524E6E3E4E6E4E4752B00DCE4E7E4E4E5E35207053AE4E7E5E6E8E6E7E6E4E5E5E6E4E5E6E5E5E5E7E7E6E5E5E5E6E5E3E5E6E5E4E7E5E4E7E6E9E8E8E8E6E3E5E6E7E7E7E5E7E6E6E6E5E4E4E4E5E5E6E6E5E3E5E5E5E5E6E7E7E5E4E5E5E6E6E5E6E8E6E7E4E7E5E6E8E7E5E6E4E1E1E3E7E8E7E6E6E5E6E6E6E2E6E6E8E7E6E7E5E6E7E7E7E8E6E8E7E8E8E8E6E5E7E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000990000000001000001E3E6E6E7E7E7E7E7E9E7E9E9E5E7E5E7E4E4E4E5E2BCE02200DCE3E4C0BEBA8ED6E3E3E1D89D73BAE1E4E0E3E5E1B73859526AA4ACE4E5E02D6A62B7DCE196E2E4A49BE1662F3EDCD8E5E4E1E468A8E0E0D85F90E3E4E4E092DFE2E3E1DF505BE5E5E590000000BEE5E6E5E3A4150024E3E5E6E6E6E443129BE4E6E5E6E5E4E5E4755B5422E4E6E7E6E5E6E5E4E4E4E4E7E7E8E7E7E6E6E5E4E4E6E6E4E6E5E4E2E3E5E4E6E6E6E8E6E5E4E5E6E5E6E6E4E4E3E1E5E4E4E4E8E5E6E6E6E4E3E4E8E7E5E5E4E6E6E7E3E5E4E5E6E5E6E6E6E7DBE4E6E7E6E7E6E1E5E5DCE0E3E4E5E4E5E6E5E5E6E6E7E6E6E4E5E6E6E6E4AAE5E3E6E5E5E5E6E6E5E5E7E5E4E6E7E7E8E7E7E6E6E6E8E7E7E7E5E6E6E8E3E4E3E2E600A1E10AE0E6E4B5D68389E4B5E5E4A1E0C75BE1E5E2E3DCE196963820192B50DFE5E3E06F2FC5E2DCE5E4E2E4DFE2310700DDE2E3E6BEE5E4ACBAE1D492C7E4D2E3E5DFE4E2E4DCE2C5C9E2E5E5E6E199E1E7E7E5E5E5E43600C2E4E5E5E4E2E31500E4E7E5E6E5E5E5E5E38EDD261DE5E7E7E6E4E5E6E4E3E4E5E8E7E7E7E8E8E6A8E5E6E6E7E5E3E6E2E8E7E8E4E3E6E6E7E7E5E6E6E7E3E7E7E2E5E5E3E9E6E7E6E5E4E5E5E7E7E8E7E7E6E7E7E5E5E6E5E8E7E8E6C9E6E6E6E7E6E6E6E8E8E8E8E6E6E6E6E7E5E6E7E3E4E5E5E7E8E5E4E7E7E6E6E8E7E7E7E5E6E7E792E6E6DDE8E7E9E7E6E4E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000009B0000000001000001E8E7E7E7E6E7E6E7E8E8E8B5E8E5E5E8E4E4E4E3E3E152C7DBA8E5E3C08EAAA6BEE4E4E4E138A6316DDBE3E3DFE7CB33072F33A1E5E6E6E79985A1E03E73E3E2E6E4E4E51B380103D6E1E5E6E5E4BEAFC9DCB1D6D0E3E4D2E5E5E5E5E4E5C5D2E2E4E5E3E522432BC7E5E4E5E5E04547E6E5E6E6E6D60000E6E7E7E7E6E6E5E5E633280028DCE5E5E7E7E6E6E5E7E3E6E7E6E8E7E5E6E6E6E6E5E4E5E5E4E4E4E6E7E6E6C5E6E6E6E8E7E7E7E7E5E7E6E5E6A4E6E5E6E6E6E7E6E4E5E7E8E7E7E5E5E5E6E7E8E7E7E4E2E4E5E6E5E6E5E6E7E7E6E8E7E5E7E6E7E7E5E5E5E3E3E6E4E3E6E6E6E7E6E7E7E6E6E9E8E8E7E7E7E7E4E9E8E7E7E7E7E7E6E6E5E7E7E7E6E6E7E7E6E6E6E8E8E8E8EAE8EAE8E5E6E5E3E4E5E4E4E0E3E1E5E28E8B0078E3E1E0E5AABE9DB3E3BEE4E2E0997ABE0543C5E2E5E5E5D83E59502407D8E1E4E4E4DEA4000510E0E5E4E5E4E5E0B7549F6FE5E1E6E5E3E4E4E4E5E3E4C987E3E3E6E59B1B413EBEE6E5E8E5E3E0E4E6E7E8E6E5E30050C7E5E6E8E7E6E6E4E7E65DE50CE3E5E6E4E6E6E7E7E7E7E8E7E6E6E7E6E5E5E6E6E7E5E5E4E5E5E6E5E5E6E5E8E1E6E8E8E7E9C0E7E5E7E7E6E6E5E6E5E7E7E7E6E5E6E7E5E5E5E7E6E6E5E7E8E6E7E7E4E7E7E7E7E5E5E6E7E5E6E7E6E5E6E6E6E7E6E8E4E5E5E5E7E6E5E6E7E7E8E7E6E6E7E6E9E8E8E8E8E8E5A6E6E7E7E6E8E7E8E8E6E4E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000009D0000000001000001E4E5E2E5E7E8E7E8E6E6E6E7E6E5E6E4E5E4E4E0E5E2E5E3DFE2E2E2C7D099544C7AE3DFE3D6AF454CC9E4E4E6E0D085506A925FE2E2E4E3E3471DE062ACDBE3E3E3E6E4E0994E59E0E4E0E4E3E3E29D80D296D6E2E5E5E5E6E6E6E6E3E231B1E5E5E4E2BA269B00E0E5E4E5E6E4E3E6E6E7E4E7E6E6E6E200E3E5E1E3E5E5E3E4E600E49BE1E6E6E8E7E8E7E5E5E5E5E6E6E7E8E6E5E4E6E3E5E5E4E7E7E6E6E6E7E7E7E6E5E5E3E3E3E4E4E5E6E5E6E6E5E3E3E6E7E6E7E7E6E7E7E6E5E6E6E5E3E5E4E5E6E6E7E3E2E4E6E3E6E5E3E3E1E4E3E7E5E7E6E5E3E4E5E6E6E6D0E4E6E4E7E6E5E5E6E4E2E4E6E7E7E6E6E77CE6E9E8E7E6E7BEE5E6E6E6E6E5E6E7E8E7E7E8E7E7E7E7E7E2E6E5E5E4E3E4E4E2E3E2E2E2E20000E2E3E2E4E2473EA4DEE4E5E4281D9DE2E3E2E4E3BC5F547A5492E4DFE2E3E3AC9289A4BEB5E3E2E5E4E3E2B35757DEE3E5E6E4E4E4E1E4B3E2E4E5E6E7E7E5E3E4E5E0B1B1BEE3E5E6E47C47201596E6E4E5E6E5C0E5E6E7E6E7E6E5E5E00EE2E3E5E5E5E5E6E7E6C52F01E4E6E6E6E6E6E5E5E6E6E6E5E5E4E5E6E4E4E4E5E3E5E5E4E5E6E6E5E6E7E7E7E6E7E7E5E4E6E6E5E5E6E7E5E4E6E5E5E4E6E4E5E5E5E6E6E6E6E6E6E7E9E8E6E4E6E6E5E6E6E7E6E7E6E5E6E7E5E6E8E8E7E7E5E6E6E6E7E6E7E5E4E4E5E4E6E7E7E7E6E6E8E8E8E7E8E7E6E7E7E7E6E7E6E6E6E8E7E8E5E6E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C02000000000000010000009F0000000001000001E6E5E6E6E7E7E7E8E7E7E7E6E6E6E6E5E1E2E2E2E2E1E312000057E3E3E0C99D5F00E4E3E2E575000075E1E3E1E06A4C179DBA4520E2E5E4E4D0E3E13EA4E4E1E2E2E4B5E1E3E2C9BAE4E3E0E7E2E5E4E215DB8EE4E4E5E5E5E4E4E6E32F0C71E7E4E6E5A119200043E6E7E5E3E292E3E3E3E5E4E4E4E5E4E4E5E1E5E3E1E2E5E7E6E3E5E5E4E5B7E8E7E7E7E7E5E5E7E4E7E6E7E5E7E6E4D0E5E4E4E5E5E4E6E5E4E6E5E8E6E2E6E5E5E5E4E7E6E7E7E2E5E4E5E6E5E6E6E7E7E6E6E5E5E5E5E6E4E5E5E6E4E5E6E6E4E5E6E8E6E6DFE8E5E5E8E6E8E6E7E5E3E6E4E7E5E5E5E3E5E6E4E6E7E9E8E8E7E8E7E6E7E7E2E6E6E6E7E5E7E7E5E6E6E7E5E9E8E7E7E6E6E7E7E8E6E8E8E7E7E7E6E2E4E2E3E6E4E4E4E2E3E4E00000BCE4E4E4E4E16FE2E2E3E3E2E3100043C7CBE6E5C98EB7E3BC0C28DBE2E3E4D4E250C741E1E2E5E5E6E7E6E5E6E5E4E0E2E3E6E5E2E3897E7800E2E6E5E5E6E7E6E5E410E433B7E4E5E6E2D400E000E6E6E6E5E4E4E2E6E6E7E7E5E5E3E4DFE4E2E3E507E5E3E5E5E5E6E7E2E6E7E7E7E7EAE6E6E4E4E7E7E5E5E7E6E6DFE6E5E8E7E7E6E6E5E5B1E5E5E6E7E6E2E4E4E4E4E7E6E6E8E4E5E5E5E5E7E6E6E6E6E7E7E6E4E3E6E5E5E5E4E7E6E5E6E7E6E8E7E8E7E6E8E5E2E3E5E7E6E6E5E7E6E6E6E4E5E3E4E6E6E4E6E3E7E6E6E7E7E6E6E6E6E7E5E6E7E7E7E9E7E7E7E7E7E7E7E8E7E7E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000A10000000001000001E7E7E8E8E8E8E8E8E87EE8E8E6E4E5E4E4E3E2E1E5E4E4E3DF47E0E4E1E4E4E2E5E3E1E3E3E2E2C0128BE1E0E4E36DE3D0E07154806FE4E2E2E5CB45C01D94E0E2E2E2E1E5E4BE5903E3E4E4E5E3E3E4E0100EAAE3E3E5E4E5E5E2E5E4E0AAE1E8E7E7E7E4E3660000C9E2E4E4E1E4E3E6E5E6E7E8E6E6E3E3E6E5E4E66F41E3E5E3E5E2E5E5E7E5E6E5E5E4E8E6E6E6E9E7E7E7E5E4E4E4E4E4E5E6E5E6E4E4E4E5E6E5E5E7E7E8E6E6E5E4E6E7E6E6E4E5E5E5E7E9E6E6E5E6E7E7E4E5E4E4E7E6E8E7E6E6E5E4E4E6E5E5E7E6E5E4E2E4E7E8E9E1E6E6E8E7E6E6E6E6E7E5E7E6E6E7E6E6E8E6E6E6E7E6E5E5E6E6E8E6E7E6E6E5E6E7E7E8E7E9E6E3E6E3E7E6E7E6E8E8E7E7E7E7E6E6E6E5E6E8E2E3E4E3E4E5E4E2E4E5E5E5DEE3E1E3E2E159E3E4E3CB0C17788E75E2E2E5E4E38E01B71D90E4E1E0E3E2E0BCCD47E3E4E5E7E5E6E6B112664EE5E4D8E5E4E4E55D0AB3E0E4E2E3E5E4E4E4E35D0010E4E6E4E4E5E4000000E2E2E3D4E4E3E3E4E6E7E7E5E6E3E5E6E4E6E4E4E226E3E6E5E1E3E3E3E2E1E6E5E5E4E5E6E7E4E6E7E7E5E6E6E6E7E2E5E5E5E4E5E4E3E6E6E5E6E9E7E7E5E4E5E4E4E5E4E5E6E5E4E5E5E5E5E5E5E8E7E8E8E5E5E4E5E7E7E7E7E6E5E5E6E5E6E6E6E8E7E8E8E6E6E6E6E8E7E7E6E6E6E6E8E5E5E5E4E7E6E8E7E4E7E4E6E8E7E6E7E7E8E7E8E8E8E8E5E7E8E6E6E7E7E6E6E7E6E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000A30000000001000001E6E6E6E6D2E6E7E7E9E8E9E9E7E7E7E4E3E3E2DBE3E3E4E5E1E3E3E3E4E0E2E3E4E2A8E5E3E2E5E09D4C3AE3E4E6E7E7E7E4D21928E000E6E3E5E5E587D4E2E3E5E3E4E3E6E62B1D0500C2E3E7E6E6E7E5E0E3E3E6E5E6E5E5E4E4DCE4B754009FE5E7E7E4E500A8E2E5E6E5E4E5E6E5E4E4E4E2E6E5E7E6E4E5E5D2E6E7E5E6E6E7E7E7E4E4E4E3E5E4E3E6E4E7E5E6E8E6E7E7E7E4E6E3E4E6E4E6E7E7E6E6E8E3E7E7E6E7E5E5E6E5E5E4E8E5E5E5E7E7E6E6E9E6E7E3E8E7E8E7E4E3E5E4E7E6E8E8E5E3E4E5E8E7E6E7E8E6E5E7E7E6E7E9E6E5E0E5E5E5E6E6E6E6E5DDE8E7E7E7E6E6E6C9E3E0E6E6E6E5E5E6E4E5E5E5E7E7E7E6E8E7E8E8E7E6E6E6E7E5E7E6E7E8E8E8E8E8E8E8E8E7E6E5E4E0E4E2E3E1A8E4E3E4DBE2E3E2E4E0E6E4E5E4E3E1E5E0E24C45E5E4E3E6E4E5E4E05000C7E1E4E5E4E6C0E1D8E2CDE2E7E5E626E5A6A60005E1E4E5E6E4E5E7E5E5E6E6E5E3E7E4E5E4E5E3B3E3AA59E3E6E3E6E50AB7E5E5E6E8E4E6E8E6E6E6E5E6E6E7E5E5E5E5E4E5E5E6E6E5E8E6BAE5E9E6E6E7E3E2E4E5E7E8E8E6E6E6E8E7E9E7E8E6E6E7E6E6E7E5E5E5E6E7E8E6E6E5E3E4E6E7E5E7E6E6E8E6E8E6E7E7E7E6E5E6E5E4E5E4E6E4E6E7E8E7E8E7E6E5E4E6E7E7E8E7E7E7E6E7E8E7E7E7E5E5E6E7E7E8E5E7E5E6E4E6E8E7E8E8E7E5A6E6E7E7E7E8E3E5E5E7E6E7E7E6E8E7E9E7E8E8E8E8E6E6E6E5000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000A50000000001000001E7E7E7E7E7E7E9E7E9E7E8E8E2E7E7E3E3E4A4E3E5E0E3D4A4E2E3E4E4E3E5E5E7E7E6E6E69FE0E7E420017CE1E1E5E3E4E4E13315A4A4E4E6E7E4E5E4E5E6E2E5E5E4E2E5E6E3CB158375E4E7E6E6E5E5E5E0E5E6E7E6E5E6E6E4E5E6E457332FE6E6E6E2E696E380E3E4E4E3E6E4E5E6E6E6E7E6E6E8E7E7E5E5E5E4E5E5E2E8E7E7E7E5E6E5E6E6E7E5E5E7E7E7E8E6E3E6E7E3E6E6E6E4E7E7E6E4E5E6E5E5E5E6E6E5E5E5E4E6E7E5E5E7E6E6E5E6E7E5E7E5E6E6E5E7E5E6E3E5E6E5E7E7E6E5E6E6E7E6E7E7E7E8E6E7E6E8E7E3E7E8E7E6E5E5E7E8E6E5E7E8E6E5E6E8E7E8E6E6E7E6E6E6E7E6E7E6E6E5E6E7E6E7E5E8E8E8E9E8E7E8E7E6E6E6E6E8E7E8E8E7E7E6E6EAE9E9EAE6E7E8E8E1ACE2E2E3E4E2E3E564E2E4E4CDE5B1E1BCE6E7E5E5E7E5E5E27AE4E5E4E5E6E2E5E473E2DCE4E5E2C9E5E4E2E2E4B7E3E5E4E4E2E5E4E2549675E5E5E5E3E6E4E5E3E5E4E5E4E2E6E3E3E3E5E5A800C2E5E5E5E6E5E4D4E5E6E6E5E5E5E4E5E4E5E4E4E4E4E4E6E6E4E4E6E6E7E5E4E4E5E6E5E7E8E6E6E6E6E5E6E6E4E6E5E7E9E7E5E7E6E5E7E7E7E6E6E5E5E4E4E4E5E6E5E6E5E5E6E6E5E5E4E6E5E6E6E5E8E6E7E4E4E4E5E6E9E8E8E4E5E5E8E8E7E6E5E6E7E7E8E6E6E6E7E7E8E5E6E6E7E8E7E8E9E8E7E6E6E6E6E6E6E7E7ACE7E7E6E5E6E6E7E8E7E5E7E3E7E8E8E7E7E8E6E7E9E8E8E8E7E6E7E6E7E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000A70000000001000001E7E7E7E7E7E9E9E9E8E8E8E8E7E8E9E8E3E4E5E4E0DFB7E4E7E6E7E6E04131E5E6E5E5E5E4E4E5E39D80E6E5E5E675E6E7E7E7C0C0E2E5E4E6E4E5E4E2E4E3E3E6E7E6E7E6E5E5E6E4E2E5E4E1E2E6E7E4E6E5E5E4E5E5E7E6E6C5E5E6E4E12BE2E7E6D8E5E6E2E2E4E4E5E5E4E4E6E7E8E6E6E7E6E6E6E6E6E5E7E7E5E5E2E6E4E4E5E4E8E7E6E7E1E5E5E6E7E8E8C5E6E6E7E5E5E6E6E3E6E5E7E7E6E6E6E6E7E8E7E7E4E6E5E6E5E6E6E5E5E5E6E5E6E7E5E5E6E5E3E8E8E8E6E8E5E7E5E7E7E7E8E8E6E7E5E8E7E8E6E7E5E6E6E6E7E2E7E7E8E7E5E8E8E7E6E7E6E5E3E5E4E0E6E7E7E8E9E7E9E7E7E7E8E7E8E7E8E8E8E8E6E6E5E5E9E8E9E8E7E6E7E7E8E7E7E7E7E5E7E7E7E7E7E7E7E8E8E9E3E2E3E2E6E6E4E6E4E4E4E5E3E5E5E4E7E580C9E4DDE5E5E3E5E7A8E6E5E6E6E3E5E5E3E5E5E3E5E6E5E4E4E4E5E4E6E5E5E4E4E5E492E3E6E6E6E6E4E4E4E5E6E7E7E7E5E6E6E6E6E4E5E4E5E4E3E3E5E5E5E7E8E7E6E8E8E9E8E9E6E4E5E7E6E7E6E6E480E5E5E6E7E8E7E4E6E4E4E7E5E6E6E8E9E8E6E6E8E8E6E6E5E6E7E8E7E8E7E4E6CDE6E6E7E6E6E5E4E4E5E6E6E7E6E6E4E5E6E5E5E4E4E6E6E7D2E7E8E8E9E8E7E8E8E9E7E5E6E4E6E5E5E8E5E7E6E4E5E7E7E6E8E7E6E9E8E7E8E8E6E8E7E7E7DEE7E6E6E6E7E8E7E7E3E7E8E7E8E6E6E6E7E7E8E7E7E6E6E7E7E6E7E7E7E8E7E7E8E7E8E7E8E7E5E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000A90000000001000001E8E8E8E9E5E6E6E6E7E6E6E7E2E2E3E1E3E3E2E3E6E5E5E4E4E5E3E4E5E3E2E6283AE4E5E4E119E57CE2E6E7E6E7E7E4E6E5E5E692E1E5E5E3E4E3E4E4E5E5E4E5E6E4E7E6A1E7E6E6E6E6E7E6E6E5E3E5E4E5E3E6E6E5E6E6E6E6E5E4E5E5E6E5E6E6E6E7E5E5E5E4E6E5E3E4E3E3E4E4E5E5E5E5BEE5E5E4E4E6E4E6E7E4E6E8E5E7E6E7E4E6E5E6E4C5E6E7E7E7E7E8E7E8E7E6E6E7E7E5E4E5E4E4E4E4E3E6E3E4E3E6E6E8E7E7E6E4E5E7E6E6E8E5E5E7E7E4E5E6E7E6E5E7E7E3E4E6E5E8E1E7E5E7E3E6E6E5E5E4E6E8E6E7E8E5E5E4E4E85DE7E8E5E6E8E7E8E7E6E7E6E6E6E6E5E3E7E7E8E8E7E7E9E8E8E9E9E9E8EAE2E8E7E7E6E6E6E7E6E7E6E7E8E8E8E8E8E8E6E3E9EAE7EAE1E3E4E3E5E4E4E4E373E2E2E5E4E4E4E5E3E4E6B3E0E5E5E6E5E4E5E5C0E5E7E2E6E5689B9FE5E4E3E0E4E7E4E5E4E3E3E3E4E4E3E4E3E3E4E5E5E5E4E1E3E5E7E6E5E6E5E6E6E6E5E5E6E6E5E6E6E5E5E5E2E4E3E0E4E5E4E5E4E5E5E6E4E4E2E5E0E5E3E5E6E6E4E5E3E5E5E5E6E5E2E3E3E2E6E6E7E7E6E6E5E4E5E5C0E5E5E5E5E6E6E6E7E6E6E7E6E5E6E6E6E7E5E5E3E4E4E5E5E1E5E2E6E6E8E7E6E5E6E6E5E7E5E5E5E6E3E6E5E7E8E6E7E7E7E7E7E8E5E1E5E5E7E5E7E7E6E7E4E5E0E7E7E6E5E6E3E5E7E9E7E8E8E7E7E8E8E7E7E7E6E6E8E6E6E6E7E6E6E7E7E6E8E8E6E8E8E8E7E6E7E7E7E7E7E7E8E7E7E6E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000AB0000000001000001E6E6E6E6E9E8E8E8E8E8E7E6E4E4E3E5E2E3E4E1E6E6E5E0E5E6E5E4E8D0E7E8E4A1DE96AAE2E5E6E5E2E5E2E6E6E02B2F414CE4DFE1E4E5E5E5E6E4E4E3E4E5E5E5E5E4C7E7E5E5E4E4E2E4E6E7E7E6C7E5E5E596E1CDE5E4E4E5E4E6E5E1E4E6E6E8E8E6E4E4E5E7E7E4E5E4E5E4CBE5E6E7A8E7E5E6E5E6E7E7E7E5E5E7E5E6A1E3E6E7E5E6E3E4E6BEE7E7E5E5E5E6E3E6E5E6E6E6E5E6E6E1E8CDE1E4E5E6E4E3E3E5E7E7E6E5E5E6E4E4E3E4E5E5E8E7E7E6E6E7E6E8E5E7E7E6E6E6E6E7E7E7E5E6E7E7E9E7E6E8E6E4E5E7E8E6DDE5E6E6E8E7E7E8E8E8E8E6E7E5E4E9E8E8E8E7E7E8E5E7E7E7E7E6E7E8E6E7E7E6E9E8E6E6E4E7E7E7E6E6E6E6E5E9E7E7E8E7E8E7E7E8E8E8E9E1E3E3E3E3E5E3E5E5E5E4E4E7E7E7E7E5E5E5E6E5E5E4E4E7E7E6E72F43E4E2E8B533E771262831BEE5E6E3E5E44EE5E2E3DFDDE5E5E6E6E6E6E5E6E6E7E5E7E6E4E5E6E4E1E5E6E6E5E6E5E6E3E4E6E6D6E6E6E7E6E6E7E6E5E4E3E4E7E3E5E5E0E4E46FE6E2E7E7E6E51DE7E5E6E5E6E5E4E4E5E6E6E5E7E7E7E6E6E6E8E6E6E7E7E7E6E8E7E7E4E4E2C2E6E6E2E5E3E5E5E7E6E5E5E6E7E7E8E7E7E7E5E5E5E6E7E6E6E5E5E5E6E7E9E1E7E6E7E7E7E6E5E7E7E7E7E8E6E5E5E7E6E6E5E7E8E9E7E8E7E7E7E6E8E7E6E8E6E6E8E6E7E6E7E6E7E7E6E7E8E8E7E6E8E8E9E9E8E8E6E7E8E7E7E7E8E7E4E7E8E8E9E9E6E5E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000AD0000000001000001E6E5E6E6E9E7E7E8E8EAE9EAE8E6E5E6E3E2E3E4E2E3E5E3E2E5E6E4E5E300E6E6E6E0E6E7E2E6E3E1E4E0BCE8E5DEE7DDE6D44EE1E0E596A4E649E6E6DDE3A1E6E6E6E738E296B324E4E3A65D7AC2E5E7E7E5E6E5E2E4E3E5E5E4E4E5C0E5E6E5E5E673E4E5E4E5A1E6E6E8E5E4E6E4E6D2C7E2E4E5E5E6E4E8E3CDE1E6E5E1E3E3E2E4E5E5E6E1E5E56FE6E6E6E6E5E7E4E7E8E6E8E6E6E5E5E6E4E6E5E6E7E8E5E5E7E6E8E7E7E7E6E5E7E7E6E6E7E8E4E6E6E5E5E7E5E8E8E8E7E7E5E7E6E6E6E8E7E7E6E7E6E8E5E0E8E9E7E8E7E6E6E5E6E7E7E6E6E6E7E8E6E7E7E7E8E387E8E8E7E8E7E7E6E5E5E5E7E7E76DE6E6E6E7E7E8E7E7E7E4E7E7E6E6E5E5E8E7E8E8E7E7E6E6E8E8E7ACE4E4E2E3E3E4E3E4E7E6E6E5E7E6E5E6E6E4E5E5E7E6E6E8E7E5E6E6E5E6E6E7E5E5E6E6E7E7E7E6E7E1E7E5E6E7E6E7E7E7E468CDE5E3E4E7E2A6E0E3E6E3E6E0CDE7E7E5E5E6E475CDE5E5E7E7E6E7E5E1E5E4E6E5E6E5E8E7E5E2E6DBE4E7E8E7E6E5E5E4E5E4E7E6E7E8E5E5E6E2E6E6E6E7E6E6E8E6AFE7E6E7E7E8E9E5E6E5E5E6E9E8E8E8E6E5E7E7E9E8E7E7E6E8E8E2E6E6E7E7E6E6E7E8E8E9E9E8E6E6E6E6E9E8E8E8E7E9E8E9E7E8E8E8E6E7EBE8E8E8E6E7E7E7E6E7E7E6E6E7E9E5E7E8E7E8E7E7E8E7E6E7E7E8E7E8E7E8E7E7E8E7E8E7E9E9E9E8E6E6E6E6E8E7E7E7E7E8E9E7E8E6E6E7E8E8E6E7E6E5E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000AF0000000001000001E7E7E6E7E9E8E9E9E0E8E7E8E6E9E9E8E5E4E5E6E4E6E6E6E7E6E6E7E6E4E5E5E6E7E5E5E6E6E5E7E6E6E7E7E8E7E7E7E7E6E6E7E6E6E6E5E5E6E6E6E6E6E6E6E7E8E6E6E8E6E8E8E7E7E7E8E6E6E7E6E6E7E6A6E4E5E5E6E7E7E8E8E6E5E4E4E6E7E6E7E7E7E7E6EAE7E7E7E6E7E6E7E6E8E9E8EAE8E8E8E6E7E9E7E8E6E7E7E6E5E7E7E7E8E4E7E9E8E8E8E7E4E1E8E6E8E7E7E7E7E8E7E8E5E6E6E8E7E8E8E8E8E9E9E9E9E8E9E8E8E7E8E7E6E7E7E8E7E6E8E7E7E6E8E9E9E7E9E8E8E3E6E8E8E7E8E8E8E9E7E8E8E8E8E9E9E9E7E7E6E7E8E8E8E8E8E7E7E8E7E7E7E8E6E8E8E9E8E7E7E6E6E8E8E7E8E8E8E6E8EAEAE9EAE7E7E9E8E6E7E8E8E6E6E6E6E8E8E8E7E7E8E8E7EAE7E9E8E8E6E6E7E5E6E5E5E6E5E6E5E5E6E5E5E6E7E6E7E6E6E6E5E8E5E6E8E4E5E4E5E7E6E7E7E7E7E8E7E6E6E4E6E7E4E6E7E7E5E5E5E6E5E7E6E8E7E8E8E7E6E6E6E7E7E6E8E5E5E6E7E7E585E7E8E7E8E9E6E6E7E6E7E7E6E6E8E6E6A6E7E6E6E6E8E8E8E7E7E8E8E7E7E7E5E6E2E7E8E7E6E5E6E4E7E9E7E8E7E7E7E7E8E8E7E8E785E8E8E8E0E8E9E8E8E7E8E6E7E6E7E8E8E8E7E8E8E9E8E7E7E8E8E8E7E9E6E6E6E7E7E9E8E8E9E8E6E7E7E6E5E6E6E8E6E7E8E7E7E6E7E9E8E8E9E6E6E6E7E6E6E6E6E8E8E8E8E8E8E7E8E7E7E8E8E6E6E8E7E6E6E7E6E8E8E8E6E6E7E7E8E9E7E7E7E9E8E7E8D4E6E8E6EAE8E8E8E6E6E6E6000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000001000000B10000000001000001E6E6E6E6E8E7E8E9E9E8E7E8E5E8E8E8E6E4E5E5E6E5E6E5E7E7E8E8E1E5E4E5E7E6E7E7E5E6E5E6E6E741E5E7E6E8E8E6E5E6E5E8E6E7E8E5E6E5E6E93CE5E7E6E5E4E6E6E7E6E5E7E5E7E5E5E5E6E6E6E6E7E6E5E6E7E7E6E7E6E6E6E6E5E5E6E7E6E7E6E5E6E6E6E8E7E7E7E7E7E8E8E8E7E8E8E6E7E7E6E6E6E6E6E5E6E6E8E6E7E8E8E8E7E8E9E9E9E7E8E6E8E8E6E4E7E7E8E7E7E7E7E5E6E6E7E7E7E7E7E6E8E8E6E7E6B5E7E7E7E7E7E6E7E7E8E7E7E7E9E8E8E8E7E7E7E7E7E7E7E9E6E8E7E7E7E6E6E6E7E8E8E8E8E7E7E7E8E8EAE8E7E8E8E8E8E8E7E8E8E6E6E6E6E6E5E6E8E8E7E7E6E7E5E6E8E6E7E7E7E7E7E7E6E5E6E6E7E7E6E7E6E6E6E6E8E8E7E8E7E7E8E8EAE9E8E6E8E7E9E7E3E3E6E6E6E6E7E6E7E7E6E7E6E6E6E4E6E5E6E6E6E5E5E5E7E7E8E7E8E8E8E8E5E6E6E6E8E7E7E7E6E5E4E5E6E6E8E7E1E8E8E7E9E8E9E8E8E7E8E7E7E7E7E6E6E7E7E7E6E7E8E8E6E7E7E8E7E7E8E6E8E8E7E8E7E7E7E7C9E6E9E7E7E7E7E7E8E9E1EAE8E8E6E8E8E7E8E7E6E6E7E7E7E2E7E7EAE9E8E8E6E9E3E8E7E8E8E7E6E6E6E6E7E7E8E6E6E6E6E7E7E6E8E6E7E6E7E7E8E8E7E7E8E5E8E7E6E8E7E8E7E7E7E6E7E9E8EAE7E8E9E8E7E6E8E8E7E8E9E8E7E7E7E6EAE8E8E7E7E7E8E7E6E7E9E9E8E8E6E7E6E7E7E8E7E7E8E7E8E7E7E7E8E8E8E6E7E6E7E7E8E8E7E9E6E6E7E7E8E2E8E7E6E8E8E8E6E6E6E7000000
|
||||||
|
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 540 540 0 802100001C0200000000000000000000B30000000001000001E6E4E5E5E7E7E8E7E9E9E9E8E6E8E8E8E4E6E5B3E4E4E5E6E5E5E5E7E5E5E5E6E6E6E6E5E9E7E8E7E5E5E5E6E8E8E7E7E7E9E9E8E8E6E8E7E6E6E7E8E6E5E5E5E7E7E7E4E6E6E6E7E7E6E6E6E6E6E7E8E6E6E664E8E7E6E6E6E7E8D6E7E5E6E6E9E7E7E6E6E7E6E6E6DCE8E8E8E7E8E8E7E8E6E8E9E7E5E6E6E4E6E6E6E7E7E7E8E8E7E7E8E7E8E7EAE6E7E8E7E7E7E8E9EAE9E9E6E6E6E7E7E7EAE9E8E7E7E7E8E6E6E7E8E6E8E8E7E7E6E6E6E7E7E8E8E7E8E4E8E6E7E7E7E9E6E9E6E7E6E7E8E8E9E7E7E7E6E8E9E8E9E8E9E7E7E7E7E5E7E2E8E7E7E8E7E6E7E6E6E6E7E7E6E7E8E5E8E6E8E7E8E9E9E8E6E5E7E7E9E8E9E9E7E5E7E6E7E7E6E7E6E6E6E5E8E8E8E7E7E7E8E8EAEAEAEAE6E6E8E6E5E5E6E6E4E3E4E4E6E4E5E7E6E6E5E5E6E6E6E7E8E6E8E8E8E7E9E7E7E6E7E7E9E7E7E8E8E4E7E8E7E7E7E6E7E7E7E6E5E4E5E6E7E3E4E5E6E6E6E4E9E8E7E8E7E8E7E9E6E6E6E6E7E7E6E4E5E4E5E4E5E6E6E6E8E7E6E7E7E7E8E6E5E7E7E6E3E7E6E6E8E5E6E6E8E7E8E8E7E6E7E7E8E8E7E7E6E6E7E7E6E8E5E8E5E5E5E6E8E9EAE9E9E8E9E9E9E9E8E7E6E7E7E99BE5E6E6E8E8E0E7E9E9E8E8EAE7E9E9E9E8E8E8E7E7E5E8E9E7E6E8E6E7E7E8EAE9E7E8E9E9E9E8E7E7E6E7E8E8E6E7E7E7E7E7E6E7E7E7EAE6E6E8E6E6E6E5E8E8E8E8E7E8E7E7E5E6E7E6E8E8E6E7E5E6E6E5E8E8E7E9E8E8E8E8E6E6E5E6000000
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
File diff suppressed because one or more lines are too long
@@ -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 129 0 0 40 38 0 00009C37FE5C669C2D000A01014101C10000D11BB7134A090FA1000000000100000000000003
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE011100
|
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 129 0 0 266 7 0 0000FE01130100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE021100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE025400
|
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 1 131 0 0 7 7 0 06000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 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 3 129 0 0 266 7 0 0000FE00910100
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
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 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 1 131 0 0 7 7 0 06000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 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 3 129 0 0 266 7 0 0000FE00910100
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
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 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 1 131 0 0 7 7 0 06000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
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 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 1 131 0 0 7 7 0 05000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 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 3 129 0 0 266 7 0 0000FE00910100
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
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 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 1 131 0 0 7 7 0 06000000000000
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 3 129 0 0 266 7 0 0000FE00910101
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 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 3 129 0 0 266 7 0 0000FE00910100
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
|
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 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 1 131 0 0 7 7 0 05000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037100
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE03752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE04752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037200
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047200
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE037600
|
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE047600
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE04651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE05651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE046600
|
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 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 1 131 0 0 7 7 0 06000000000100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
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 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 3 129 0 0 266 7 0 0000FE00910100
|
||||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
|
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 1 0 0 1 1 0 A8
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0468214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0568214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE05811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE06811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE05831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE06831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE06A100
|
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE07A100
|
||||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE06A200
|
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE07A200
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,14 @@ d.open_sync()
|
|||||||
template = FPrint.Print.new(d)
|
template = FPrint.Print.new(d)
|
||||||
|
|
||||||
def enroll_progress(*args):
|
def enroll_progress(*args):
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
|
||||||
print('enroll progress: ' + str(args))
|
print('enroll progress: ' + str(args))
|
||||||
|
|
||||||
# List, enroll, list, verify, delete, list
|
# List, enroll, list, verify, delete, list
|
||||||
print("enrolling")
|
print("enrolling")
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
p = d.enroll_sync(template, None, enroll_progress, None)
|
p = d.enroll_sync(template, None, enroll_progress, None)
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
print("enroll done")
|
print("enroll done")
|
||||||
|
|
||||||
print("listing")
|
print("listing")
|
||||||
@@ -33,7 +36,9 @@ print("listing done")
|
|||||||
assert len(stored) == 1
|
assert len(stored) == 1
|
||||||
assert stored[0].equal(p)
|
assert stored[0].equal(p)
|
||||||
print("verifying")
|
print("verifying")
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
verify_res, verify_print = d.verify_sync(p)
|
verify_res, verify_print = d.verify_sync(p)
|
||||||
|
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||||
print("verify done")
|
print("verify done")
|
||||||
assert verify_res == True
|
assert verify_res == True
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0000
|
A: bcdDevice=0000
|
||||||
A: bmAttributes=a0
|
A: bmAttributes=a0
|
||||||
A: busnum=1
|
A: busnum=1\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
|
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
|
||||||
A: dev=189:69
|
A: dev=189:69
|
||||||
A: devnum=70
|
A: devnum=70\n
|
||||||
A: devpath=1
|
A: devpath=1
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=00bd
|
A: idProduct=00bd
|
||||||
|
|||||||
@@ -279,4 +279,6 @@ fpi_device_fake_class_init (FpiDeviceFakeClass *klass)
|
|||||||
dev_class->list = fpi_device_fake_list;
|
dev_class->list = fpi_device_fake_list;
|
||||||
dev_class->delete = fpi_device_fake_delete;
|
dev_class->delete = fpi_device_fake_delete;
|
||||||
dev_class->cancel = fpi_device_fake_cancel;
|
dev_class->cancel = fpi_device_fake_cancel;
|
||||||
|
|
||||||
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
}
|
}
|
||||||
|
|||||||
+298
-2
@@ -20,6 +20,7 @@
|
|||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
|
||||||
#include "test-utils.h"
|
#include "test-utils.h"
|
||||||
|
#include "fpi-device.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_context_new (void)
|
test_context_new (void)
|
||||||
@@ -49,7 +50,7 @@ test_context_has_virtual_device (void)
|
|||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
fpt_setup_virtual_device_environment ();
|
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
context = fp_context_new ();
|
context = fp_context_new ();
|
||||||
devices = fp_context_get_devices (context);
|
devices = fp_context_get_devices (context);
|
||||||
@@ -81,7 +82,7 @@ test_context_enumerates_new_devices (void)
|
|||||||
|
|
||||||
context = fp_context_new ();
|
context = fp_context_new ();
|
||||||
|
|
||||||
fpt_setup_virtual_device_environment ();
|
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
|
||||||
fp_context_enumerate (context);
|
fp_context_enumerate (context);
|
||||||
devices = fp_context_get_devices (context);
|
devices = fp_context_get_devices (context);
|
||||||
@@ -92,6 +93,296 @@ test_context_enumerates_new_devices (void)
|
|||||||
fpt_teardown_virtual_device_environment ();
|
fpt_teardown_virtual_device_environment ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEV_REMOVED_CB 1
|
||||||
|
#define CTX_DEVICE_REMOVED_CB 2
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_removed_cb (FpDevice *device, FptContext *tctx)
|
||||||
|
{
|
||||||
|
g_assert_nonnull (device);
|
||||||
|
g_assert_true (device == tctx->device);
|
||||||
|
|
||||||
|
g_assert_null (tctx->user_data);
|
||||||
|
tctx->user_data = GINT_TO_POINTER (DEV_REMOVED_CB);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
context_device_removed_cb (FpContext *ctx, FpDevice *device, FptContext *tctx)
|
||||||
|
{
|
||||||
|
g_assert_nonnull (device);
|
||||||
|
g_assert_true (device == tctx->device);
|
||||||
|
|
||||||
|
/* "device-removed" on context is always after "removed" on device */
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
tctx->user_data = GINT_TO_POINTER (CTX_DEVICE_REMOVED_CB);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_context_remove_device_closed (void)
|
||||||
|
{
|
||||||
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
gboolean removed;
|
||||||
|
|
||||||
|
tctx->user_data = NULL;
|
||||||
|
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||||
|
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||||
|
|
||||||
|
/* Triggering remove on closed device. */
|
||||||
|
fpi_device_remove (tctx->device);
|
||||||
|
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||||
|
g_assert_true (removed);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* device-removed is dispatched from idle. */
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The device is now destroyed and device-removed was called. */
|
||||||
|
g_assert_null (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||||
|
|
||||||
|
fpt_teardown_virtual_device_environment ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(FpPrint) print = NULL;
|
||||||
|
GError **error = user_data;
|
||||||
|
|
||||||
|
g_assert_nonnull (error);
|
||||||
|
g_assert_false (fp_device_close_finish (FP_DEVICE (device), res, error));
|
||||||
|
g_assert_null (print);
|
||||||
|
g_assert_nonnull (*error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_context_remove_device_closing (void)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
tctx->user_data = NULL;
|
||||||
|
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||||
|
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||||
|
|
||||||
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
/* Triggering remove on device that is being closed. */
|
||||||
|
fp_device_close (tctx->device, NULL, close_done_cb, &close_error);
|
||||||
|
fpi_device_remove (tctx->device);
|
||||||
|
|
||||||
|
/* Removed but not yet notified*/
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||||
|
g_assert_true (removed);
|
||||||
|
g_assert_null (tctx->user_data);
|
||||||
|
|
||||||
|
/* Running the mainloop now will cause the close to fail eventually. */
|
||||||
|
while (!close_error)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
g_assert_error (close_error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||||
|
|
||||||
|
/* Now the removed callback has been called already. */
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* While device-removed needs another idle iteration. */
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_null (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||||
|
|
||||||
|
fpt_teardown_virtual_device_environment ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_context_remove_device_open (void)
|
||||||
|
{
|
||||||
|
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
gboolean removed = FALSE;
|
||||||
|
|
||||||
|
tctx->user_data = NULL;
|
||||||
|
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||||
|
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||||
|
|
||||||
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
/* Triggering remove on open device. */
|
||||||
|
fpi_device_remove (tctx->device);
|
||||||
|
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||||
|
g_assert_true (removed);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* At this point, the "removed" cb on the device should have been called!
|
||||||
|
* Iterating the mainloop will not change anything.
|
||||||
|
*/
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* On close, the device will be removed from the context,
|
||||||
|
* but only a main loop iteration later. */
|
||||||
|
fp_device_close_sync (tctx->device, NULL, &error);
|
||||||
|
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
g_assert_null (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||||
|
|
||||||
|
fpt_teardown_virtual_device_environment ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(FpPrint) print = NULL;
|
||||||
|
gboolean *data = user_data;
|
||||||
|
|
||||||
|
g_assert_true (fp_device_open_finish (FP_DEVICE (device), res, &error));
|
||||||
|
g_assert_null (print);
|
||||||
|
g_assert_null (error);
|
||||||
|
|
||||||
|
*data = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_context_remove_device_opening (void)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
tctx->user_data = NULL;
|
||||||
|
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||||
|
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||||
|
|
||||||
|
fp_device_open (tctx->device, NULL, open_done_cb, &open_done);
|
||||||
|
g_assert_false (open_done);
|
||||||
|
|
||||||
|
fpi_device_remove (tctx->device);
|
||||||
|
|
||||||
|
/* Removed but not yet notified*/
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||||
|
g_assert_true (removed);
|
||||||
|
g_assert_null (tctx->user_data);
|
||||||
|
|
||||||
|
/* Running the mainloop now will cause the open to *succeed* despite removal! */
|
||||||
|
while (!open_done)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
|
/* Now the removed callback has been called already. */
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
fp_device_close_sync (tctx->device, NULL, &close_error);
|
||||||
|
g_assert_error (close_error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||||
|
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* The device-removed signal needs an idle iteration. */
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_null (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||||
|
|
||||||
|
fpt_teardown_virtual_device_environment ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enroll_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(FpPrint) print = NULL;
|
||||||
|
GError **error = user_data;
|
||||||
|
|
||||||
|
g_assert_nonnull (error);
|
||||||
|
print = fp_device_enroll_finish (FP_DEVICE (device), res, error);
|
||||||
|
g_assert_null (print);
|
||||||
|
g_assert_nonnull (*error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_context_remove_device_active (void)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
FpPrint *template;
|
||||||
|
gboolean removed = FALSE;
|
||||||
|
|
||||||
|
tctx->user_data = NULL;
|
||||||
|
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||||
|
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||||
|
|
||||||
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
/* Start an enroll that we can cancel/fail later.
|
||||||
|
* NOTE: We need to cancel explicitly as remove() does not trigger a failure!
|
||||||
|
*/
|
||||||
|
template = fp_print_new (tctx->device);
|
||||||
|
cancellable = g_cancellable_new ();
|
||||||
|
fp_device_enroll (tctx->device, template, cancellable, NULL, NULL, NULL, enroll_done_cb, &enroll_error);
|
||||||
|
|
||||||
|
/* Triggering remove on active device. */
|
||||||
|
fpi_device_remove (tctx->device);
|
||||||
|
|
||||||
|
/* The removed property has changed, but the cb has *not* been called yet. */
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||||
|
g_assert_true (removed);
|
||||||
|
g_assert_null (tctx->user_data);
|
||||||
|
|
||||||
|
/* Running the mainloop now will cause the operation to fail eventually. */
|
||||||
|
while (!enroll_error)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
|
/* The virtual image device throws an PROTO error internally,
|
||||||
|
* but we should still receive a REMOVED error here. */
|
||||||
|
g_assert_error (enroll_error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* Now we close the device, state remains unchanged mostly. */
|
||||||
|
fp_device_close_sync (tctx->device, NULL, &error);
|
||||||
|
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||||
|
g_assert_nonnull (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||||
|
|
||||||
|
/* And "device-removed" is called */
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_null (tctx->device);
|
||||||
|
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||||
|
|
||||||
|
fpt_teardown_virtual_device_environment ();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -101,6 +392,11 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/context/no-devices", test_context_has_no_devices);
|
g_test_add_func ("/context/no-devices", test_context_has_no_devices);
|
||||||
g_test_add_func ("/context/has-virtual-device", test_context_has_virtual_device);
|
g_test_add_func ("/context/has-virtual-device", test_context_has_virtual_device);
|
||||||
g_test_add_func ("/context/enumerates-new-devices", test_context_enumerates_new_devices);
|
g_test_add_func ("/context/enumerates-new-devices", test_context_enumerates_new_devices);
|
||||||
|
g_test_add_func ("/context/remove-device-closed", test_context_remove_device_closed);
|
||||||
|
g_test_add_func ("/context/remove-device-closing", test_context_remove_device_closing);
|
||||||
|
g_test_add_func ("/context/remove-device-open", test_context_remove_device_open);
|
||||||
|
g_test_add_func ("/context/remove-device-opening", test_context_remove_device_opening);
|
||||||
|
g_test_add_func ("/context/remove-device-active", test_context_remove_device_active);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-14
@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
|||||||
static void
|
static void
|
||||||
test_device_open_async (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);
|
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
|
static void
|
||||||
test_device_close_async (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);
|
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||||
while (!tctx->user_data)
|
while (!tctx->user_data)
|
||||||
@@ -76,7 +76,7 @@ static void
|
|||||||
test_device_open_sync (void)
|
test_device_open_sync (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
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);
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@@ -97,7 +97,7 @@ static void
|
|||||||
test_device_open_sync_notify (void)
|
test_device_open_sync_notify (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
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);
|
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
||||||
fp_device_open_sync (tctx->device, NULL, &error);
|
fp_device_open_sync (tctx->device, NULL, &error);
|
||||||
@@ -109,7 +109,7 @@ static void
|
|||||||
test_device_close_sync (void)
|
test_device_close_sync (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
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_open_sync (tctx->device, NULL, NULL);
|
||||||
fp_device_close_sync (tctx->device, NULL, &error);
|
fp_device_close_sync (tctx->device, NULL, &error);
|
||||||
@@ -131,7 +131,7 @@ static void
|
|||||||
test_device_close_sync_notify (void)
|
test_device_close_sync_notify (void)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
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_open_sync (tctx->device, NULL, NULL);
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_driver (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
||||||
@@ -153,7 +153,7 @@ test_device_get_driver (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_device_id (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
||||||
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_name (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
||||||
@@ -172,16 +172,25 @@ test_device_get_name (void)
|
|||||||
static void
|
static void
|
||||||
test_device_get_scan_type (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_device_get_finger_status (void)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_device_get_nr_enroll_stages (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
||||||
@@ -190,7 +199,7 @@ test_device_get_nr_enroll_stages (void)
|
|||||||
static void
|
static void
|
||||||
test_device_supports_identify (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_true (fp_device_supports_identify (tctx->device));
|
g_assert_true (fp_device_supports_identify (tctx->device));
|
||||||
@@ -199,7 +208,7 @@ test_device_supports_identify (void)
|
|||||||
static void
|
static void
|
||||||
test_device_supports_capture (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_true (fp_device_supports_capture (tctx->device));
|
g_assert_true (fp_device_supports_capture (tctx->device));
|
||||||
@@ -208,7 +217,7 @@ test_device_supports_capture (void)
|
|||||||
static void
|
static void
|
||||||
test_device_has_storage (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);
|
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||||
g_assert_false (fp_device_has_storage (tctx->device));
|
g_assert_false (fp_device_has_storage (tctx->device));
|
||||||
@@ -229,6 +238,7 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/device/sync/get_device_id", test_device_get_device_id);
|
g_test_add_func ("/device/sync/get_device_id", test_device_get_device_id);
|
||||||
g_test_add_func ("/device/sync/get_name", test_device_get_name);
|
g_test_add_func ("/device/sync/get_name", test_device_get_name);
|
||||||
g_test_add_func ("/device/sync/get_scan_type", test_device_get_scan_type);
|
g_test_add_func ("/device/sync/get_scan_type", test_device_get_scan_type);
|
||||||
|
g_test_add_func ("/device/sync/get_finger_status", test_device_get_finger_status);
|
||||||
g_test_add_func ("/device/sync/get_nr_enroll_stages", test_device_get_nr_enroll_stages);
|
g_test_add_func ("/device/sync/get_nr_enroll_stages", test_device_get_nr_enroll_stages);
|
||||||
g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify);
|
g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify);
|
||||||
g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture);
|
g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture);
|
||||||
|
|||||||
+588
-135
File diff suppressed because it is too large
Load Diff
Executable
+24
@@ -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"
|
||||||
+31
-9
@@ -22,16 +22,31 @@
|
|||||||
|
|
||||||
#include "test-utils.h"
|
#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
|
void
|
||||||
fpt_teardown_virtual_device_environment (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)
|
if (path)
|
||||||
{
|
{
|
||||||
g_autofree char *temp_dir = g_path_get_dirname (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_unlink (path);
|
||||||
g_rmdir (temp_dir);
|
g_rmdir (temp_dir);
|
||||||
}
|
}
|
||||||
@@ -44,19 +59,23 @@ on_signal_event (int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fpt_setup_virtual_device_environment (void)
|
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autofree char *temp_dir = NULL;
|
g_autofree char *temp_dir = NULL;
|
||||||
g_autofree char *temp_path = 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);
|
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
|
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id);
|
||||||
g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
|
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 (SIGKILL, on_signal_event);
|
||||||
signal (SIGABRT, on_signal_event);
|
signal (SIGABRT, on_signal_event);
|
||||||
@@ -78,13 +97,16 @@ fpt_context_new (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FptContext *
|
FptContext *
|
||||||
fpt_context_new_with_virtual_imgdev (void)
|
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||||
{
|
{
|
||||||
FptContext *tctx;
|
FptContext *tctx;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
unsigned int i;
|
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 ();
|
tctx = fpt_context_new ();
|
||||||
devices = fp_context_get_devices (tctx->fp_context);
|
devices = fp_context_get_devices (tctx->fp_context);
|
||||||
@@ -96,7 +118,7 @@ fpt_context_new_with_virtual_imgdev (void)
|
|||||||
{
|
{
|
||||||
FpDevice *device = devices->pdata[i];
|
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;
|
tctx->device = device;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+9
-2
@@ -19,7 +19,14 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#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);
|
void fpt_teardown_virtual_device_environment (void);
|
||||||
|
|
||||||
typedef struct _FptContext
|
typedef struct _FptContext
|
||||||
@@ -30,7 +37,7 @@ typedef struct _FptContext
|
|||||||
} FptContext;
|
} FptContext;
|
||||||
|
|
||||||
FptContext * fpt_context_new (void);
|
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);
|
void fpt_context_free (FptContext *test_context);
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ try:
|
|||||||
if os.path.exists(os.path.join(ddir, "custom.ioctl")):
|
if os.path.exists(os.path.join(ddir, "custom.ioctl")):
|
||||||
custom()
|
custom()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Store created output files for inspection (in the build directory)
|
||||||
|
outdir = os.path.join('errors', os.path.basename(ddir))
|
||||||
|
shutil.copytree(tmpdir, outdir, dirs_exist_ok=True)
|
||||||
|
raise e
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0060
|
A: bcdDevice=0060
|
||||||
A: bmAttributes=a0
|
A: bmAttributes=a0
|
||||||
A: busnum=1
|
A: busnum=1\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
H: descriptors=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||||
A: dev=189:3
|
A: dev=189:3
|
||||||
A: devnum=4
|
A: devnum=4\n
|
||||||
A: devpath=9
|
A: devpath=9
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0050
|
A: idProduct=0050
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,307 @@
|
|||||||
|
P: /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3
|
||||||
|
N: bus/usb/002/005=12011001FF10FF088A130500900C0000000109022700010100A0320904000003FF000000070501024000000705810240000007058202400000
|
||||||
|
E: DEVNAME=/dev/bus/usb/002/005
|
||||||
|
E: DEVTYPE=usb_device
|
||||||
|
E: DRIVER=usb
|
||||||
|
E: PRODUCT=138a/5/c90
|
||||||
|
E: TYPE=255/16/255
|
||||||
|
E: BUSNUM=002
|
||||||
|
E: DEVNUM=005
|
||||||
|
E: MAJOR=189
|
||||||
|
E: MINOR=132
|
||||||
|
E: SUBSYSTEM=usb
|
||||||
|
E: ID_VENDOR=138a
|
||||||
|
E: ID_VENDOR_ENC=138a
|
||||||
|
E: ID_VENDOR_ID=138a
|
||||||
|
E: ID_MODEL=0005
|
||||||
|
E: ID_MODEL_ENC=0005
|
||||||
|
E: ID_MODEL_ID=0005
|
||||||
|
E: ID_REVISION=0c90
|
||||||
|
E: ID_SERIAL=138a_0005
|
||||||
|
E: ID_BUS=usb
|
||||||
|
E: ID_USB_INTERFACES=:ff0000:
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc.
|
||||||
|
E: ID_MODEL_FROM_DATABASE=VFS301 Fingerprint Reader
|
||||||
|
E: ID_PATH=pci-0000:00:1d.0-usb-0:1.3
|
||||||
|
E: ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3
|
||||||
|
E: LIBFPRINT_DRIVER=Validity VFS301
|
||||||
|
A: authorized=1
|
||||||
|
A: avoid_reset_quirk=0
|
||||||
|
A: bConfigurationValue=1
|
||||||
|
A: bDeviceClass=ff
|
||||||
|
A: bDeviceProtocol=ff
|
||||||
|
A: bDeviceSubClass=10
|
||||||
|
A: bMaxPacketSize0=8
|
||||||
|
A: bMaxPower=100mA
|
||||||
|
A: bNumConfigurations=1
|
||||||
|
A: bNumInterfaces= 1
|
||||||
|
A: bcdDevice=0c90
|
||||||
|
A: bmAttributes=a0
|
||||||
|
A: busnum=2\n
|
||||||
|
A: configuration=
|
||||||
|
H: descriptors=12011001FF10FF088A130500900C0000000109022700010100A0320904000003FF000000070501024000000705810240000007058202400000
|
||||||
|
A: dev=189:132
|
||||||
|
A: devnum=5\n
|
||||||
|
A: devpath=1.3
|
||||||
|
L: driver=../../../../../../bus/usb/drivers/usb
|
||||||
|
A: idProduct=0005
|
||||||
|
A: idVendor=138a
|
||||||
|
A: ltm_capable=no
|
||||||
|
A: maxchild=0
|
||||||
|
L: port=../2-1:1.0/2-1-port3
|
||||||
|
A: power/active_duration=1612976
|
||||||
|
A: power/async=enabled
|
||||||
|
A: power/autosuspend=2
|
||||||
|
A: power/autosuspend_delay_ms=2000
|
||||||
|
A: power/connected_duration=2159928
|
||||||
|
A: power/control=auto
|
||||||
|
A: power/level=auto
|
||||||
|
A: power/persist=1
|
||||||
|
A: power/runtime_active_kids=0
|
||||||
|
A: power/runtime_active_time=1612851
|
||||||
|
A: power/runtime_enabled=enabled
|
||||||
|
A: power/runtime_status=active
|
||||||
|
A: power/runtime_suspended_time=546887
|
||||||
|
A: power/runtime_usage=0
|
||||||
|
A: power/wakeup=disabled
|
||||||
|
A: power/wakeup_abort_count=
|
||||||
|
A: power/wakeup_active=
|
||||||
|
A: power/wakeup_active_count=
|
||||||
|
A: power/wakeup_count=
|
||||||
|
A: power/wakeup_expire_count=
|
||||||
|
A: power/wakeup_last_time_ms=
|
||||||
|
A: power/wakeup_max_time_ms=
|
||||||
|
A: power/wakeup_total_time_ms=
|
||||||
|
A: quirks=0x0
|
||||||
|
A: removable=fixed
|
||||||
|
A: rx_lanes=1
|
||||||
|
A: speed=12
|
||||||
|
A: tx_lanes=1
|
||||||
|
A: urbnum=7
|
||||||
|
A: version= 1.10
|
||||||
|
|
||||||
|
P: /devices/pci0000:00/0000:00:1d.0/usb2/2-1
|
||||||
|
N: bus/usb/002/002=12010002090001408780200000000000000109021900010100E0000904000001090000000705810302000C
|
||||||
|
E: DEVNAME=/dev/bus/usb/002/002
|
||||||
|
E: DEVTYPE=usb_device
|
||||||
|
E: DRIVER=usb
|
||||||
|
E: PRODUCT=8087/20/0
|
||||||
|
E: TYPE=9/0/1
|
||||||
|
E: BUSNUM=002
|
||||||
|
E: DEVNUM=002
|
||||||
|
E: MAJOR=189
|
||||||
|
E: MINOR=129
|
||||||
|
E: SUBSYSTEM=usb
|
||||||
|
E: ID_VENDOR=8087
|
||||||
|
E: ID_VENDOR_ENC=8087
|
||||||
|
E: ID_VENDOR_ID=8087
|
||||||
|
E: ID_MODEL=0020
|
||||||
|
E: ID_MODEL_ENC=0020
|
||||||
|
E: ID_MODEL_ID=0020
|
||||||
|
E: ID_REVISION=0000
|
||||||
|
E: ID_SERIAL=8087_0020
|
||||||
|
E: ID_BUS=usb
|
||||||
|
E: ID_USB_INTERFACES=:090000:
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Intel Corp.
|
||||||
|
E: ID_MODEL_FROM_DATABASE=Integrated Rate Matching Hub
|
||||||
|
E: ID_PATH=pci-0000:00:1d.0-usb-0:1
|
||||||
|
E: ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1
|
||||||
|
E: ID_FOR_SEAT=usb-pci-0000_00_1d_0-usb-0_1
|
||||||
|
E: TAGS=:seat:
|
||||||
|
A: authorized=1
|
||||||
|
A: avoid_reset_quirk=0
|
||||||
|
A: bConfigurationValue=1
|
||||||
|
A: bDeviceClass=09
|
||||||
|
A: bDeviceProtocol=01
|
||||||
|
A: bDeviceSubClass=00
|
||||||
|
A: bMaxPacketSize0=64
|
||||||
|
A: bMaxPower=0mA
|
||||||
|
A: bNumConfigurations=1
|
||||||
|
A: bNumInterfaces= 1
|
||||||
|
A: bcdDevice=0000
|
||||||
|
A: bmAttributes=e0
|
||||||
|
A: busnum=2\n
|
||||||
|
A: configuration=
|
||||||
|
H: descriptors=12010002090001408780200000000000000109021900010100E0000904000001090000000705810302000C
|
||||||
|
A: dev=189:129
|
||||||
|
A: devnum=2\n
|
||||||
|
A: devpath=1
|
||||||
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
|
A: idProduct=0020
|
||||||
|
A: idVendor=8087
|
||||||
|
A: ltm_capable=no
|
||||||
|
A: maxchild=8
|
||||||
|
L: port=../2-0:1.0/usb2-port1
|
||||||
|
A: power/active_duration=2160820
|
||||||
|
A: power/async=enabled
|
||||||
|
A: power/autosuspend=0
|
||||||
|
A: power/autosuspend_delay_ms=0
|
||||||
|
A: power/connected_duration=2160824
|
||||||
|
A: power/control=auto
|
||||||
|
A: power/level=auto
|
||||||
|
A: power/runtime_active_kids=3
|
||||||
|
A: power/runtime_active_time=2160531
|
||||||
|
A: power/runtime_enabled=enabled
|
||||||
|
A: power/runtime_status=active
|
||||||
|
A: power/runtime_suspended_time=0
|
||||||
|
A: power/runtime_usage=0
|
||||||
|
A: power/wakeup=disabled
|
||||||
|
A: power/wakeup_abort_count=
|
||||||
|
A: power/wakeup_active=
|
||||||
|
A: power/wakeup_active_count=
|
||||||
|
A: power/wakeup_count=
|
||||||
|
A: power/wakeup_expire_count=
|
||||||
|
A: power/wakeup_last_time_ms=
|
||||||
|
A: power/wakeup_max_time_ms=
|
||||||
|
A: power/wakeup_total_time_ms=
|
||||||
|
A: quirks=0x0
|
||||||
|
A: removable=fixed
|
||||||
|
A: rx_lanes=1
|
||||||
|
A: speed=480
|
||||||
|
A: tx_lanes=1
|
||||||
|
A: urbnum=75
|
||||||
|
A: version= 2.00
|
||||||
|
|
||||||
|
P: /devices/pci0000:00/0000:00:1d.0/usb2
|
||||||
|
N: bus/usb/002/001=12010002090000406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
||||||
|
E: DEVNAME=/dev/bus/usb/002/001
|
||||||
|
E: DEVTYPE=usb_device
|
||||||
|
E: DRIVER=usb
|
||||||
|
E: PRODUCT=1d6b/2/504
|
||||||
|
E: TYPE=9/0/0
|
||||||
|
E: BUSNUM=002
|
||||||
|
E: DEVNUM=001
|
||||||
|
E: MAJOR=189
|
||||||
|
E: MINOR=128
|
||||||
|
E: SUBSYSTEM=usb
|
||||||
|
E: ID_VENDOR=Linux_5.4.0-48-generic_ehci_hcd
|
||||||
|
E: ID_VENDOR_ENC=Linux\x205.4.0-48-generic\x20ehci_hcd
|
||||||
|
E: ID_VENDOR_ID=1d6b
|
||||||
|
E: ID_MODEL=EHCI_Host_Controller
|
||||||
|
E: ID_MODEL_ENC=EHCI\x20Host\x20Controller
|
||||||
|
E: ID_MODEL_ID=0002
|
||||||
|
E: ID_REVISION=0504
|
||||||
|
E: ID_SERIAL=Linux_5.4.0-48-generic_ehci_hcd_EHCI_Host_Controller_0000:00:1d.0
|
||||||
|
E: ID_SERIAL_SHORT=0000:00:1d.0
|
||||||
|
E: ID_BUS=usb
|
||||||
|
E: ID_USB_INTERFACES=:090000:
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||||
|
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||||
|
E: ID_PATH=pci-0000:00:1d.0
|
||||||
|
E: ID_PATH_TAG=pci-0000_00_1d_0
|
||||||
|
E: ID_FOR_SEAT=usb-pci-0000_00_1d_0
|
||||||
|
E: TAGS=:seat:
|
||||||
|
A: authorized=1
|
||||||
|
A: authorized_default=1
|
||||||
|
A: avoid_reset_quirk=0
|
||||||
|
A: bConfigurationValue=1
|
||||||
|
A: bDeviceClass=09
|
||||||
|
A: bDeviceProtocol=00
|
||||||
|
A: bDeviceSubClass=00
|
||||||
|
A: bMaxPacketSize0=64
|
||||||
|
A: bMaxPower=0mA
|
||||||
|
A: bNumConfigurations=1
|
||||||
|
A: bNumInterfaces= 1
|
||||||
|
A: bcdDevice=0504
|
||||||
|
A: bmAttributes=e0
|
||||||
|
A: busnum=2\n
|
||||||
|
A: configuration=
|
||||||
|
H: descriptors=12010002090000406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
||||||
|
A: dev=189:128
|
||||||
|
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-48-generic ehci_hcd
|
||||||
|
A: maxchild=3
|
||||||
|
A: power/active_duration=2161060
|
||||||
|
A: power/async=enabled
|
||||||
|
A: power/autosuspend=0
|
||||||
|
A: power/autosuspend_delay_ms=0
|
||||||
|
A: power/connected_duration=2161060
|
||||||
|
A: power/control=auto
|
||||||
|
A: power/level=auto
|
||||||
|
A: power/runtime_active_kids=1
|
||||||
|
A: power/runtime_active_time=2161035
|
||||||
|
A: power/runtime_enabled=enabled
|
||||||
|
A: power/runtime_status=active
|
||||||
|
A: power/runtime_suspended_time=0
|
||||||
|
A: power/runtime_usage=0
|
||||||
|
A: power/wakeup=disabled
|
||||||
|
A: power/wakeup_abort_count=
|
||||||
|
A: power/wakeup_active=
|
||||||
|
A: power/wakeup_active_count=
|
||||||
|
A: power/wakeup_count=
|
||||||
|
A: power/wakeup_expire_count=
|
||||||
|
A: power/wakeup_last_time_ms=
|
||||||
|
A: power/wakeup_max_time_ms=
|
||||||
|
A: power/wakeup_total_time_ms=
|
||||||
|
A: product=EHCI Host Controller
|
||||||
|
A: quirks=0x0
|
||||||
|
A: removable=unknown
|
||||||
|
A: rx_lanes=1
|
||||||
|
A: serial=0000:00:1d.0
|
||||||
|
A: speed=480
|
||||||
|
A: tx_lanes=1
|
||||||
|
A: urbnum=26
|
||||||
|
A: version= 2.00
|
||||||
|
|
||||||
|
P: /devices/pci0000:00/0000:00:1d.0
|
||||||
|
E: DRIVER=ehci-pci
|
||||||
|
E: PCI_CLASS=C0320
|
||||||
|
E: PCI_ID=8086:3B34
|
||||||
|
E: PCI_SUBSYS_ID=103C:7001
|
||||||
|
E: PCI_SLOT_NAME=0000:00:1d.0
|
||||||
|
E: MODALIAS=pci:v00008086d00003B34sv0000103Csd00007001bc0Csc03i20
|
||||||
|
E: SUBSYSTEM=pci
|
||||||
|
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||||
|
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||||
|
E: ID_PCI_INTERFACE_FROM_DATABASE=EHCI
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||||
|
E: ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
|
||||||
|
A: ari_enabled=0
|
||||||
|
A: broken_parity_status=0
|
||||||
|
A: class=0x0c0320
|
||||||
|
A: companion=
|
||||||
|
H: config=8680343B060090020520030C00000000005810DB0000000000000000000000000000000000000000000000003C1001700000000050000000000000000B010000
|
||||||
|
A: consistent_dma_mask_bits=32
|
||||||
|
A: d3cold_allowed=1
|
||||||
|
A: device=0x3b34
|
||||||
|
A: dma_mask_bits=32
|
||||||
|
L: driver=../../../bus/pci/drivers/ehci-pci
|
||||||
|
A: driver_override=(null)
|
||||||
|
A: enable=1
|
||||||
|
A: irq=21
|
||||||
|
A: local_cpulist=0-7
|
||||||
|
A: local_cpus=ff
|
||||||
|
A: modalias=pci:v00008086d00003B34sv0000103Csd00007001bc0Csc03i20
|
||||||
|
A: msi_bus=1
|
||||||
|
A: numa_node=-1
|
||||||
|
A: pools=poolinfo - 0.1\nehci_sitd 0 0 96 0\nehci_itd 0 0 192 0\nehci_qh 12 42 96 1\nehci_qtd 13 84 96 2\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 2 32 128 1\nbuffer-32 0 0 32 0
|
||||||
|
A: power/async=enabled
|
||||||
|
A: power/control=on
|
||||||
|
A: power/runtime_active_kids=1
|
||||||
|
A: power/runtime_active_time=2161633
|
||||||
|
A: power/runtime_enabled=forbidden
|
||||||
|
A: power/runtime_status=active
|
||||||
|
A: power/runtime_suspended_time=0
|
||||||
|
A: power/runtime_usage=1
|
||||||
|
A: power/wakeup=enabled
|
||||||
|
A: power/wakeup_abort_count=0
|
||||||
|
A: power/wakeup_active=0
|
||||||
|
A: power/wakeup_active_count=0
|
||||||
|
A: power/wakeup_count=0
|
||||||
|
A: power/wakeup_expire_count=0
|
||||||
|
A: power/wakeup_last_time_ms=0
|
||||||
|
A: power/wakeup_max_time_ms=0
|
||||||
|
A: power/wakeup_total_time_ms=0
|
||||||
|
A: resource=0x00000000db105800 0x00000000db105bff 0x0000000000040200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
|
||||||
|
A: revision=0x05
|
||||||
|
A: subsystem_device=0x7001
|
||||||
|
A: subsystem_vendor=0x103c
|
||||||
|
A: uframe_periodic_max=100
|
||||||
|
A: vendor=0x8086
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ A: bNumConfigurations=1
|
|||||||
A: bNumInterfaces= 1
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0078
|
A: bcdDevice=0078
|
||||||
A: bmAttributes=a0
|
A: bmAttributes=a0
|
||||||
A: busnum=2
|
A: busnum=2\n
|
||||||
A: configuration=
|
A: configuration=
|
||||||
H: descriptors=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
H: descriptors=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||||
A: dev=189:144
|
A: dev=189:144
|
||||||
A: devnum=17
|
A: devnum=17\n
|
||||||
A: devpath=6
|
A: devpath=6
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0017
|
A: idProduct=0017
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,222 @@
|
|||||||
|
P: /devices/pci0000:00/0000:00:14.0/usb1/1-7
|
||||||
|
N: bus/usb/001/003=12010002FF10FF088A13910064010000010109023500010100A0320904000005FF000000070501024000000705810240000007058202400000070583030800040705840310000A
|
||||||
|
E: DEVNAME=/dev/bus/usb/001/003
|
||||||
|
E: DEVTYPE=usb_device
|
||||||
|
E: DRIVER=usb
|
||||||
|
E: PRODUCT=138a/91/164
|
||||||
|
E: TYPE=255/16/255
|
||||||
|
E: BUSNUM=001
|
||||||
|
E: DEVNUM=003
|
||||||
|
E: MAJOR=189
|
||||||
|
E: MINOR=2
|
||||||
|
E: SUBSYSTEM=usb
|
||||||
|
E: ID_VENDOR=138a
|
||||||
|
E: ID_VENDOR_ENC=138a
|
||||||
|
E: ID_VENDOR_ID=138a
|
||||||
|
E: ID_MODEL=0091
|
||||||
|
E: ID_MODEL_ENC=0091
|
||||||
|
E: ID_MODEL_ID=0091
|
||||||
|
E: ID_REVISION=0164
|
||||||
|
E: ID_SERIAL=138a_0091_ba1ea8009583
|
||||||
|
E: ID_SERIAL_SHORT=ba1ea8009583
|
||||||
|
E: ID_BUS=usb
|
||||||
|
E: ID_USB_INTERFACES=:ff0000:
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc.
|
||||||
|
E: ID_AUTOSUSPEND=1
|
||||||
|
E: ID_MODEL_FROM_DATABASE=VFS7552 Touch Fingerprint Sensor
|
||||||
|
E: ID_PATH=pci-0000:00:14.0-usb-0:7
|
||||||
|
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_7
|
||||||
|
A: authorized=1\n
|
||||||
|
A: avoid_reset_quirk=0\n
|
||||||
|
A: bConfigurationValue=1\n
|
||||||
|
A: bDeviceClass=ff\n
|
||||||
|
A: bDeviceProtocol=ff\n
|
||||||
|
A: bDeviceSubClass=10\n
|
||||||
|
A: bMaxPacketSize0=8\n
|
||||||
|
A: bMaxPower=100mA\n
|
||||||
|
A: bNumConfigurations=1\n
|
||||||
|
A: bNumInterfaces= 1\n
|
||||||
|
A: bcdDevice=0164\n
|
||||||
|
A: bmAttributes=a0\n
|
||||||
|
A: busnum=1\n
|
||||||
|
A: configuration=
|
||||||
|
H: descriptors=12010002FF10FF088A13910064010000010109023500010100A0320904000005FF000000070501024000000705810240000007058202400000070583030800040705840310000A
|
||||||
|
A: dev=189:2\n
|
||||||
|
A: devnum=3\n
|
||||||
|
A: devpath=7\n
|
||||||
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
|
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4c/device:4d/device:54
|
||||||
|
A: idProduct=0091\n
|
||||||
|
A: idVendor=138a\n
|
||||||
|
A: ltm_capable=no\n
|
||||||
|
A: maxchild=0\n
|
||||||
|
L: port=../1-0:1.0/usb1-port7
|
||||||
|
A: power/active_duration=385364\n
|
||||||
|
A: power/autosuspend=2\n
|
||||||
|
A: power/autosuspend_delay_ms=2000\n
|
||||||
|
A: power/connected_duration=34389164\n
|
||||||
|
A: power/control=auto\n
|
||||||
|
A: power/level=auto\n
|
||||||
|
A: power/persist=1\n
|
||||||
|
A: power/runtime_active_time=392057\n
|
||||||
|
A: power/runtime_status=active\n
|
||||||
|
A: power/runtime_suspended_time=33996840\n
|
||||||
|
A: power/wakeup=disabled\n
|
||||||
|
A: power/wakeup_abort_count=\n
|
||||||
|
A: power/wakeup_active=\n
|
||||||
|
A: power/wakeup_active_count=\n
|
||||||
|
A: power/wakeup_count=\n
|
||||||
|
A: power/wakeup_expire_count=\n
|
||||||
|
A: power/wakeup_last_time_ms=\n
|
||||||
|
A: power/wakeup_max_time_ms=\n
|
||||||
|
A: power/wakeup_total_time_ms=\n
|
||||||
|
A: quirks=0x0\n
|
||||||
|
A: removable=fixed\n
|
||||||
|
A: rx_lanes=1\n
|
||||||
|
A: serial=ba1ea8009583\n
|
||||||
|
A: speed=12\n
|
||||||
|
A: tx_lanes=1\n
|
||||||
|
A: urbnum=356510\n
|
||||||
|
A: version= 2.00\n
|
||||||
|
|
||||||
|
P: /devices/pci0000:00/0000:00:14.0/usb1
|
||||||
|
N: bus/usb/001/001=12010002090001406B1D020011050302010109021900010100E0000904000001090000000705810304000C
|
||||||
|
E: DEVNAME=/dev/bus/usb/001/001
|
||||||
|
E: DEVTYPE=usb_device
|
||||||
|
E: DRIVER=usb
|
||||||
|
E: PRODUCT=1d6b/2/511
|
||||||
|
E: TYPE=9/0/1
|
||||||
|
E: BUSNUM=001
|
||||||
|
E: DEVNUM=001
|
||||||
|
E: MAJOR=189
|
||||||
|
E: MINOR=0
|
||||||
|
E: SUBSYSTEM=usb
|
||||||
|
E: ID_VENDOR=Linux_5.11.2-arch1-1_xhci-hcd
|
||||||
|
E: ID_VENDOR_ENC=Linux\x205.11.2-arch1-1\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=0511
|
||||||
|
E: ID_SERIAL=Linux_5.11.2-arch1-1_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
|
||||||
|
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
||||||
|
E: TAGS=:seat:
|
||||||
|
E: CURRENT_TAGS=:seat:
|
||||||
|
A: authorized=1\n
|
||||||
|
A: authorized_default=1\n
|
||||||
|
A: avoid_reset_quirk=0\n
|
||||||
|
A: bConfigurationValue=1\n
|
||||||
|
A: bDeviceClass=09\n
|
||||||
|
A: bDeviceProtocol=01\n
|
||||||
|
A: bDeviceSubClass=00\n
|
||||||
|
A: bMaxPacketSize0=64\n
|
||||||
|
A: bMaxPower=0mA\n
|
||||||
|
A: bNumConfigurations=1\n
|
||||||
|
A: bNumInterfaces= 1\n
|
||||||
|
A: bcdDevice=0511\n
|
||||||
|
A: bmAttributes=e0\n
|
||||||
|
A: busnum=1\n
|
||||||
|
A: configuration=
|
||||||
|
H: descriptors=12010002090001406B1D020011050302010109021900010100E0000904000001090000000705810304000C
|
||||||
|
A: dev=189:0\n
|
||||||
|
A: devnum=1\n
|
||||||
|
A: devpath=0\n
|
||||||
|
L: driver=../../../../bus/usb/drivers/usb
|
||||||
|
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4c/device:4d
|
||||||
|
A: idProduct=0002\n
|
||||||
|
A: idVendor=1d6b\n
|
||||||
|
A: interface_authorized_default=1\n
|
||||||
|
A: ltm_capable=no\n
|
||||||
|
A: manufacturer=Linux 5.11.2-arch1-1 xhci-hcd\n
|
||||||
|
A: maxchild=16\n
|
||||||
|
A: power/active_duration=3289930\n
|
||||||
|
A: power/autosuspend=0\n
|
||||||
|
A: power/autosuspend_delay_ms=0\n
|
||||||
|
A: power/connected_duration=34389654\n
|
||||||
|
A: power/control=auto\n
|
||||||
|
A: power/level=auto\n
|
||||||
|
A: power/runtime_active_time=3289845\n
|
||||||
|
A: power/runtime_status=active\n
|
||||||
|
A: power/runtime_suspended_time=31099805\n
|
||||||
|
A: power/wakeup=disabled\n
|
||||||
|
A: power/wakeup_abort_count=\n
|
||||||
|
A: power/wakeup_active=\n
|
||||||
|
A: power/wakeup_active_count=\n
|
||||||
|
A: power/wakeup_count=\n
|
||||||
|
A: power/wakeup_expire_count=\n
|
||||||
|
A: power/wakeup_last_time_ms=\n
|
||||||
|
A: power/wakeup_max_time_ms=\n
|
||||||
|
A: power/wakeup_total_time_ms=\n
|
||||||
|
A: product=xHCI Host Controller\n
|
||||||
|
A: quirks=0x0\n
|
||||||
|
A: removable=unknown\n
|
||||||
|
A: rx_lanes=1\n
|
||||||
|
A: serial=0000:00:14.0\n
|
||||||
|
A: speed=480\n
|
||||||
|
A: tx_lanes=1\n
|
||||||
|
A: urbnum=2355\n
|
||||||
|
A: version= 2.00\n
|
||||||
|
|
||||||
|
P: /devices/pci0000:00/0000:00:14.0
|
||||||
|
E: DRIVER=xhci_hcd
|
||||||
|
E: PCI_CLASS=C0330
|
||||||
|
E: PCI_ID=8086:A12F
|
||||||
|
E: PCI_SUBSYS_ID=1028:07BE
|
||||||
|
E: PCI_SLOT_NAME=0000:00:14.0
|
||||||
|
E: MODALIAS=pci:v00008086d0000A12Fsv00001028sd000007BEbc0Csc03i30
|
||||||
|
E: SUBSYSTEM=pci
|
||||||
|
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||||
|
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||||
|
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||||
|
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||||
|
E: ID_MODEL_FROM_DATABASE=100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller
|
||||||
|
A: ari_enabled=0\n
|
||||||
|
A: broken_parity_status=0\n
|
||||||
|
A: class=0x0c0330\n
|
||||||
|
H: config=86802FA1060490023130030C000080000400D1ED0000000000000000000000000000000000000000000000002810BE07000000007000000000000000FF010000
|
||||||
|
A: consistent_dma_mask_bits=64\n
|
||||||
|
A: d3cold_allowed=1\n
|
||||||
|
A: device=0xa12f\n
|
||||||
|
A: dma_mask_bits=64\n
|
||||||
|
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||||
|
A: driver_override=(null)\n
|
||||||
|
A: enable=1\n
|
||||||
|
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4c
|
||||||
|
L: iommu=../../virtual/iommu/dmar1
|
||||||
|
L: iommu_group=../../../kernel/iommu_groups/4
|
||||||
|
A: irq=143\n
|
||||||
|
A: local_cpulist=0-7\n
|
||||||
|
A: local_cpus=ff\n
|
||||||
|
A: modalias=pci:v00008086d0000A12Fsv00001028sd000007BEbc0Csc03i30\n
|
||||||
|
A: msi_bus=1\n
|
||||||
|
A: msi_irqs/143=msi\n
|
||||||
|
A: numa_node=-1\n
|
||||||
|
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 7 10 2112 10\nxHCI ring segments 30 38 4096 38\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
|
||||||
|
A: power/control=on\n
|
||||||
|
A: power/runtime_active_time=34390988\n
|
||||||
|
A: power/runtime_status=active\n
|
||||||
|
A: power/runtime_suspended_time=0\n
|
||||||
|
A: power/wakeup=enabled\n
|
||||||
|
A: power/wakeup_abort_count=0\n
|
||||||
|
A: power/wakeup_active=0\n
|
||||||
|
A: power/wakeup_active_count=0\n
|
||||||
|
A: power/wakeup_count=0\n
|
||||||
|
A: power/wakeup_expire_count=0\n
|
||||||
|
A: power/wakeup_last_time_ms=0\n
|
||||||
|
A: power/wakeup_max_time_ms=0\n
|
||||||
|
A: power/wakeup_total_time_ms=0\n
|
||||||
|
A: power_state=D0\n
|
||||||
|
A: resource=0x00000000edd10000 0x00000000edd1ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
|
||||||
|
A: revision=0x31\n
|
||||||
|
A: subsystem_device=0x07be\n
|
||||||
|
A: subsystem_vendor=0x1028\n
|
||||||
|
A: vendor=0x8086\n
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user