mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
119 Commits
v1.90.6
...
benzea/add
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f13ddc40d | ||
|
|
e0f081c6e3 | ||
|
|
ae1fb4094b | ||
|
|
13350e05a2 | ||
|
|
3ea9cc90fe | ||
|
|
e862e8e881 | ||
|
|
60f5cd650a | ||
|
|
7ff36888b7 | ||
|
|
e3043123f5 | ||
|
|
77400b7a60 | ||
|
|
8d83e5eb38 | ||
|
|
e59d5451cc | ||
|
|
798bc4ee1e | ||
|
|
0e732dbafa | ||
|
|
84112abc71 | ||
|
|
c221c6b63e | ||
|
|
6e28b9a8c4 | ||
|
|
e5589a0ec2 | ||
|
|
966703057d | ||
|
|
9e164485f0 | ||
|
|
3bb38e2ff6 | ||
|
|
6a62d32c81 | ||
|
|
b2a64cc980 | ||
|
|
88117c172e | ||
|
|
27a62443a1 | ||
|
|
2f7c78eb97 | ||
|
|
74f8a8ee27 | ||
|
|
acd0a10e76 | ||
|
|
27c2466bda | ||
|
|
33ba248c44 | ||
|
|
43cf28b9da | ||
|
|
4da52f78f6 | ||
|
|
e4e0937848 | ||
|
|
25a6c916aa | ||
|
|
51009b48a0 | ||
|
|
e1e3f6955e | ||
|
|
c495b82000 | ||
|
|
d90ee96df8 | ||
|
|
36304b736b | ||
|
|
31e34bd4bd | ||
|
|
ec4c7ca5a9 | ||
|
|
8d21a9c27c | ||
|
|
c4069065f9 | ||
|
|
31541edc58 | ||
|
|
549718753f | ||
|
|
cfde050220 | ||
|
|
88a38c38af | ||
|
|
7ffcc2f9e7 | ||
|
|
1dae6796f7 | ||
|
|
0bb0492025 | ||
|
|
3db0858fb0 | ||
|
|
2382506491 | ||
|
|
08f4be707c | ||
|
|
3693c39bc5 | ||
|
|
993109a7f8 | ||
|
|
18db20d160 | ||
|
|
89b4c4ee75 | ||
|
|
153b24a95a | ||
|
|
8c45c0952e | ||
|
|
c3ece8621d | ||
|
|
67cb61cc18 | ||
|
|
33ffadf402 | ||
|
|
162a83e484 | ||
|
|
dfb27222eb | ||
|
|
81e53c422d | ||
|
|
be0b4ae2bb | ||
|
|
56bcf1ffdd | ||
|
|
665de7813b | ||
|
|
a291d17f26 | ||
|
|
e8886dbc6b | ||
|
|
3d6fb15b5c | ||
|
|
43d0dfdd8f | ||
|
|
50f522583e | ||
|
|
f0443ba2f3 | ||
|
|
546f35132c | ||
|
|
ce9527d2cb | ||
|
|
89890dbd1f | ||
|
|
e0c41c5444 | ||
|
|
3b83157e9b | ||
|
|
57f836a0f6 | ||
|
|
170924ee4f | ||
|
|
63bfaf4f60 | ||
|
|
2f6adce2fa | ||
|
|
018641ad20 | ||
|
|
8ded064e65 | ||
|
|
3f7a638eed | ||
|
|
253750ec08 | ||
|
|
5df14206d8 | ||
|
|
2f2da87240 | ||
|
|
533180a2e6 | ||
|
|
99c269b3fe | ||
|
|
66fc93eeff | ||
|
|
284f6f1ef8 | ||
|
|
1f2d723485 | ||
|
|
f6179d6cc4 | ||
|
|
cbce56c142 | ||
|
|
55a2bb5536 | ||
|
|
16095a21fd | ||
|
|
80dbc9c0cb | ||
|
|
944e0d0383 | ||
|
|
349fbeb834 | ||
|
|
17a8bacfaf | ||
|
|
6d4b498dae | ||
|
|
7c2a67a954 | ||
|
|
a6c2509ca8 | ||
|
|
8254b9e99e | ||
|
|
943c64d96f | ||
|
|
f852d972a5 | ||
|
|
35d2d78e67 | ||
|
|
3d5db6a391 | ||
|
|
2ee0d16784 | ||
|
|
e6712fbcca | ||
|
|
ee928db5b2 | ||
|
|
d6ca8ff2b0 | ||
|
|
b1b20f8ab9 | ||
|
|
7e2b89791e | ||
|
|
3560a0f1e7 | ||
|
|
ed5339c4f5 | ||
|
|
2d10d864d8 |
@@ -61,7 +61,7 @@ test:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
||||
- meson --werror -Ddrivers=all -Db_coverage=true -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
|
||||
- ninja -C _build coverage
|
||||
@@ -78,7 +78,7 @@ test_valgrind:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- meson -Ddrivers=all . _build
|
||||
- meson -Ddrivers=all -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
||||
|
||||
@@ -109,6 +109,15 @@ test_indent:
|
||||
- git diff
|
||||
- "! git status -s | grep -q ."
|
||||
|
||||
test_unsupported_list:
|
||||
stage: check-source
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
allow_failure: true
|
||||
script:
|
||||
- tests/hwdb-check-unsupported.py
|
||||
|
||||
flatpak:
|
||||
stage: flatpak
|
||||
extends: .flatpak
|
||||
@@ -140,5 +149,17 @@ container_fedora_build:
|
||||
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
||||
variables:
|
||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||
# a list of packages to install
|
||||
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES
|
||||
# a list of packages to install; we only include mbedtls here
|
||||
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES mbedtls-devel
|
||||
FDO_DISTRIBUTION_EXEC: |
|
||||
cd /tmp
|
||||
mkdir -p /usr/local/bin
|
||||
git clone https://github.com/benzea/SecureDeviceConnectionProtocol.git
|
||||
# Don't bother with cmake
|
||||
gcc -l mbedcrypto -I SecureDeviceConnectionProtocol/src/include \
|
||||
SecureDeviceConnectionProtocol/src/test/virt_device.c \
|
||||
SecureDeviceConnectionProtocol/src/client/client.c \
|
||||
SecureDeviceConnectionProtocol/src/test/helpers.c \
|
||||
SecureDeviceConnectionProtocol/src/test/testkeys.c \
|
||||
-o /usr/local/bin/sdcp_virt_device
|
||||
rm -rf SecureDeviceConnectionProtocol
|
||||
|
||||
10
NEWS
10
NEWS
@@ -1,6 +1,16 @@
|
||||
This file lists notable changes in each release. For the full history of all
|
||||
changes, see ChangeLog.
|
||||
|
||||
2020-12-01: v1.90.7 release
|
||||
|
||||
Highlights:
|
||||
* vfs5011: Fix possible use-after-free
|
||||
* goodixmoc: Add two new PIDs (0x63AC, 0x639C)
|
||||
* goodixmoc: Support finger status API
|
||||
* synaptics: Only identify within provided prints
|
||||
* synaptics: Reject devices with old firmware during probe (#239)
|
||||
|
||||
|
||||
2020-12-01: v1.90.6 release
|
||||
|
||||
This release is primarily a bugfix release for some older issues.
|
||||
|
||||
264
data/autosuspend.hwdb
Normal file
264
data/autosuspend.hwdb
Normal file
@@ -0,0 +1,264 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# This file has been generated using fprint-list-udev-hwdb with all drivers enabled
|
||||
|
||||
# Supported by libfprint driver aes1610
|
||||
usb:v08FFp1600*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes1660
|
||||
usb:v08FFp1660*
|
||||
usb:v08FFp1680*
|
||||
usb:v08FFp1681*
|
||||
usb:v08FFp1682*
|
||||
usb:v08FFp1683*
|
||||
usb:v08FFp1684*
|
||||
usb:v08FFp1685*
|
||||
usb:v08FFp1686*
|
||||
usb:v08FFp1687*
|
||||
usb:v08FFp1688*
|
||||
usb:v08FFp1689*
|
||||
usb:v08FFp168A*
|
||||
usb:v08FFp168B*
|
||||
usb:v08FFp168C*
|
||||
usb:v08FFp168D*
|
||||
usb:v08FFp168E*
|
||||
usb:v08FFp168F*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes2501
|
||||
usb:v08FFp2500*
|
||||
usb:v08FFp2580*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes2550
|
||||
usb:v08FFp2550*
|
||||
usb:v08FFp2810*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes2660
|
||||
usb:v08FFp2660*
|
||||
usb:v08FFp2680*
|
||||
usb:v08FFp2681*
|
||||
usb:v08FFp2682*
|
||||
usb:v08FFp2683*
|
||||
usb:v08FFp2684*
|
||||
usb:v08FFp2685*
|
||||
usb:v08FFp2686*
|
||||
usb:v08FFp2687*
|
||||
usb:v08FFp2688*
|
||||
usb:v08FFp2689*
|
||||
usb:v08FFp268A*
|
||||
usb:v08FFp268B*
|
||||
usb:v08FFp268C*
|
||||
usb:v08FFp268D*
|
||||
usb:v08FFp268E*
|
||||
usb:v08FFp268F*
|
||||
usb:v08FFp2691*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes3500
|
||||
usb:v08FFp5731*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver aes4000
|
||||
usb:v5501p08FF*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver elan
|
||||
usb:v04F3p0903*
|
||||
usb:v04F3p0907*
|
||||
usb:v04F3p0C01*
|
||||
usb:v04F3p0C02*
|
||||
usb:v04F3p0C03*
|
||||
usb:v04F3p0C04*
|
||||
usb:v04F3p0C05*
|
||||
usb:v04F3p0C06*
|
||||
usb:v04F3p0C07*
|
||||
usb:v04F3p0C08*
|
||||
usb:v04F3p0C09*
|
||||
usb:v04F3p0C0A*
|
||||
usb:v04F3p0C0B*
|
||||
usb:v04F3p0C0C*
|
||||
usb:v04F3p0C0D*
|
||||
usb:v04F3p0C0E*
|
||||
usb:v04F3p0C0F*
|
||||
usb:v04F3p0C10*
|
||||
usb:v04F3p0C11*
|
||||
usb:v04F3p0C12*
|
||||
usb:v04F3p0C13*
|
||||
usb:v04F3p0C14*
|
||||
usb:v04F3p0C15*
|
||||
usb:v04F3p0C16*
|
||||
usb:v04F3p0C17*
|
||||
usb:v04F3p0C18*
|
||||
usb:v04F3p0C19*
|
||||
usb:v04F3p0C1A*
|
||||
usb:v04F3p0C1B*
|
||||
usb:v04F3p0C1C*
|
||||
usb:v04F3p0C1D*
|
||||
usb:v04F3p0C1E*
|
||||
usb:v04F3p0C1F*
|
||||
usb:v04F3p0C20*
|
||||
usb:v04F3p0C21*
|
||||
usb:v04F3p0C22*
|
||||
usb:v04F3p0C23*
|
||||
usb:v04F3p0C24*
|
||||
usb:v04F3p0C25*
|
||||
usb:v04F3p0C26*
|
||||
usb:v04F3p0C27*
|
||||
usb:v04F3p0C28*
|
||||
usb:v04F3p0C29*
|
||||
usb:v04F3p0C2A*
|
||||
usb:v04F3p0C2B*
|
||||
usb:v04F3p0C2C*
|
||||
usb:v04F3p0C2D*
|
||||
usb:v04F3p0C2E*
|
||||
usb:v04F3p0C2F*
|
||||
usb:v04F3p0C30*
|
||||
usb:v04F3p0C31*
|
||||
usb:v04F3p0C32*
|
||||
usb:v04F3p0C33*
|
||||
usb:v04F3p0C42*
|
||||
usb:v04F3p0C4D*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver etes603
|
||||
usb:v1C7Ap0603*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver goodixmoc
|
||||
usb:v27C6p5840*
|
||||
usb:v27C6p6496*
|
||||
usb:v27C6p60A2*
|
||||
usb:v27C6p63AC*
|
||||
usb:v27C6p639C*
|
||||
usb:v27C6p6594*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver synaptics
|
||||
usb:v06CBp00BD*
|
||||
usb:v06CBp00E9*
|
||||
usb:v06CBp00DF*
|
||||
usb:v06CBp00F9*
|
||||
usb:v06CBp00FC*
|
||||
usb:v06CBp00C2*
|
||||
usb:v06CBp00C9*
|
||||
usb:v06CBp00E7*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver upeksonly
|
||||
usb:v147Ep2016*
|
||||
usb:v147Ep1000*
|
||||
usb:v147Ep1001*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver upektc
|
||||
usb:v0483p2015*
|
||||
usb:v147Ep3001*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver upektc_img
|
||||
usb:v147Ep2020*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver uru4000
|
||||
usb:v045Ep00BC*
|
||||
usb:v045Ep00BD*
|
||||
usb:v045Ep00CA*
|
||||
usb:v05BAp0007*
|
||||
usb:v05BAp0008*
|
||||
usb:v05BAp000A*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver vcom5s
|
||||
usb:v061Ap0110*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver vfs0050
|
||||
usb:v138Ap0050*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver vfs101
|
||||
usb:v138Ap0001*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver vfs301
|
||||
usb:v138Ap0005*
|
||||
usb:v138Ap0008*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Supported by libfprint driver vfs5011
|
||||
usb:v138Ap0010*
|
||||
usb:v138Ap0011*
|
||||
usb:v138Ap0015*
|
||||
usb:v138Ap0017*
|
||||
usb:v138Ap0018*
|
||||
ID_AUTOSUSPEND=1
|
||||
|
||||
# Known unsupported devices
|
||||
usb:v04F3p036B*
|
||||
usb:v04F3p0C00*
|
||||
usb:v04F3p0C4B*
|
||||
usb:v04F3p0C4C*
|
||||
usb:v04F3p0C4F*
|
||||
usb:v04F3p0C57*
|
||||
usb:v04F3p2706*
|
||||
usb:v06CBp0081*
|
||||
usb:v06CBp0088*
|
||||
usb:v06CBp008A*
|
||||
usb:v06CBp009A*
|
||||
usb:v06CBp009B*
|
||||
usb:v06CBp00A2*
|
||||
usb:v06CBp00B7*
|
||||
usb:v06CBp00BB*
|
||||
usb:v06CBp00BE*
|
||||
usb:v06CBp00CB*
|
||||
usb:v06CBp00D8*
|
||||
usb:v06CBp00DA*
|
||||
usb:v0A5Cp5801*
|
||||
usb:v0A5Cp5805*
|
||||
usb:v0A5Cp5834*
|
||||
usb:v0A5Cp5843*
|
||||
usb:v10A5p0007*
|
||||
usb:v1188p9545*
|
||||
usb:v138Ap0007*
|
||||
usb:v138Ap003A*
|
||||
usb:v138Ap003C*
|
||||
usb:v138Ap003D*
|
||||
usb:v138Ap003F*
|
||||
usb:v138Ap0090*
|
||||
usb:v138Ap0091*
|
||||
usb:v138Ap0092*
|
||||
usb:v138Ap0094*
|
||||
usb:v138Ap0097*
|
||||
usb:v138Ap009D*
|
||||
usb:v138Ap00AB*
|
||||
usb:v147Ep1002*
|
||||
usb:v1491p0088*
|
||||
usb:v16D1p1027*
|
||||
usb:v1C7Ap0300*
|
||||
usb:v1C7Ap0570*
|
||||
usb:v1C7Ap0575*
|
||||
usb:v27C6p5042*
|
||||
usb:v27C6p5110*
|
||||
usb:v27C6p5117*
|
||||
usb:v27C6p5201*
|
||||
usb:v27C6p521D*
|
||||
usb:v27C6p5301*
|
||||
usb:v27C6p530C*
|
||||
usb:v27C6p532D*
|
||||
usb:v27C6p533C*
|
||||
usb:v27C6p5381*
|
||||
usb:v27C6p5385*
|
||||
usb:v27C6p538C*
|
||||
usb:v27C6p538D*
|
||||
usb:v27C6p5395*
|
||||
usb:v27C6p5584*
|
||||
usb:v27C6p55A2*
|
||||
usb:v27C6p55A4*
|
||||
usb:v27C6p55B4*
|
||||
usb:v27C6p5740*
|
||||
usb:v2808p9338*
|
||||
usb:v298Dp2033*
|
||||
usb:v3538p0930*
|
||||
ID_AUTOSUSPEND=1
|
||||
9
data/meson.build
Normal file
9
data/meson.build
Normal file
@@ -0,0 +1,9 @@
|
||||
if get_option('udev_rules')
|
||||
# This file has to be updated using
|
||||
# ninja -C <builddir> libfprint/sync-udev-hwdb
|
||||
|
||||
install_data('autosuspend.hwdb',
|
||||
rename: '60-autosuspend-@0@.hwdb'.format(versioned_libname),
|
||||
install_dir: udev_hwdb_dir,
|
||||
)
|
||||
endif
|
||||
@@ -85,6 +85,12 @@ FP_TYPE_IMAGE_DEVICE
|
||||
FpImageDevice
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fp-sdcp-device</FILE>
|
||||
FP_TYPE_SDCP_DEVICE
|
||||
FpSdcpDevice
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fp-print</FILE>
|
||||
FP_TYPE_PRINT
|
||||
@@ -186,6 +192,26 @@ fpi_image_device_image_captured
|
||||
fpi_image_device_retry_scan
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-sdcp-device</FILE>
|
||||
<TITLE>Internal FpSdcpDevice</TITLE>
|
||||
FpiSdcpClaim
|
||||
FpSdcpDeviceClass
|
||||
fpi_sdcp_claim_copy
|
||||
fpi_sdcp_claim_free
|
||||
fpi_sdcp_claim_get_type
|
||||
fpi_sdcp_claim_new
|
||||
fpi_sdcp_device_connect_complete
|
||||
fpi_sdcp_device_get_connect_data
|
||||
fpi_sdcp_device_get_reconnect_data
|
||||
fpi_sdcp_device_reconnect_complete
|
||||
fpi_sdcp_device_enroll_commit_complete
|
||||
fpi_sdcp_device_enroll_ready
|
||||
fpi_sdcp_device_enroll_set_nonce
|
||||
fpi_sdcp_device_identify_retry
|
||||
fpi_sdcp_device_identify_complete
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-log</FILE>
|
||||
fp_dbg
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<xi:include href="xml/fp-context.xml"/>
|
||||
<xi:include href="xml/fp-device.xml"/>
|
||||
<xi:include href="xml/fp-image-device.xml"/>
|
||||
<xi:include href="xml/fp-sdcp-device.xml"/>
|
||||
<xi:include href="xml/fp-print.xml"/>
|
||||
<xi:include href="xml/fp-image.xml"/>
|
||||
</part>
|
||||
@@ -38,6 +39,7 @@
|
||||
<title>Device methods for drivers</title>
|
||||
<xi:include href="xml/fpi-device.xml"/>
|
||||
<xi:include href="xml/fpi-image-device.xml"/>
|
||||
<xi:include href="xml/fpi-sdcp-device.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="driver-helpers">
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#define AES1660_FRAME_SIZE 0x244
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
/* First init sequence, 0x07 cmd returns following before INIT1:
|
||||
* { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x00 }
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#define AES2660_FRAME_SIZE 0x354
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
/* First init sequence, 0x07 cmd returns following before INIT1:
|
||||
* { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x00 }
|
||||
*/
|
||||
|
||||
@@ -53,10 +53,12 @@ struct _FpiDeviceGoodixMoc
|
||||
pgxfp_sensor_cfg_t sensorcfg;
|
||||
gint enroll_stage;
|
||||
gint max_enroll_stage;
|
||||
gint max_stored_prints;
|
||||
GCancellable *cancellable;
|
||||
GPtrArray *list_result;
|
||||
guint8 template_id[TEMPLATE_ID_SIZE];
|
||||
gboolean is_enroll_identify;
|
||||
gboolean is_power_button_shield_on;
|
||||
|
||||
};
|
||||
|
||||
@@ -126,7 +128,7 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
}
|
||||
|
||||
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
|
||||
if(crc32_calc != *(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len))
|
||||
if(crc32_calc != GUINT32_FROM_LE (*(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)))
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -308,6 +310,35 @@ goodix_sensor_cmd (FpiDeviceGoodixMoc *self,
|
||||
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* fp_pwr_btn_shield_cb Function
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void
|
||||
fp_pwr_btn_shield_cb (FpiDeviceGoodixMoc *self,
|
||||
gxfp_cmd_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
if (resp->result >= GX_FAILED)
|
||||
{
|
||||
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||
return;
|
||||
}
|
||||
if (resp->power_button_shield_resp.resp_cmd1 == MOC_CMD1_PWR_BTN_SHIELD_ON)
|
||||
self->is_power_button_shield_on = true;
|
||||
else
|
||||
self->is_power_button_shield_on = false;
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* fp_verify_xxxx Function
|
||||
@@ -330,7 +361,9 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_PRESENT,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
if (resp->capture_data_resp.img_quality == 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
@@ -341,6 +374,7 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self,
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
||||
return;
|
||||
}
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
@@ -415,7 +449,7 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
||||
fpi_device_identify_report (device, NULL, NULL, error);
|
||||
}
|
||||
|
||||
fpi_ssm_mark_completed (self->task_ssm);
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
|
||||
}
|
||||
|
||||
@@ -432,7 +466,18 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_VERIFY_PWR_BTN_SHIELD_ON:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||
false,
|
||||
NULL,
|
||||
0,
|
||||
fp_pwr_btn_shield_cb);
|
||||
break;
|
||||
|
||||
case FP_VERIFY_CAPTURE:
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
|
||||
true,
|
||||
(const guint8 *) ¶m,
|
||||
@@ -447,6 +492,14 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
TEMPLATE_ID_SIZE,
|
||||
fp_verify_cb);
|
||||
break;
|
||||
|
||||
case FP_VERIFY_PWR_BTN_SHIELD_OFF:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||
false,
|
||||
NULL,
|
||||
0,
|
||||
fp_pwr_btn_shield_cb);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -461,9 +514,9 @@ fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
if (error && error->domain == FP_DEVICE_RETRY)
|
||||
{
|
||||
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
|
||||
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, error);
|
||||
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
|
||||
else
|
||||
fpi_device_identify_report (dev, NULL, NULL, error);
|
||||
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY)
|
||||
@@ -560,6 +613,13 @@ fp_enroll_enum_cb (FpiDeviceGoodixMoc *self,
|
||||
resp->result));
|
||||
return;
|
||||
}
|
||||
if (resp->finger_list_resp.finger_num >= self->max_stored_prints)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
}
|
||||
|
||||
@@ -620,7 +680,9 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_PRESENT,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
|
||||
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
|
||||
{
|
||||
@@ -742,7 +804,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
/* if reach max timeout(5sec) finger not up, swtich to finger up again */
|
||||
/* if reach max timeout(5sec) finger not up, switch to finger up again */
|
||||
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP);
|
||||
@@ -755,6 +817,9 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||
"Switch finger mode failed"));
|
||||
return;
|
||||
}
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
if (self->enroll_stage < self->max_enroll_stage)
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
@@ -793,6 +858,16 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_PWR_BTN_SHIELD_ON:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||
false,
|
||||
NULL,
|
||||
0,
|
||||
fp_pwr_btn_shield_cb);
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_IDENTIFY:
|
||||
{
|
||||
dummy[0] = 0x01;
|
||||
@@ -817,6 +892,9 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CAPTURE:
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT,
|
||||
true,
|
||||
(const guint8 *) &dummy,
|
||||
@@ -904,9 +982,17 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_PWR_BTN_SHIELD_OFF:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||
false,
|
||||
NULL,
|
||||
0,
|
||||
fp_pwr_btn_shield_cb);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -975,7 +1061,7 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
self->max_stored_prints = resp->finger_config.max_stored_prints;
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
@@ -1259,6 +1345,9 @@ gx_fp_init (FpDevice *device)
|
||||
GError *error = NULL;
|
||||
int ret = 0;
|
||||
|
||||
self->max_stored_prints = FP_MAX_FINGERNUM;
|
||||
self->is_power_button_shield_on = false;
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
self->sensorcfg = g_new0 (gxfp_sensor_cfg_t, 1);
|
||||
@@ -1293,20 +1382,59 @@ gx_fp_init (FpDevice *device)
|
||||
}
|
||||
|
||||
static void
|
||||
gx_fp_exit (FpDevice *device)
|
||||
gx_fp_release_interface (FpiDeviceGoodixMoc *self,
|
||||
GError *error)
|
||||
{
|
||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||
GError *error = NULL;
|
||||
g_autoptr(GError) release_error = NULL;
|
||||
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_pointer (&self->sensorcfg, g_free);
|
||||
|
||||
/* Release usb interface */
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
|
||||
0, 0, &error);
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)),
|
||||
0, 0, &release_error);
|
||||
/* Retain passed error if set, otherwise propagate error from release. */
|
||||
if (error == NULL)
|
||||
error = g_steal_pointer (&release_error);
|
||||
|
||||
/* Notify close complete */
|
||||
fpi_device_close_complete (FP_DEVICE (self), error);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gx_fp_exit_cb (FpiDeviceGoodixMoc *self,
|
||||
gxfp_cmd_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
|
||||
|
||||
if (resp->result >= GX_FAILED)
|
||||
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
|
||||
self->is_power_button_shield_on = false;
|
||||
gx_fp_release_interface (self, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gx_fp_exit (FpDevice *device)
|
||||
{
|
||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||
|
||||
if (self->is_power_button_shield_on)
|
||||
{
|
||||
goodix_sensor_cmd (self,
|
||||
MOC_CMD0_PWR_BTN_SHIELD,
|
||||
MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||
false,
|
||||
NULL,
|
||||
0,
|
||||
gx_fp_exit_cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
gx_fp_release_interface (self, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1408,7 +1536,6 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
||||
static void
|
||||
gx_fp_cancel (FpDevice *device)
|
||||
{
|
||||
|
||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||
|
||||
/* Cancel any current interrupt transfer (resulting us to go into
|
||||
@@ -1424,6 +1551,9 @@ static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x27c6, .pid = 0x5840, },
|
||||
{ .vid = 0x27c6, .pid = 0x6496, },
|
||||
{ .vid = 0x27c6, .pid = 0x60A2, },
|
||||
{ .vid = 0x27c6, .pid = 0x63AC, },
|
||||
{ .vid = 0x27c6, .pid = 0x639C, },
|
||||
{ .vid = 0x27c6, .pid = 0x6594, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ typedef enum {
|
||||
|
||||
|
||||
typedef enum {
|
||||
FP_ENROLL_ENUM = 0,
|
||||
FP_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||
FP_ENROLL_ENUM,
|
||||
FP_ENROLL_IDENTIFY,
|
||||
FP_ENROLL_CREATE,
|
||||
FP_ENROLL_CAPTURE,
|
||||
@@ -48,11 +49,14 @@ typedef enum {
|
||||
FP_ENROLL_WAIT_FINGER_UP,
|
||||
FP_ENROLL_CHECK_DUPLICATE,
|
||||
FP_ENROLL_COMMIT,
|
||||
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||
FP_ENROLL_NUM_STATES,
|
||||
} FpEnrollState;
|
||||
|
||||
typedef enum {
|
||||
FP_VERIFY_CAPTURE = 0,
|
||||
FP_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||
FP_VERIFY_CAPTURE,
|
||||
FP_VERIFY_IDENTIFY,
|
||||
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||
FP_VERIFY_NUM_STATES,
|
||||
} FpVerifyState;
|
||||
|
||||
@@ -141,8 +141,11 @@ crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes)
|
||||
static void
|
||||
crc32_final (gf_crc32_context *ctx, uint8_t *md)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
|
||||
ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE);
|
||||
memcpy (md, &ctx->crc, 4);
|
||||
crc = GUINT32_TO_LE (ctx->crc);
|
||||
memcpy (md, &crc, 4);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@@ -184,7 +187,7 @@ init_pack_header (
|
||||
pheader->cmd1 = LOBYTE (cmd);
|
||||
pheader->packagenum = packagenum;
|
||||
pheader->reserved = dump_seq++;
|
||||
pheader->len = len + PACKAGE_CRC_SIZE;
|
||||
pheader->len = GUINT16_TO_LE (len + PACKAGE_CRC_SIZE);
|
||||
pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6);
|
||||
pheader->rev_crc8 = ~pheader->crc8;
|
||||
}
|
||||
@@ -224,14 +227,14 @@ gx_proto_parse_header (
|
||||
{
|
||||
if (!buffer || !pheader)
|
||||
return -1;
|
||||
if (buffer_len < PACKAGE_HEADER_SIZE)
|
||||
if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
|
||||
return -1;
|
||||
|
||||
memcpy (pheader, buffer, sizeof (pack_header));
|
||||
|
||||
pheader->len = GUINT16_FROM_LE ( *(uint16_t *) (buffer + 4));
|
||||
pheader->len = GUINT16_FROM_LE (pheader->len);
|
||||
if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
|
||||
return -1;
|
||||
pheader->len -= PACKAGE_CRC_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -248,7 +251,7 @@ gx_proto_parse_fingerid (
|
||||
if (!template || !fid_buffer)
|
||||
return -1;
|
||||
|
||||
if (fid_buffer_size < 70)
|
||||
if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
|
||||
return -1;
|
||||
|
||||
buffer = fid_buffer;
|
||||
@@ -256,28 +259,30 @@ gx_proto_parse_fingerid (
|
||||
|
||||
if (buffer[Offset++] != 67)
|
||||
return -1;
|
||||
fid_buffer_size--;
|
||||
|
||||
template->type = buffer[Offset++];
|
||||
fid_buffer_size--;
|
||||
template->finger_index = buffer[Offset++];
|
||||
fid_buffer_size--;
|
||||
Offset++;
|
||||
|
||||
memcpy (template->accountid, &buffer[Offset], 32);
|
||||
Offset += 32;
|
||||
|
||||
memcpy (template->tid, &buffer[Offset], 32);
|
||||
Offset += 32; // Offset == 68
|
||||
|
||||
memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
|
||||
Offset += sizeof (template->accountid);
|
||||
memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
|
||||
Offset += sizeof (template->tid); // Offset == 68
|
||||
template->payload.size = buffer[Offset++];
|
||||
memset (template->payload.data, 0, 56);
|
||||
if (template->payload.size > sizeof (template->payload.data))
|
||||
return -1;
|
||||
memset (template->payload.data, 0, template->payload.size);
|
||||
memcpy (template->payload.data, &buffer[Offset], template->payload.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_cmd_response_t presp)
|
||||
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
uint16_t offset = 0;
|
||||
uint8_t *fingerlist = NULL;
|
||||
|
||||
if (!buffer || !presp)
|
||||
@@ -289,33 +294,65 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
|
||||
{
|
||||
case RESPONSE_PACKAGE_CMD:
|
||||
{
|
||||
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
|
||||
return -1;
|
||||
presp->parse_msg.ack_cmd = buffer[1];
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_UPDATE_CONFIG:
|
||||
{
|
||||
presp->finger_config.status = buffer[0];
|
||||
if (buffer_len >= 3)
|
||||
presp->finger_config.max_stored_prints = buffer[2];
|
||||
else
|
||||
/* to compatiable old version firmware */
|
||||
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_COMMITENROLLMENT:
|
||||
case MOC_CMD0_DELETETEMPLATE:
|
||||
/* just check result */
|
||||
break;
|
||||
|
||||
case MOC_CMD0_PWR_BTN_SHIELD:
|
||||
presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
|
||||
if (buffer_len >= 2)
|
||||
{
|
||||
uint8_t support_pwr_shield = buffer[1];
|
||||
if (support_pwr_shield == 0xFF)
|
||||
g_debug ("Power button shield feature not supported!\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_GET_VERSION:
|
||||
if (buffer_len < sizeof (gxfp_version_info_t) + 1)
|
||||
return -1;
|
||||
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
|
||||
break;
|
||||
|
||||
case MOC_CMD0_CAPTURE_DATA:
|
||||
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
|
||||
{
|
||||
if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
|
||||
return -1;
|
||||
presp->capture_data_resp.img_quality = buffer[1];
|
||||
presp->capture_data_resp.img_coverage = buffer[2];
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_ENROLL_INIT:
|
||||
if (buffer_len < sizeof (gxfp_enroll_init_t) + 1)
|
||||
return -1;
|
||||
if (presp->result == GX_SUCCESS)
|
||||
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
|
||||
break;
|
||||
|
||||
case MOC_CMD0_ENROLL:
|
||||
if (buffer_len < sizeof (gxfp_enroll_update_t))
|
||||
return -1;
|
||||
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
|
||||
presp->enroll_update.img_overlay = buffer[1];
|
||||
presp->enroll_update.img_preoverlay = buffer[2];
|
||||
@@ -325,7 +362,11 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
|
||||
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
|
||||
if (presp->check_duplicate_resp.duplicate)
|
||||
{
|
||||
uint16_t tid_size = GUINT16_FROM_LE (*(buffer + 1));
|
||||
if (buffer_len < 3)
|
||||
return -1;
|
||||
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
|
||||
if ((buffer_len < tid_size + 3) || (buffer_len > sizeof (template_format_t)) + 3)
|
||||
return -1;
|
||||
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
|
||||
}
|
||||
break;
|
||||
@@ -333,18 +374,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
|
||||
case MOC_CMD0_GETFINGERLIST:
|
||||
if (presp->result != GX_SUCCESS)
|
||||
break;
|
||||
if (buffer_len < 2)
|
||||
return -1;
|
||||
presp->finger_list_resp.finger_num = buffer[1];
|
||||
if (presp->finger_list_resp.finger_num > FP_MAX_FINGERNUM)
|
||||
{
|
||||
presp->finger_list_resp.finger_num = 0;
|
||||
presp->result = GX_ERROR_NO_AVAILABLE_SPACE;
|
||||
break;
|
||||
}
|
||||
fingerlist = buffer + 2;
|
||||
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
|
||||
{
|
||||
uint16_t fingerid_length = GUINT16_FROM_LE (*(fingerlist + offset));
|
||||
uint16_t fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
|
||||
offset += 2;
|
||||
if (buffer_len < fingerid_length + offset + 2)
|
||||
return -1;
|
||||
if (gx_proto_parse_fingerid (fingerlist + offset,
|
||||
fingerid_length,
|
||||
&presp->finger_list_resp.finger_list[num]) != 0)
|
||||
@@ -366,14 +405,16 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_c
|
||||
presp->verify.match = (buffer[0] == 0) ? true : false;
|
||||
if (presp->verify.match)
|
||||
{
|
||||
if (buffer_len < sizeof (template_format_t) + 10)
|
||||
return -1;
|
||||
offset += 1;
|
||||
presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset));
|
||||
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||
offset += 2;
|
||||
score = GUINT32_FROM_LE (*(buffer + offset));
|
||||
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
|
||||
offset += 4;
|
||||
study = GUINT16_FROM_LE (*(buffer + offset));
|
||||
study = buffer[offset];
|
||||
offset += 1;
|
||||
fingerid_size = GUINT16_FROM_LE (*(buffer + offset));
|
||||
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||
offset += 2;
|
||||
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
|
||||
{
|
||||
@@ -411,7 +452,7 @@ gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig)
|
||||
memset (pconfig, 0, sizeof (*pconfig));
|
||||
|
||||
//NOTICE: Do not change any value!
|
||||
memcpy (&pconfig->config, sensor_config, 26);
|
||||
memcpy (&pconfig->config, sensor_config, G_N_ELEMENTS (sensor_config));
|
||||
pconfig->reserved[0] = 1;
|
||||
|
||||
gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define PACKAGE_CRC_SIZE (4)
|
||||
#define PACKAGE_HEADER_SIZE (8)
|
||||
|
||||
#define FP_MAX_FINGERNUM (10)
|
||||
#define FP_MAX_FINGERNUM (20)
|
||||
|
||||
#define TEMPLATE_ID_SIZE (32)
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
#define MOC_CMD1_GET_FINGER_MODE 0x00
|
||||
#define MOC_CMD1_SET_FINGER_DOWN 0x01
|
||||
#define MOC_CMD1_SET_FINGER_UP 0x02
|
||||
|
||||
#define MOC_CMD0_PWR_BTN_SHIELD 0xE0
|
||||
#define MOC_CMD1_PWR_BTN_SHIELD_OFF 0x00
|
||||
#define MOC_CMD1_PWR_BTN_SHIELD_ON 0x01
|
||||
|
||||
/* */
|
||||
|
||||
typedef struct _gxfp_version_info
|
||||
@@ -89,7 +94,7 @@ typedef struct _gxfp_version_info
|
||||
uint8_t interface[GX_VERSION_LEN];
|
||||
uint8_t protocol[GX_VERSION_LEN];
|
||||
uint8_t flashVersion[GX_VERSION_LEN];
|
||||
uint8_t reserved[62];
|
||||
uint8_t reserved[38];
|
||||
} gxfp_version_info_t, *pgxfp_version_info_t;
|
||||
|
||||
|
||||
@@ -167,6 +172,16 @@ typedef struct _fp_finger_status
|
||||
uint8_t status;
|
||||
} fp_finger_status_t, *pfp_finger_status_t;
|
||||
|
||||
typedef struct _fp_finger_config
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t max_stored_prints;
|
||||
} fp_finger_config_t, *pfp_finger_config_t;
|
||||
|
||||
typedef struct _fp_pwr_btn_shield
|
||||
{
|
||||
uint8_t resp_cmd1;
|
||||
} fp_pwr_btn_shield_t, *pfp_pwr_btn_shield_t;
|
||||
|
||||
typedef struct _fp_cmd_response
|
||||
{
|
||||
@@ -183,6 +198,8 @@ typedef struct _fp_cmd_response
|
||||
gxfp_enum_fingerlist_t finger_list_resp;
|
||||
gxfp_version_info_t version_info;
|
||||
fp_finger_status_t finger_status;
|
||||
fp_finger_config_t finger_config;
|
||||
fp_pwr_btn_shield_t power_button_shield_resp;
|
||||
};
|
||||
} gxfp_cmd_response_t, *pgxfp_cmd_response_t;
|
||||
|
||||
@@ -219,7 +236,7 @@ int gx_proto_parse_header (uint8_t *buffer,
|
||||
|
||||
int gx_proto_parse_body (uint16_t cmd,
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
uint16_t buffer_len,
|
||||
pgxfp_cmd_response_t presponse);
|
||||
|
||||
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
|
||||
|
||||
static void init_identify_msg (FpDevice *device);
|
||||
static void compose_and_send_identify_msg (FpDevice *device);
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xE9, },
|
||||
@@ -121,7 +124,7 @@ cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
{
|
||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK)
|
||||
{
|
||||
fp_dbg ("Received cancellation success resonse");
|
||||
fp_dbg ("Received cancellation success response");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
g_error_new_literal (G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED,
|
||||
@@ -345,7 +348,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
||||
* may only be a cancellation currently). */
|
||||
if (seq_num <= 0)
|
||||
{
|
||||
self->last_seq_num = MAX (1, self->last_seq_num + 1);
|
||||
self->last_seq_num = MAX (1, (self->last_seq_num + 1) & 0xff);
|
||||
real_seq_num = self->last_seq_num;
|
||||
if (seq_num == 0)
|
||||
self->cmd_seq_num = self->last_seq_num;
|
||||
@@ -451,6 +454,37 @@ parse_print_data (GVariant *data,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static FpPrint *
|
||||
create_print (FpiDeviceSynaptics *self,
|
||||
guint8 *user_id,
|
||||
guint8 finger_id)
|
||||
{
|
||||
FpPrint *print;
|
||||
g_autofree gchar *user_id_safe;
|
||||
GVariant *data = NULL;
|
||||
GVariant *uid = NULL;
|
||||
|
||||
user_id_safe = g_strndup ((char *) user_id, BMKT_MAX_USER_ID_LEN);
|
||||
|
||||
print = fp_print_new (FP_DEVICE (self));
|
||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
user_id_safe,
|
||||
strlen (user_id_safe),
|
||||
1);
|
||||
data = g_variant_new ("(y@ay)",
|
||||
finger_id,
|
||||
uid);
|
||||
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
fpi_print_set_device_stored (print, TRUE);
|
||||
g_object_set (print, "fpi-data", data, NULL);
|
||||
g_object_set (print, "description", user_id_safe, NULL);
|
||||
|
||||
fpi_print_fill_from_user_id (print, user_id_safe);
|
||||
|
||||
return print;
|
||||
}
|
||||
|
||||
static void
|
||||
list_msg_cb (FpiDeviceSynaptics *self,
|
||||
bmkt_response_t *resp,
|
||||
@@ -503,10 +537,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
||||
|
||||
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||
{
|
||||
GVariant *data = NULL;
|
||||
GVariant *uid = NULL;
|
||||
FpPrint *print;
|
||||
gchar *userid;
|
||||
|
||||
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
||||
continue;
|
||||
@@ -519,23 +550,9 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
||||
get_enroll_templates_resp->templates[n].user_id,
|
||||
get_enroll_templates_resp->templates[n].finger_id);
|
||||
|
||||
userid = (gchar *) get_enroll_templates_resp->templates[n].user_id;
|
||||
|
||||
print = fp_print_new (FP_DEVICE (self));
|
||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
print = create_print (self,
|
||||
get_enroll_templates_resp->templates[n].user_id,
|
||||
get_enroll_templates_resp->templates[n].user_id_len,
|
||||
1);
|
||||
data = g_variant_new ("(y@ay)",
|
||||
get_enroll_templates_resp->templates[n].finger_id,
|
||||
uid);
|
||||
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
fpi_print_set_device_stored (print, TRUE);
|
||||
g_object_set (print, "fpi-data", data, NULL);
|
||||
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
|
||||
|
||||
fpi_print_fill_from_user_id (print, userid);
|
||||
get_enroll_templates_resp->templates[n].finger_id);
|
||||
|
||||
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
|
||||
}
|
||||
@@ -649,7 +666,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
||||
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
||||
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
||||
fpi_device_verify_complete (device, NULL);
|
||||
verify_complete_after_finger_removal (self);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -725,6 +742,12 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
||||
fp_info ("Place Finger on the Sensor!");
|
||||
break;
|
||||
|
||||
case BMKT_RSP_SEND_NEXT_USER_ID:
|
||||
{
|
||||
compose_and_send_identify_msg (device);
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ID_FAIL:
|
||||
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
||||
{
|
||||
@@ -760,45 +783,47 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
||||
FpPrint *print = NULL;
|
||||
GPtrArray *prints = NULL;
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
guint8 finger;
|
||||
const guint8 *user_id;
|
||||
gsize user_id_len = 0;
|
||||
gint cnt = 0;
|
||||
gboolean find = FALSE;
|
||||
gboolean found = FALSE;
|
||||
guint index;
|
||||
|
||||
print = create_print (self,
|
||||
resp->response.id_resp.user_id,
|
||||
resp->response.id_resp.finger_id);
|
||||
|
||||
fpi_device_get_identify_data (device, &prints);
|
||||
|
||||
for (cnt = 0; cnt < prints->len; cnt++)
|
||||
{
|
||||
print = g_ptr_array_index (prints, cnt);
|
||||
g_object_get (print, "fpi-data", &data, NULL);
|
||||
g_debug ("data is %p", data);
|
||||
parse_print_data (data, &finger, &user_id, &user_id_len);
|
||||
if (user_id)
|
||||
{
|
||||
if (memcmp (resp->response.id_resp.user_id, user_id, user_id_len) == 0)
|
||||
{
|
||||
find = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(find)
|
||||
{
|
||||
fpi_device_identify_report (device, print, print, NULL);
|
||||
fpi_device_identify_complete (device, NULL);
|
||||
}
|
||||
found = g_ptr_array_find_with_equal_func (prints,
|
||||
print,
|
||||
(GEqualFunc) fp_print_equal,
|
||||
&index);
|
||||
|
||||
if (found)
|
||||
fpi_device_identify_report (device, g_ptr_array_index (prints, index), print, NULL);
|
||||
else
|
||||
{
|
||||
fpi_device_identify_report (device, NULL, NULL, NULL);
|
||||
fpi_device_identify_report (device, NULL, print, NULL);
|
||||
|
||||
identify_complete_after_finger_removal (self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
identify (FpDevice *device)
|
||||
{
|
||||
init_identify_msg (device);
|
||||
compose_and_send_identify_msg (device);
|
||||
}
|
||||
|
||||
static void
|
||||
init_identify_msg (FpDevice *device)
|
||||
{
|
||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||
|
||||
self->id_idx = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
compose_and_send_identify_msg (FpDevice *device)
|
||||
{
|
||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||
FpPrint *print = NULL;
|
||||
@@ -808,13 +833,26 @@ identify (FpDevice *device)
|
||||
guint8 finger;
|
||||
const guint8 *user_id;
|
||||
gsize user_id_len = 0;
|
||||
gint cnt = 0;
|
||||
g_autofree guint8 *payload = NULL;
|
||||
guint8 payload_len = 0;
|
||||
guint8 payloadOffset = 0;
|
||||
|
||||
fpi_device_get_identify_data (device, &prints);
|
||||
|
||||
for (cnt = 0; cnt < prints->len; cnt++)
|
||||
if (prints->len > UINT8_MAX)
|
||||
{
|
||||
print = g_ptr_array_index (prints, cnt);
|
||||
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_debug ("data is %p", data);
|
||||
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
||||
@@ -823,13 +861,49 @@ identify (FpDevice *device)
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(self->id_idx == 0)
|
||||
{
|
||||
/*
|
||||
* Construct payload.
|
||||
* 1st byte is total number of IDs in list.
|
||||
* 2nd byte is number of IDs in list.
|
||||
* 1 byte for each ID length, maximum id length is 100.
|
||||
* user_id_len bytes of each ID
|
||||
*/
|
||||
payload_len = 2 + 1 + user_id_len;
|
||||
payload = g_malloc0 (payload_len);
|
||||
payload[payloadOffset] = prints->len;
|
||||
payloadOffset += 1;
|
||||
payload[payloadOffset] = 1; /* send one id per message */
|
||||
payloadOffset += 1;
|
||||
payload[payloadOffset] = user_id_len;
|
||||
payloadOffset += 1;
|
||||
memcpy (&payload[payloadOffset], user_id, user_id_len);
|
||||
payloadOffset += user_id_len;
|
||||
|
||||
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
|
||||
enroll_msg_cb (FpiDeviceSynaptics *self,
|
||||
bmkt_response_t *resp,
|
||||
@@ -1059,6 +1133,44 @@ delete_print (FpDevice *device)
|
||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_DEL_USER_FP, payload, user_id_len + 1, delete_msg_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
prob_msg_cb (FpiDeviceSynaptics *self,
|
||||
bmkt_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
GUsbDevice *usb_dev = NULL;
|
||||
g_autofree gchar *serial = NULL;
|
||||
|
||||
usb_dev = fpi_device_get_usb_device (FP_DEVICE (self));
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (FP_DEVICE (self), NULL, NULL,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "unsupported firmware version"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
serial = g_strdup ("emulated-device");
|
||||
else
|
||||
serial = g_usb_device_get_string_descriptor (usb_dev,
|
||||
g_usb_device_get_serial_number_index (usb_dev),
|
||||
&error);
|
||||
|
||||
if (resp->result == BMKT_SUCCESS)
|
||||
{
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (FP_DEVICE (self), serial, NULL, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Probe fingerprint sensor failed with %d!", resp->result);
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (FP_DEVICE (self), serial, NULL, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dev_probe (FpDevice *device)
|
||||
{
|
||||
@@ -1159,40 +1271,7 @@ dev_probe (FpDevice *device)
|
||||
fp_dbg ("Target: %d", self->mis_version.target);
|
||||
fp_dbg ("Product: %d", self->mis_version.product);
|
||||
|
||||
|
||||
/* We need at least firmware version 10.1, and for 10.1 build 2989158 */
|
||||
if (self->mis_version.version_major < 10 ||
|
||||
self->mis_version.version_minor < 1 ||
|
||||
(self->mis_version.version_major == 10 &&
|
||||
self->mis_version.version_minor == 1 &&
|
||||
self->mis_version.build_num < 2989158))
|
||||
{
|
||||
fp_warn ("Firmware version %d.%d with build number %d is unsupported",
|
||||
self->mis_version.version_major,
|
||||
self->mis_version.version_minor,
|
||||
self->mis_version.build_num);
|
||||
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Unsupported firmware version "
|
||||
"(%d.%d with build number %d)",
|
||||
self->mis_version.version_major,
|
||||
self->mis_version.version_minor,
|
||||
self->mis_version.build_num);
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
/* This is the same as the serial_number from above, hex encoded and somewhat reordered */
|
||||
/* Should we add in more, e.g. the chip revision? */
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
serial = g_strdup ("emulated-device");
|
||||
else
|
||||
serial = g_usb_device_get_string_descriptor (usb_dev,
|
||||
g_usb_device_get_serial_number_index (usb_dev),
|
||||
&error);
|
||||
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
|
||||
fpi_device_probe_complete (device, serial, NULL, error);
|
||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_FPS_INIT, NULL, 0, prob_msg_cb);
|
||||
|
||||
return;
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ struct _FpiDeviceSynaptics
|
||||
FpiSsm *cmd_ssm;
|
||||
FpiUsbTransfer *cmd_pending_transfer;
|
||||
gboolean cmd_complete_on_removal;
|
||||
guint8 id_idx;
|
||||
|
||||
bmkt_sensor_version_t mis_version;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#pragma once
|
||||
|
||||
#define UPEKTC_CMD_LEN 0x40
|
||||
|
||||
@@ -375,6 +375,10 @@ stop_irq_handler (FpImageDevice *dev, irqs_stopped_cb_fn cb)
|
||||
g_cancellable_cancel (self->irq_cancellable);
|
||||
self->irqs_stopped_cb = cb;
|
||||
}
|
||||
else
|
||||
{
|
||||
cb (dev);
|
||||
}
|
||||
}
|
||||
|
||||
/***** STATE CHANGING *****/
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
/* There are many similar blocks in the data below, also the data are
|
||||
* self-similar (looks like some config blocks? pokes like in vfs101?) */
|
||||
|
||||
|
||||
@@ -815,13 +815,11 @@ dev_close (FpImageDevice *dev)
|
||||
GError *error = NULL;
|
||||
FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011 (dev);
|
||||
|
||||
;
|
||||
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||
0, 0, &error);
|
||||
|
||||
g_free (self->capture_buffer);
|
||||
g_slist_free_full (self->rows, g_free);
|
||||
g_slist_free_full (g_steal_pointer (&self->rows), g_free);
|
||||
|
||||
fpi_image_device_close_complete (dev, error);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#define VFS5011_LINE_SIZE 240
|
||||
#define VFS5011_IMAGE_WIDTH 160
|
||||
|
||||
|
||||
355
libfprint/drivers/virtual-device-listener.c
Normal file
355
libfprint/drivers/virtual-device-listener.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Socket utilities for "simple" device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "virtual_device_connection"
|
||||
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gunixsocketaddress.h>
|
||||
|
||||
#include "virtual-device-private.h"
|
||||
|
||||
struct _FpDeviceVirtualListener
|
||||
{
|
||||
GSocketListener parent_instance;
|
||||
|
||||
GSocketConnection *connection;
|
||||
GCancellable *cancellable;
|
||||
guint cancellable_id;
|
||||
|
||||
FpDeviceVirtualListenerConnectionCb ready_cb;
|
||||
gpointer ready_cb_data;
|
||||
|
||||
gint socket_fd;
|
||||
gint client_fd;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FpDeviceVirtualListener, fp_device_virtual_listener, G_TYPE_SOCKET_LISTENER)
|
||||
|
||||
static void start_listen (FpDeviceVirtualListener *self);
|
||||
|
||||
FpDeviceVirtualListener *
|
||||
fp_device_virtual_listener_new (void)
|
||||
{
|
||||
return g_object_new (fp_device_virtual_listener_get_type (), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_device_virtual_listener_dispose (GObject *object)
|
||||
{
|
||||
FpDeviceVirtualListener *self = FP_DEVICE_VIRTUAL_LISTENER (object);
|
||||
|
||||
if (self->cancellable_id)
|
||||
{
|
||||
g_cancellable_disconnect (self->cancellable, self->cancellable_id);
|
||||
self->cancellable_id = 0;
|
||||
}
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->connection);
|
||||
|
||||
self->ready_cb = NULL;
|
||||
|
||||
G_OBJECT_CLASS (fp_device_virtual_listener_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_device_virtual_listener_class_init (FpDeviceVirtualListenerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = fp_device_virtual_listener_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
fp_device_virtual_listener_init (FpDeviceVirtualListener *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualListener *self = user_data;
|
||||
GSocketConnection *connection;
|
||||
|
||||
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
||||
res,
|
||||
NULL,
|
||||
&error);
|
||||
if (!connection)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
g_warning ("Error accepting a new connection: %s", error->message);
|
||||
start_listen (self);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always allow further connections.
|
||||
* If we get a new one, we generally just close the old connection. */
|
||||
start_listen (self);
|
||||
if (self->connection)
|
||||
{
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
}
|
||||
|
||||
self->connection = connection;
|
||||
fp_dbg ("Got a new connection!");
|
||||
|
||||
self->ready_cb (self, self->ready_cb_data);
|
||||
}
|
||||
|
||||
static void
|
||||
start_listen (FpDeviceVirtualListener *self)
|
||||
{
|
||||
g_socket_listener_accept_async (G_SOCKET_LISTENER (self),
|
||||
self->cancellable,
|
||||
new_connection_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_cancelled (GCancellable *cancellable,
|
||||
FpDeviceVirtualListener *self)
|
||||
{
|
||||
fp_device_virtual_listener_connection_close (self);
|
||||
g_socket_listener_close (G_SOCKET_LISTENER (self));
|
||||
g_clear_object (&self->cancellable);
|
||||
self->ready_cb = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fp_device_virtual_listener_start (FpDeviceVirtualListener *self,
|
||||
const char *address,
|
||||
GCancellable *cancellable,
|
||||
FpDeviceVirtualListenerConnectionCb cb,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GSocketAddress) addr = NULL;
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_return_val_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self), FALSE);
|
||||
g_return_val_if_fail (cb != NULL, FALSE);
|
||||
g_return_val_if_fail (self->ready_cb == NULL, FALSE);
|
||||
|
||||
self->client_fd = -1;
|
||||
|
||||
g_socket_listener_set_backlog (G_SOCKET_LISTENER (self), 1);
|
||||
|
||||
/* Remove any left over socket. */
|
||||
g_unlink (address);
|
||||
|
||||
addr = g_unix_socket_address_new (address);
|
||||
|
||||
if (!g_socket_listener_add_address (G_SOCKET_LISTENER (self),
|
||||
addr,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
error))
|
||||
{
|
||||
g_warning ("Could not listen on unix socket: %s", (*error)->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->ready_cb = cb;
|
||||
self->ready_cb_data = user_data;
|
||||
self->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
|
||||
if (self->cancellable)
|
||||
self->cancellable_id = g_cancellable_connect (self->cancellable,
|
||||
G_CALLBACK (on_cancelled), self, NULL);
|
||||
|
||||
start_listen (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fp_device_virtual_listener_connection_close (FpDeviceVirtualListener *self)
|
||||
{
|
||||
g_return_val_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self), FALSE);
|
||||
|
||||
if (!self->connection)
|
||||
return FALSE;
|
||||
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_read_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GTask) task = user_data;
|
||||
FpDeviceVirtualListener *self = g_task_get_source_object (task);
|
||||
gboolean all;
|
||||
gboolean success;
|
||||
gsize bytes;
|
||||
|
||||
all = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "all"));
|
||||
|
||||
if (all)
|
||||
{
|
||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
||||
}
|
||||
else
|
||||
{
|
||||
gssize sbytes;
|
||||
|
||||
sbytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
|
||||
bytes = sbytes;
|
||||
success = (sbytes >= 0);
|
||||
}
|
||||
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
return;
|
||||
|
||||
/* If we are cancelled, just return immediately. */
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
|
||||
{
|
||||
g_task_return_int (task, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this error is for an old connection (that should be closed already),
|
||||
* then just give up immediately with a CLOSED error.
|
||||
*/
|
||||
if (self->connection &&
|
||||
g_io_stream_get_input_stream (G_IO_STREAM (self->connection)) != G_INPUT_STREAM (source_object))
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_CLOSED,
|
||||
"Error on old connection, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!success || bytes == 0)
|
||||
{
|
||||
/* We accept it if someone tries to read twice and just return that error. */
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
|
||||
{
|
||||
if (self->connection)
|
||||
{
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Got empty data");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_task_return_int (task, bytes);
|
||||
}
|
||||
|
||||
void
|
||||
fp_device_virtual_listener_read (FpDeviceVirtualListener *self,
|
||||
gboolean all,
|
||||
void *buffer,
|
||||
gsize count,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GTask) task = NULL;
|
||||
GInputStream *stream;
|
||||
|
||||
g_return_if_fail (FP_IS_DEVICE_VIRTUAL_LISTENER (self));
|
||||
|
||||
task = g_task_new (self, self->cancellable, callback, user_data);
|
||||
g_object_set_data (G_OBJECT (task), "all", GINT_TO_POINTER (all));
|
||||
|
||||
if (!self->connection || g_io_stream_is_closed (G_IO_STREAM (self->connection)))
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
|
||||
"Listener not connected to any stream");
|
||||
return;
|
||||
}
|
||||
|
||||
stream = g_io_stream_get_input_stream (G_IO_STREAM (self->connection));
|
||||
if (all)
|
||||
{
|
||||
g_input_stream_read_all_async (stream, buffer, count,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_stream_read_cb,
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_input_stream_read_async (stream, buffer, count,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_stream_read_cb,
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
}
|
||||
|
||||
gsize
|
||||
fp_device_virtual_listener_read_finish (FpDeviceVirtualListener *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), 0);
|
||||
|
||||
return g_task_propagate_int (G_TASK (result), error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fp_device_virtual_listener_write_sync (FpDeviceVirtualListener *self,
|
||||
const char *buffer,
|
||||
gsize count,
|
||||
GError **error)
|
||||
{
|
||||
if (!self->connection || g_io_stream_is_closed (G_IO_STREAM (self->connection)))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED,
|
||||
"Listener not connected to any stream");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (self->connection)),
|
||||
buffer,
|
||||
count,
|
||||
NULL,
|
||||
self->cancellable,
|
||||
error);
|
||||
}
|
||||
109
libfprint/drivers/virtual-device-private.h
Normal file
109
libfprint/drivers/virtual-device-private.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Virtual driver for "simple" device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a virtual driver to debug the non-image based drivers. A small
|
||||
* python script is provided to connect to it via a socket, allowing
|
||||
* prints to registered programmatically.
|
||||
* Using this, it is possible to test libfprint and fprintd.
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "fpi-device.h"
|
||||
|
||||
#define MAX_LINE_LEN 1024
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualListener, fp_device_virtual_listener, FP, DEVICE_VIRTUAL_LISTENER, GSocketListener)
|
||||
|
||||
typedef void (*FpDeviceVirtualListenerConnectionCb) (FpDeviceVirtualListener *listener,
|
||||
gpointer user_data);
|
||||
|
||||
FpDeviceVirtualListener * fp_device_virtual_listener_new (void);
|
||||
|
||||
gboolean fp_device_virtual_listener_start (FpDeviceVirtualListener *listener,
|
||||
const char *address,
|
||||
GCancellable *cancellable,
|
||||
FpDeviceVirtualListenerConnectionCb cb,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean fp_device_virtual_listener_connection_close (FpDeviceVirtualListener *listener);
|
||||
|
||||
void fp_device_virtual_listener_read (FpDeviceVirtualListener *listener,
|
||||
gboolean all,
|
||||
void *buffer,
|
||||
gsize count,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gsize fp_device_virtual_listener_read_finish (FpDeviceVirtualListener *listener,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
gboolean fp_device_virtual_listener_write_sync (FpDeviceVirtualListener *self,
|
||||
const char *buffer,
|
||||
gsize count,
|
||||
GError **error);
|
||||
|
||||
|
||||
struct _FpDeviceVirtualDevice
|
||||
{
|
||||
FpDevice parent;
|
||||
|
||||
FpDeviceVirtualListener *listener;
|
||||
GCancellable *cancellable;
|
||||
|
||||
char recv_buf[MAX_LINE_LEN];
|
||||
|
||||
GPtrArray *pending_commands;
|
||||
|
||||
GHashTable *prints_storage;
|
||||
|
||||
guint wait_command_id;
|
||||
guint sleep_timeout_id;
|
||||
guint enroll_stages_passed;
|
||||
gboolean match_reported;
|
||||
gboolean supports_cancellation;
|
||||
gboolean injected_synthetic_cmd;
|
||||
gboolean ignore_wait;
|
||||
gboolean keep_alive;
|
||||
};
|
||||
|
||||
/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
|
||||
* contents without having to use a shared private struct instead. */
|
||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP, DEVICE_VIRTUAL_DEVICE, FpDevice)
|
||||
|
||||
struct _FpDeviceVirtualDeviceStorage
|
||||
{
|
||||
FpDeviceVirtualDevice parent;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_storage, FP, DEVICE_VIRTUAL_DEVICE_STORAGE, FpDeviceVirtualDevice)
|
||||
|
||||
|
||||
char * process_cmds (FpDeviceVirtualDevice * self, gboolean scan, GError **error);
|
||||
char * start_scan_command (FpDeviceVirtualDevice *self,
|
||||
GError **error);
|
||||
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
|
||||
GError *error);
|
||||
gboolean should_wait_to_sleep (FpDeviceVirtualDevice *self,
|
||||
const char *scan_id,
|
||||
GError *error);
|
||||
247
libfprint/drivers/virtual-device-storage.c
Normal file
247
libfprint/drivers/virtual-device-storage.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Virtual driver for "simple" device debugging with storage
|
||||
*
|
||||
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
|
||||
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a virtual driver to debug the non-image based drivers. A small
|
||||
* python script is provided to connect to it via a socket, allowing
|
||||
* prints to registered programmatically.
|
||||
* Using this, it is possible to test libfprint and fprintd.
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "virtual_device_storage"
|
||||
|
||||
#include "virtual-device-private.h"
|
||||
#include "fpi-log.h"
|
||||
|
||||
G_DEFINE_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_storage, fpi_device_virtual_device_get_type ())
|
||||
|
||||
static GPtrArray * get_stored_prints (FpDeviceVirtualDevice * self);
|
||||
|
||||
static void
|
||||
dev_identify (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
g_autofree char *scan_id = NULL;
|
||||
|
||||
scan_id = start_scan_command (self, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
|
||||
return;
|
||||
|
||||
if (scan_id)
|
||||
{
|
||||
g_autoptr(GPtrArray) stored = get_stored_prints (self);
|
||||
GPtrArray *prints;
|
||||
GVariant *data = NULL;
|
||||
FpPrint *new_scan;
|
||||
FpPrint *match = NULL;
|
||||
guint idx;
|
||||
|
||||
new_scan = fp_print_new (dev);
|
||||
fpi_print_set_type (new_scan, FPI_PRINT_RAW);
|
||||
fpi_print_set_device_stored (new_scan, TRUE);
|
||||
data = g_variant_new_string (scan_id);
|
||||
g_object_set (new_scan, "fpi-data", data, NULL);
|
||||
|
||||
fpi_device_get_identify_data (dev, &prints);
|
||||
g_debug ("Trying to identify print '%s' against a gallery of %u prints", scan_id, prints->len);
|
||||
|
||||
if (!g_ptr_array_find_with_equal_func (stored,
|
||||
new_scan,
|
||||
(GEqualFunc) fp_print_equal,
|
||||
NULL))
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND);
|
||||
else if (g_ptr_array_find_with_equal_func (prints,
|
||||
new_scan,
|
||||
(GEqualFunc) fp_print_equal,
|
||||
&idx))
|
||||
match = g_ptr_array_index (prints, idx);
|
||||
|
||||
if (!self->match_reported)
|
||||
{
|
||||
self->match_reported = TRUE;
|
||||
fpi_device_identify_report (dev,
|
||||
match,
|
||||
new_scan,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else if (error && error->domain == FP_DEVICE_RETRY)
|
||||
{
|
||||
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
|
||||
if (should_wait_to_sleep (self, scan_id, error))
|
||||
return;
|
||||
|
||||
self->match_reported = FALSE;
|
||||
fpi_device_identify_complete (dev, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
struct ListData
|
||||
{
|
||||
FpDevice *dev;
|
||||
GPtrArray *res;
|
||||
};
|
||||
|
||||
static void
|
||||
dev_list_insert_print (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ListData *data = user_data;
|
||||
FpPrint *print = fp_print_new (data->dev);
|
||||
GVariant *var = NULL;
|
||||
|
||||
fpi_print_fill_from_user_id (print, key);
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
var = g_variant_new_string (key);
|
||||
g_object_set (print, "fpi-data", var, NULL);
|
||||
g_object_ref_sink (print);
|
||||
|
||||
g_ptr_array_add (data->res, print);
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
get_stored_prints (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
GPtrArray * prints_list;
|
||||
struct ListData data;
|
||||
|
||||
prints_list = g_ptr_array_new_full (g_hash_table_size (self->prints_storage),
|
||||
g_object_unref);
|
||||
data.dev = FP_DEVICE (self);
|
||||
data.res = prints_list;
|
||||
|
||||
g_hash_table_foreach (self->prints_storage, dev_list_insert_print, &data);
|
||||
|
||||
return prints_list;
|
||||
}
|
||||
|
||||
static void
|
||||
dev_list (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GPtrArray) prints_list = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
|
||||
process_cmds (vdev, FALSE, &error);
|
||||
if (should_wait_for_command (vdev, error))
|
||||
return;
|
||||
|
||||
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_list_complete (dev, get_stored_prints (vdev), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_delete (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
FpPrint *print = NULL;
|
||||
const char *id = NULL;
|
||||
|
||||
process_cmds (vdev, FALSE, &error);
|
||||
if (should_wait_for_command (vdev, error))
|
||||
return;
|
||||
|
||||
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
fpi_device_delete_complete (dev, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_get_delete_data (dev, &print);
|
||||
|
||||
g_object_get (print, "fpi-data", &data, NULL);
|
||||
if (data == NULL)
|
||||
{
|
||||
fpi_device_delete_complete (dev,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||
return;
|
||||
}
|
||||
|
||||
id = g_variant_get_string (data, NULL);
|
||||
|
||||
fp_dbg ("Deleting print %s for user %s",
|
||||
id,
|
||||
fp_print_get_username (print));
|
||||
|
||||
if (g_hash_table_remove (vdev->prints_storage, id))
|
||||
fpi_device_delete_complete (dev, NULL);
|
||||
else
|
||||
fpi_device_delete_complete (dev,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_storage_init (FpDeviceVirtualDeviceStorage *self)
|
||||
{
|
||||
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (self);
|
||||
|
||||
vdev->prints_storage = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_storage_finalize (GObject *object)
|
||||
{
|
||||
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
g_clear_pointer (&vdev->prints_storage, g_hash_table_destroy);
|
||||
G_OBJECT_CLASS (fpi_device_virtual_device_storage_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static const FpIdEntry driver_ids[] = {
|
||||
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE" },
|
||||
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_IDENT" },
|
||||
{ .virtual_envvar = NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = fpi_device_virtual_device_storage_finalize;
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual device with storage and identification for debugging";
|
||||
dev_class->id_table = driver_ids;
|
||||
|
||||
dev_class->identify = dev_identify;
|
||||
dev_class->list = dev_list;
|
||||
dev_class->delete = dev_delete;
|
||||
}
|
||||
779
libfprint/drivers/virtual-device.c
Normal file
779
libfprint/drivers/virtual-device.c
Normal file
@@ -0,0 +1,779 @@
|
||||
/*
|
||||
* Virtual driver for "simple" device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
|
||||
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a virtual driver to debug the non-image based drivers. A small
|
||||
* python script is provided to connect to it via a socket, allowing
|
||||
* prints to registered programmatically.
|
||||
* Using this, it is possible to test libfprint and fprintd.
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "virtual_device"
|
||||
|
||||
#include "virtual-device-private.h"
|
||||
#include "fpi-log.h"
|
||||
|
||||
G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE)
|
||||
|
||||
#define INSERT_CMD_PREFIX "INSERT "
|
||||
#define REMOVE_CMD_PREFIX "REMOVE "
|
||||
#define SCAN_CMD_PREFIX "SCAN "
|
||||
#define ERROR_CMD_PREFIX "ERROR "
|
||||
#define RETRY_CMD_PREFIX "RETRY "
|
||||
#define FINGER_CMD_PREFIX "FINGER "
|
||||
#define SLEEP_CMD_PREFIX "SLEEP "
|
||||
#define SET_ENROLL_STAGES_PREFIX "SET_ENROLL_STAGES "
|
||||
#define SET_SCAN_TYPE_PREFIX "SET_SCAN_TYPE "
|
||||
#define SET_CANCELLATION_PREFIX "SET_CANCELLATION_ENABLED "
|
||||
#define SET_KEEP_ALIVE_PREFIX "SET_KEEP_ALIVE "
|
||||
|
||||
#define LIST_CMD "LIST"
|
||||
#define UNPLUG_CMD "UNPLUG"
|
||||
|
||||
static void
|
||||
maybe_continue_current_action (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
FpDevice *dev = FP_DEVICE (self);
|
||||
|
||||
if (self->sleep_timeout_id)
|
||||
return;
|
||||
|
||||
switch (fpi_device_get_current_action (dev))
|
||||
{
|
||||
case FPI_DEVICE_ACTION_ENROLL:
|
||||
FP_DEVICE_GET_CLASS (self)->enroll (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_VERIFY:
|
||||
FP_DEVICE_GET_CLASS (self)->verify (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_IDENTIFY:
|
||||
FP_DEVICE_GET_CLASS (self)->identify (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_LIST:
|
||||
FP_DEVICE_GET_CLASS (self)->list (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_DELETE:
|
||||
FP_DEVICE_GET_CLASS (self)->delete (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_OPEN:
|
||||
FP_DEVICE_GET_CLASS (self)->open (dev);
|
||||
break;
|
||||
|
||||
case FPI_DEVICE_ACTION_CLOSE:
|
||||
FP_DEVICE_GET_CLASS (self)->close (dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sleep_timeout_cb (gpointer data)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = data;
|
||||
|
||||
self->sleep_timeout_id = 0;
|
||||
|
||||
if (g_cancellable_is_cancelled (self->cancellable))
|
||||
return FALSE;
|
||||
|
||||
g_debug ("Sleeping completed");
|
||||
maybe_continue_current_action (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *
|
||||
process_cmds (FpDeviceVirtualDevice * self,
|
||||
gboolean scan,
|
||||
GError **error)
|
||||
{
|
||||
if (g_cancellable_is_cancelled (self->cancellable) ||
|
||||
(fpi_device_get_current_action (FP_DEVICE (self)) != FPI_DEVICE_ACTION_NONE &&
|
||||
g_cancellable_is_cancelled (fpi_device_get_cancellable (FP_DEVICE (self)))))
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
|
||||
"Operation was cancelled");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (self->pending_commands->len > 0)
|
||||
{
|
||||
gchar *cmd = g_ptr_array_index (self->pending_commands, 0);
|
||||
|
||||
g_debug ("Processing command %s", cmd);
|
||||
|
||||
/* These are always processed. */
|
||||
if (g_str_has_prefix (cmd, INSERT_CMD_PREFIX))
|
||||
{
|
||||
g_assert (self->prints_storage);
|
||||
g_hash_table_add (self->prints_storage,
|
||||
g_strdup (cmd + strlen (INSERT_CMD_PREFIX)));
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
continue;
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, REMOVE_CMD_PREFIX))
|
||||
{
|
||||
g_assert (self->prints_storage);
|
||||
if (!g_hash_table_remove (self->prints_storage,
|
||||
cmd + strlen (REMOVE_CMD_PREFIX)))
|
||||
g_warning ("ID %s was not found in storage", cmd + strlen (REMOVE_CMD_PREFIX));
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
continue;
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, SLEEP_CMD_PREFIX))
|
||||
{
|
||||
guint64 sleep_ms = g_ascii_strtoull (cmd + strlen (SLEEP_CMD_PREFIX), NULL, 10);
|
||||
|
||||
g_debug ("Sleeping %lums", sleep_ms);
|
||||
self->sleep_timeout_id = g_timeout_add (sleep_ms, sleep_timeout_cb, self);
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, ERROR_CMD_PREFIX))
|
||||
{
|
||||
g_propagate_error (error,
|
||||
fpi_device_error_new (g_ascii_strtoull (cmd + strlen (ERROR_CMD_PREFIX), NULL, 10)));
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we are not scanning, then we have to stop here. */
|
||||
if (!scan)
|
||||
{
|
||||
g_warning ("Could not process command: %s", cmd);
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_str_has_prefix (cmd, SCAN_CMD_PREFIX))
|
||||
{
|
||||
char *res = g_strdup (cmd + strlen (SCAN_CMD_PREFIX));
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
return res;
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, RETRY_CMD_PREFIX))
|
||||
{
|
||||
g_propagate_error (error,
|
||||
fpi_device_retry_new (g_ascii_strtoull (cmd + strlen (RETRY_CMD_PREFIX), NULL, 10)));
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, FINGER_CMD_PREFIX))
|
||||
{
|
||||
gboolean finger_present;
|
||||
|
||||
finger_present = g_ascii_strtoull (cmd + strlen (FINGER_CMD_PREFIX), NULL, 10) != 0;
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
finger_present ? FP_FINGER_STATUS_PRESENT : FP_FINGER_STATUS_NONE,
|
||||
finger_present ? FP_FINGER_STATUS_NONE : FP_FINGER_STATUS_PRESENT);
|
||||
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Could not process command: %s", cmd);
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* No commands left, throw a timeout error. */
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No commands left that can be run!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
write_key_to_listener (void *key, void *val, void *user_data)
|
||||
{
|
||||
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (user_data);
|
||||
|
||||
if (!fp_device_virtual_listener_write_sync (listener, key, strlen (key), NULL) ||
|
||||
!fp_device_virtual_listener_write_sync (listener, "\n", 1, NULL))
|
||||
g_warning ("Error writing reply to LIST command");
|
||||
}
|
||||
|
||||
static void
|
||||
recv_instruction_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||
gsize bytes;
|
||||
|
||||
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
|
||||
fp_dbg ("Got instructions of length %ld", bytes);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
g_warning ("Error receiving instruction data: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
FpDeviceVirtualDevice *self;
|
||||
g_autofree char *cmd = NULL;
|
||||
|
||||
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||
|
||||
cmd = g_strndup (self->recv_buf, bytes);
|
||||
fp_dbg ("Received command %s", cmd);
|
||||
|
||||
if (g_str_has_prefix (cmd, LIST_CMD))
|
||||
{
|
||||
if (self->prints_storage)
|
||||
g_hash_table_foreach (self->prints_storage, write_key_to_listener, listener);
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, UNPLUG_CMD))
|
||||
{
|
||||
fpi_device_remove (FP_DEVICE (self));
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, SET_ENROLL_STAGES_PREFIX))
|
||||
{
|
||||
guint stages;
|
||||
|
||||
stages = g_ascii_strtoull (cmd + strlen (SET_ENROLL_STAGES_PREFIX), NULL, 10);
|
||||
fpi_device_set_nr_enroll_stages (FP_DEVICE (self), stages);
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, SET_SCAN_TYPE_PREFIX))
|
||||
{
|
||||
const char *scan_type = cmd + strlen (SET_SCAN_TYPE_PREFIX);
|
||||
g_autoptr(GEnumClass) scan_types = g_type_class_ref (fp_scan_type_get_type ());
|
||||
GEnumValue *value = g_enum_get_value_by_nick (scan_types, scan_type);
|
||||
|
||||
if (value)
|
||||
fpi_device_set_scan_type (FP_DEVICE (self), value->value);
|
||||
else
|
||||
g_warning ("Scan type '%s' not found", scan_type);
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, SET_CANCELLATION_PREFIX))
|
||||
{
|
||||
self->supports_cancellation = g_ascii_strtoull (
|
||||
cmd + strlen (SET_CANCELLATION_PREFIX), NULL, 10) != 0;
|
||||
|
||||
g_debug ("Cancellation support toggled: %d",
|
||||
self->supports_cancellation);
|
||||
}
|
||||
else if (g_str_has_prefix (cmd, SET_KEEP_ALIVE_PREFIX))
|
||||
{
|
||||
self->keep_alive = g_ascii_strtoull (
|
||||
cmd + strlen (SET_KEEP_ALIVE_PREFIX), NULL, 10) != 0;
|
||||
|
||||
g_debug ("Keep alive toggled: %d", self->keep_alive);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ptr_array_add (self->pending_commands, g_steal_pointer (&cmd));
|
||||
g_clear_handle_id (&self->wait_command_id, g_source_remove);
|
||||
|
||||
maybe_continue_current_action (self);
|
||||
}
|
||||
}
|
||||
|
||||
fp_device_virtual_listener_connection_close (listener);
|
||||
}
|
||||
|
||||
static void
|
||||
recv_instruction (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
fp_device_virtual_listener_read (self->listener,
|
||||
FALSE,
|
||||
self->recv_buf,
|
||||
sizeof (self->recv_buf),
|
||||
recv_instruction_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_listener_connected (FpDeviceVirtualListener *listener,
|
||||
gpointer user_data)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||
|
||||
recv_instruction (self);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_init (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GCancellable) cancellable = NULL;
|
||||
g_autoptr(FpDeviceVirtualListener) listener = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
process_cmds (self, FALSE, &error);
|
||||
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
fpi_device_open_complete (dev, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
else if (self->sleep_timeout_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (self->listener)
|
||||
{
|
||||
fpi_device_open_complete (dev, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
listener = fp_device_virtual_listener_new ();
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
if (!fp_device_virtual_listener_start (listener,
|
||||
fpi_device_get_virtual_env (FP_DEVICE (self)),
|
||||
cancellable,
|
||||
on_listener_connected,
|
||||
self,
|
||||
&error))
|
||||
{
|
||||
fpi_device_open_complete (dev, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
self->listener = g_steal_pointer (&listener);
|
||||
self->cancellable = g_steal_pointer (&cancellable);
|
||||
|
||||
fpi_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wait_for_command_timeout (gpointer data)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (data);
|
||||
GError *error = NULL;
|
||||
|
||||
self->wait_command_id = 0;
|
||||
|
||||
switch (fpi_device_get_current_action (FP_DEVICE (self)))
|
||||
{
|
||||
case FPI_DEVICE_ACTION_LIST:
|
||||
case FPI_DEVICE_ACTION_DELETE:
|
||||
self->ignore_wait = TRUE;
|
||||
maybe_continue_current_action (self);
|
||||
self->ignore_wait = FALSE;
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
error = g_error_new (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "No commands arrived in time to run!");
|
||||
fpi_device_action_error (FP_DEVICE (self), error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
should_wait_for_command (FpDeviceVirtualDevice *self,
|
||||
GError *error)
|
||||
{
|
||||
if (!error && self->sleep_timeout_id)
|
||||
return TRUE;
|
||||
|
||||
if (self->ignore_wait)
|
||||
return FALSE;
|
||||
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
return FALSE;
|
||||
|
||||
if (self->wait_command_id)
|
||||
return FALSE;
|
||||
|
||||
self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
start_scan_command (FpDeviceVirtualDevice *self,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
g_autofree char *scan_id = NULL;
|
||||
|
||||
if (fp_device_get_finger_status (FP_DEVICE (self)) == FP_FINGER_STATUS_NONE)
|
||||
self->injected_synthetic_cmd = FALSE;
|
||||
|
||||
scan_id = process_cmds (self, TRUE, &local_error);
|
||||
|
||||
if (!self->sleep_timeout_id)
|
||||
{
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
}
|
||||
|
||||
if (should_wait_for_command (self, local_error))
|
||||
{
|
||||
g_assert (!scan_id);
|
||||
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
|
||||
"Still waiting for command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (local_error)
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
else
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_PRESENT,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
|
||||
return g_steal_pointer (&scan_id);
|
||||
}
|
||||
|
||||
gboolean
|
||||
should_wait_to_sleep (FpDeviceVirtualDevice *self,
|
||||
const char *scan_id,
|
||||
GError *error)
|
||||
{
|
||||
const gchar *cmd;
|
||||
|
||||
if (self->sleep_timeout_id)
|
||||
return TRUE;
|
||||
|
||||
if (!self->pending_commands->len)
|
||||
return FALSE;
|
||||
|
||||
cmd = g_ptr_array_index (self->pending_commands, 0);
|
||||
|
||||
if (g_str_has_prefix (cmd, SLEEP_CMD_PREFIX))
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
g_free (process_cmds (self, FALSE, &local_error));
|
||||
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return FALSE;
|
||||
|
||||
g_assert (!self->injected_synthetic_cmd);
|
||||
g_assert (self->sleep_timeout_id != 0);
|
||||
|
||||
if (!self->pending_commands->len)
|
||||
{
|
||||
g_autofree char *injected_cmd = NULL;
|
||||
|
||||
if (scan_id)
|
||||
injected_cmd = g_strconcat (SCAN_CMD_PREFIX, scan_id, NULL);
|
||||
else if (error && error->domain == FP_DEVICE_ERROR)
|
||||
injected_cmd = g_strdup_printf (ERROR_CMD_PREFIX " %d", error->code);
|
||||
else if (error && error->domain == FP_DEVICE_RETRY)
|
||||
injected_cmd = g_strdup_printf (RETRY_CMD_PREFIX " %d", error->code);
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
g_debug ("Sleeping now, command queued for later: %s", injected_cmd);
|
||||
|
||||
g_ptr_array_insert (self->pending_commands, 0, g_steal_pointer (&injected_cmd));
|
||||
self->injected_synthetic_cmd = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return self->sleep_timeout_id != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dev_verify (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
g_autofree char *scan_id = NULL;
|
||||
|
||||
scan_id = start_scan_command (self, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
|
||||
return;
|
||||
|
||||
if (scan_id)
|
||||
{
|
||||
GVariant *data = NULL;
|
||||
FpPrint *new_scan;
|
||||
FpPrint *print;
|
||||
gboolean success;
|
||||
|
||||
g_debug ("Virtual device scanned print %s", scan_id);
|
||||
fpi_device_get_verify_data (dev, &print);
|
||||
|
||||
new_scan = fp_print_new (dev);
|
||||
fpi_print_set_type (new_scan, FPI_PRINT_RAW);
|
||||
if (self->prints_storage)
|
||||
fpi_print_set_device_stored (new_scan, TRUE);
|
||||
data = g_variant_new_string (scan_id);
|
||||
g_object_set (new_scan, "fpi-data", data, NULL);
|
||||
|
||||
if (self->prints_storage && !g_hash_table_contains (self->prints_storage, scan_id))
|
||||
{
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND);
|
||||
success = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = fp_print_equal (print, new_scan);
|
||||
}
|
||||
|
||||
if (!self->match_reported)
|
||||
{
|
||||
self->match_reported = TRUE;
|
||||
fpi_device_verify_report (dev,
|
||||
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
||||
new_scan,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
g_debug ("Virtual device scan failed with error: %s", error->message);
|
||||
}
|
||||
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
|
||||
if (error && error->domain == FP_DEVICE_RETRY)
|
||||
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
|
||||
|
||||
if (should_wait_to_sleep (self, scan_id, error))
|
||||
return;
|
||||
|
||||
self->match_reported = FALSE;
|
||||
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
static void
|
||||
dev_enroll (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
FpPrint *print = NULL;
|
||||
g_autofree char *id = NULL;
|
||||
|
||||
id = start_scan_command (self, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
|
||||
return;
|
||||
|
||||
fpi_device_get_enroll_data (dev, &print);
|
||||
|
||||
if (id)
|
||||
{
|
||||
GVariant *data;
|
||||
gboolean completed;
|
||||
|
||||
if (self->prints_storage && g_hash_table_contains (self->prints_storage, id))
|
||||
{
|
||||
if (should_wait_to_sleep (self, id, error))
|
||||
return;
|
||||
|
||||
fpi_device_enroll_complete (dev, NULL,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->enroll_stages_passed == 0)
|
||||
{
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
data = g_variant_new_string (id);
|
||||
g_object_set (print, "fpi-data", data, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gboolean changed;
|
||||
|
||||
g_object_get (print, "fpi-data", &data, NULL);
|
||||
changed = !g_str_equal (id, g_variant_get_string (data, NULL));
|
||||
g_variant_unref (data);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
g_set_error (&error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL, "ID Mismatch");
|
||||
fpi_device_enroll_progress (dev, self->enroll_stages_passed, NULL,
|
||||
g_steal_pointer (&error));
|
||||
|
||||
if (!should_wait_to_sleep (self, id, error))
|
||||
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self->enroll_stages_passed++;
|
||||
completed = self->enroll_stages_passed == fp_device_get_nr_enroll_stages (FP_DEVICE (self));
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
completed ?
|
||||
FP_FINGER_STATUS_NEEDED :
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
|
||||
fpi_device_enroll_progress (dev, self->enroll_stages_passed, print, NULL);
|
||||
|
||||
if (completed)
|
||||
{
|
||||
if (self->prints_storage)
|
||||
{
|
||||
fpi_print_set_device_stored (print, TRUE);
|
||||
g_hash_table_add (self->prints_storage, g_strdup (id));
|
||||
}
|
||||
|
||||
fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
|
||||
self->enroll_stages_passed = 0;
|
||||
}
|
||||
else if (!should_wait_to_sleep (self, id, error))
|
||||
{
|
||||
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
|
||||
if (error && error->domain == FP_DEVICE_RETRY)
|
||||
{
|
||||
fpi_device_enroll_progress (dev, self->enroll_stages_passed, NULL, g_steal_pointer (&error));
|
||||
|
||||
if (!should_wait_to_sleep (self, id, error))
|
||||
self->sleep_timeout_id = g_idle_add (sleep_timeout_cb, self);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (should_wait_to_sleep (self, id, error))
|
||||
return;
|
||||
|
||||
self->enroll_stages_passed = 0;
|
||||
fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dev_cancel (FpDevice *dev)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
|
||||
if (self->injected_synthetic_cmd)
|
||||
{
|
||||
self->injected_synthetic_cmd = FALSE;
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
}
|
||||
|
||||
if (!self->supports_cancellation)
|
||||
return;
|
||||
|
||||
g_debug ("Got cancellation!");
|
||||
g_clear_handle_id (&self->sleep_timeout_id, g_source_remove);
|
||||
|
||||
maybe_continue_current_action (self);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_listener (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->listener);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_deinit (FpDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
|
||||
process_cmds (self, FALSE, &error);
|
||||
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
fpi_device_close_complete (dev, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
else if (self->sleep_timeout_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_handle_id (&self->wait_command_id, g_source_remove);
|
||||
g_clear_handle_id (&self->sleep_timeout_id, g_source_remove);
|
||||
|
||||
if (!self->keep_alive)
|
||||
stop_listener (self);
|
||||
|
||||
fpi_device_close_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_finalize (GObject *object)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
stop_listener (self);
|
||||
g_clear_pointer (&self->pending_commands, g_ptr_array_unref);
|
||||
G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_init (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
self->supports_cancellation = TRUE;
|
||||
self->pending_commands = g_ptr_array_new_with_free_func (g_free);
|
||||
}
|
||||
|
||||
static const FpIdEntry driver_ids[] = {
|
||||
{ .virtual_envvar = "FP_VIRTUAL_DEVICE", },
|
||||
{ .virtual_envvar = NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = fpi_device_virtual_device_finalize;
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual device for debugging";
|
||||
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||
dev_class->id_table = driver_ids;
|
||||
dev_class->nr_enroll_stages = 5;
|
||||
|
||||
dev_class->open = dev_init;
|
||||
dev_class->close = dev_deinit;
|
||||
dev_class->verify = dev_verify;
|
||||
dev_class->enroll = dev_enroll;
|
||||
dev_class->cancel = dev_cancel;
|
||||
}
|
||||
@@ -29,25 +29,18 @@
|
||||
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "virtual-device-private.h"
|
||||
|
||||
#include "../fpi-image.h"
|
||||
#include "../fpi-image-device.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixsocketaddress.h>
|
||||
|
||||
struct _FpDeviceVirtualImage
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
GSocketListener *listener;
|
||||
GSocketConnection *connection;
|
||||
GCancellable *listen_cancellable;
|
||||
FpDeviceVirtualListener *listener;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gint socket_fd;
|
||||
gint client_fd;
|
||||
|
||||
gboolean automatic_finger;
|
||||
FpImage *recv_img;
|
||||
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_DEFINE_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FP_TYPE_IMAGE_DEVICE)
|
||||
|
||||
static void start_listen (FpDeviceVirtualImage *dev);
|
||||
static void recv_image (FpDeviceVirtualImage *dev,
|
||||
GInputStream *stream);
|
||||
static void recv_image (FpDeviceVirtualImage *self);
|
||||
|
||||
static void
|
||||
recv_image_img_recv_cb (GObject *source_object,
|
||||
@@ -66,35 +57,20 @@ recv_image_img_recv_cb (GObject *source_object,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||
FpDeviceVirtualImage *self;
|
||||
FpImageDevice *device;
|
||||
gboolean success;
|
||||
gsize bytes = 0;
|
||||
gsize bytes;
|
||||
|
||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
||||
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
|
||||
|
||||
/* Can't use self if the operation was cancelled. */
|
||||
if (!success && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
if (!bytes || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
|
||||
return;
|
||||
|
||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
device = FP_IMAGE_DEVICE (self);
|
||||
|
||||
/* Consider success if we received the right amount of data, otherwise
|
||||
* an error must have happened. */
|
||||
if (bytes < self->recv_img->width * self->recv_img->height)
|
||||
{
|
||||
if (!success)
|
||||
g_warning ("Error receiving image data: %s", error->message);
|
||||
else
|
||||
g_warning ("Error receiving image data: end of stream before all data was read");
|
||||
|
||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->automatic_finger)
|
||||
fpi_image_device_report_finger_status (device, TRUE);
|
||||
fpi_image_device_image_captured (device, g_steal_pointer (&self->recv_img));
|
||||
@@ -102,7 +78,7 @@ recv_image_img_recv_cb (GObject *source_object,
|
||||
fpi_image_device_report_finger_status (device, FALSE);
|
||||
|
||||
/* And, listen for more images from the same client. */
|
||||
recv_image (self, G_INPUT_STREAM (source_object));
|
||||
recv_image (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -112,37 +88,30 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualImage *self;
|
||||
gboolean success;
|
||||
FpDeviceVirtualListener *listener = FP_DEVICE_VIRTUAL_LISTENER (source_object);
|
||||
gsize bytes;
|
||||
|
||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
||||
bytes = fp_device_virtual_listener_read_finish (listener, res, &error);
|
||||
|
||||
if (!success || bytes != sizeof (self->recv_img_hdr))
|
||||
{
|
||||
if (!success)
|
||||
if (error)
|
||||
{
|
||||
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;
|
||||
|
||||
g_warning ("Error receiving header for image data: %s", error->message);
|
||||
}
|
||||
else if (bytes != 0)
|
||||
{
|
||||
g_warning ("Received incomplete header before end of stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
if (!bytes)
|
||||
return;
|
||||
}
|
||||
|
||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000)
|
||||
{
|
||||
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
fp_device_virtual_listener_connection_close (listener);
|
||||
}
|
||||
|
||||
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
|
||||
@@ -178,153 +147,80 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||
|
||||
default:
|
||||
/* disconnect client, it didn't play fair */
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
fp_device_virtual_listener_connection_close (listener);
|
||||
}
|
||||
|
||||
/* And, listen for more images from the same client. */
|
||||
recv_image (self, G_INPUT_STREAM (source_object));
|
||||
recv_image (self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
|
||||
g_debug ("image data: %p", self->recv_img->data);
|
||||
g_input_stream_read_all_async (G_INPUT_STREAM (source_object),
|
||||
fp_device_virtual_listener_read (listener,
|
||||
TRUE,
|
||||
(guint8 *) self->recv_img->data,
|
||||
self->recv_img->width * self->recv_img->height,
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
recv_image_img_recv_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
recv_image (FpDeviceVirtualImage *self, GInputStream *stream)
|
||||
recv_image (FpDeviceVirtualImage *self)
|
||||
{
|
||||
FpiImageDeviceState state;
|
||||
|
||||
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_IDLE)
|
||||
{
|
||||
g_input_stream_read_all_async (stream,
|
||||
fp_device_virtual_listener_read (self->listener,
|
||||
TRUE,
|
||||
self->recv_img_hdr,
|
||||
sizeof (self->recv_img_hdr),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
recv_image_hdr_recv_cb,
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||
on_listener_connected (FpDeviceVirtualListener *listener,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
GSocketConnection *connection;
|
||||
GInputStream *stream;
|
||||
FpDeviceVirtualImage *dev = user_data;
|
||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
FpiImageDeviceState state;
|
||||
|
||||
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))
|
||||
self->automatic_finger = TRUE;
|
||||
|
||||
g_object_get (self,
|
||||
"fpi-image-device-state", &state,
|
||||
NULL);
|
||||
/* Only read if we are in AWAIT_FINGER_* or CAPTURE states */
|
||||
if (state <= FPI_IMAGE_DEVICE_STATE_DEACTIVATING)
|
||||
return;
|
||||
|
||||
g_warning ("Error accepting a new connection: %s", error->message);
|
||||
start_listen (dev);
|
||||
}
|
||||
|
||||
/* Always accept further connections (but we disconnect them immediately
|
||||
* if we already have a connection). */
|
||||
start_listen (dev);
|
||||
|
||||
if (dev->connection)
|
||||
{
|
||||
/* We may not have noticed that the stream was closed,
|
||||
* if the device is deactivated.
|
||||
* Cancel any ongoing operation on the old connection. */
|
||||
g_cancellable_cancel (dev->cancellable);
|
||||
g_clear_object (&dev->cancellable);
|
||||
dev->cancellable = g_cancellable_new ();
|
||||
|
||||
g_clear_object (&dev->connection);
|
||||
}
|
||||
|
||||
if (dev->connection)
|
||||
{
|
||||
g_warning ("Rejecting new connection");
|
||||
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||
g_object_unref (connection);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->connection = connection;
|
||||
dev->automatic_finger = TRUE;
|
||||
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
|
||||
|
||||
fp_dbg ("Got a new connection!");
|
||||
recv_image (dev, stream);
|
||||
}
|
||||
|
||||
static void
|
||||
start_listen (FpDeviceVirtualImage *dev)
|
||||
{
|
||||
g_socket_listener_accept_async (dev->listener,
|
||||
dev->listen_cancellable,
|
||||
new_connection_cb,
|
||||
dev);
|
||||
recv_image (self);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GSocketListener) listener = NULL;
|
||||
g_autoptr(FpDeviceVirtualListener) listener = NULL;
|
||||
g_autoptr(GCancellable) cancellable = NULL;
|
||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||
const char *env;
|
||||
|
||||
g_autoptr(GSocketAddress) addr = NULL;
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
self->client_fd = -1;
|
||||
listener = fp_device_virtual_listener_new ();
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||
|
||||
listener = g_socket_listener_new ();
|
||||
g_socket_listener_set_backlog (listener, 1);
|
||||
|
||||
/* Remove any left over socket. */
|
||||
g_unlink (env);
|
||||
|
||||
addr = g_unix_socket_address_new (env);
|
||||
|
||||
if (!g_socket_listener_add_address (listener,
|
||||
addr,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
if (!fp_device_virtual_listener_start (listener,
|
||||
fpi_device_get_virtual_env (FP_DEVICE (self)),
|
||||
cancellable,
|
||||
on_listener_connected,
|
||||
self,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||
|
||||
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
||||
|
||||
fpi_image_device_open_complete (dev, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
self->listener = g_steal_pointer (&listener);
|
||||
self->cancellable = g_cancellable_new ();
|
||||
self->listen_cancellable = g_cancellable_new ();
|
||||
|
||||
start_listen (self);
|
||||
self->cancellable = g_steal_pointer (&cancellable);
|
||||
|
||||
/* Delay result to open up the possibility of testing race conditions. */
|
||||
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_open_complete, NULL, NULL);
|
||||
@@ -338,11 +234,8 @@ dev_deinit (FpImageDevice *dev)
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_cancellable_cancel (self->listen_cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->listen_cancellable);
|
||||
g_clear_object (&self->listener);
|
||||
g_clear_object (&self->connection);
|
||||
|
||||
/* Delay result to open up the possibility of testing race conditions. */
|
||||
fpi_device_add_timeout (FP_DEVICE (dev), 100, (FpTimeoutFunc) fpi_image_device_close_complete, NULL, NULL);
|
||||
@@ -353,23 +246,16 @@ dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||
|
||||
fpi_image_device_activate_complete (dev, NULL);
|
||||
/* Start reading (again). */
|
||||
recv_image (self);
|
||||
|
||||
if (self->connection)
|
||||
recv_image (self, g_io_stream_get_input_stream (G_IO_STREAM (self->connection)));
|
||||
fpi_image_device_activate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
/* XXX: Need to wait for the operation to be cancelled. */
|
||||
fpi_device_add_timeout (FP_DEVICE (dev), 10, (FpTimeoutFunc) fpi_image_device_deactivate_complete, NULL, NULL);
|
||||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
676
libfprint/drivers/virtual-sdcp.c
Normal file
676
libfprint/drivers/virtual-sdcp.c
Normal file
@@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Virtual driver for SDCP device debugging
|
||||
*
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a virtual test driver to test the basic SDCP functionality.
|
||||
* It uses the test binaries from Microsoft, which were extended to allow
|
||||
* a simple chat with the device.
|
||||
* The environment variable contains the to be executed binary including
|
||||
* arguments. This binary should be compiled from the code in
|
||||
* https://github.com/Microsoft/SecureDeviceConnectionProtocol
|
||||
* or, until it is merged upstream
|
||||
* https://github.com/benzea/SecureDeviceConnectionProtocol
|
||||
*
|
||||
* Note that using this as an external executable has the advantage that we
|
||||
* do not need to link against mbedtls or any other crypto library.
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "virtual_sdcp"
|
||||
|
||||
#include "fpi-log.h"
|
||||
#include "fpi-ssm.h"
|
||||
|
||||
#include "../fpi-sdcp-device.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
struct _FpDeviceVirtualSdcp
|
||||
{
|
||||
FpSdcpDevice parent;
|
||||
|
||||
GSubprocess *proc;
|
||||
GOutputStream *proc_stdin;
|
||||
GInputStream *proc_stdout;
|
||||
|
||||
/* Only valid while a read/write is pending */
|
||||
GByteArray *msg_out;
|
||||
GByteArray *msg_in;
|
||||
|
||||
GByteArray *connect_msg;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FPI, DEVICE_VIRTUAL_SDCP, FpSdcpDevice)
|
||||
G_DEFINE_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FP_TYPE_SDCP_DEVICE)
|
||||
|
||||
guint8 ca_1[] = {
|
||||
0x30, 0x82, 0x03, 0xFD, 0x30, 0x82, 0x03, 0x82, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
|
||||
0x00, 0x00, 0x00, 0x07, 0xE8, 0x9D, 0x61, 0x62, 0x4D, 0x46, 0x0F, 0x95, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81,
|
||||
0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
|
||||
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
|
||||
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
|
||||
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
|
||||
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25,
|
||||
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65,
|
||||
0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41,
|
||||
0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x33, 0x31, 0x31,
|
||||
0x39, 0x35, 0x34, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x31, 0x33, 0x31, 0x32, 0x30,
|
||||
0x30, 0x34, 0x35, 0x33, 0x5A, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57,
|
||||
0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
|
||||
0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06,
|
||||
0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20,
|
||||
0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65,
|
||||
0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20,
|
||||
0x32, 0x30, 0x31, 0x38, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
|
||||
0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBE,
|
||||
0x4B, 0x90, 0x6E, 0x24, 0xFC, 0xA1, 0x53, 0xC8, 0xA7, 0x3C, 0x70, 0xE8, 0x97, 0xCD, 0x1B, 0x31,
|
||||
0xE4, 0x95, 0x91, 0x7A, 0x58, 0xA2, 0x86, 0xA8, 0x70, 0xF6, 0x09, 0x30, 0x77, 0x99, 0x3D, 0x10,
|
||||
0xDF, 0xF7, 0x95, 0x0F, 0x68, 0x83, 0xE6, 0xA4, 0x11, 0x7C, 0xDA, 0x82, 0xE7, 0x0B, 0x8B, 0xF2,
|
||||
0x9D, 0x6B, 0x5B, 0xF5, 0x3E, 0x77, 0xB4, 0xC1, 0x0E, 0x49, 0x00, 0x83, 0xBA, 0x94, 0xF8, 0xA3,
|
||||
0x82, 0x01, 0xD7, 0x30, 0x82, 0x01, 0xD3, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01,
|
||||
0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
|
||||
0x04, 0x16, 0x04, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB,
|
||||
0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04,
|
||||
0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B,
|
||||
0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06,
|
||||
0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A,
|
||||
0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E,
|
||||
0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F,
|
||||
0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30,
|
||||
0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A,
|
||||
0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D,
|
||||
0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01,
|
||||
0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04,
|
||||
0x18, 0x30, 0x16, 0x80, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB,
|
||||
0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x68, 0x06, 0x03, 0x55, 0x1D, 0x1F,
|
||||
0x04, 0x61, 0x30, 0x5F, 0x30, 0x5D, 0xA0, 0x5B, 0xA0, 0x59, 0x86, 0x57, 0x68, 0x74, 0x74, 0x70,
|
||||
0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
|
||||
0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F,
|
||||
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25,
|
||||
0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E,
|
||||
0x63, 0x72, 0x6C, 0x30, 0x75, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
|
||||
0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86,
|
||||
0x59, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
|
||||
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
|
||||
0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32,
|
||||
0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25,
|
||||
0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25,
|
||||
0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86,
|
||||
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x87, 0xB6,
|
||||
0x82, 0xF3, 0xDA, 0xBE, 0xB1, 0x7B, 0x98, 0x7D, 0x3D, 0x0A, 0x90, 0xA8, 0xF5, 0xBF, 0x15, 0xC3,
|
||||
0xEE, 0x8A, 0x4E, 0xC0, 0x7B, 0x10, 0x1D, 0xA9, 0xE3, 0x0B, 0xEC, 0x2C, 0x53, 0x4E, 0xA7, 0xBD,
|
||||
0xF1, 0x6C, 0xAD, 0x18, 0x55, 0xBA, 0x25, 0x73, 0x55, 0xB7, 0x5B, 0x12, 0x24, 0xF4, 0x02, 0x31,
|
||||
0x00, 0xAF, 0x02, 0x9C, 0x4B, 0x92, 0xD0, 0x72, 0xA5, 0x80, 0xCA, 0x69, 0x2B, 0x38, 0x50, 0x64,
|
||||
0xD8, 0x58, 0x9E, 0xEA, 0xD6, 0x35, 0xCF, 0x68, 0x98, 0x92, 0x81, 0x09, 0x61, 0xC2, 0xBD, 0xB1,
|
||||
0x4C, 0x7F, 0xAE, 0x55, 0x7B, 0xFC, 0x22, 0xDD, 0xD6, 0xB7, 0x7C, 0xB5, 0xA8, 0x18, 0x5D, 0x33,
|
||||
0x04
|
||||
};
|
||||
guint8 ca_2[] = {
|
||||
0x30, 0x82, 0x04, 0x56, 0x30, 0x82, 0x03, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
|
||||
0x00, 0x00, 0x00, 0x03, 0x6C, 0xCF, 0xED, 0xE2, 0x44, 0x70, 0x19, 0xBF, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81,
|
||||
0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
|
||||
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
|
||||
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
|
||||
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
|
||||
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x3E, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35,
|
||||
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x44, 0x65,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
|
||||
0x20, 0x32, 0x30, 0x31, 0x37, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x31,
|
||||
0x39, 0x34, 0x39, 0x33, 0x38, 0x5A, 0x17, 0x0D, 0x33, 0x33, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39,
|
||||
0x35, 0x39, 0x33, 0x38, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A,
|
||||
0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
|
||||
0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C,
|
||||
0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
|
||||
0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48,
|
||||
0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x76, 0x30, 0x10,
|
||||
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22,
|
||||
0x03, 0x62, 0x00, 0x04, 0x1D, 0xDD, 0x08, 0x02, 0x03, 0x25, 0x75, 0x20, 0xE2, 0x71, 0x8B, 0xAD,
|
||||
0x28, 0x09, 0x82, 0xE9, 0x06, 0xEE, 0x83, 0xC5, 0x3A, 0x6C, 0x4B, 0x71, 0x92, 0x50, 0x4E, 0x20,
|
||||
0xE9, 0x72, 0xB4, 0xFC, 0x53, 0x2A, 0xEF, 0x5D, 0xCC, 0x9A, 0xB4, 0xCD, 0x76, 0xB8, 0x94, 0x97,
|
||||
0x44, 0xB2, 0x71, 0x0E, 0xC9, 0xB1, 0x16, 0x03, 0xA1, 0x65, 0x2B, 0xB9, 0xE8, 0x5D, 0x5F, 0xF2,
|
||||
0x30, 0x2E, 0xDD, 0xB1, 0x2B, 0x20, 0xFC, 0xBE, 0x00, 0x88, 0xEA, 0x1F, 0xA7, 0x7F, 0x99, 0x84,
|
||||
0x98, 0x7C, 0x71, 0x3E, 0x4D, 0x34, 0x83, 0x69, 0x9B, 0x08, 0xCB, 0x78, 0xB2, 0x4B, 0xBD, 0xD7,
|
||||
0x3E, 0xBE, 0x67, 0xA0, 0xA3, 0x82, 0x01, 0xFC, 0x30, 0x82, 0x01, 0xF8, 0x30, 0x10, 0x06, 0x09,
|
||||
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D,
|
||||
0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03,
|
||||
0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x65, 0x06,
|
||||
0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00,
|
||||
0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01,
|
||||
0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34,
|
||||
0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F,
|
||||
0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F,
|
||||
0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E,
|
||||
0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
|
||||
0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30,
|
||||
0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03,
|
||||
0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06,
|
||||
0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x14, 0xDA, 0x5B, 0xF1, 0x0E, 0x66,
|
||||
0x47, 0xD1, 0x5D, 0x13, 0x5F, 0x5B, 0x7A, 0xEB, 0xEB, 0x5F, 0x01, 0x08, 0xB5, 0x49, 0x30, 0x7A,
|
||||
0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x73, 0x30, 0x71, 0x30, 0x6F, 0xA0, 0x6D, 0xA0, 0x6B, 0x86,
|
||||
0x69, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
|
||||
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
|
||||
0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32,
|
||||
0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32,
|
||||
0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25,
|
||||
0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x81, 0x87, 0x06, 0x08, 0x2B,
|
||||
0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7B, 0x30, 0x79, 0x30, 0x77, 0x06, 0x08, 0x2B,
|
||||
0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x6B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
|
||||
0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F,
|
||||
0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x4D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32,
|
||||
0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25,
|
||||
0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30,
|
||||
0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37,
|
||||
0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
|
||||
0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x56, 0x2A, 0xAD, 0x72, 0x4C, 0xB9, 0x8C, 0xB3, 0x23,
|
||||
0x80, 0xF5, 0x5F, 0xF8, 0x21, 0x94, 0x66, 0x0F, 0x76, 0x77, 0xE2, 0x7B, 0x03, 0xDD, 0x30, 0x5E,
|
||||
0xCB, 0x90, 0xCA, 0x78, 0xE6, 0x0B, 0x2D, 0x12, 0xE5, 0xF7, 0x67, 0x31, 0x58, 0x71, 0xE6, 0xF3,
|
||||
0x64, 0xC1, 0x04, 0xB3, 0x8B, 0xE9, 0xE2, 0x02, 0x31, 0x00, 0xB9, 0x20, 0x61, 0xB9, 0xD0, 0x5E,
|
||||
0x3A, 0xA4, 0xA2, 0x8A, 0xFE, 0x1D, 0xFC, 0x27, 0x61, 0x0B, 0x98, 0x16, 0x8C, 0x02, 0x9C, 0x20,
|
||||
0x7F, 0xEE, 0xF3, 0xCB, 0x1F, 0x0A, 0x37, 0x62, 0xB1, 0x8E, 0xCE, 0xD9, 0x9A, 0x9E, 0xAC, 0xE6,
|
||||
0x1A, 0xD4, 0xB8, 0xF1, 0xA8, 0x2B, 0xB1, 0xB4, 0x40, 0x9B
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
msg_written_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
|
||||
FpiSsm *ssm = user_data;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
|
||||
|
||||
g_clear_pointer (&self->msg_out, g_byte_array_unref);
|
||||
g_assert (self->msg_out == NULL);
|
||||
|
||||
if (!g_output_stream_write_all_finish (stream, res, NULL, &error))
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
msg_received_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GInputStream *stream = G_INPUT_STREAM (source_object);
|
||||
FpiSsm *ssm = user_data;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
|
||||
gsize read;
|
||||
|
||||
g_assert (self->msg_out == NULL);
|
||||
|
||||
if (!g_input_stream_read_all_finish (stream, res, &read, &error) ||
|
||||
read != self->msg_in->len)
|
||||
{
|
||||
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||
|
||||
if (!error)
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Received EOF while reading from test binary.");
|
||||
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
|
||||
enum {
|
||||
SEND_MESSAGE,
|
||||
RECV_MESSAGE,
|
||||
SEND_RECV_STATES
|
||||
};
|
||||
|
||||
static void
|
||||
send_recv_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||
{
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case SEND_MESSAGE:
|
||||
g_output_stream_write_all_async (self->proc_stdin,
|
||||
self->msg_out->data,
|
||||
self->msg_out->len,
|
||||
G_PRIORITY_DEFAULT,
|
||||
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||
msg_written_cb,
|
||||
ssm);
|
||||
break;
|
||||
|
||||
case RECV_MESSAGE:
|
||||
g_input_stream_read_all_async (self->proc_stdout,
|
||||
self->msg_in->data,
|
||||
self->msg_in->len,
|
||||
G_PRIORITY_DEFAULT,
|
||||
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||
msg_received_cb,
|
||||
ssm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connect_2_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
g_autoptr(GBytes) recv_data = NULL;
|
||||
g_autoptr(GBytes) r_d = NULL;
|
||||
g_autoptr(FpiSdcpClaim) claim = NULL;
|
||||
g_autoptr(GBytes) mac = NULL;
|
||||
g_autoptr(GBytes) ca_1_bytes = NULL, ca_2_bytes = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
guint16 cert_size;
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
|
||||
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (&cert_size, self->connect_msg->data + 32, 2);
|
||||
g_byte_array_append (self->connect_msg, self->msg_in->data, self->msg_in->len);
|
||||
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||
/* Double check that the size is correct. */
|
||||
g_assert (self->connect_msg->len == 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32);
|
||||
recv_data = g_byte_array_free_to_bytes (g_steal_pointer (&self->connect_msg));
|
||||
|
||||
claim = fpi_sdcp_claim_new ();
|
||||
r_d = g_bytes_new_from_bytes (recv_data, 0, 32);
|
||||
claim->cert_m = g_bytes_new_from_bytes (recv_data, 34, cert_size);
|
||||
claim->pk_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size, 65);
|
||||
claim->pk_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65, 65);
|
||||
claim->h_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65, 32);
|
||||
claim->s_m = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32, 64);
|
||||
claim->s_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64, 64);
|
||||
mac = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64 + 64, 32);
|
||||
|
||||
ca_1_bytes = g_bytes_new_static (ca_1, G_N_ELEMENTS (ca_1));
|
||||
ca_2_bytes = g_bytes_new_static (ca_2, G_N_ELEMENTS (ca_2));
|
||||
|
||||
fpi_sdcp_device_set_intermediat_cas (FP_SDCP_DEVICE (dev),
|
||||
ca_1_bytes,
|
||||
ca_2_bytes);
|
||||
|
||||
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), r_d, claim, mac, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
connect_1_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
guint16 cert_size;
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
|
||||
self->connect_msg = g_steal_pointer (&self->msg_in);
|
||||
|
||||
memcpy (&cert_size, self->connect_msg->data + 32, 2);
|
||||
|
||||
/* Nothing to send and the rest to receive. */
|
||||
self->msg_out = g_byte_array_new ();
|
||||
self->msg_in = g_byte_array_new ();
|
||||
g_byte_array_set_size (self->msg_in, 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32 - self->connect_msg->len);
|
||||
|
||||
/* New SSM */
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect 2");
|
||||
fpi_ssm_start (ssm, connect_2_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
connect (FpSdcpDevice *dev)
|
||||
{
|
||||
g_autoptr(GBytes) r_h = NULL;
|
||||
g_autoptr(GBytes) pk_h = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_assert (self->proc);
|
||||
g_assert (self->connect_msg == NULL);
|
||||
|
||||
fpi_sdcp_device_get_connect_data (dev, &r_h, &pk_h);
|
||||
|
||||
self->msg_out = g_byte_array_new ();
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "C", 1);
|
||||
g_byte_array_append (self->msg_out,
|
||||
g_bytes_get_data (r_h, NULL),
|
||||
g_bytes_get_size (r_h));
|
||||
g_byte_array_append (self->msg_out,
|
||||
g_bytes_get_data (pk_h, NULL),
|
||||
g_bytes_get_size (pk_h));
|
||||
|
||||
self->msg_in = g_byte_array_new ();
|
||||
g_byte_array_set_size (self->msg_in, 34);
|
||||
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect");
|
||||
fpi_ssm_start (ssm, connect_1_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
reconnect_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
g_autoptr(GBytes) mac = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, error);
|
||||
return;
|
||||
}
|
||||
|
||||
mac = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||
|
||||
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
reconnect (FpSdcpDevice *dev)
|
||||
{
|
||||
g_autoptr(GBytes) r_h = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_assert (self->proc);
|
||||
|
||||
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||
|
||||
self->msg_out = g_byte_array_new ();
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "R", 1);
|
||||
g_byte_array_append (self->msg_out,
|
||||
g_bytes_get_data (r_h, NULL),
|
||||
g_bytes_get_size (r_h));
|
||||
|
||||
self->msg_in = g_byte_array_new ();
|
||||
g_byte_array_set_size (self->msg_in, 32);
|
||||
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "connect 2");
|
||||
fpi_ssm_start (ssm, reconnect_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_begin_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
g_autoptr(GBytes) nonce = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
|
||||
return;
|
||||
}
|
||||
|
||||
nonce = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||
|
||||
fpi_sdcp_device_enroll_set_nonce (FP_SDCP_DEVICE (dev), nonce);
|
||||
|
||||
/* Claim that we completed one enroll step. */
|
||||
fpi_device_enroll_progress (dev, 1, NULL, NULL);
|
||||
|
||||
/* And signal that we are ready to commit. */
|
||||
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_begin (FpSdcpDevice *dev)
|
||||
{
|
||||
g_autoptr(GBytes) r_h = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_assert (self->proc);
|
||||
|
||||
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||
|
||||
self->msg_out = g_byte_array_new ();
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "E", 1);
|
||||
|
||||
/* Expect 32 byte nonce */
|
||||
self->msg_in = g_byte_array_new ();
|
||||
g_byte_array_set_size (self->msg_in, 32);
|
||||
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "enroll_begin");
|
||||
fpi_ssm_start (ssm, enroll_begin_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_commit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
|
||||
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Signal that we have committed. We don't expect a response
|
||||
* from the virtual device (even though that is kind of broken).
|
||||
*/
|
||||
fpi_sdcp_device_enroll_commit_complete (FP_SDCP_DEVICE (dev), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
enroll_commit (FpSdcpDevice *dev, GBytes *id_in)
|
||||
{
|
||||
g_autoptr(GBytes) r_h = NULL;
|
||||
g_autoptr(GBytes) id = id_in;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_assert (self->proc);
|
||||
|
||||
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||
|
||||
self->msg_out = g_byte_array_new ();
|
||||
self->msg_in = g_byte_array_new ();
|
||||
if (id)
|
||||
{
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "F", 1);
|
||||
g_byte_array_append (self->msg_out,
|
||||
g_bytes_get_data (id, NULL),
|
||||
g_bytes_get_size (id));
|
||||
|
||||
/* NOTE: No response from device, assume commit works. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cancel enroll (does not receive a reply) */
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "G", 1);
|
||||
|
||||
/* NOTE: No response from device, assume cancellation works. */
|
||||
}
|
||||
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "enroll_commit");
|
||||
fpi_ssm_start (ssm, enroll_commit_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
identify_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
g_autoptr(GBytes) reply = NULL;
|
||||
g_autoptr(GBytes) id = NULL;
|
||||
g_autoptr(GBytes) mac = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (dev), NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
reply = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||
id = g_bytes_new_from_bytes (reply, 0, 32);
|
||||
mac = g_bytes_new_from_bytes (reply, 32, 32);
|
||||
|
||||
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (self), id, mac, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
identify (FpSdcpDevice *dev)
|
||||
{
|
||||
g_autoptr(GBytes) nonce = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_assert (self->proc);
|
||||
|
||||
fpi_sdcp_device_get_identify_data (dev, &nonce);
|
||||
|
||||
self->msg_out = g_byte_array_new ();
|
||||
g_byte_array_append (self->msg_out, (const guint8 *) "I", 1);
|
||||
g_byte_array_append (self->msg_out, g_bytes_get_data (nonce, NULL), g_bytes_get_size (nonce));
|
||||
|
||||
/* Expect 64 byte nonce */
|
||||
self->msg_in = g_byte_array_new ();
|
||||
g_byte_array_set_size (self->msg_in, 64);
|
||||
|
||||
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, "identify");
|
||||
fpi_ssm_start (ssm, identify_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
probe (FpDevice *dev)
|
||||
{
|
||||
g_auto(GStrv) argv = NULL;
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||
GError *error = NULL;
|
||||
const char *env;
|
||||
|
||||
/* We launch the test binary alread at probe time and quit only when
|
||||
* the object is finalized. This allows testing reconnect properly.
|
||||
*
|
||||
* Also, we'll fail probe if something goes wrong executing it.
|
||||
*/
|
||||
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||
|
||||
if (!g_shell_parse_argv (env, NULL, &argv, &error))
|
||||
goto out;
|
||||
|
||||
self->proc = g_subprocess_newv ((const char * const *) argv,
|
||||
G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
||||
&error);
|
||||
if (!self->proc)
|
||||
goto out;
|
||||
|
||||
self->proc_stdin = g_object_ref (g_subprocess_get_stdin_pipe (self->proc));
|
||||
self->proc_stdout = g_object_ref (g_subprocess_get_stdout_pipe (self->proc));
|
||||
|
||||
|
||||
out:
|
||||
fpi_device_probe_complete (dev, "virtual-sdcp", NULL, error);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_close (FpDevice *dev)
|
||||
{
|
||||
/* No-op, needs to be defined. */
|
||||
fpi_device_close_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_sdcp_init (FpDeviceVirtualSdcp *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_sdcp_finalize (GObject *obj)
|
||||
{
|
||||
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (obj);
|
||||
|
||||
/* Just kill the subprocess, no need to be graceful here. */
|
||||
if (self->proc)
|
||||
g_subprocess_force_exit (self->proc);
|
||||
|
||||
g_clear_object (&self->proc);
|
||||
g_clear_object (&self->proc_stdin);
|
||||
g_clear_object (&self->proc_stdout);
|
||||
|
||||
G_OBJECT_CLASS (fpi_device_virtual_sdcp_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static const FpIdEntry driver_ids[] = {
|
||||
{ .virtual_envvar = "FP_VIRTUAL_SDCP" },
|
||||
{ .virtual_envvar = NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
fpi_device_virtual_sdcp_class_init (FpDeviceVirtualSdcpClass *klass)
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
FpSdcpDeviceClass *sdcp_class = FP_SDCP_DEVICE_CLASS (klass);
|
||||
|
||||
obj_class->finalize = fpi_device_virtual_sdcp_finalize;
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual SDCP device talking to MS test code";
|
||||
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||
dev_class->id_table = driver_ids;
|
||||
dev_class->nr_enroll_stages = 1;
|
||||
|
||||
/* The SDCP base class may need to override this in the long run */
|
||||
dev_class->probe = probe;
|
||||
dev_class->close = dev_close;
|
||||
|
||||
sdcp_class->connect = connect;
|
||||
sdcp_class->reconnect = reconnect;
|
||||
|
||||
sdcp_class->enroll_begin = enroll_begin;
|
||||
sdcp_class->enroll_commit = enroll_commit;
|
||||
|
||||
sdcp_class->identify = identify;
|
||||
}
|
||||
@@ -185,7 +185,7 @@ fp_device_get_property (GObject *object,
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NR_ENROLL_STAGES:
|
||||
g_value_set_int (value, priv->nr_enroll_stages);
|
||||
g_value_set_uint (value, priv->nr_enroll_stages);
|
||||
break;
|
||||
|
||||
case PROP_SCAN_TYPE:
|
||||
@@ -197,7 +197,7 @@ fp_device_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_DRIVER:
|
||||
g_value_set_static_string (value, FP_DEVICE_GET_CLASS (priv)->id);
|
||||
g_value_set_static_string (value, FP_DEVICE_GET_CLASS (self)->id);
|
||||
break;
|
||||
|
||||
case PROP_DEVICE_ID:
|
||||
@@ -792,7 +792,7 @@ fp_device_close_finish (FpDevice *device,
|
||||
* in. The driver may make use of this metadata, when e.g. storing the print on
|
||||
* device memory. It is undefined whether this print is filled in by the driver
|
||||
* and returned, or whether the driver will return a newly created print after
|
||||
* enrollment successed.
|
||||
* enrollment succeeded.
|
||||
*/
|
||||
void
|
||||
fp_device_enroll (FpDevice *device,
|
||||
@@ -979,7 +979,7 @@ fp_device_verify_finish (FpDevice *device,
|
||||
|
||||
data = g_task_get_task_data (G_TASK (result));
|
||||
|
||||
*print = data->print;
|
||||
*print = data ? data->print : NULL;
|
||||
if (*print)
|
||||
g_object_ref (*print);
|
||||
}
|
||||
@@ -1092,13 +1092,13 @@ fp_device_identify_finish (FpDevice *device,
|
||||
|
||||
if (print)
|
||||
{
|
||||
*print = data->print;
|
||||
*print = data ? data->print : NULL;
|
||||
if (*print)
|
||||
g_object_ref (*print);
|
||||
}
|
||||
if (match)
|
||||
{
|
||||
*match = data->match;
|
||||
*match = data ? data->match : NULL;
|
||||
if (*match)
|
||||
g_object_ref (*match);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ typedef enum {
|
||||
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
|
||||
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
|
||||
* @FP_DEVICE_ERROR_REMOVED: The device has been removed.
|
||||
* @FP_DEVICE_ERROR_UNTRUSTED: Device cannot be trusted
|
||||
*
|
||||
* Error codes for device operations. More specific errors from other domains
|
||||
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
|
||||
@@ -109,6 +110,7 @@ typedef enum {
|
||||
FP_DEVICE_ERROR_DATA_DUPLICATE,
|
||||
/* Leave some room to add more DATA related errors */
|
||||
FP_DEVICE_ERROR_REMOVED = 0x100,
|
||||
FP_DEVICE_ERROR_UNTRUSTED,
|
||||
} FpDeviceError;
|
||||
|
||||
GQuark fp_device_retry_quark (void);
|
||||
|
||||
@@ -281,7 +281,7 @@ fp_print_class_init (FpPrintClass *klass)
|
||||
"Type",
|
||||
"Private: The type of the print data",
|
||||
FPI_TYPE_PRINT_TYPE,
|
||||
FPI_PRINT_RAW,
|
||||
FPI_PRINT_UNDEFINED,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
@@ -582,7 +582,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
|
||||
if (g_strcmp0 (self->device_id, other->device_id))
|
||||
return FALSE;
|
||||
|
||||
if (self->type == FPI_PRINT_RAW)
|
||||
if (self->type == FPI_PRINT_RAW || self->type == FPI_PRINT_SDCP)
|
||||
{
|
||||
return g_variant_equal (self->data, other->data);
|
||||
}
|
||||
@@ -847,7 +847,7 @@ fp_print_deserialize (const guchar *data,
|
||||
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
|
||||
}
|
||||
}
|
||||
else if (type == FPI_PRINT_RAW)
|
||||
else if (type == FPI_PRINT_RAW || type == FPI_PRINT_SDCP)
|
||||
{
|
||||
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
|
||||
|
||||
|
||||
58
libfprint/fp-sdcp-device-private.h
Normal file
58
libfprint/fp-sdcp-device-private.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fpi-sdcp-device.h"
|
||||
|
||||
#include <nss.h>
|
||||
#include <keyhi.h>
|
||||
#include <keythi.h>
|
||||
#include <pk11pub.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GError *enroll_pre_commit_error;
|
||||
|
||||
/* XXX: Do we want a separate SDCP session object?
|
||||
*/
|
||||
|
||||
GPtrArray *intermediate_cas;
|
||||
|
||||
/* Host random for the connection */
|
||||
guint8 host_random[32];
|
||||
|
||||
NSSInitContext *nss_init_context;
|
||||
PK11SlotInfo *slot;
|
||||
SECKEYPrivateKey *host_key_private;
|
||||
SECKEYPublicKey *host_key_public;
|
||||
|
||||
/* Master secret is required for reconnects.
|
||||
* TODO: We probably want to serialize this to disk so it can survive
|
||||
* fprintd idle shutdown. */
|
||||
PK11SymKey *master_secret;
|
||||
PK11SymKey *mac_secret;
|
||||
|
||||
} FpSdcpDevicePrivate;
|
||||
|
||||
void fpi_sdcp_device_connect (FpSdcpDevice *self);
|
||||
void fpi_sdcp_device_reconnect (FpSdcpDevice *self);
|
||||
|
||||
void fpi_sdcp_device_enroll (FpSdcpDevice *self);
|
||||
void fpi_sdcp_device_identify (FpSdcpDevice *self);
|
||||
141
libfprint/fp-sdcp-device.c
Normal file
141
libfprint/fp-sdcp-device.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "sdcp_device"
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "fp-sdcp-device-private.h"
|
||||
|
||||
/**
|
||||
* SECTION: fp-sdcp-device
|
||||
* @title: FpSdcpDevice
|
||||
* @short_description: SDCP device subclass
|
||||
*
|
||||
* This is a base class for devices implementing the SDCP security protocol.
|
||||
*/
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpSdcpDevice, fp_sdcp_device, FP_TYPE_DEVICE)
|
||||
|
||||
#if 0
|
||||
/* XXX: We'll very likely want/need some properties on this class. */
|
||||
enum {
|
||||
PROP_0,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
#endif
|
||||
|
||||
/*******************************************************/
|
||||
|
||||
/* Callbacks/vfuncs */
|
||||
static void
|
||||
fp_sdcp_device_open (FpDevice *device)
|
||||
{
|
||||
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
|
||||
/* Try a reconnect if we still have the mac secret. */
|
||||
if (priv->mac_secret)
|
||||
fpi_sdcp_device_reconnect (self);
|
||||
else
|
||||
fpi_sdcp_device_connect (self);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_enroll (FpDevice *device)
|
||||
{
|
||||
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||
|
||||
fpi_sdcp_device_enroll (self);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_identify (FpDevice *device)
|
||||
{
|
||||
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||
|
||||
fpi_sdcp_device_identify (self);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
static void
|
||||
fp_sdcp_device_finalize (GObject *object)
|
||||
{
|
||||
FpSdcpDevice *self = (FpSdcpDevice *) object;
|
||||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
|
||||
g_clear_pointer (&priv->intermediate_cas, g_ptr_array_unref);
|
||||
g_clear_pointer (&priv->slot, PK11_FreeSlot);
|
||||
g_clear_pointer (&priv->host_key_private, SECKEY_DestroyPrivateKey);
|
||||
g_clear_pointer (&priv->host_key_public, SECKEY_DestroyPublicKey);
|
||||
g_clear_pointer (&priv->master_secret, PK11_FreeSymKey);
|
||||
g_clear_pointer (&priv->mac_secret, PK11_FreeSymKey);
|
||||
g_clear_pointer (&priv->nss_init_context, NSS_ShutdownContext);
|
||||
|
||||
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_constructed (GObject *obj)
|
||||
{
|
||||
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->constructed (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_class_init (FpSdcpDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
FpDeviceClass *fp_device_class = FP_DEVICE_CLASS (klass);
|
||||
|
||||
object_class->finalize = fp_sdcp_device_finalize;
|
||||
object_class->get_property = fp_sdcp_device_get_property;
|
||||
object_class->constructed = fp_sdcp_device_constructed;
|
||||
|
||||
fp_device_class->open = fp_sdcp_device_open;
|
||||
fp_device_class->enroll = fp_sdcp_device_enroll;
|
||||
fp_device_class->verify = fp_sdcp_device_identify;
|
||||
fp_device_class->identify = fp_sdcp_device_identify;
|
||||
|
||||
#if 0
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
fp_sdcp_device_init (FpSdcpDevice *self)
|
||||
{
|
||||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
|
||||
priv->intermediate_cas = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
|
||||
}
|
||||
29
libfprint/fp-sdcp-device.h
Normal file
29
libfprint/fp-sdcp-device.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fp-device.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FP_TYPE_SDCP_DEVICE (fp_sdcp_device_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (FpSdcpDevice, fp_sdcp_device, FP, SDCP_DEVICE, FpDevice)
|
||||
|
||||
G_END_DECLS
|
||||
@@ -143,6 +143,10 @@ fpi_device_error_new (FpDeviceError error)
|
||||
msg = "This device has been removed from the system.";
|
||||
break;
|
||||
|
||||
case FP_DEVICE_ERROR_UNTRUSTED:
|
||||
msg = "Could not verify integrity of the device, it cannot be trusted!";
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Unsupported error, returning general error instead!");
|
||||
error = FP_DEVICE_ERROR_GENERAL;
|
||||
@@ -216,6 +220,7 @@ fpi_device_set_nr_enroll_stages (FpDevice *device,
|
||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||
|
||||
g_return_if_fail (FP_IS_DEVICE (device));
|
||||
g_return_if_fail (enroll_stages > 0);
|
||||
|
||||
priv->nr_enroll_stages = enroll_stages;
|
||||
g_object_notify (G_OBJECT (device), "nr-enroll-stages");
|
||||
@@ -751,6 +756,21 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
||||
priv->current_action = FPI_DEVICE_ACTION_NONE;
|
||||
priv->current_task_idle_return_source = NULL;
|
||||
|
||||
if (action == FPI_DEVICE_ACTION_OPEN &&
|
||||
data->type != FP_DEVICE_TASK_RETURN_ERROR)
|
||||
{
|
||||
priv->is_open = TRUE;
|
||||
g_object_notify (G_OBJECT (data->device), "open");
|
||||
}
|
||||
else if (action == FPI_DEVICE_ACTION_CLOSE)
|
||||
{
|
||||
/* Always consider the device closed. Drivers should try hard to close the
|
||||
* device. Generally, e.g. cancellations should be ignored.
|
||||
*/
|
||||
priv->is_open = FALSE;
|
||||
g_object_notify (G_OBJECT (data->device), "open");
|
||||
}
|
||||
|
||||
/* Return FP_DEVICE_ERROR_REMOVED if the device is removed,
|
||||
* with the exception of a successful open, which is an odd corner case. */
|
||||
if (priv->is_removed &&
|
||||
@@ -760,7 +780,7 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
||||
g_task_return_error (task, fpi_device_error_new (FP_DEVICE_ERROR_REMOVED));
|
||||
|
||||
/* NOTE: The removed signal will be emitted from the GTask
|
||||
* notify::completed if that is neccessary. */
|
||||
* notify::completed if that is necessary. */
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -920,12 +940,6 @@ fpi_device_open_complete (FpDevice *device, GError *error)
|
||||
clear_device_cancel_action (device);
|
||||
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE);
|
||||
|
||||
if (!error)
|
||||
{
|
||||
priv->is_open = TRUE;
|
||||
g_object_notify (G_OBJECT (device), "open");
|
||||
}
|
||||
|
||||
if (!error)
|
||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||
GUINT_TO_POINTER (TRUE));
|
||||
@@ -976,12 +990,6 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always consider the device closed. Drivers should try hard to close the
|
||||
* device. Generally, e.g. cancellations should be ignored.
|
||||
*/
|
||||
priv->is_open = FALSE;
|
||||
g_object_notify (G_OBJECT (device), "open");
|
||||
|
||||
if (!error)
|
||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||
GUINT_TO_POINTER (TRUE));
|
||||
@@ -1529,7 +1537,7 @@ fpi_device_report_finger_status (FpDevice *device,
|
||||
* fpi_device_report_finger_status_changes:
|
||||
* @device: The #FpDevice
|
||||
* @added_status: The #FpFingerStatusFlags to add
|
||||
* @added_status: The #FpFingerStatusFlags to remove
|
||||
* @removed_status: The #FpFingerStatusFlags to remove
|
||||
*
|
||||
* Report the finger status for the @device adding the @added_status flags
|
||||
* and removing the @removed_status flags.
|
||||
|
||||
@@ -11,11 +11,13 @@ G_BEGIN_DECLS
|
||||
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
|
||||
* @FPI_PRINT_RAW: A raw print where the data is directly compared
|
||||
* @FPI_PRINT_NBIS: NBIS minutiae comparison
|
||||
* @FPI_PRINT_SDCP: Print from an SDCP conforming device
|
||||
*/
|
||||
typedef enum {
|
||||
FPI_PRINT_UNDEFINED = 0,
|
||||
FPI_PRINT_RAW,
|
||||
FPI_PRINT_NBIS,
|
||||
FPI_PRINT_SDCP,
|
||||
} FpiPrintType;
|
||||
|
||||
/**
|
||||
|
||||
1469
libfprint/fpi-sdcp-device.c
Normal file
1469
libfprint/fpi-sdcp-device.c
Normal file
File diff suppressed because it is too large
Load Diff
142
libfprint/fpi-sdcp-device.h
Normal file
142
libfprint/fpi-sdcp-device.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
#include "fpi-device.h"
|
||||
#include "fp-sdcp-device.h"
|
||||
|
||||
/**
|
||||
* FpiSdcpClaim:
|
||||
* @cert_m: The per-model ECDSA certificate (x509 ASN.1 DER encoded)
|
||||
* @pk_d: The device public key (65 bytes)
|
||||
* @pk_f: The firmware public key (65 bytes)
|
||||
* @h_f: The firmware hash
|
||||
* @s_m: Signature over @pk_d using the per-model private key (64 bytes)
|
||||
* @s_d: Signature over h_f and pk_f using the device private key (64 bytes)
|
||||
*
|
||||
* Structure to hold the claim as produced by the device during a secure
|
||||
* connect. See the SDCP specification for more details.
|
||||
*
|
||||
* Note all of these may simply be memory views into a larger #GBytes created
|
||||
* using g_bytes_new_from_bytes().
|
||||
*/
|
||||
struct _FpiSdcpClaim
|
||||
{
|
||||
/*< public >*/
|
||||
GBytes *cert_m;
|
||||
GBytes *pk_d;
|
||||
GBytes *pk_f;
|
||||
GBytes *h_f;
|
||||
GBytes *s_m;
|
||||
GBytes *s_d;
|
||||
};
|
||||
typedef struct _FpiSdcpClaim FpiSdcpClaim;
|
||||
|
||||
GType fpi_sdcp_claim_get_type (void) G_GNUC_CONST;
|
||||
FpiSdcpClaim *fpi_sdcp_claim_new (void);
|
||||
FpiSdcpClaim *fpi_sdcp_claim_copy (FpiSdcpClaim *other);
|
||||
void fpi_sdcp_claim_free (FpiSdcpClaim *claim);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSdcpClaim, fpi_sdcp_claim_free)
|
||||
|
||||
|
||||
/**
|
||||
* FpSdcpDeviceClass:
|
||||
* @connect: Establish SDCP connection. Similar to open in #FpDeviceClass
|
||||
* but called connect to mirror the SDCP specification.
|
||||
* @reconnect: Perform a faster reconnect. Drivers do not need to provide this
|
||||
* function. If reconnect fails, then a normal connect will be tried.
|
||||
* @enroll_begin: Start the enrollment procedure. In the absence of an error,
|
||||
* the driver must call fpi_sdcp_device_enroll_set_nonce() at any point. It
|
||||
* also must report enrollment progress using fpi_device_enroll_progress().
|
||||
* It should also store available metadata about the print in device memory.
|
||||
* The operation is completed with fpi_sdcp_device_enroll_ready().
|
||||
* @enroll_commit: Complete the enrollment procedure. This commits the newly
|
||||
* enrolled print to the device memory. Will only be called if enroll_begin
|
||||
* succeeded. The passed id may be %NULL, in that case the driver must
|
||||
* abort the enrollment process. id is owned by the base class and remains
|
||||
* valid throughout the operation.
|
||||
* @identify: Start identification process. On completion, the driver must call
|
||||
* fpi_sdcp_device_identify_complete(). To request the user to retry the
|
||||
* fpi_sdcp_device_identify_retry() function is used.
|
||||
*
|
||||
*
|
||||
* These are the main entry points for drivers implementing SDCP.
|
||||
*
|
||||
* Drivers *must* eventually call the corresponding function to finish the
|
||||
* operation.
|
||||
*
|
||||
* XXX: Is the use of fpi_device_action_error() acceptable?
|
||||
*
|
||||
* Drivers *must* also handle cancellation properly for any long running
|
||||
* operation (i.e. any operation that requires capturing). It is entirely fine
|
||||
* to ignore cancellation requests for short operations (e.g. open/close).
|
||||
*
|
||||
* This API is solely intended for drivers. It is purely internal and neither
|
||||
* API nor ABI stable.
|
||||
*/
|
||||
struct _FpSdcpDeviceClass
|
||||
{
|
||||
FpDeviceClass parent_class;
|
||||
|
||||
void (*connect) (FpSdcpDevice *dev);
|
||||
void (*reconnect) (FpSdcpDevice *dev);
|
||||
void (*close) (FpSdcpDevice *dev);
|
||||
void (*enroll_begin) (FpSdcpDevice *dev);
|
||||
void (*enroll_commit) (FpSdcpDevice *dev,
|
||||
GBytes *id);
|
||||
void (*identify) (FpSdcpDevice *dev);
|
||||
};
|
||||
|
||||
void fpi_sdcp_device_set_intermediat_cas (FpSdcpDevice *self,
|
||||
GBytes *ca_1,
|
||||
GBytes *ca_2);
|
||||
|
||||
void fpi_sdcp_device_get_connect_data (FpSdcpDevice *self,
|
||||
GBytes **r_h,
|
||||
GBytes **pk_h);
|
||||
void fpi_sdcp_device_connect_complete (FpSdcpDevice *self,
|
||||
GBytes *r_d,
|
||||
FpiSdcpClaim *claim,
|
||||
GBytes *mac,
|
||||
GError *error);
|
||||
|
||||
void fpi_sdcp_device_get_reconnect_data (FpSdcpDevice *self,
|
||||
GBytes **r_h);
|
||||
void fpi_sdcp_device_reconnect_complete (FpSdcpDevice *self,
|
||||
GBytes *mac,
|
||||
GError *error);
|
||||
|
||||
void fpi_sdcp_device_enroll_set_nonce (FpSdcpDevice *self,
|
||||
GBytes *nonce);
|
||||
void fpi_sdcp_device_enroll_ready (FpSdcpDevice *self,
|
||||
GError *error);
|
||||
void fpi_sdcp_device_enroll_commit_complete (FpSdcpDevice *self,
|
||||
GError *error);
|
||||
|
||||
void fpi_sdcp_device_get_identify_data (FpSdcpDevice *self,
|
||||
GBytes **nonce);
|
||||
void fpi_sdcp_device_identify_retry (FpSdcpDevice *self,
|
||||
GError *error);
|
||||
void fpi_sdcp_device_identify_complete (FpSdcpDevice *self,
|
||||
GBytes *id,
|
||||
GBytes *mac,
|
||||
GError *error);
|
||||
@@ -74,7 +74,7 @@
|
||||
* upon success (or fails).
|
||||
*
|
||||
* Your completion callback should examine the return value of
|
||||
* fpi_ssm_get_error() in ordater to determine whether the #FpiSsm completed or
|
||||
* fpi_ssm_get_error() in order to determine whether the #FpiSsm completed or
|
||||
* failed. An error code of zero indicates successful completion.
|
||||
*/
|
||||
|
||||
@@ -130,6 +130,7 @@ fpi_ssm_new_full (FpDevice *dev,
|
||||
{
|
||||
FpiSsm *machine;
|
||||
|
||||
BUG_ON (dev == NULL);
|
||||
BUG_ON (nr_states < 1);
|
||||
BUG_ON (handler == NULL);
|
||||
|
||||
@@ -155,6 +156,8 @@ fpi_ssm_set_data (FpiSsm *machine,
|
||||
gpointer ssm_data,
|
||||
GDestroyNotify ssm_data_destroy)
|
||||
{
|
||||
g_return_if_fail (machine);
|
||||
|
||||
if (machine->ssm_data_destroy && machine->ssm_data)
|
||||
machine->ssm_data_destroy (machine->ssm_data);
|
||||
|
||||
@@ -173,12 +176,16 @@ fpi_ssm_set_data (FpiSsm *machine,
|
||||
void *
|
||||
fpi_ssm_get_data (FpiSsm *machine)
|
||||
{
|
||||
g_return_val_if_fail (machine, NULL);
|
||||
|
||||
return machine->ssm_data;
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_ssm_clear_delayed_action (FpiSsm *machine)
|
||||
{
|
||||
g_return_if_fail (machine);
|
||||
|
||||
if (machine->cancellable_id)
|
||||
{
|
||||
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
|
||||
@@ -235,6 +242,8 @@ fpi_ssm_set_delayed_action_timeout (FpiSsm *machine,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func)
|
||||
{
|
||||
g_return_if_fail (machine);
|
||||
|
||||
BUG_ON (machine->completed);
|
||||
BUG_ON (machine->timeout != NULL);
|
||||
|
||||
@@ -302,6 +311,8 @@ __ssm_call_handler (FpiSsm *machine)
|
||||
void
|
||||
fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
|
||||
{
|
||||
g_return_if_fail (ssm != NULL);
|
||||
|
||||
BUG_ON (!ssm->completed);
|
||||
ssm->callback = callback;
|
||||
ssm->cur_state = 0;
|
||||
@@ -336,6 +347,9 @@ __subsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
||||
void
|
||||
fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
|
||||
{
|
||||
g_return_if_fail (parent != NULL);
|
||||
g_return_if_fail (child != NULL);
|
||||
|
||||
BUG_ON (parent->timeout);
|
||||
child->parentsm = parent;
|
||||
|
||||
@@ -355,6 +369,8 @@ fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
|
||||
void
|
||||
fpi_ssm_mark_completed (FpiSsm *machine)
|
||||
{
|
||||
g_return_if_fail (machine != NULL);
|
||||
|
||||
BUG_ON (machine->completed);
|
||||
BUG_ON (machine->timeout != NULL);
|
||||
|
||||
@@ -427,6 +443,7 @@ fpi_ssm_mark_completed_delayed (FpiSsm *machine,
|
||||
void
|
||||
fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
|
||||
{
|
||||
g_return_if_fail (machine != NULL);
|
||||
g_assert (error);
|
||||
if (machine->error)
|
||||
{
|
||||
@@ -534,6 +551,8 @@ fpi_ssm_next_state_delayed (FpiSsm *machine,
|
||||
void
|
||||
fpi_ssm_jump_to_state (FpiSsm *machine, int state)
|
||||
{
|
||||
g_return_if_fail (machine != NULL);
|
||||
|
||||
BUG_ON (machine->completed);
|
||||
BUG_ON (state < 0 || state >= machine->nr_states);
|
||||
BUG_ON (machine->timeout != NULL);
|
||||
@@ -598,6 +617,20 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
||||
g_source_set_name (machine->timeout, source_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_ssm_get_device:
|
||||
* @machine: an #FpiSsm state machine
|
||||
*
|
||||
* Returns the device that the SSM has been associated with.
|
||||
*
|
||||
* Returns: (transfer none): the #FpDevice.
|
||||
*/
|
||||
FpDevice *
|
||||
fpi_ssm_get_device (FpiSsm *machine)
|
||||
{
|
||||
return machine->dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_ssm_get_cur_state:
|
||||
* @machine: an #FpiSsm state machine
|
||||
@@ -610,6 +643,8 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
||||
int
|
||||
fpi_ssm_get_cur_state (FpiSsm *machine)
|
||||
{
|
||||
g_return_val_if_fail (machine != NULL, 0);
|
||||
|
||||
return machine->cur_state;
|
||||
}
|
||||
|
||||
@@ -624,6 +659,8 @@ fpi_ssm_get_cur_state (FpiSsm *machine)
|
||||
GError *
|
||||
fpi_ssm_get_error (FpiSsm *machine)
|
||||
{
|
||||
g_return_val_if_fail (machine != NULL, NULL);
|
||||
|
||||
return machine->error;
|
||||
}
|
||||
|
||||
@@ -638,6 +675,8 @@ fpi_ssm_get_error (FpiSsm *machine)
|
||||
GError *
|
||||
fpi_ssm_dup_error (FpiSsm *machine)
|
||||
{
|
||||
g_return_val_if_fail (machine != NULL, NULL);
|
||||
|
||||
if (machine->error)
|
||||
return g_error_copy (machine->error);
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ void fpi_ssm_mark_failed (FpiSsm *machine,
|
||||
void fpi_ssm_set_data (FpiSsm *machine,
|
||||
gpointer ssm_data,
|
||||
GDestroyNotify ssm_data_destroy);
|
||||
|
||||
FpDevice * fpi_ssm_get_device (FpiSsm *machine);
|
||||
gpointer fpi_ssm_get_data (FpiSsm *machine);
|
||||
GError * fpi_ssm_get_error (FpiSsm *machine);
|
||||
GError * fpi_ssm_dup_error (FpiSsm *machine);
|
||||
|
||||
@@ -187,7 +187,7 @@ fpi_usb_transfer_fill_bulk (FpiUsbTransfer *transfer,
|
||||
* fpi_usb_transfer_fill_bulk_full:
|
||||
* @transfer: The #FpiUsbTransfer
|
||||
* @endpoint: The endpoint to send the transfer to
|
||||
* @buffer: The data to send. A buffer will be created and managed for you if you pass NULL.
|
||||
* @buffer: The data to send.
|
||||
* @length: The size of @buffer
|
||||
* @free_func: (destroy buffer): Destroy notify for @buffer
|
||||
*
|
||||
@@ -275,7 +275,7 @@ fpi_usb_transfer_fill_interrupt (FpiUsbTransfer *transfer,
|
||||
* fpi_usb_transfer_fill_interrupt_full:
|
||||
* @transfer: The #FpiUsbTransfer
|
||||
* @endpoint: The endpoint to send the transfer to
|
||||
* @buffer: The data to send. A buffer will be created and managed for you if you pass NULL.
|
||||
* @buffer: The data to send.
|
||||
* @length: The size of @buffer
|
||||
* @free_func: (destroy buffer): Destroy notify for @buffer
|
||||
*
|
||||
|
||||
@@ -83,6 +83,8 @@ main (int argc, char **argv)
|
||||
g_print ("\n");
|
||||
g_print ("This is a list of supported devices in libfprint's development version. Those drivers might not all be available in the stable, released version. If in doubt, contact your distribution or systems integrator for details.\n");
|
||||
g_print ("\n");
|
||||
g_print ("The quality and functionality of drivers varies widely. libfprint maintainers may not be able to help with issues arising from their use.\n");
|
||||
g_print ("\n");
|
||||
g_print ("## USB devices\n");
|
||||
g_print ("\n");
|
||||
g_print ("USB ID | Driver\n");
|
||||
|
||||
@@ -45,12 +45,9 @@ static const FpIdEntry whitelist_id_table[] = {
|
||||
{ .vid = 0x06cb, .pid = 0x00b7 },
|
||||
{ .vid = 0x06cb, .pid = 0x00bb },
|
||||
{ .vid = 0x06cb, .pid = 0x00be },
|
||||
{ .vid = 0x06cb, .pid = 0x00c2 },
|
||||
{ .vid = 0x06cb, .pid = 0x00c9 },
|
||||
{ .vid = 0x06cb, .pid = 0x00cb },
|
||||
{ .vid = 0x06cb, .pid = 0x00d8 },
|
||||
{ .vid = 0x06cb, .pid = 0x00da },
|
||||
{ .vid = 0x06cb, .pid = 0x00e7 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5801 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5805 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5834 },
|
||||
@@ -110,6 +107,7 @@ static const FpIdEntry blacklist_id_table[] = {
|
||||
static const FpDeviceClass whitelist = {
|
||||
.type = FP_DEVICE_TYPE_USB,
|
||||
.id_table = whitelist_id_table,
|
||||
.id = "whitelist",
|
||||
.full_name = "Hardcoded whitelist"
|
||||
};
|
||||
|
||||
@@ -140,33 +138,56 @@ print_driver (const FpDeviceClass *cls)
|
||||
|
||||
if (g_hash_table_lookup (printed, key) != NULL)
|
||||
{
|
||||
if (cls == &whitelist)
|
||||
g_warning ("%s implemented by driver %s",
|
||||
key, (const char *) g_hash_table_lookup (printed, key));
|
||||
g_free (key);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
||||
g_hash_table_insert (printed, key, (void *) cls->id);
|
||||
|
||||
if (num_printed == 0)
|
||||
g_print ("# %s\n", cls->full_name);
|
||||
{
|
||||
if (cls != &whitelist)
|
||||
g_print ("\n# Supported by libfprint driver %s\n", cls->id);
|
||||
else
|
||||
g_print ("\n# Known unsupported devices\n");
|
||||
}
|
||||
|
||||
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n",
|
||||
g_print ("usb:v%04Xp%04X*\n",
|
||||
entry->vid, entry->pid);
|
||||
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n",
|
||||
entry->vid, entry->pid, cls->full_name);
|
||||
num_printed++;
|
||||
}
|
||||
|
||||
if (num_printed > 0)
|
||||
g_print ("\n");
|
||||
g_print (" ID_AUTOSUSPEND=1\n");
|
||||
}
|
||||
|
||||
static int
|
||||
driver_compare (gconstpointer p1, gconstpointer p2)
|
||||
{
|
||||
g_autoptr(FpDeviceClass) cls1 = g_type_class_ref (*(GType *) p1);
|
||||
g_autoptr(FpDeviceClass) cls2 = g_type_class_ref (*(GType *) p2);
|
||||
|
||||
return g_strcmp0 (cls1->id, cls2->id);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_autoptr(GArray) drivers = fpi_get_driver_types ();
|
||||
g_autofree char *program_name = NULL;
|
||||
guint i;
|
||||
|
||||
program_name = g_path_get_basename (argv[0]);
|
||||
|
||||
g_print ("# SPDX-License-Identifier: LGPL-2.1-or-later\n");
|
||||
g_print ("# This file has been generated using %s with all drivers enabled\n",
|
||||
program_name);
|
||||
|
||||
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
g_array_sort (drivers, driver_compare);
|
||||
|
||||
for (i = 0; i < drivers->len; i++)
|
||||
{
|
||||
@@ -78,108 +78,146 @@ nbis_sources = [
|
||||
'nbis/mindtct/xytreps.c',
|
||||
]
|
||||
|
||||
aeslib = false
|
||||
aesx660 = false
|
||||
aes3k = false
|
||||
drivers_sources = []
|
||||
drivers_cflags = []
|
||||
driver_sources = {
|
||||
'upekts' :
|
||||
[ 'drivers/upekts.c', 'drivers/upek_proto.c' ],
|
||||
'upektc' :
|
||||
[ 'drivers/upektc.c' ],
|
||||
'upeksonly' :
|
||||
[ 'drivers/upeksonly.c' ],
|
||||
'uru4000' :
|
||||
[ 'drivers/uru4000.c' ],
|
||||
'aes1610' :
|
||||
[ 'drivers/aes1610.c' ],
|
||||
'aes1660' :
|
||||
[ 'drivers/aes1660.c' ],
|
||||
'aes2501' :
|
||||
[ 'drivers/aes2501.c' ],
|
||||
'aes2550' :
|
||||
[ 'drivers/aes2550.c' ],
|
||||
'aes2660' :
|
||||
[ 'drivers/aes2660.c' ],
|
||||
'aes3500' :
|
||||
[ 'drivers/aes3500.c' ],
|
||||
'aes4000' :
|
||||
[ 'drivers/aes4000.c' ],
|
||||
'vcom5s' :
|
||||
[ 'drivers/vcom5s.c' ],
|
||||
'vfs101' :
|
||||
[ 'drivers/vfs101.c' ],
|
||||
'vfs301' :
|
||||
[ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ],
|
||||
'vfs5011' :
|
||||
[ 'drivers/vfs5011.c' ],
|
||||
'upektc_img' :
|
||||
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
|
||||
'etes603' :
|
||||
[ 'drivers/etes603.c' ],
|
||||
'vfs0050' :
|
||||
[ 'drivers/vfs0050.c' ],
|
||||
'elan' :
|
||||
[ 'drivers/elan.c' ],
|
||||
'virtual_image' :
|
||||
[ 'drivers/virtual-image.c' ],
|
||||
'virtual_device' :
|
||||
[ 'drivers/virtual-device.c' ],
|
||||
'virtual_device_storage' :
|
||||
[ 'drivers/virtual-device-storage.c' ],
|
||||
'virtual_sdcp' :
|
||||
[ 'drivers/virtual-sdcp.c' ],
|
||||
'synaptics' :
|
||||
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
|
||||
'goodixmoc' :
|
||||
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
|
||||
}
|
||||
|
||||
helper_sources = {
|
||||
'sdcp' :
|
||||
[ 'fp-sdcp-device.c', 'fpi-sdcp-device.c' ],
|
||||
'aeslib' :
|
||||
[ 'drivers/aeslib.c' ],
|
||||
'aesx660' :
|
||||
[ 'drivers/aesx660.c' ],
|
||||
'aes3k' :
|
||||
[ 'drivers/aes3k.c' ],
|
||||
'virtual' :
|
||||
[ 'drivers/virtual-device-listener.c' ],
|
||||
}
|
||||
|
||||
driver_helpers = {
|
||||
'aes1610' : [ 'aeslib' ],
|
||||
'aes1660' : [ 'aeslib', 'aesx660' ],
|
||||
'aes2501' : [ 'aeslib' ],
|
||||
'aes2550' : [ 'aeslib' ],
|
||||
'aes2660' : [ 'aeslib', 'aesx660' ],
|
||||
'aes3500' : [ 'aeslib', 'aes3k' ],
|
||||
'aes4000' : [ 'aeslib', 'aes3k' ],
|
||||
'virtual_image' : [ 'virtual' ],
|
||||
'virtual_device' : [ 'virtual' ],
|
||||
'virtual_device_storage' : [ 'virtual' ],
|
||||
'virtual_sdcp' : [ 'sdcp' ],
|
||||
}
|
||||
|
||||
helpers = []
|
||||
foreach driver : drivers
|
||||
if driver == 'upekts'
|
||||
drivers_sources += [ 'drivers/upekts.c', 'drivers/upek_proto.c' ]
|
||||
if driver in driver_helpers
|
||||
foreach helper : driver_helpers[driver]
|
||||
if helper not in helpers
|
||||
helpers += helper
|
||||
endif
|
||||
if driver == 'upektc'
|
||||
drivers_sources += [ 'drivers/upektc.c' ]
|
||||
endif
|
||||
if driver == 'upeksonly'
|
||||
drivers_sources += [ 'drivers/upeksonly.c' ]
|
||||
endif
|
||||
if driver == 'uru4000'
|
||||
drivers_sources += [ 'drivers/uru4000.c' ]
|
||||
endif
|
||||
if driver == 'aes1610'
|
||||
drivers_sources += [ 'drivers/aes1610.c' ]
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes1660'
|
||||
drivers_sources += [ 'drivers/aes1660.c' ]
|
||||
aeslib = true
|
||||
aesx660 = true
|
||||
endif
|
||||
if driver == 'aes2501'
|
||||
drivers_sources += [ 'drivers/aes2501.c' ]
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes2550'
|
||||
drivers_sources += [ 'drivers/aes2550.c' ]
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes2660'
|
||||
drivers_sources += [ 'drivers/aes2660.c' ]
|
||||
aeslib = true
|
||||
aesx660 = true
|
||||
endif
|
||||
if driver == 'aes3500'
|
||||
drivers_sources += [ 'drivers/aes3500.c' ]
|
||||
aeslib = true
|
||||
aes3k = true
|
||||
endif
|
||||
if driver == 'aes4000'
|
||||
drivers_sources += [ 'drivers/aes4000.c' ]
|
||||
aeslib = true
|
||||
aes3k = true
|
||||
endif
|
||||
if driver == 'vcom5s'
|
||||
drivers_sources += [ 'drivers/vcom5s.c' ]
|
||||
endif
|
||||
if driver == 'vfs101'
|
||||
drivers_sources += [ 'drivers/vfs101.c' ]
|
||||
endif
|
||||
if driver == 'vfs301'
|
||||
drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ]
|
||||
endif
|
||||
if driver == 'vfs5011'
|
||||
drivers_sources += [ 'drivers/vfs5011.c' ]
|
||||
endif
|
||||
if driver == 'upektc_img'
|
||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
|
||||
endif
|
||||
if driver == 'etes603'
|
||||
drivers_sources += [ 'drivers/etes603.c' ]
|
||||
endif
|
||||
if driver == 'vfs0050'
|
||||
drivers_sources += [ 'drivers/vfs0050.c' ]
|
||||
endif
|
||||
if driver == 'elan'
|
||||
drivers_sources += [ 'drivers/elan.c' ]
|
||||
endif
|
||||
if driver == 'virtual_image'
|
||||
drivers_sources += [ 'drivers/virtual-image.c' ]
|
||||
endif
|
||||
if driver == 'synaptics'
|
||||
drivers_sources += [
|
||||
'drivers/synaptics/synaptics.c',
|
||||
'drivers/synaptics/bmkt_message.c',
|
||||
]
|
||||
endif
|
||||
if driver == 'goodixmoc'
|
||||
drivers_sources += [
|
||||
'drivers/goodixmoc/goodix.c',
|
||||
'drivers/goodixmoc/goodix_proto.c',
|
||||
]
|
||||
endforeach
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if aeslib
|
||||
drivers_sources += [ 'drivers/aeslib.c' ]
|
||||
drivers_sources = []
|
||||
drivers_cflags = []
|
||||
foreach driver: drivers
|
||||
drivers_sources += driver_sources[driver]
|
||||
endforeach
|
||||
foreach helper : helpers
|
||||
drivers_sources += helper_sources[helper]
|
||||
endforeach
|
||||
|
||||
optional_deps = []
|
||||
|
||||
# Resolve extra dependencies
|
||||
foreach i : helpers + drivers
|
||||
driver = i
|
||||
foreach d, helper : driver_helpers
|
||||
if i in helpers
|
||||
driver = d
|
||||
break
|
||||
endif
|
||||
if aesx660
|
||||
drivers_sources += ['drivers/aesx660.c' ]
|
||||
endif
|
||||
if aes3k
|
||||
drivers_sources += ['drivers/aes3k.c' ]
|
||||
endforeach
|
||||
|
||||
if i == 'aes3k'
|
||||
imaging_dep = dependency('pixman-1', required: false)
|
||||
if not imaging_dep.found()
|
||||
error('pixman is required for @0@ and possibly others'.format(driver))
|
||||
endif
|
||||
|
||||
other_sources = []
|
||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||
optional_deps += imaging_dep
|
||||
elif i == 'uru4000'
|
||||
nss_dep = dependency('nss', required: false)
|
||||
if not nss_dep.found()
|
||||
error('nss is required for uru4000')
|
||||
endif
|
||||
|
||||
optional_deps += nss_dep
|
||||
elif i == 'sdcp'
|
||||
nss_dep = dependency('nss', version: '>=3.55', required: false)
|
||||
if not nss_dep.found()
|
||||
error('nss >=3.55 is required for SDCP support (@0@ and possibly others)'.format(driver))
|
||||
endif
|
||||
|
||||
optional_deps += nss_dep
|
||||
else
|
||||
deps = []
|
||||
continue
|
||||
endif
|
||||
|
||||
endforeach
|
||||
|
||||
fp_enums = gnome.mkenums_simple('fp-enums',
|
||||
sources: libfprint_public_headers,
|
||||
@@ -198,6 +236,28 @@ enums_dep = declare_dependency(
|
||||
sources: [ fp_enums_h, fpi_enums_h ]
|
||||
)
|
||||
|
||||
# Export the drivers' types to the core code
|
||||
drivers_type_list = []
|
||||
drivers_type_func = []
|
||||
drivers_type_list += '#include <glib-object.h>'
|
||||
drivers_type_list += '#include "fpi-context.h"'
|
||||
drivers_type_list += ''
|
||||
drivers_type_func += 'GArray *'
|
||||
drivers_type_func += 'fpi_get_driver_types (void)'
|
||||
drivers_type_func += '{'
|
||||
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
||||
drivers_type_func += ' GType t;'
|
||||
drivers_type_func += ''
|
||||
foreach driver: supported_drivers
|
||||
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
||||
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
||||
drivers_type_func += ' g_array_append_val (drivers, t);'
|
||||
drivers_type_func += ''
|
||||
endforeach
|
||||
drivers_type_list += ''
|
||||
drivers_type_func += ' return drivers;'
|
||||
drivers_type_func += '}'
|
||||
|
||||
drivers_sources += configure_file(input: 'empty_file',
|
||||
output: 'fpi-drivers.c',
|
||||
capture: true,
|
||||
@@ -212,10 +272,8 @@ deps = [
|
||||
glib_dep,
|
||||
gobject_dep,
|
||||
gusb_dep,
|
||||
imaging_dep,
|
||||
mathlib_dep,
|
||||
nss_dep,
|
||||
]
|
||||
] + optional_deps
|
||||
|
||||
# These are empty and only exist so that the include directories are created
|
||||
# in the build tree. This silences a build time warning.
|
||||
@@ -234,6 +292,8 @@ libnbis = static_library('nbis',
|
||||
'-Wno-error=redundant-decls',
|
||||
'-Wno-redundant-decls',
|
||||
'-Wno-discarded-qualifiers',
|
||||
'-Wno-array-bounds',
|
||||
'-Wno-array-parameter',
|
||||
]),
|
||||
install: false)
|
||||
|
||||
@@ -256,11 +316,10 @@ libfprint_drivers = static_library('fprint-drivers',
|
||||
mapfile = files('libfprint.ver')
|
||||
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
|
||||
|
||||
libfprint = library(versioned_libname.split('lib')[1],
|
||||
libfprint = shared_library(versioned_libname.split('lib')[1],
|
||||
sources: [
|
||||
fp_enums,
|
||||
libfprint_sources,
|
||||
other_sources,
|
||||
],
|
||||
soversion: soversion,
|
||||
version: libversion,
|
||||
@@ -293,20 +352,30 @@ libfprint_private_dep = declare_dependency(
|
||||
]
|
||||
)
|
||||
|
||||
udev_rules = executable('fprint-list-udev-rules',
|
||||
'fprint-list-udev-rules.c',
|
||||
udev_hwdb = executable('fprint-list-udev-hwdb',
|
||||
'fprint-list-udev-hwdb.c',
|
||||
dependencies: libfprint_private_dep,
|
||||
link_with: libfprint_drivers,
|
||||
install: false)
|
||||
|
||||
if get_option('udev_rules')
|
||||
custom_target('udev-rules',
|
||||
output: '60-@0@-autosuspend.rules'.format(versioned_libname),
|
||||
udev_hwdb_generator = custom_target('udev-hwdb',
|
||||
output: 'autosuspend.hwdb',
|
||||
depend_files: drivers_sources,
|
||||
capture: true,
|
||||
command: [ udev_rules ],
|
||||
install: true,
|
||||
install_dir: udev_rules_dir)
|
||||
endif
|
||||
command: [ udev_hwdb ],
|
||||
install: false,
|
||||
)
|
||||
|
||||
custom_target('sync-udev-hwdb',
|
||||
depends: udev_hwdb_generator,
|
||||
output: 'sync-udev-hwdb',
|
||||
install: false,
|
||||
command: [
|
||||
'cp', '-v',
|
||||
udev_hwdb_generator.full_path(),
|
||||
meson.source_root() / 'data'
|
||||
]
|
||||
)
|
||||
|
||||
supported_devices = executable('fprint-list-supported-devices',
|
||||
'fprint-list-supported-devices.c',
|
||||
|
||||
86
meson.build
86
meson.build
@@ -1,5 +1,5 @@
|
||||
project('libfprint', [ 'c', 'cpp' ],
|
||||
version: '1.90.6',
|
||||
version: '1.90.7',
|
||||
license: 'LGPLv2.1+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
@@ -88,7 +88,12 @@ cairo_dep = dependency('cairo', required: false)
|
||||
|
||||
# Drivers
|
||||
drivers = get_option('drivers').split(',')
|
||||
virtual_drivers = [ 'virtual_image' ]
|
||||
virtual_drivers = [
|
||||
'virtual_image',
|
||||
'virtual_device',
|
||||
'virtual_device_storage',
|
||||
'virtual_sdcp',
|
||||
]
|
||||
default_drivers = [
|
||||
'upektc_img',
|
||||
'vfs5011',
|
||||
@@ -113,6 +118,13 @@ default_drivers = [
|
||||
'goodixmoc',
|
||||
]
|
||||
|
||||
# FIXME: All the drivers should be fixed by adjusting the byte order.
|
||||
# See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/236
|
||||
endian_independent_drivers = virtual_drivers + [
|
||||
'aes3500',
|
||||
'synaptics',
|
||||
]
|
||||
|
||||
all_drivers = default_drivers + virtual_drivers
|
||||
|
||||
if drivers == [ 'all' ]
|
||||
@@ -127,60 +139,43 @@ if drivers.length() == 0 or drivers[0] == ''
|
||||
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
|
||||
endif
|
||||
|
||||
nss_dep = dependency('', required: false)
|
||||
imaging_dep = dependency('', required: false)
|
||||
libfprint_conf.set10('HAVE_PIXMAN', false)
|
||||
foreach driver: drivers
|
||||
if driver == 'uru4000'
|
||||
nss_dep = dependency('nss', required: false)
|
||||
if not nss_dep.found()
|
||||
error('NSS is required for the URU4000/URU4500 driver')
|
||||
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
|
||||
endif
|
||||
if driver == 'aes3500' or driver == 'aes4000'
|
||||
imaging_dep = dependency('pixman-1', required: false)
|
||||
if not imaging_dep.found()
|
||||
error('pixman is required for imaging support')
|
||||
endforeach
|
||||
endif
|
||||
|
||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||
endif
|
||||
if not all_drivers.contains(driver)
|
||||
error('Invalid driver \'' + driver + '\'')
|
||||
supported_drivers = []
|
||||
foreach driver: drivers
|
||||
if build_machine.endian() == 'little' or driver in endian_independent_drivers
|
||||
supported_drivers += driver
|
||||
else
|
||||
warning('Driver @0@ is not supported by big endian cpu @1@. Please, fix it!'.format(
|
||||
driver, build_machine.cpu()))
|
||||
endif
|
||||
endforeach
|
||||
|
||||
# Export the drivers' types to the core code
|
||||
drivers_type_list = []
|
||||
drivers_type_func = []
|
||||
drivers_type_list += '#include <glib-object.h>'
|
||||
drivers_type_list += '#include "fpi-context.h"'
|
||||
drivers_type_list += ''
|
||||
drivers_type_func += 'GArray *'
|
||||
drivers_type_func += 'fpi_get_driver_types (void)'
|
||||
drivers_type_func += '{'
|
||||
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
||||
drivers_type_func += ' GType t;'
|
||||
drivers_type_func += ''
|
||||
foreach driver: drivers
|
||||
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
||||
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
||||
drivers_type_func += ' g_array_append_val (drivers, t);'
|
||||
drivers_type_func += ''
|
||||
endforeach
|
||||
drivers_type_list += ''
|
||||
drivers_type_func += ' return drivers;'
|
||||
drivers_type_func += '}'
|
||||
if default_drivers_are_enabled and supported_drivers != drivers
|
||||
default_drivers_are_enabled = false
|
||||
endif
|
||||
|
||||
root_inc = include_directories('.')
|
||||
|
||||
if get_option('udev_rules')
|
||||
udev_rules_dir = get_option('udev_rules_dir')
|
||||
udev_hwdb_dir = get_option('udev_hwdb_dir')
|
||||
|
||||
if udev_rules_dir == 'auto'
|
||||
if udev_hwdb_dir == 'auto'
|
||||
udev_dep = dependency('udev')
|
||||
udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/rules.d'
|
||||
udev_hwdb_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/hwdb.d'
|
||||
endif
|
||||
else
|
||||
udev_hwdb_dir = false
|
||||
endif
|
||||
|
||||
if get_option('gtk-examples')
|
||||
@@ -192,9 +187,11 @@ if get_option('gtk-examples')
|
||||
endif
|
||||
endif
|
||||
|
||||
# Some dependency resolving happens inside here
|
||||
subdir('libfprint')
|
||||
|
||||
configure_file(output: 'config.h', configuration: libfprint_conf)
|
||||
|
||||
subdir('libfprint')
|
||||
subdir('examples')
|
||||
if get_option('doc')
|
||||
gnome = import('gnome')
|
||||
@@ -204,6 +201,7 @@ if get_option('gtk-examples')
|
||||
subdir('demo')
|
||||
endif
|
||||
|
||||
subdir('data')
|
||||
subdir('tests')
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
|
||||
@@ -10,8 +10,8 @@ option('udev_rules',
|
||||
description: 'Whether to create a udev rules file',
|
||||
type: 'boolean',
|
||||
value: true)
|
||||
option('udev_rules_dir',
|
||||
description: 'Installation path for udev rules',
|
||||
option('udev_hwdb_dir',
|
||||
description: 'Installation path for udev hwdb',
|
||||
type: 'string',
|
||||
value: 'auto')
|
||||
option('gtk-examples',
|
||||
@@ -22,3 +22,8 @@ option('doc',
|
||||
description: 'Whether to build the API documentation',
|
||||
type: 'boolean',
|
||||
value: true)
|
||||
|
||||
option('sdcp_virt_binary',
|
||||
description: 'Path to virtual SDCP test binary, please refer to CI for more details.',
|
||||
type: 'string',
|
||||
value: '')
|
||||
|
||||
@@ -12,8 +12,11 @@ case "$1" in
|
||||
;;
|
||||
esac
|
||||
|
||||
ARGS=4
|
||||
JOBS=4
|
||||
|
||||
pushd "$SRCROOT"
|
||||
uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/`
|
||||
git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/ | xargs -n$ARGS -P $JOBS uncrustify -c "$CFG" $OPTS
|
||||
RES=$?
|
||||
popd
|
||||
exit $RES
|
||||
@@ -27,7 +27,7 @@ A new 'capture' test is created by means of `capture.py` script:
|
||||
- `export LD_PRELOAD=<meson-build-dir>/libfprint/libfprint-2.so`
|
||||
- `export GI_TYPELIB_PATH=<meson-build-dir>/libfprint`
|
||||
|
||||
Also, sometimes the driver must be adopted to the emulated environment
|
||||
Also, sometimes the driver must be adapted to the emulated environment
|
||||
(mainly if it uses random numbers, see `synaptics.c` for an example).
|
||||
Set the following environment variable to enable this adaptation:
|
||||
- `export FP_DEVICE_EMULATION=1`
|
||||
@@ -41,6 +41,11 @@ A new 'capture' test is created by means of `capture.py` script:
|
||||
The following USB device is used in the example above:
|
||||
`/dev/bus/usb/001/005`.
|
||||
|
||||
For the following commands, it is assumed that the user that's
|
||||
running the commands has full access to the device node, whether
|
||||
by running the commands as `root`, or changing the permissions for
|
||||
that device node.
|
||||
|
||||
4. Record information about this device:
|
||||
|
||||
`umockdev-record /dev/bus/usb/001/005 > DRIVER/device`
|
||||
|
||||
@@ -35,11 +35,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0000
|
||||
A: bmAttributes=80
|
||||
A: busnum=3
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12011001FFFFFF08FF0831570000000100010902200001010080320904000002FFFFFF000705810240000007050202080000
|
||||
A: dev=189:259
|
||||
A: devnum=4
|
||||
A: devnum=4\n
|
||||
A: devpath=1.1.3
|
||||
L: driver=../../../../../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=5731
|
||||
@@ -106,11 +106,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=9100
|
||||
A: bmAttributes=e0
|
||||
A: busnum=3
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
||||
A: dev=189:258
|
||||
A: devnum=3
|
||||
A: devnum=3\n
|
||||
A: devpath=1.1
|
||||
L: driver=../../../../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0006
|
||||
@@ -186,11 +186,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=9100
|
||||
A: bmAttributes=e0
|
||||
A: busnum=3
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12011002090001403022060000910102000109021900010100E0000904000001090000000705810301000C
|
||||
A: dev=189:257
|
||||
A: devnum=2
|
||||
A: devnum=2\n
|
||||
A: devpath=1
|
||||
L: driver=../../../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0006
|
||||
@@ -270,11 +270,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0415
|
||||
A: bmAttributes=e0
|
||||
A: busnum=3
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020015040302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:256
|
||||
A: devnum=1
|
||||
A: devnum=1\n
|
||||
A: devpath=0
|
||||
L: driver=../../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0002
|
||||
|
||||
@@ -36,11 +36,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0140
|
||||
A: bmAttributes=80
|
||||
A: busnum=1
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
|
||||
A: dev=189:93
|
||||
A: devnum=94
|
||||
A: devnum=94\n
|
||||
A: devpath=4.4
|
||||
L: driver=../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0c26
|
||||
@@ -107,11 +107,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=5284
|
||||
A: bmAttributes=e0
|
||||
A: busnum=1
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
|
||||
A: dev=189:82
|
||||
A: devnum=83
|
||||
A: devnum=83\n
|
||||
A: devpath=4
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=1018
|
||||
@@ -189,11 +189,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0503
|
||||
A: bmAttributes=e0
|
||||
A: busnum=1
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:0
|
||||
A: devnum=1
|
||||
A: devnum=1\n
|
||||
A: devpath=0
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0002
|
||||
|
||||
@@ -1,307 +1,217 @@
|
||||
@DEV /dev/bus/usb/001/003
|
||||
@DEV /dev/bus/usb/003/008
|
||||
USBDEVFS_GET_CAPABILITIES 0 FD010000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 D00000000500BA4500611A297F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000008009D6200D00001B5A57582000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000008009D6200D00000239572F5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980001FE415050000000000030313030303232384C454E4F564F0000474D3138384230004746333230360000312E30322E30310055534200000000005642530000000000303030303030303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051239DE6303030303033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F410C0A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F3EB36C6A
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980002FE4150500000000000303130303032343744454C4C00000000474D3138384230004746353238380000312E30342E30352E31302E3530000000000000000000000000000000000000005553420000000000564253000000000030303030303030330000000000000000000000000000000000000000000000000000000000003B5CB43C000000000000555342000000000056425300000000003030303030303033000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F41080A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F0558B152
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000208004BB400C00101C96A6C6B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000208004BB400C001005F5A6B1C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030500FB040093B3ED01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000002050049B600C27E4B39
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030700D12E0014140342C8AE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00100020400BE41BBC7BACE
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000004080036C900A60001F1AFC9FB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000004080036C900E00101C26FC596000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000050600609F000094D6C40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000030700AC53000F411A349263
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E0010005080054AB00141441240D0ECF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000003050022DD00CA3B9C30
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000060800E01F00A20001605AE410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000060800E01F00A60001BCF2ED17000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A2000007070007F8005564FA6B157100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000042400F40B000000000000000000000000000000000000000000000000000000000000000095D4A28A
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000070600B64900007A6860130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000040700BA45000F41625785F3
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000080800CC3300A500013F9036A9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000080800CC3300A20001BA8679AC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A50000090500DE2103D6515435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A10000050500807F007BE269C4
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000090C00BC430054640027004D0084CD5EED0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A500000524009F60000000000000000000000000000000000000000000000000000000000000000048D9D8CB
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000A08001AE500A10001AE651B42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000A08001AE500A5000172CD1245000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000B250002FD00B786B17D6A044D24C1651C2B1A76F6396D790639F58CA6D62DDDB8E179A9BD4A6C5C6C9200000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000607006C93000F41A33C2AB4
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A500000B050008F703C6DBFA26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A100000605003DC200632D10DE
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000C0800679800A200011C98B985000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000C0800679800A100014526FF87000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000D0700807F0059643EDA283F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000007070055AA016450891085EC
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000D25007F8000D7843025CC713EA1543DF81EBAAF6BE244543EB9F4BC6FA74E8F246A711CD8C3EA54665F00000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000007070007F8000F41630A457A
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000E0800B14E00A000013F11196A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000E0800B14E00A2000151C59D69000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000000F070004FB000000E0109A2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200080500629D004A354747
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000F0C00C13E003E620027005900101FD1980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000008070012ED016450F8E6B5D9
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001008003FC000B002017532670A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001008003FC000A0000187F37724000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200114500A15E008E0091009E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000988D37C39E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000907002BD4000F41D2CA1A81
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001107008A7500000002FCFB4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020009050009F6004270904E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000120800E91600A20001A47AD7CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000120800E91600B00201386F43E6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001307000EF1004B640F46BD2D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000A0700C43B016450398D1A9E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001345007788008A009C009400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D000000000000000000BEDDBBB29400880008009A0099008B00080008009100850000000000000000008F00A4009B0090008F00A100A000940088009A0097008D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000A07009669000F41D397DA08
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000140800946B00A0000121EDB70D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000140800946B00A200014F39330E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000015070021DE0000007BC22C5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000B0500DF200052FA3E5D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000150C00E41B004E640027004F00755632510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000B0700AF50016450F9BB7550
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000016080042BD00B002019E7183CF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000016080042BD00A000016CB093E1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200174500DC23008200A200AA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000F1B14CECAA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000C0700EB14000F416BC2A256
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000170700F708000000BAA9831600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000C0500C93600FFA00844
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001808006E9100A20001D8B88A5E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001808006E9100B0020144AD1E73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001907008976005664DBD4593000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000D0700D22D01645041EE0D0E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200194500F00F008C009C009600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C000000000000000000E3A1F2A19600080086009D0097008E00810092009100850000000000000000008F00A4009A008F008E00A1009F00920087009A0096008C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000D0700807F000F41ABF4CD98
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001A0800B84700A00001FB312AB1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001A0800B84700A2000195E5AEB2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001B07000DF2000000CA0273AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000E05001FE000EF2AA657
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001B0C00C8370048640027005A00021B15CE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000E07006F9001645040B3CD87
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001C0800C53A00B00201E2B3DE5A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001C0800C53A00A000011072CE74000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001D45005BA400A8009100AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C000000000000000000000000008A57E0B3AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000F070056A9000F416A9F62DF
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001D0700708F003A000B89A2D100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000F0500748B00E76F715E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001E080013EC00A2000133FB6E9B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001E080013EC00B00201AFEEFAB6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001F0700F40B005A625A6BF72B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000100700E11E016450A25FACED
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001F45008D720008009900920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D00000000000000000069C4E77C920086008800960097008D007F0091008D00850000000000000000008F00A4009B0090008F00A100A000930087009A0096008D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000100700B34C000F4148456C7B
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000200800DE2100A000011D15EAC2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000200800DE2100A2000173C16EC1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002107006B94002900A6F807F200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200110500FA0500438F0629
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000210C00AE510048640027005500DD002B870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001107008A750164506269C323
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000022080008F700B00201A289DE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000022080008F700A000015048CE2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200234500966900870088008800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D0000000000000000000000000074CA825A8800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000120700659A000F41892EC33C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000230700BD420000008C0CEEF100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020012050047B8005B407F33
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000240800758A00A20001D5DFAEE8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000240800758A00B0020149CA3AC5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000250700926D00556427B73E5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001307005CA3016450A3026C64
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200254500EB14008D00A100900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C0000000000000000000F8D1061900087000800980099008C00080008000800080000000000000000008F00A3009A008F008E00A0009F00930087009A0096008C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001307000EF1000F414918ACF2
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000260800A35C00A00001F6560E07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000260800A35C00A2000198828A04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000027070016E90058265460564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001405003AC500FE5F9E23
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000270C00D32C0057640027004E0017D2351D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001407004AB5016450DB617BF4
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002808008F7000B00201DE4B8395000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002808008F7000A000012C8A93BB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020029450011EE007B00950097006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D000000000000000000000000007AB44F7697006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000150700738C000F41F14DD4AC
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002907003AC500000044F2661300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020015050051AE00F61A492A
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002A080059A600A200010F033354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002A080059A600B002019316A779000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002B0700BE4100566455244C8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001607009C630164501A0AD4B3
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002B4500C7380089009C00920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D000000000000000000A0269EE8920008008A00990098008A007F0093008E00860000000000000000008F00A4009A008F008E00A100A000930087009A0096008D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000160700CE31000F41F0101425
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002C080024DB00A000018A945392000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002C080024DB00A20001E440D791000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002D0700916E005F2DD3D14D7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200170500877800E690E739
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002D0C0054AB004A64002700590057B20D220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000170700F708016450DA3CBB7D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002E0800F20D00B0020135086750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002E0800F20D00A00001C7C9777E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002F45006C9300A80083008A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000DD3369188A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000180700E21D000F4141D04BDE
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002F070047B8004C4C4EAAB86E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200180500C03F00B4605C02
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003008007C8300A2000111FF9D33000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003008007C8300B002018DEA091E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003107009B6400586440DB796400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000190700DB240164506BFCE486
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200314500E21D00080008000800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C000000000000000000E0BA753D0800080088009A0096008F00820092009000080000000000000000008F00A3009A008F008E00A000A000930087009A0096008C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001907008976000F4181E62410
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000320800AA5500A0000132763DDC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000320800AA5500A200015CA2B9DF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003307001FE072635FE0E8A18200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001A050016E900A4EAF211
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000330C00DA25005464002700500088A694DC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001A070066990164506AA1240F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000340800D72800B002012BF4C937000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000340800D72800A00001D935D919000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020035450049B6007D00920094008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000000000000000000000520A47F394008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001B07005FA0000F41408D8B57
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000350700629D0000006775A83E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001B05007D8200ACAF2518
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000036080001FE00A20001FABC79F6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000036080001FE00B0020166A9EDDB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000370700E619005964B9BF1A2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001C07001BE4016450D2F45C51
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003745009F600008000800080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C000000000000000000F054EC42080008008600970095000800830090008D00880000000000000000008F00A3009A008F008E00A100A000930087009A0096008C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001C070049B6000F4138EE9CC7
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003808002DD200A000014EB46049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003808002DD200A200012060E44A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003907009867725F526A136B6D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001D050000FF0009B0C408
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000390C005DA2004A640027004F005D569D1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001D0700708F01645012C2339F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003A0800FB0400B00201F128548B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003A0800FB0400A0000103E944A5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003B4500659A0084007D008B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000BAEEF1FA8B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001E07009F60000F41F9853380
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003B07004EB1000000D6B5F7C500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A300001E0700B649000F41F8F75650
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003C0800867900A20001867E2463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003C0800867900A30001B114E662000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003D0700619E005864307089D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001F0700A659016450D3A99CD8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A300003D0500629D009DDA98C4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A400001F6A001EE1640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900E6F6BD05
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003E080050AF00A00001A5F7848C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003E080050AF00A40001795F8D8B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003F0700E51A0063324BE2275A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200200500708F00DCB5EECB
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A400003F05006B940099962233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E0000020040049B6AEA0E8AB
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004008001BE400B00201E7BD49D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004008001BE400E00001D5F1C38E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200414500857A0078006F0074009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C0000000000000000000000000079DB6FC674009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000021070039C6000F41C7E8B94B
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000004108001BE400000000315A099D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A60000210500B74800B39B168D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000420800CD3200A2000136F5F911000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000420800CD3200A60001EA5DF016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004307002AD5005A647427533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000220700D6290164502CAFB954
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 A60000436C00EC130001640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900FA60A49A000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00100220400FD0253E4FA3B
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000440800B04F00A00001B36299D7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000440800B04F00E0010132DE18BE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000045070005FA0061447F5F4C1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200230500CD3200C47A97D1
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E00100450800D22D000000002B1189D3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000230700EF100100238AF5F029
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000460800669900B002010CFEAD15000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000460800669900A2000190EB3938000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200474500F807009500860087008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C0000000000000000000000000074D7CC3787008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000240700F906000F417EE0019C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000470C0016E9004C640027004D005C10F4310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000242400B7480000000000000000000000000000000000000000000000000000000000000000664B5D3F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004808004AB500A200014A37A484000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004808004AB500A50001CF21EB81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000490700AD52005764F1A7756700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000250700C03F01645054CCAEC4
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000499200D22D004C642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50C82BB7E8C2D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E000002504008976203A9633
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004A08009C6300A0000169BE046B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004A08009C6300E00001A9339E1B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000004B070029D60041281F96933800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002605000DF20079AA0FDB
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000004B08009C63004C642A9C8BFEAB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E0010026040056A9D15D8DC2
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004C0800E11E00B00201703CF080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004C0800E11E00E00101034161C7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002004D45007F80009E008E008E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000D393E7738E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB000F417FBDC115
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E001004D0800837C004C642ACB9D5A09000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB010023F3CB2730
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004E080037C800A20001A1744041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0700D02F005964C7DF8EA700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000028070051AE016450E45131B6
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0C0047B80052640027004D00E19CE96F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A500002824004DB200000000000000000000000000000000000000000000000000000000000000003DB8032C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000500800B94600A000017742AA0C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000500800B94600A500019C80610A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005107000CF300624F1EC75A2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002905004AB5002B5AB4E0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A5000051920021DE0052642A00000000640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04D4A2B430F0D25BF63D97E631EC0F0F86A6A3DCDEF50CCC7D08E82D30303030303030302D302D30303030303030302D6E6F626F647900954F9F36EAEDD0364E04
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 12 12 0 E00000290400738C14C55D45
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005208006F9000B00201C8DE9ECE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005208006F9000E00001FA921490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200534500F10E0077007A00720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000000000000000000000C5190965720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002A0700D52A000F41CF205E67
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 E000005308006F900052642AB5A4CC36000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A700002A6A0044BB640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479001CF66539
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000054080012ED00A20001BF88EE26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000054080012ED00A70001544A2520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000550700F50A0058641D3C23CD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002B0700EC13016450E50CF13F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000560800C43B00A000019C014EC9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000570700718E726054F685049700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002C05008A7500968A2CEA
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000580800E81700B00201B41CC35B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005945007689008C007100780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000D98A26F0780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002D0700C33C000F41B74349F7
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005A08003EC100A200016554739A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200005B0700D926005964EDCD672F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002E07002CD30164505C0449E8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005C080043BC00A00001E0C3135C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005D0700F609725F58291DE42400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002F050037C8008E4555F0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005E0800956A00B002015F5F279E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005F45000BF400A30088009D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C000000000000000000000000001A1438ED9D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000300700F00F000F4154F2E814
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000060080058A700A200018370B3E9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000610700BF400059646AA8553300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000310700C9360164507EDE474C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006208008E7100A00001A0F91306000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000006307003BC4006432979DA1E700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020032050004FB00326A5B9D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000640800F30C00B00201B97BE7ED000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002006545006D92008D008F008A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000394AB8458A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200003307004DB2000F4155AF289D
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000066080025DA00A200016833572C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000670700C23D0057645CD0AEF300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000034070009F6016450C7D6FF9B
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000068080009F600A00001DC3B4E93000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000690700BC43002E00509568C700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A3000035070019E6000F41EC883513
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006A0800DF2000A30001C8D82C7D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A300006B05003BC40055C25B16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A40000366A006798640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900B5C8699F
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006C0800A25D00A40001A68D87BD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A400006D0500996600E41BAEE2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A60000370500689700E8D1ECD8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006E0800748B00A6000185042752000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 A600006F6C0055AA0001640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479006EA4C362000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000380700A15E010023D1112994
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000392400847B000000000000000000000000000000000000000000000000000000000000000038910386
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 a200003a07007788010023107a86d3
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 a500003b240052ad0000000000000000000000000000000000000000000000000000000000000000828af704
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 a700003c6a009b64640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4650312d30303030303030302d302d30303030303030302d6e6f626f647900473c9b29
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000074080051AE00A70001AC924B34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000075050011EE00ACFFDA28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000055050052AD00C5D5FE86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -20,6 +20,7 @@ d.open_sync()
|
||||
template = FPrint.Print.new(d)
|
||||
|
||||
def enroll_progress(*args):
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NEEDED
|
||||
print('enroll progress: ' + str(args))
|
||||
|
||||
def identify_done(dev, res):
|
||||
@@ -31,7 +32,9 @@ def identify_done(dev, res):
|
||||
|
||||
# List, enroll, list, verify, identify, delete
|
||||
print("enrolling")
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
p = d.enroll_sync(template, None, enroll_progress, None)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("enroll done")
|
||||
|
||||
print("listing")
|
||||
@@ -40,7 +43,9 @@ print("listing done")
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p)
|
||||
print("verifying")
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
verify_res, verify_print = d.verify_sync(p)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("verify done")
|
||||
del p
|
||||
assert verify_res == True
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8
|
||||
N: bus/usb/001/003=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||
E: DEVNAME=/dev/bus/usb/001/003
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3/3-2
|
||||
N: bus/usb/003/008=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||
E: DEVNAME=/dev/bus/usb/003/008
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: PRODUCT=27c6/60a2/100
|
||||
E: PRODUCT=27c6/5840/100
|
||||
E: TYPE=239/0/0
|
||||
E: BUSNUM=001
|
||||
E: DEVNUM=003
|
||||
E: BUSNUM=003
|
||||
E: DEVNUM=008
|
||||
E: MAJOR=189
|
||||
E: MINOR=2
|
||||
E: MINOR=263
|
||||
E: SUBSYSTEM=usb
|
||||
E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
|
||||
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
|
||||
E: ID_VENDOR_ID=27c6
|
||||
E: ID_MODEL=Goodix_USB2.0_MISC
|
||||
E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC
|
||||
E: ID_MODEL_ID=60a2
|
||||
E: ID_MODEL_ID=5840
|
||||
E: ID_REVISION=0100
|
||||
E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDCBEE4D7B_XXXX_MOC_B0
|
||||
E: ID_SERIAL_SHORT=UIDCBEE4D7B_XXXX_MOC_B0
|
||||
E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDE1AD5CBA_XXXX_MOC_B0
|
||||
E: ID_SERIAL_SHORT=UIDE1AD5CBA_XXXX_MOC_B0
|
||||
E: ID_BUS=usb
|
||||
E: ID_USB_INTERFACES=:ff0000:
|
||||
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:8
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8
|
||||
E: LIBFPRINT_DRIVER=AuthenTec AES1610
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:2
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2
|
||||
E: LIBFPRINT_DRIVER=Goodix MOC Fingerprint Sensor
|
||||
A: authorized=1
|
||||
A: avoid_reset_quirk=0
|
||||
A: bConfigurationValue=1
|
||||
@@ -37,32 +37,32 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0100
|
||||
A: bmAttributes=a0
|
||||
A: busnum=1
|
||||
A: configuration=UIDCBEE4D7B_XXXX_MOC_B0
|
||||
H: descriptors=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||
A: dev=189:2
|
||||
A: devnum=3
|
||||
A: devpath=8
|
||||
A: busnum=3\n
|
||||
A: configuration=UIDE1AD5CBA_XXXX_MOC_B0
|
||||
H: descriptors=12010002EF000040C627405800010102030109022000010103A0320904000002FF0000040705830240000007050102400000
|
||||
A: dev=189:263
|
||||
A: devnum=8\n
|
||||
A: devpath=2
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=60a2
|
||||
A: idProduct=5840
|
||||
A: idVendor=27c6
|
||||
A: ltm_capable=no
|
||||
A: manufacturer=Goodix Technology Co., Ltd.
|
||||
A: maxchild=0
|
||||
L: port=../1-0:1.0/usb1-port8
|
||||
A: power/active_duration=324448
|
||||
L: port=../3-0:1.0/usb3-port2
|
||||
A: power/active_duration=2684
|
||||
A: power/async=enabled
|
||||
A: power/autosuspend=2
|
||||
A: power/autosuspend_delay_ms=2000
|
||||
A: power/connected_duration=5916532
|
||||
A: power/connected_duration=54348
|
||||
A: power/control=auto
|
||||
A: power/level=auto
|
||||
A: power/persist=1
|
||||
A: power/runtime_active_kids=0
|
||||
A: power/runtime_active_time=327268
|
||||
A: power/runtime_active_time=2518
|
||||
A: power/runtime_enabled=enabled
|
||||
A: power/runtime_status=active
|
||||
A: power/runtime_suspended_time=5588987
|
||||
A: power/runtime_suspended_time=51550
|
||||
A: power/runtime_usage=0
|
||||
A: power/wakeup=disabled
|
||||
A: power/wakeup_abort_count=
|
||||
@@ -75,38 +75,39 @@ A: power/wakeup_max_time_ms=
|
||||
A: power/wakeup_total_time_ms=
|
||||
A: product=Goodix USB2.0 MISC
|
||||
A: quirks=0x0
|
||||
A: removable=fixed
|
||||
A: removable=removable
|
||||
A: rx_lanes=1
|
||||
A: serial=UIDCBEE4D7B_XXXX_MOC_B0
|
||||
A: serial=UIDE1AD5CBA_XXXX_MOC_B0
|
||||
A: speed=12
|
||||
A: tx_lanes=1
|
||||
A: urbnum=2180
|
||||
A: urbnum=15
|
||||
A: version= 2.00
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb1
|
||||
N: bus/usb/001/001=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
||||
E: DEVNAME=/dev/bus/usb/001/001
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3
|
||||
N: bus/usb/003/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||
E: DEVNAME=/dev/bus/usb/003/001
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: PRODUCT=1d6b/2/504
|
||||
E: PRODUCT=1d6b/2/508
|
||||
E: TYPE=9/0/1
|
||||
E: BUSNUM=001
|
||||
E: BUSNUM=003
|
||||
E: DEVNUM=001
|
||||
E: MAJOR=189
|
||||
E: MINOR=0
|
||||
E: MINOR=256
|
||||
E: SUBSYSTEM=usb
|
||||
E: ID_VENDOR=Linux_5.4.0-29-generic_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x205.4.0-29-generic\x20xhci-hcd
|
||||
E: ID_VENDOR=Linux_5.8.0-38-generic_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x205.8.0-38-generic\x20xhci-hcd
|
||||
E: ID_VENDOR_ID=1d6b
|
||||
E: ID_MODEL=xHCI_Host_Controller
|
||||
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_MODEL_ID=0002
|
||||
E: ID_REVISION=0504
|
||||
E: ID_SERIAL=Linux_5.4.0-29-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_REVISION=0508
|
||||
E: ID_SERIAL=Linux_5.8.0-38-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_BUS=usb
|
||||
E: ID_USB_INTERFACES=:090000:
|
||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
@@ -123,33 +124,33 @@ A: bMaxPacketSize0=64
|
||||
A: bMaxPower=0mA
|
||||
A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0504
|
||||
A: bcdDevice=0508
|
||||
A: bmAttributes=e0
|
||||
A: busnum=1
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:0
|
||||
A: devnum=1
|
||||
H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:256
|
||||
A: devnum=1\n
|
||||
A: devpath=0
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0002
|
||||
A: idVendor=1d6b
|
||||
A: interface_authorized_default=1
|
||||
A: ltm_capable=no
|
||||
A: manufacturer=Linux 5.4.0-29-generic xhci-hcd
|
||||
A: maxchild=12
|
||||
A: power/active_duration=5879432
|
||||
A: manufacturer=Linux 5.8.0-38-generic xhci-hcd
|
||||
A: maxchild=4
|
||||
A: power/active_duration=2790916
|
||||
A: power/async=enabled
|
||||
A: power/autosuspend=0
|
||||
A: power/autosuspend_delay_ms=0
|
||||
A: power/connected_duration=5916912
|
||||
A: power/connected_duration=15607832
|
||||
A: power/control=auto
|
||||
A: power/level=auto
|
||||
A: power/runtime_active_kids=2
|
||||
A: power/runtime_active_time=5879430
|
||||
A: power/runtime_active_kids=1
|
||||
A: power/runtime_active_time=2790874
|
||||
A: power/runtime_enabled=enabled
|
||||
A: power/runtime_status=active
|
||||
A: power/runtime_suspended_time=37481
|
||||
A: power/runtime_suspended_time=12816956
|
||||
A: power/runtime_usage=0
|
||||
A: power/wakeup=disabled
|
||||
A: power/wakeup_abort_count=
|
||||
@@ -167,5 +168,7 @@ A: rx_lanes=1
|
||||
A: serial=0000:00:14.0
|
||||
A: speed=480
|
||||
A: tx_lanes=1
|
||||
A: urbnum=1319
|
||||
A: urbnum=584
|
||||
A: version= 2.00
|
||||
|
||||
|
||||
|
||||
54
tests/hwdb-check-unsupported.py
Executable file
54
tests/hwdb-check-unsupported.py
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urllib
|
||||
import urllib.request
|
||||
import re
|
||||
|
||||
error = False
|
||||
|
||||
try:
|
||||
response = urllib.request.urlopen('https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md')
|
||||
except:
|
||||
print("Could not download current list of unsupported devices, skipping test.")
|
||||
sys.exit(77)
|
||||
data = response.read().decode('utf-8')
|
||||
|
||||
devices = []
|
||||
devices_re = re.compile(r'^.*([0-9a-fA-F]{4}):([0-9a-fA-F]{4}).*$', re.MULTILINE)
|
||||
for m in devices_re.finditer(data):
|
||||
vid = m.group(1)
|
||||
pid = m.group(2)
|
||||
devices.append((vid, pid))
|
||||
|
||||
generator = open(os.path.join(os.path.dirname(__file__), '..', 'libfprint', 'fprint-list-udev-hwdb.c')).read()
|
||||
|
||||
id_re = re.compile(' { .vid = 0x([a-fA-F0-9]*), .pid = 0x([a-fA-F0-9]*) }')
|
||||
# Check everything is the same
|
||||
started = False
|
||||
for l in generator.split('\n'):
|
||||
m = id_re.match(l)
|
||||
if m is None:
|
||||
# Stop on the first line that does not match anymore
|
||||
if started:
|
||||
break
|
||||
continue
|
||||
else:
|
||||
started = True
|
||||
|
||||
vid_pid = (m.group(1), m.group(2))
|
||||
try:
|
||||
devices.remove(vid_pid)
|
||||
except ValueError:
|
||||
print("Generator has entry that is not on wiki: {}:{}".format(*vid_pid))
|
||||
error = True
|
||||
|
||||
for vid_pid in devices:
|
||||
print("New entry from wiki is missing: {}:{}".format(*vid_pid))
|
||||
error = True
|
||||
|
||||
if error:
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(0)
|
||||
@@ -5,14 +5,22 @@ envs.set('G_MESSAGES_DEBUG', 'all')
|
||||
|
||||
# Setup paths
|
||||
envs.set('MESON_SOURCE_ROOT', meson.source_root())
|
||||
envs.set('MESON_BUILD_ROOT', meson.build_root())
|
||||
envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
|
||||
|
||||
# Set FP_DEVICE_EMULATION so that drivers can adapt (e.g. to use fixed
|
||||
# random numbers rather than proper ones)
|
||||
envs.set('FP_DEVICE_EMULATION', '1')
|
||||
|
||||
# Path to SDCP virtual device binary, only used for virtual-sdcp test
|
||||
envs.set('SDCP_VIRT_BINARY', get_option('sdcp_virt_binary'))
|
||||
|
||||
# Set a colon-separated list of native drivers we enable in tests
|
||||
envs.set('FP_DRIVERS_WHITELIST', 'virtual_image')
|
||||
envs.set('FP_DRIVERS_WHITELIST', ':'.join([
|
||||
'virtual_image',
|
||||
'virtual_device',
|
||||
'virtual_device_storage',
|
||||
]))
|
||||
|
||||
envs.set('NO_AT_BRIDGE', '1')
|
||||
|
||||
@@ -28,20 +36,27 @@ drivers_tests = [
|
||||
|
||||
if get_option('introspection')
|
||||
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
|
||||
virtual_devices_tests = [
|
||||
'virtual-image',
|
||||
'virtual-device',
|
||||
]
|
||||
|
||||
if 'virtual_image' in drivers
|
||||
python3 = find_program('python3')
|
||||
unittest_inspector = find_program('unittest_inspector.py')
|
||||
base_args = files('virtual-image.py')
|
||||
suite = []
|
||||
|
||||
r = run_command(unittest_inspector, files('virtual-image.py'))
|
||||
foreach vdtest: virtual_devices_tests
|
||||
driver_name = '_'.join(vdtest.split('-'))
|
||||
if driver_name in drivers
|
||||
python3 = find_program('python3')
|
||||
base_args = files(vdtest + '.py')
|
||||
suite = ['virtual-driver']
|
||||
|
||||
r = run_command(unittest_inspector, files(vdtest + '.py'))
|
||||
unit_tests = r.stdout().strip().split('\n')
|
||||
|
||||
if r.returncode() == 0 and unit_tests.length() > 0
|
||||
suite += 'virtual-image'
|
||||
suite += vdtest
|
||||
else
|
||||
unit_tests = ['virtual-image']
|
||||
unit_tests = [vdtest]
|
||||
endif
|
||||
|
||||
foreach ut: unit_tests
|
||||
@@ -57,10 +72,52 @@ if get_option('introspection')
|
||||
suite: ut_suite,
|
||||
depends: libfprint_typelib,
|
||||
env: envs,
|
||||
workdir: meson.current_source_dir(),
|
||||
)
|
||||
endforeach
|
||||
else
|
||||
test('virtual-image',
|
||||
test(vdtest,
|
||||
find_program('sh'),
|
||||
args: ['-c', 'exit 77']
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if 'virtual_sdcp' in drivers and get_option('sdcp_virt_binary') != ''
|
||||
python3 = find_program('python3')
|
||||
unittest_inspector = find_program('unittest_inspector.py')
|
||||
base_args = files('virtual-sdcp.py')
|
||||
suite = []
|
||||
|
||||
r = run_command(unittest_inspector, files('virtual-sdcp.py'))
|
||||
unit_tests = r.stdout().strip().split('\n')
|
||||
|
||||
if r.returncode() == 0 and unit_tests.length() > 0
|
||||
suite += 'virtual-sdcp'
|
||||
else
|
||||
unit_tests = ['virtual-sdcp']
|
||||
endif
|
||||
|
||||
sdcp_envs = envs
|
||||
sdcp_envs.set('FP_DEVICE_EMULATION', '0')
|
||||
foreach ut: unit_tests
|
||||
ut_suite = suite
|
||||
ut_args = base_args
|
||||
if unit_tests.length() > 1
|
||||
ut_args += ut
|
||||
ut_suite += ut.split('.')[0]
|
||||
endif
|
||||
test(ut,
|
||||
python3,
|
||||
args: ut_args,
|
||||
suite: ut_suite,
|
||||
depends: libfprint_typelib,
|
||||
env: sdcp_envs,
|
||||
workdir: meson.current_source_dir(),
|
||||
)
|
||||
endforeach
|
||||
else
|
||||
test('virtual-sdcp',
|
||||
find_program('sh'),
|
||||
args: ['-c', 'exit 77']
|
||||
)
|
||||
@@ -70,11 +127,13 @@ if get_option('introspection')
|
||||
driver_envs = envs
|
||||
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
|
||||
|
||||
if driver_test in drivers and gusb_dep.version().version_compare('>= 0.3.0')
|
||||
if (driver_test in supported_drivers and
|
||||
gusb_dep.version().version_compare('>= 0.3.0'))
|
||||
test(driver_test,
|
||||
find_program('umockdev-test.py'),
|
||||
args: join_paths(meson.current_source_dir(), driver_test),
|
||||
env: driver_envs,
|
||||
workdir: meson.current_source_dir(),
|
||||
suite: ['drivers'],
|
||||
timeout: 10,
|
||||
depends: libfprint_typelib,
|
||||
@@ -168,6 +227,13 @@ foreach test_name: unit_tests
|
||||
)
|
||||
endforeach
|
||||
|
||||
# Run udev rule generator with fatal warnings
|
||||
envs.set('UDEV_HWDB', udev_hwdb.full_path())
|
||||
envs.set('UDEV_HWDB_CHECK_CONTENTS', default_drivers_are_enabled ? '1' : '0')
|
||||
test('udev-hwdb',
|
||||
find_program('test-generated-hwdb.sh'),
|
||||
env: envs)
|
||||
|
||||
gdb = find_program('gdb', required: false)
|
||||
if gdb.found()
|
||||
add_test_setup('gdb',
|
||||
@@ -188,6 +254,7 @@ if valgrind.found()
|
||||
timeout_multiplier: 10,
|
||||
env: [
|
||||
'G_SLICE=always-malloc',
|
||||
'UNDER_VALGRIND=1',
|
||||
('LIBFPRINT_TEST_WRAPPER=@0@ --tool=memcheck --leak-check=full ' +
|
||||
'--suppressions=@1@ --suppressions=@2@').format(
|
||||
valgrind.path(), glib_suppressions, python_suppressions)
|
||||
|
||||
BIN
tests/sdcp-key-db/cert9.db
Normal file
BIN
tests/sdcp-key-db/cert9.db
Normal file
Binary file not shown.
BIN
tests/sdcp-key-db/key4.db
Normal file
BIN
tests/sdcp-key-db/key4.db
Normal file
Binary file not shown.
@@ -4,14 +4,16 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 01
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 40 38 0 00009C37FE5C669C2D000A01014101C10000D11BB7134A090FA1000000000100000000000003
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE011100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE01130100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE025400
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE021100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02130100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE03512000014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE035400
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
@@ -20,13 +22,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255010C
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355010C
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
@@ -35,19 +37,19 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550119
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550119
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550125
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550125
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -56,13 +58,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550125
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550125
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -71,13 +73,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550132
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550132
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -86,13 +88,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255013E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355013E
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -101,13 +103,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255013E
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355013E
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -116,13 +118,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0255014B
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE0355014B
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
@@ -131,7 +133,7 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
@@ -140,13 +142,13 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550157
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550157
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE026000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE036000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
@@ -155,21 +157,21 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 37 37 0 A7FE02512000014650312D30303030303030302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE02550164
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE03550164
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE02591F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE03591F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE03752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE037200
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE037600
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE04651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE046600
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 41 0 0000FE04752301012007014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE047200
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE047600
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE05651E4650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE056600
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE046000
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE056000
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 06000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910101
|
||||
@@ -178,9 +180,9 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 35 35 0 A7FE04651E4650312D30303030303030302D302
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 7 0 0000FE00910100
|
||||
USBDEVFS_REAPURBNDELAY 0 1 131 0 0 7 7 0 05000000000100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 1 1 0 A8
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0468214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE05811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE05831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE06A100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE06A200
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 39 0 0000FE0568214F2B014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 36 36 0 A7FE06811F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 37 0 0000FE06831F014650312D30303030303030302D302D30303030303030302D6E6F626F6479
|
||||
USBDEVFS_REAPURBNDELAY 0 3 1 0 0 5 5 0 A7FE07A100
|
||||
USBDEVFS_REAPURBNDELAY 0 3 129 0 0 266 6 0 0000FE07A200
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0000
|
||||
A: bmAttributes=a0
|
||||
A: busnum=1
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002FF10FF08CB06BD0000000000010109022700010100A0320904000003FF000000070501024000000705810240000007058303080004
|
||||
A: dev=189:69
|
||||
A: devnum=70
|
||||
A: devnum=70\n
|
||||
A: devpath=1
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=00bd
|
||||
|
||||
@@ -50,7 +50,7 @@ test_context_has_virtual_device (void)
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
fpt_setup_virtual_device_environment ();
|
||||
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
context = fp_context_new ();
|
||||
devices = fp_context_get_devices (context);
|
||||
@@ -82,7 +82,7 @@ test_context_enumerates_new_devices (void)
|
||||
|
||||
context = fp_context_new ();
|
||||
|
||||
fpt_setup_virtual_device_environment ();
|
||||
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_context_enumerate (context);
|
||||
devices = fp_context_get_devices (context);
|
||||
@@ -120,7 +120,7 @@ context_device_removed_cb (FpContext *ctx, FpDevice *device, FptContext *tctx)
|
||||
static void
|
||||
test_context_remove_device_closed (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
gboolean removed;
|
||||
|
||||
tctx->user_data = NULL;
|
||||
@@ -162,7 +162,7 @@ close_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||
static void
|
||||
test_context_remove_device_closing (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(GError) close_error = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean removed;
|
||||
@@ -207,7 +207,7 @@ test_context_remove_device_closing (void)
|
||||
static void
|
||||
test_context_remove_device_open (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean removed = FALSE;
|
||||
|
||||
@@ -267,7 +267,7 @@ open_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||
static void
|
||||
test_context_remove_device_opening (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(GError) close_error = NULL;
|
||||
gboolean open_done = FALSE;
|
||||
gboolean removed;
|
||||
@@ -287,7 +287,7 @@ test_context_remove_device_opening (void)
|
||||
g_assert_true (removed);
|
||||
g_assert_null (tctx->user_data);
|
||||
|
||||
/* Running the mainloop now will cause the open to *succeed* dispite removal! */
|
||||
/* Running the mainloop now will cause the open to *succeed* despite removal! */
|
||||
while (!open_done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
@@ -327,7 +327,7 @@ enroll_done_cb (GObject *device, GAsyncResult *res, gpointer user_data)
|
||||
static void
|
||||
test_context_remove_device_active (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GCancellable) cancellable = NULL;
|
||||
g_autoptr(GError) enroll_error = NULL;
|
||||
|
||||
@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
static void
|
||||
test_device_open_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
|
||||
@@ -59,7 +59,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
static void
|
||||
test_device_close_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
while (!tctx->user_data)
|
||||
@@ -76,7 +76,7 @@ static void
|
||||
test_device_open_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
@@ -97,7 +97,7 @@ static void
|
||||
test_device_open_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
@@ -109,7 +109,7 @@ static void
|
||||
test_device_close_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
@@ -131,7 +131,7 @@ static void
|
||||
test_device_close_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
|
||||
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
|
||||
static void
|
||||
test_device_get_driver (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
||||
@@ -153,7 +153,7 @@ test_device_get_driver (void)
|
||||
static void
|
||||
test_device_get_device_id (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
||||
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
|
||||
static void
|
||||
test_device_get_name (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
||||
@@ -172,7 +172,7 @@ test_device_get_name (void)
|
||||
static void
|
||||
test_device_get_scan_type (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
||||
@@ -181,7 +181,7 @@ test_device_get_scan_type (void)
|
||||
static void
|
||||
test_device_get_finger_status (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpint (fp_device_get_finger_status (tctx->device), ==, FP_FINGER_STATUS_NONE);
|
||||
@@ -190,7 +190,7 @@ test_device_get_finger_status (void)
|
||||
static void
|
||||
test_device_get_nr_enroll_stages (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
||||
@@ -199,7 +199,7 @@ test_device_get_nr_enroll_stages (void)
|
||||
static void
|
||||
test_device_supports_identify (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_identify (tctx->device));
|
||||
@@ -208,7 +208,7 @@ test_device_supports_identify (void)
|
||||
static void
|
||||
test_device_supports_capture (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_capture (tctx->device));
|
||||
@@ -217,7 +217,7 @@ test_device_supports_capture (void)
|
||||
static void
|
||||
test_device_has_storage (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_false (fp_device_has_storage (tctx->device));
|
||||
|
||||
@@ -433,7 +433,7 @@ test_driver_set_nr_enroll_stages (void)
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
|
||||
g_autoptr(GParamSpec) pspec = NULL;
|
||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||
int expected_stages = g_random_int_range (G_MININT32, G_MAXINT32);
|
||||
int expected_stages = g_random_int_range (1, G_MAXINT32);
|
||||
|
||||
g_signal_connect (device, "notify::nr-enroll-stages", G_CALLBACK (on_device_notify), NULL);
|
||||
fpi_device_set_nr_enroll_stages (device, expected_stages);
|
||||
@@ -443,6 +443,18 @@ test_driver_set_nr_enroll_stages (void)
|
||||
|
||||
pspec = g_steal_pointer (&fake_dev->user_data);
|
||||
g_assert_cmpstr (pspec->name, ==, "nr-enroll-stages");
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*enroll_stages > 0*");
|
||||
fpi_device_set_nr_enroll_stages (device, 0);
|
||||
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*enroll_stages > 0*");
|
||||
fpi_device_set_nr_enroll_stages (device, -2);
|
||||
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
|
||||
g_test_assert_expected_messages ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
24
tests/test-generated-hwdb.sh
Executable file
24
tests/test-generated-hwdb.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
[ -x "$UDEV_HWDB" ] || exit 1
|
||||
|
||||
if [ "$UDEV_HWDB_CHECK_CONTENTS" == 1 ]; then
|
||||
generated_rules=$(mktemp "${TMPDIR:-/tmp}/libfprint-XXXXXX.hwdb")
|
||||
else
|
||||
generated_rules=/dev/null
|
||||
fi
|
||||
|
||||
$UDEV_HWDB > "$generated_rules"
|
||||
|
||||
if [ "$UDEV_HWDB_CHECK_CONTENTS" != 1 ]; then
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! diff -u "$MESON_SOURCE_ROOT/data/autosuspend.hwdb" "$generated_rules"; then
|
||||
echo "E: Autosuspend file needs to be re-generated!"
|
||||
echo " ninja -C $MESON_BUILD_ROOT libfprint/sync-udev-hwdb"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm "$generated_rules"
|
||||
@@ -22,16 +22,31 @@
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
struct
|
||||
{
|
||||
const char *envvar;
|
||||
const char *driver_id;
|
||||
const char *device_id;
|
||||
} devtype_vars[FPT_NUM_VIRTUAL_DEVICE_TYPES] = {
|
||||
{ "FP_VIRTUAL_IMAGE", "virtual_image", "virtual_image" }, /* FPT_VIRTUAL_DEVICE_IMAGE */
|
||||
{ "FP_VIRTUAL_DEVICE", "virtual_device", "virtual_device" }, /* FPT_VIRTUAL_DEVICE_NONIMAGE */
|
||||
{ "FP_VIRTUAL_DEVICE_STORAGE", "virtual_device_storage", "virtual_device_storage" } /* FPT_VIRTUAL_DEVICE_NONIMAGE_STORAGE */
|
||||
};
|
||||
|
||||
static FptVirtualDeviceType global_devtype;
|
||||
|
||||
void
|
||||
fpt_teardown_virtual_device_environment (void)
|
||||
{
|
||||
const char *path = g_getenv ("FP_VIRTUAL_IMAGE");
|
||||
const char *path;
|
||||
|
||||
path = g_getenv (devtype_vars[global_devtype].envvar);
|
||||
|
||||
if (path)
|
||||
{
|
||||
g_autofree char *temp_dir = g_path_get_dirname (path);
|
||||
|
||||
g_unsetenv ("FP_VIRTUAL_IMAGE");
|
||||
g_unsetenv (devtype_vars[global_devtype].envvar);
|
||||
g_unlink (path);
|
||||
g_rmdir (temp_dir);
|
||||
}
|
||||
@@ -44,19 +59,23 @@ on_signal_event (int sig)
|
||||
}
|
||||
|
||||
void
|
||||
fpt_setup_virtual_device_environment (void)
|
||||
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autofree char *temp_dir = NULL;
|
||||
g_autofree char *temp_path = NULL;
|
||||
g_autofree char *filename = NULL;
|
||||
|
||||
g_assert_null (g_getenv ("FP_VIRTUAL_IMAGE"));
|
||||
g_assert_null (g_getenv (devtype_vars[devtype].envvar));
|
||||
|
||||
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
|
||||
g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
|
||||
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id);
|
||||
temp_path = g_build_filename (temp_dir, filename, NULL);
|
||||
g_setenv (devtype_vars[devtype].envvar, temp_path, TRUE);
|
||||
|
||||
global_devtype = devtype;
|
||||
|
||||
signal (SIGKILL, on_signal_event);
|
||||
signal (SIGABRT, on_signal_event);
|
||||
@@ -78,13 +97,16 @@ fpt_context_new (void)
|
||||
}
|
||||
|
||||
FptContext *
|
||||
fpt_context_new_with_virtual_imgdev (void)
|
||||
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||
{
|
||||
FptContext *tctx;
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
fpt_setup_virtual_device_environment ();
|
||||
g_assert_true (devtype >= FPT_VIRTUAL_DEVICE_IMAGE &&
|
||||
devtype < FPT_NUM_VIRTUAL_DEVICE_TYPES);
|
||||
|
||||
fpt_setup_virtual_device_environment (devtype);
|
||||
|
||||
tctx = fpt_context_new ();
|
||||
devices = fp_context_get_devices (tctx->fp_context);
|
||||
@@ -96,7 +118,7 @@ fpt_context_new_with_virtual_imgdev (void)
|
||||
{
|
||||
FpDevice *device = devices->pdata[i];
|
||||
|
||||
if (g_strcmp0 (fp_device_get_driver (device), "virtual_image") == 0)
|
||||
if (g_strcmp0 (fp_device_get_driver (device), devtype_vars[devtype].driver_id) == 0)
|
||||
{
|
||||
tctx->device = device;
|
||||
break;
|
||||
|
||||
@@ -19,7 +19,14 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
void fpt_setup_virtual_device_environment (void);
|
||||
typedef enum {
|
||||
FPT_VIRTUAL_DEVICE_IMAGE = 0,
|
||||
FPT_VIRTUAL_DEVICE_NONIMAGE,
|
||||
FPT_VIRTUAL_DEVICE_NONIMAGE_STORAGE,
|
||||
FPT_NUM_VIRTUAL_DEVICE_TYPES
|
||||
} FptVirtualDeviceType;
|
||||
|
||||
void fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype);
|
||||
void fpt_teardown_virtual_device_environment (void);
|
||||
|
||||
typedef struct _FptContext
|
||||
@@ -30,7 +37,7 @@ typedef struct _FptContext
|
||||
} FptContext;
|
||||
|
||||
FptContext * fpt_context_new (void);
|
||||
FptContext * fpt_context_new_with_virtual_imgdev (void);
|
||||
FptContext * fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype);
|
||||
|
||||
void fpt_context_free (FptContext *test_context);
|
||||
|
||||
|
||||
0
tests/umockdev-test.py
Normal file → Executable file
0
tests/umockdev-test.py
Normal file → Executable file
@@ -38,11 +38,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0060
|
||||
A: bmAttributes=a0
|
||||
A: busnum=1
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=12011001FF10FF088A13500060000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||
A: dev=189:3
|
||||
A: devnum=4
|
||||
A: devnum=4\n
|
||||
A: devpath=9
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0050
|
||||
|
||||
@@ -37,11 +37,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0c90
|
||||
A: bmAttributes=a0
|
||||
A: busnum=2
|
||||
A: busnum=2\n
|
||||
A: configuration=
|
||||
H: descriptors=12011001FF10FF088A130500900C0000000109022700010100A0320904000003FF000000070501024000000705810240000007058202400000
|
||||
A: dev=189:132
|
||||
A: devnum=5
|
||||
A: devnum=5\n
|
||||
A: devpath=1.3
|
||||
L: driver=../../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0005
|
||||
@@ -120,11 +120,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0000
|
||||
A: bmAttributes=e0
|
||||
A: busnum=2
|
||||
A: busnum=2\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001408780200000000000000109021900010100E0000904000001090000000705810302000C
|
||||
A: dev=189:129
|
||||
A: devnum=2
|
||||
A: devnum=2\n
|
||||
A: devpath=1
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0020
|
||||
@@ -204,11 +204,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0504
|
||||
A: bmAttributes=e0
|
||||
A: busnum=2
|
||||
A: busnum=2\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090000406B1D020004050302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:128
|
||||
A: devnum=1
|
||||
A: devnum=1\n
|
||||
A: devpath=0
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0002
|
||||
|
||||
@@ -35,11 +35,11 @@ A: bNumConfigurations=1
|
||||
A: bNumInterfaces= 1
|
||||
A: bcdDevice=0078
|
||||
A: bmAttributes=a0
|
||||
A: busnum=2
|
||||
A: busnum=2\n
|
||||
A: configuration=
|
||||
H: descriptors=12011001FF11FF088A13170078000000010109022E00010100A0320904000004FF00000007050102400000070581024000000705820240000007058303080004
|
||||
A: dev=189:144
|
||||
A: devnum=17
|
||||
A: devnum=17\n
|
||||
A: devpath=6
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
A: idProduct=0017
|
||||
|
||||
1112
tests/virtual-device.py
Normal file
1112
tests/virtual-device.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -223,6 +223,10 @@ class VirtualImage(unittest.TestCase):
|
||||
ctx.iteration(True)
|
||||
|
||||
self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NONE)
|
||||
self.assertEqual(self._enrolled.props.driver, self.dev.get_driver())
|
||||
self.assertEqual(self._enrolled.props.device_id, self.dev.get_device_id())
|
||||
self.assertEqual(self._enrolled.props.device_stored, self.dev.has_storage())
|
||||
self.assertIsNone(self._enrolled.get_image())
|
||||
|
||||
return self._enrolled
|
||||
|
||||
@@ -244,6 +248,7 @@ class VirtualImage(unittest.TestCase):
|
||||
while self._verify_match is None:
|
||||
ctx.iteration(True)
|
||||
assert(self._verify_match)
|
||||
self.assertIsNotNone(self._verify_fp.props.image)
|
||||
|
||||
self._verify_match = None
|
||||
self._verify_fp = None
|
||||
|
||||
144
tests/virtual-sdcp.py
Normal file
144
tests/virtual-sdcp.py
Normal file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
try:
|
||||
import gi
|
||||
import os
|
||||
|
||||
from gi.repository import GLib, Gio
|
||||
|
||||
import unittest
|
||||
import subprocess
|
||||
import shutil
|
||||
import tempfile
|
||||
except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
FPrint = None
|
||||
|
||||
# Re-run the test with the passed wrapper if set
|
||||
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
|
||||
if wrapper:
|
||||
wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
|
||||
sys.argv[1:]
|
||||
os.unsetenv('LIBFPRINT_TEST_WRAPPER')
|
||||
sys.exit(subprocess.check_call(wrap_cmd))
|
||||
|
||||
# Only permit loading virtual_sdcp driver for tests in this file
|
||||
os.environ['FP_DRIVERS_WHITELIST'] = 'virtual_sdcp'
|
||||
|
||||
if hasattr(os.environ, 'MESON_SOURCE_ROOT'):
|
||||
root = os.environ['MESON_SOURCE_ROOT']
|
||||
else:
|
||||
root = os.path.join(os.path.dirname(__file__), '..')
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
class VirtualSDCP(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.environ['FP_VIRTUAL_SDCP'] = os.environ['SDCP_VIRT_BINARY']
|
||||
|
||||
cls.ctx = FPrint.Context()
|
||||
|
||||
cls.dev = None
|
||||
for dev in cls.ctx.get_devices():
|
||||
cls.dev = dev
|
||||
break
|
||||
|
||||
assert cls.dev is not None, "You need to compile with virtual_sdcp for testing"
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.dev
|
||||
del cls.ctx
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def enroll(self, progress_cb=None):
|
||||
# Enroll another print
|
||||
template = FPrint.Print.new(self.dev)
|
||||
template.props.finger = FPrint.Finger.LEFT_THUMB
|
||||
template.props.username = "testuser"
|
||||
template.props.description = "test print"
|
||||
datetime = GLib.DateTime.new_now_local()
|
||||
date = GLib.Date()
|
||||
date.set_dmy(*datetime.get_ymd()[::-1])
|
||||
template.props.enroll_date = date
|
||||
return self.dev.enroll_sync(template, None, progress_cb, None)
|
||||
|
||||
def test_connect(self):
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
|
||||
def test_reconnect(self):
|
||||
# Ensure device was opened once before, this may be a reconnect if
|
||||
# it is the same process as another test.
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
|
||||
# Check that a reconnect happens on next open. To know about this, we
|
||||
# need to parse check log messages for that.
|
||||
success = [False]
|
||||
def log_func(domain, level, msg):
|
||||
print("log: '%s', '%s', '%s'" % (str(domain), str(level), msg))
|
||||
if msg == 'Reconnect succeeded':
|
||||
success[0] = True
|
||||
|
||||
# Call default handler
|
||||
GLib.log_default_handler(domain, level, msg)
|
||||
|
||||
handler_id = GLib.log_set_handler('libfprint-sdcp_device', GLib.LogLevelFlags.LEVEL_DEBUG, log_func)
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
GLib.log_remove_handler('libfprint-sdcp_device', handler_id)
|
||||
assert success[0]
|
||||
|
||||
def test_enroll(self):
|
||||
self.dev.open_sync()
|
||||
|
||||
# Must return a print
|
||||
assert isinstance(self.enroll(), FPrint.Print)
|
||||
|
||||
self.dev.close_sync()
|
||||
|
||||
|
||||
def test_verify(self):
|
||||
self.dev.open_sync()
|
||||
|
||||
# Enroll a new print (will be the last), check that it verifies
|
||||
p = self.enroll()
|
||||
match, dev_print = self.dev.verify_sync(p)
|
||||
assert match
|
||||
|
||||
# The returned "device" print is identical
|
||||
assert p.equal(dev_print)
|
||||
|
||||
# We can do the same with it
|
||||
match, dev_print2 = self.dev.verify_sync(dev_print)
|
||||
assert match
|
||||
|
||||
# Now, enroll a new print, causing the old one to not match anymore
|
||||
# (the device always claims to see the last enrolled print).
|
||||
self.enroll()
|
||||
match, dev_print = self.dev.verify_sync(p)
|
||||
assert match is False
|
||||
|
||||
self.dev.close_sync()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint
|
||||
except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
# avoid writing to stderr
|
||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
||||
Reference in New Issue
Block a user