mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-09-10 13:00:08 +00:00
Compare commits
246
Commits
+86
-43
@@ -4,9 +4,10 @@ include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: master
|
||||
file: '/templates/fedora.yml'
|
||||
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml'
|
||||
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/71e636e012ae0ab04c5e0fe40ca73ada91ae6bde/flatpak/flatpak_ci_initiative.yml'
|
||||
|
||||
default:
|
||||
interruptible: true
|
||||
# Auto-retry jobs in case of infra failures
|
||||
retry:
|
||||
max: 1
|
||||
@@ -21,13 +22,15 @@ variables:
|
||||
FDO_DISTRIBUTION_TAG: $LIBFPRINT_IMAGE_TAG
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
FDO_UPSTREAM_REPO: "libfprint/$CI_PROJECT_NAME"
|
||||
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
||||
FEDORA_IMAGE: "registry.freedesktop.org/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
||||
- if: $CI_PIPELINE_SOURCE == 'push'
|
||||
- if: $CI_PIPELINE_SOURCE == 'schedule'
|
||||
- if: $CI_PROJECT_NAMESPACE == 'libfprint' && $LIBFPRINT_CI_ACTION != ''
|
||||
|
||||
stages:
|
||||
- image-build
|
||||
@@ -35,12 +38,13 @@ stages:
|
||||
- build
|
||||
- test
|
||||
- flatpak
|
||||
- deploy
|
||||
|
||||
image: $FEDORA_IMAGE
|
||||
|
||||
.build_one_driver_template: &build_one_driver
|
||||
script:
|
||||
# Build with a driver that doesn't need imaging, or nss
|
||||
# Build with a driver that doesn't need imaging, or openssl
|
||||
- meson setup _build --werror -Ddrivers=$driver
|
||||
- meson compile -C _build
|
||||
- rm -rf _build/
|
||||
@@ -56,11 +60,16 @@ image: $FEDORA_IMAGE
|
||||
script:
|
||||
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
|
||||
|
||||
.standard_job:
|
||||
rules:
|
||||
- when: on_success
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
|
||||
build:
|
||||
stage: build
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
variables:
|
||||
driver: virtual_image
|
||||
<<: *build_one_driver
|
||||
@@ -75,13 +84,12 @@ build:
|
||||
|
||||
test:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
script:
|
||||
- meson setup _build --werror -Ddrivers=all -Db_coverage=true
|
||||
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
||||
- ninja -C _build coverage
|
||||
- ninja -C _build coverage || true
|
||||
- cat _build/meson-logs/coverage.txt || true
|
||||
artifacts:
|
||||
reports:
|
||||
@@ -99,9 +107,8 @@ test:
|
||||
|
||||
test_valgrind:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
script:
|
||||
- meson setup _build -Ddrivers=all
|
||||
- meson compile -C _build
|
||||
@@ -116,11 +123,27 @@ test_valgrind:
|
||||
- _build/meson-logs/testlog-valgrind.txt
|
||||
expire_in: 1 week
|
||||
|
||||
test_asan:
|
||||
stage: test
|
||||
extends:
|
||||
- .standard_job
|
||||
script:
|
||||
- meson setup _build -Ddrivers=all -Db_sanitize=address,undefined
|
||||
- meson test -C _build --print-errorlogs --no-stdsplit
|
||||
artifacts:
|
||||
reports:
|
||||
junit: "_build/meson-logs/testlog.junit.xml"
|
||||
expose_as: 'Sanitizers test logs'
|
||||
when: always
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
- _build/meson-logs/testlog.txt
|
||||
expire_in: 1 week
|
||||
|
||||
test_installed:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
script:
|
||||
- meson setup _build --prefix=/usr -Ddrivers=all
|
||||
- meson install -C _build
|
||||
@@ -142,9 +165,8 @@ test_installed:
|
||||
|
||||
test_scan_build:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
allow_failure: true
|
||||
script:
|
||||
- meson setup _build -Ddrivers=all
|
||||
@@ -159,19 +181,23 @@ test_scan_build:
|
||||
|
||||
test_indent:
|
||||
stage: check-source
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
script:
|
||||
- scripts/uncrustify.sh
|
||||
- git diff
|
||||
- git diff-index --name-only --exit-code HEAD
|
||||
rules:
|
||||
- changes:
|
||||
compare_to: 'refs/heads/master'
|
||||
paths:
|
||||
- '**/*.c'
|
||||
- '**/*.h'
|
||||
|
||||
test_unsupported_list:
|
||||
stage: check-source
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
extends:
|
||||
- .standard_job
|
||||
allow_failure: true
|
||||
script:
|
||||
- tests/hwdb-check-unsupported.py
|
||||
@@ -191,7 +217,7 @@ flatpak:
|
||||
- if: '$CI_PROJECT_PATH != "libfprint/libfprint"'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
allow_failure: true
|
||||
@@ -212,9 +238,6 @@ flatpak:
|
||||
.container_fedora_build_base:
|
||||
extends: .fdo.container-build@fedora
|
||||
stage: image-build
|
||||
only:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "never"
|
||||
variables:
|
||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||
# a list of packages to install
|
||||
@@ -225,6 +248,8 @@ flatpak:
|
||||
libudev-devel
|
||||
FDO_DISTRIBUTION_EXEC: |
|
||||
$LIBFPRINT_EXEC
|
||||
rules:
|
||||
- when: never
|
||||
|
||||
.container_fedora_build_forced:
|
||||
variables:
|
||||
@@ -234,25 +259,43 @@ container_fedora_build_schedule:
|
||||
extends:
|
||||
- .container_fedora_build_base
|
||||
- .container_fedora_build_forced
|
||||
only:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
||||
when: always
|
||||
|
||||
container_fedora_build_manual:
|
||||
extends:
|
||||
- .container_fedora_build_base
|
||||
- .container_fedora_build_forced
|
||||
only:
|
||||
variables:
|
||||
- $LIBFPRINT_CI_ACTION == "build-image"
|
||||
rules:
|
||||
- if: $LIBFPRINT_CI_ACTION == "build-image"
|
||||
when: always
|
||||
|
||||
container_fedora_build_on_deps_changed:
|
||||
extends: .container_fedora_build_base
|
||||
only:
|
||||
variables:
|
||||
- $CI_PROJECT_NAMESPACE == "libfprint" && $CI_PIPELINE_SOURCE != "schedule"
|
||||
refs:
|
||||
- branches
|
||||
- merge_requests
|
||||
changes:
|
||||
- .gitlab-ci/libfprint-image-variables.yaml
|
||||
rules:
|
||||
- if: $CI_PROJECT_NAMESPACE == "libfprint" && $CI_PIPELINE_SOURCE != "schedule"
|
||||
changes:
|
||||
compare_to: 'refs/heads/master'
|
||||
paths:
|
||||
- '.gitlab-ci/libfprint-image-variables.yaml'
|
||||
- '.gitlab-ci/libfprint-templates.yaml'
|
||||
|
||||
pages:
|
||||
image: alpine:latest
|
||||
stage: deploy
|
||||
needs:
|
||||
- job: test
|
||||
artifacts: true
|
||||
- job: build
|
||||
artifacts: true
|
||||
script:
|
||||
- mkdir public
|
||||
- mv _build/meson-logs/coveragereport public/coverage || true
|
||||
- mv _build/doc/html public/doc
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push"
|
||||
- if: $CI_COMMIT_TAG
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
variables:
|
||||
LIBFPRINT_IMAGE_TAG: v3
|
||||
LIBFPRINT_IMAGE_TAG: v6
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
.libfprint_common_variables:
|
||||
LIBFPRINT_DEPENDENCIES:
|
||||
appstream
|
||||
doxygen
|
||||
dnf-plugins-core
|
||||
flatpak-builder
|
||||
@@ -17,12 +18,14 @@
|
||||
gtk-doc
|
||||
gtk3-devel
|
||||
libabigail
|
||||
libasan
|
||||
libgusb-devel
|
||||
libgudev-devel
|
||||
libubsan
|
||||
libX11-devel
|
||||
libXv-devel
|
||||
meson
|
||||
nss-devel
|
||||
openssl-devel
|
||||
pixman-devel
|
||||
python3-cairo
|
||||
python3-gobject
|
||||
@@ -40,10 +43,7 @@
|
||||
glibc \
|
||||
libgusb \
|
||||
libusb \
|
||||
nss \
|
||||
pixman
|
||||
|
||||
git clone https://github.com/martinpitt/umockdev.git && \
|
||||
cd umockdev && \
|
||||
meson _build --prefix=/usr && \
|
||||
ninja -C _build && ninja -C _build install
|
||||
openssl \
|
||||
pixman \
|
||||
python3-gobject \
|
||||
python3-gobject-base
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -x
|
||||
|
||||
# This wrapper just disables the malloc checker
|
||||
exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc "$@"
|
||||
exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc \
|
||||
--exclude "$PWD/_build/meson-private" \
|
||||
--exclude "$PWD/meson-private" \
|
||||
"$@"
|
||||
|
||||
@@ -1,6 +1,51 @@
|
||||
This file lists notable changes in each release. For the full history of all
|
||||
changes, see ChangeLog.
|
||||
|
||||
2026-02-10: v1.94.10 release
|
||||
|
||||
Highlights:
|
||||
* synaptics: Add USB reset in probe to recover stall condition
|
||||
* synaptics: New PIDs 0x0169, 0x019F, 0x00E9, 0x01A0, 0x0109, 0x010A
|
||||
* goodixmoc: New PID 0x66A9
|
||||
* goodixmoc: Fix crash in exit callback handler
|
||||
* fpcmoc: New PID 0xA306
|
||||
* fpcmoc: Fix interrupt cancellable leak
|
||||
* elanmoc: New PIDs 0x0CA7, 0x0CA8, 0x0CB0
|
||||
* egismoc: New PIDs 0x0584, 0x0588
|
||||
* focaltech_moc: New PIDs 0xA27A, 0x1579
|
||||
* realtek: New PID 0xFA03
|
||||
* fp-device: Clarify getter for open property
|
||||
* libfprint: Use fatal-warnings on g-i-scanner
|
||||
|
||||
2025-02-20: v1.94.9 release
|
||||
|
||||
Highlights:
|
||||
* uru4000: Use OpenSSL to perform AES-ECB encryption, as per this libfprint
|
||||
does not support on NSS, but on openssl (>= 3.0).
|
||||
* goodixmoc: New PIDs 0x60C2, 0x689A
|
||||
* synaptics: New PIDs 0x016C, 0x0174, 0x0107, 0x0108, 0x00C2, 0x00F0
|
||||
* fpcmoc: New PID 0xC844
|
||||
* focaltech_moc: New PIDs 0xA99A, 0xA57A, 0xA78A
|
||||
* elanmoc: New PIDs 0x0C98, 0x0C9D, 0x0CA3
|
||||
* elanspi: New PIDs 0x3128, 0x2766
|
||||
* fp-device: Add FP_DEVICE_RETRY_TOO_FAST retry error
|
||||
* data: AppStream meta info listing supported USB devices.
|
||||
* fixed various memory issues in multiple devices
|
||||
|
||||
2024-09-03: v1.94.8 release
|
||||
|
||||
Highlights:
|
||||
* build: Support building in non-linux unix environments (tested in FreeBSD)
|
||||
* egismoc: New PIDs 0x0583, 0x0586, 0x0587.
|
||||
* elanmoc: New PID 0x0C9F.
|
||||
* fpcmoc: New PIDs 0x9524, 0x9544.
|
||||
* goodixmoc: New PIDs 0x609A, 0x650A, 0x650C, 0x6512.
|
||||
* realtek: New PID 0x5816.
|
||||
* synaptics: New PIDs 0x00C4, 0x019D, 0x00C6.
|
||||
* fpcmoc: fix incorrect immobile handling during enrollment.
|
||||
* fpcmoc: fixed jumping to wrong state at end of custom enroll.
|
||||
* egismoc: various code cleanups.
|
||||
|
||||
2024-02-20: v1.94.7 release
|
||||
|
||||
Highlights:
|
||||
|
||||
@@ -46,6 +46,12 @@ We include **Bozorth3** from the **[US Export Controlled]**
|
||||
distribution, which we have determined to be fine
|
||||
being shipped in an open source project.
|
||||
|
||||
## Get in *touch*
|
||||
|
||||
- [IRC] - `#fprint` @ `irc.oftc.net`
|
||||
- [Matrix] - `#fprint:matrix.org` bridged to the IRC channel
|
||||
- [MailingList] - low traffic, not much used these days
|
||||
|
||||
<br/>
|
||||
|
||||
<div align="right">
|
||||
@@ -62,6 +68,9 @@ being shipped in an open source project.
|
||||
[Unsupported]: https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices
|
||||
[Supported]: https://fprint.freedesktop.org/supported-devices.html
|
||||
[Website]: https://fprint.freedesktop.org/
|
||||
[MailingList]: https://lists.freedesktop.org/mailman/listinfo/fprint
|
||||
[IRC]: ircs://irc.oftc.net:6697/#fprint
|
||||
[Matrix]: https://matrix.to/#/#fprint:matrix.org
|
||||
|
||||
[Contribute]: ./HACKING.md
|
||||
[License]: ./COPYING
|
||||
|
||||
+112
-7
@@ -77,8 +77,19 @@ usb:v1C7Ap0571*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver egis_etu905
|
||||
usb:v1C7Ap05AE*
|
||||
usb:v1C7Ap9201*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver egismoc
|
||||
usb:v1C7Ap0582*
|
||||
usb:v1C7Ap0583*
|
||||
usb:v1C7Ap0584*
|
||||
usb:v1C7Ap0586*
|
||||
usb:v1C7Ap0587*
|
||||
usb:v1C7Ap0588*
|
||||
usb:v1C7Ap05A1*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
@@ -155,7 +166,16 @@ usb:v04F3p0C82*
|
||||
usb:v04F3p0C88*
|
||||
usb:v04F3p0C8C*
|
||||
usb:v04F3p0C8D*
|
||||
usb:v04F3p0C98*
|
||||
usb:v04F3p0C99*
|
||||
usb:v04F3p0C9C*
|
||||
usb:v04F3p0C9D*
|
||||
usb:v04F3p0C9F*
|
||||
usb:v04F3p0CA3*
|
||||
usb:v04F3p0CA7*
|
||||
usb:v04F3p0CA8*
|
||||
usb:v04F3p0CB0*
|
||||
usb:v04F3p0CB2*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
@@ -167,28 +187,46 @@ usb:v1C7Ap0603*
|
||||
# Supported by libfprint driver focaltech_moc
|
||||
usb:v2808p9E48*
|
||||
usb:v2808pD979*
|
||||
usb:v2808pA27A*
|
||||
usb:v2808pA959*
|
||||
usb:v2808pA99A*
|
||||
usb:v2808pA57A*
|
||||
usb:v2808pA78A*
|
||||
usb:v2808pA97A*
|
||||
usb:v2808p1579*
|
||||
usb:v2808p077A*
|
||||
usb:v2808p079A*
|
||||
usb:v2808p5158*
|
||||
usb:v2808p6553*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver fpcmoc
|
||||
usb:v10A5pFFE0*
|
||||
usb:v10A5pA305*
|
||||
usb:v10A5pA306*
|
||||
usb:v10A5pDA04*
|
||||
usb:v10A5pD805*
|
||||
usb:v10A5pD205*
|
||||
usb:v10A5p9524*
|
||||
usb:v10A5p9544*
|
||||
usb:v10A5pC844*
|
||||
usb:v10A5p9B24*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver goodixmoc
|
||||
usb:v27C6p5840*
|
||||
usb:v27C6p6014*
|
||||
usb:v27C6p6090*
|
||||
usb:v27C6p6092*
|
||||
usb:v27C6p6094*
|
||||
usb:v27C6p609A*
|
||||
usb:v27C6p609C*
|
||||
usb:v27C6p60A2*
|
||||
usb:v27C6p60A4*
|
||||
usb:v27C6p60BC*
|
||||
usb:v27C6p60C2*
|
||||
usb:v27C6p6304*
|
||||
usb:v27C6p631C*
|
||||
usb:v27C6p633C*
|
||||
@@ -199,6 +237,8 @@ usb:v27C6p63AC*
|
||||
usb:v27C6p63BC*
|
||||
usb:v27C6p63CC*
|
||||
usb:v27C6p6496*
|
||||
usb:v27C6p650A*
|
||||
usb:v27C6p650C*
|
||||
usb:v27C6p6582*
|
||||
usb:v27C6p6584*
|
||||
usb:v27C6p658C*
|
||||
@@ -207,6 +247,16 @@ usb:v27C6p6594*
|
||||
usb:v27C6p659A*
|
||||
usb:v27C6p659C*
|
||||
usb:v27C6p6A94*
|
||||
usb:v27C6p6512*
|
||||
usb:v27C6p6890*
|
||||
usb:v27C6p689A*
|
||||
usb:v27C6p66A9*
|
||||
usb:v27C6p6984*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver mafpmoc
|
||||
usb:v3274p8012*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
@@ -217,27 +267,49 @@ usb:v298Dp1010*
|
||||
|
||||
# Supported by libfprint driver realtek
|
||||
usb:v0BDAp5813*
|
||||
usb:v0BDAp5816*
|
||||
usb:v2541pFA03*
|
||||
usb:v3274p9003*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver secugen
|
||||
usb:v1162p2200*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
# Supported by libfprint driver synaptics
|
||||
usb:v06CBp00BD*
|
||||
usb:v06CBp00C2*
|
||||
usb:v06CBp00C4*
|
||||
usb:v06CBp00C6*
|
||||
usb:v06CBp00DF*
|
||||
usb:v06CBp00E9*
|
||||
usb:v06CBp00F0*
|
||||
usb:v06CBp00F9*
|
||||
usb:v06CBp00FC*
|
||||
usb:v06CBp00C2*
|
||||
usb:v06CBp0100*
|
||||
usb:v06CBp00F0*
|
||||
usb:v06CBp0103*
|
||||
usb:v06CBp0104*
|
||||
usb:v06CBp0106*
|
||||
usb:v06CBp0107*
|
||||
usb:v06CBp0108*
|
||||
usb:v06CBp0109*
|
||||
usb:v06CBp010A*
|
||||
usb:v06CBp0123*
|
||||
usb:v06CBp0124*
|
||||
usb:v06CBp0126*
|
||||
usb:v06CBp0129*
|
||||
usb:v06CBp0168*
|
||||
usb:v06CBp015F*
|
||||
usb:v06CBp0104*
|
||||
usb:v06CBp0168*
|
||||
usb:v06CBp0169*
|
||||
usb:v06CBp016C*
|
||||
usb:v06CBp0173*
|
||||
usb:v06CBp0106*
|
||||
usb:v06CBp0174*
|
||||
usb:v06CBp019D*
|
||||
usb:v06CBp019F*
|
||||
usb:v06CBp01A0*
|
||||
usb:v06CBp01A4*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
@@ -306,7 +378,10 @@ usb:v138Ap0091*
|
||||
ID_PERSIST=0
|
||||
|
||||
# Known unsupported devices
|
||||
usb:v0A5Cp5802*
|
||||
usb:v047Dp00F2*
|
||||
usb:v047Dp8054*
|
||||
usb:v047Dp8055*
|
||||
usb:v04E8p730B*
|
||||
usb:v04F3p036B*
|
||||
usb:v04F3p0C00*
|
||||
@@ -314,27 +389,37 @@ usb:v04F3p0C4C*
|
||||
usb:v04F3p0C57*
|
||||
usb:v04F3p0C5E*
|
||||
usb:v04F3p0C5A*
|
||||
usb:v04F3p0C60*
|
||||
usb:v04F3p0C6C*
|
||||
usb:v04F3p0C70*
|
||||
usb:v04F3p0C72*
|
||||
usb:v04F3p0C77*
|
||||
usb:v04F3p0C7C*
|
||||
usb:v04F3p0C7F*
|
||||
usb:v04F3p0C80*
|
||||
usb:v04F3p0C85*
|
||||
usb:v04F3p0C90*
|
||||
usb:v04F3p2706*
|
||||
usb:v04F3p3032*
|
||||
usb:v04F3p3057*
|
||||
usb:v04F3p3104*
|
||||
usb:v04F3p310D*
|
||||
usb:v04F3p3128*
|
||||
usb:v04F3p0C8A*
|
||||
usb:v05BAp000E*
|
||||
usb:v06CBp0051*
|
||||
usb:v06CBp0081*
|
||||
usb:v06CBp0088*
|
||||
usb:v06CBp008A*
|
||||
usb:v06CBp009A*
|
||||
usb:v06CBp009B*
|
||||
usb:v06CBp00A1*
|
||||
usb:v06CBp00A2*
|
||||
usb:v06CBp00A8*
|
||||
usb:v06CBp00B7*
|
||||
usb:v06CBp00BB*
|
||||
usb:v06CBp00BC*
|
||||
usb:v06CBp00BE*
|
||||
usb:v06CBp00C4*
|
||||
usb:v06CBp00CB*
|
||||
usb:v06CBp00C9*
|
||||
usb:v06CBp00D8*
|
||||
@@ -342,8 +427,8 @@ usb:v06CBp00DA*
|
||||
usb:v06CBp00DC*
|
||||
usb:v06CBp00E4*
|
||||
usb:v06CBp00E7*
|
||||
usb:v06CBp00E9*
|
||||
usb:v06CBp00FD*
|
||||
usb:v06CBp00FF*
|
||||
usb:v0A5Cp5801*
|
||||
usb:v0A5Cp5805*
|
||||
usb:v0A5Cp5834*
|
||||
@@ -353,10 +438,20 @@ usb:v0A5Cp5842*
|
||||
usb:v0A5Cp5843*
|
||||
usb:v0A5Cp5844*
|
||||
usb:v0A5Cp5845*
|
||||
usb:v0A5Cp5860*
|
||||
usb:v0A5Cp5863*
|
||||
usb:v0A5Cp5864*
|
||||
usb:v0A5Cp5865*
|
||||
usb:v0A5Cp5866*
|
||||
usb:v0A5Cp5867*
|
||||
usb:v0BDAp5812*
|
||||
usb:v10A5p0007*
|
||||
usb:v10A5p9200*
|
||||
usb:v10A5p9201*
|
||||
usb:v10A5p9800*
|
||||
usb:v10A5pA120*
|
||||
usb:v10A5pA900*
|
||||
usb:v10A5pA921*
|
||||
usb:v10A5pE340*
|
||||
usb:v1188p9545*
|
||||
usb:v138Ap0007*
|
||||
@@ -378,6 +473,9 @@ usb:v1C7Ap0300*
|
||||
usb:v1C7Ap0575*
|
||||
usb:v1C7Ap0576*
|
||||
usb:v1C7Ap0577*
|
||||
usb:v1C7Ap057E*
|
||||
usb:v2541p0236*
|
||||
usb:v2541p9711*
|
||||
usb:v27C6p5042*
|
||||
usb:v27C6p5110*
|
||||
usb:v27C6p5117*
|
||||
@@ -406,11 +504,18 @@ usb:v27C6p5740*
|
||||
usb:v27C6p5E0A*
|
||||
usb:v27C6p581A*
|
||||
usb:v27C6p589A*
|
||||
usb:v27C6p5F10*
|
||||
usb:v27C6p5F91*
|
||||
usb:v27C6p6382*
|
||||
usb:v2808p9338*
|
||||
usb:v2808p9348*
|
||||
usb:v2808p93A9*
|
||||
usb:v2808pA658*
|
||||
usb:v2808pC652*
|
||||
usb:v2808pA553*
|
||||
usb:v298Dp2020*
|
||||
usb:v298Dp2033*
|
||||
usb:v2DF0p0003*
|
||||
usb:v3538p0930*
|
||||
ID_AUTOSUSPEND=1
|
||||
ID_PERSIST=0
|
||||
|
||||
@@ -101,11 +101,14 @@ plot_minutiae (unsigned char *rgbdata,
|
||||
{
|
||||
int i;
|
||||
|
||||
#define write_pixel(num) do { \
|
||||
rgbdata[((num) * 3)] = 0xff; \
|
||||
rgbdata[((num) * 3) + 1] = 0; \
|
||||
rgbdata[((num) * 3) + 2] = 0; \
|
||||
} while(0)
|
||||
#define write_pixel(num) \
|
||||
do \
|
||||
{ \
|
||||
rgbdata[((num) * 3)] = 0xff; \
|
||||
rgbdata[((num) * 3) + 1] = 0; \
|
||||
rgbdata[((num) * 3) + 2] = 0; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
for (i = 0; i < minutiae->len; i++)
|
||||
{
|
||||
|
||||
@@ -75,6 +75,7 @@ fp_device_clear_storage_sync
|
||||
fp_device_suspend_sync
|
||||
fp_device_resume_sync
|
||||
FpDevice
|
||||
FpTemperature
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
@@ -134,6 +135,134 @@ fpi_line_asmbl_ctx
|
||||
fpi_assemble_lines
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-byte-reader</FILE>
|
||||
<TITLE>FpiByteReader</TITLE>
|
||||
FpiByteReader
|
||||
fpi_byte_reader_new
|
||||
fpi_byte_reader_new_bytes
|
||||
fpi_byte_reader_free
|
||||
fpi_byte_reader_init
|
||||
fpi_byte_reader_init_bytes
|
||||
fpi_byte_reader_peek_sub_reader
|
||||
fpi_byte_reader_get_sub_reader
|
||||
fpi_byte_reader_set_pos
|
||||
fpi_byte_reader_get_pos
|
||||
fpi_byte_reader_get_remaining
|
||||
fpi_byte_reader_get_size
|
||||
fpi_byte_reader_skip
|
||||
fpi_byte_reader_get_bytes
|
||||
fpi_byte_reader_peek_bytes
|
||||
fpi_byte_reader_get_uint8
|
||||
fpi_byte_reader_get_int8
|
||||
fpi_byte_reader_peek_uint8
|
||||
fpi_byte_reader_peek_int8
|
||||
fpi_byte_reader_get_uint16_le
|
||||
fpi_byte_reader_get_int16_le
|
||||
fpi_byte_reader_peek_uint16_le
|
||||
fpi_byte_reader_peek_int16_le
|
||||
fpi_byte_reader_get_uint16_be
|
||||
fpi_byte_reader_get_int16_be
|
||||
fpi_byte_reader_peek_uint16_be
|
||||
fpi_byte_reader_peek_int16_be
|
||||
fpi_byte_reader_get_uint24_le
|
||||
fpi_byte_reader_get_int24_le
|
||||
fpi_byte_reader_peek_uint24_le
|
||||
fpi_byte_reader_peek_int24_le
|
||||
fpi_byte_reader_get_uint24_be
|
||||
fpi_byte_reader_get_int24_be
|
||||
fpi_byte_reader_peek_uint24_be
|
||||
fpi_byte_reader_peek_int24_be
|
||||
fpi_byte_reader_get_uint32_le
|
||||
fpi_byte_reader_get_int32_le
|
||||
fpi_byte_reader_peek_uint32_le
|
||||
fpi_byte_reader_peek_int32_le
|
||||
fpi_byte_reader_get_uint32_be
|
||||
fpi_byte_reader_get_int32_be
|
||||
fpi_byte_reader_peek_uint32_be
|
||||
fpi_byte_reader_peek_int32_be
|
||||
fpi_byte_reader_get_uint64_le
|
||||
fpi_byte_reader_get_int64_le
|
||||
fpi_byte_reader_peek_uint64_le
|
||||
fpi_byte_reader_peek_int64_le
|
||||
fpi_byte_reader_get_uint64_be
|
||||
fpi_byte_reader_get_int64_be
|
||||
fpi_byte_reader_peek_uint64_be
|
||||
fpi_byte_reader_peek_int64_be
|
||||
fpi_byte_reader_get_float32_le
|
||||
fpi_byte_reader_peek_float32_le
|
||||
fpi_byte_reader_get_float32_be
|
||||
fpi_byte_reader_peek_float32_be
|
||||
fpi_byte_reader_get_float64_le
|
||||
fpi_byte_reader_peek_float64_le
|
||||
fpi_byte_reader_get_float64_be
|
||||
fpi_byte_reader_peek_float64_be
|
||||
fpi_byte_reader_get_data
|
||||
fpi_byte_reader_peek_data
|
||||
fpi_byte_reader_get_data_static
|
||||
fpi_byte_reader_peek_data_static
|
||||
fpi_byte_reader_dup_data
|
||||
fpi_byte_reader_masked_scan_uint32
|
||||
fpi_byte_reader_masked_scan_uint32_peek
|
||||
fpi_byte_reader_skip_string
|
||||
fpi_byte_reader_skip_string_utf8
|
||||
fpi_byte_reader_skip_string_utf16
|
||||
fpi_byte_reader_skip_string_utf32
|
||||
fpi_byte_reader_peek_string
|
||||
fpi_byte_reader_peek_string_utf8
|
||||
fpi_byte_reader_get_string_utf8
|
||||
fpi_byte_reader_dup_string_utf8
|
||||
fpi_byte_reader_dup_string_utf16
|
||||
fpi_byte_reader_dup_string_utf32
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-byte-writer</FILE>
|
||||
<TITLE>FpiByteWriter</TITLE>
|
||||
FpiByteWriter
|
||||
fpi_byte_writer_new
|
||||
fpi_byte_writer_new_with_size
|
||||
fpi_byte_writer_new_with_data
|
||||
fpi_byte_writer_init
|
||||
fpi_byte_writer_init_with_size
|
||||
fpi_byte_writer_init_with_data
|
||||
fpi_byte_writer_reset
|
||||
fpi_byte_writer_reset_and_get_bytes
|
||||
fpi_byte_writer_reset_and_get_data
|
||||
fpi_byte_writer_free
|
||||
fpi_byte_writer_free_and_get_data
|
||||
fpi_byte_writer_get_remaining
|
||||
fpi_byte_writer_ensure_free_space
|
||||
fpi_byte_writer_put_bytes
|
||||
fpi_byte_writer_put_uint8
|
||||
fpi_byte_writer_put_uint16_be
|
||||
fpi_byte_writer_put_uint24_be
|
||||
fpi_byte_writer_put_uint32_be
|
||||
fpi_byte_writer_put_uint64_be
|
||||
fpi_byte_writer_put_uint16_le
|
||||
fpi_byte_writer_put_uint24_le
|
||||
fpi_byte_writer_put_uint32_le
|
||||
fpi_byte_writer_put_uint64_le
|
||||
fpi_byte_writer_put_int8
|
||||
fpi_byte_writer_put_int16_be
|
||||
fpi_byte_writer_put_int24_be
|
||||
fpi_byte_writer_put_int32_be
|
||||
fpi_byte_writer_put_int64_be
|
||||
fpi_byte_writer_put_int16_le
|
||||
fpi_byte_writer_put_int24_le
|
||||
fpi_byte_writer_put_int32_le
|
||||
fpi_byte_writer_put_int64_le
|
||||
fpi_byte_writer_put_float32_be
|
||||
fpi_byte_writer_put_float64_be
|
||||
fpi_byte_writer_put_float32_le
|
||||
fpi_byte_writer_put_float64_le
|
||||
fpi_byte_writer_put_string_utf8
|
||||
fpi_byte_writer_put_string_utf16
|
||||
fpi_byte_writer_put_string_utf32
|
||||
fpi_byte_writer_put_data
|
||||
fpi_byte_writer_fill
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-context</FILE>
|
||||
fpi_get_driver_types
|
||||
@@ -153,6 +282,7 @@ fpi_device_get_current_action
|
||||
fpi_device_retry_new
|
||||
fpi_device_error_new
|
||||
fpi_device_retry_new_msg
|
||||
fpi_device_emulation_mode_enabled
|
||||
fpi_device_error_new_msg
|
||||
fpi_device_get_driver_data
|
||||
fpi_device_get_enroll_data
|
||||
@@ -218,9 +348,12 @@ fpi_image_device_set_bz3_threshold
|
||||
<SECTION>
|
||||
<FILE>fpi-log</FILE>
|
||||
fp_dbg
|
||||
fp_dbg_hex_dump_bytes
|
||||
fp_dbg_hex_dump_data
|
||||
fp_info
|
||||
fp_warn
|
||||
fp_err
|
||||
fpi_log_is_debug_transfer_enabled
|
||||
BUG_ON
|
||||
BUG
|
||||
</SECTION>
|
||||
|
||||
@@ -48,6 +48,12 @@
|
||||
<xi:include href="xml/fpi-log.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="driver-data">
|
||||
<title>Binary buffer I/O</title>
|
||||
<xi:include href="xml/fpi-byte-reader.xml"/>
|
||||
<xi:include href="xml/fpi-byte-writer.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="driver-img">
|
||||
<title>Image manipulation</title>
|
||||
<xi:include href="xml/fpi-image.xml"/>
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Example storage clearing program, which deletes all the
|
||||
* fingers which have been previously enrolled to disk.
|
||||
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
* Copyright (C) 2024 Abhinav Baid <abhinavbaid@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "example-clear-storage"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <libfprint/fprint.h>
|
||||
#include <glib-unix.h>
|
||||
|
||||
#include "storage.h"
|
||||
#include "utilities.h"
|
||||
|
||||
typedef struct _ClearStorageData
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GCancellable *cancellable;
|
||||
unsigned int sigint_handler;
|
||||
int ret_value;
|
||||
} ClearStorageData;
|
||||
|
||||
static void
|
||||
clear_storage_data_free (ClearStorageData *clear_storage_data)
|
||||
{
|
||||
g_clear_handle_id (&clear_storage_data->sigint_handler, g_source_remove);
|
||||
g_clear_object (&clear_storage_data->cancellable);
|
||||
g_main_loop_unref (clear_storage_data->loop);
|
||||
g_free (clear_storage_data);
|
||||
}
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClearStorageData, clear_storage_data_free)
|
||||
|
||||
static void
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
ClearStorageData *clear_storage_data = user_data;
|
||||
|
||||
fp_device_close_finish (dev, res, &error);
|
||||
|
||||
if (error)
|
||||
g_warning ("Failed closing device %s", error->message);
|
||||
|
||||
g_main_loop_quit (clear_storage_data->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_storage_quit (FpDevice *dev,
|
||||
ClearStorageData *clear_storage_data)
|
||||
{
|
||||
if (!fp_device_is_open (dev))
|
||||
{
|
||||
g_main_loop_quit (clear_storage_data->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||
clear_storage_data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_clear_storage_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
ClearStorageData *clear_storage_data = user_data;
|
||||
|
||||
if (fp_device_clear_storage_finish (dev, res, &error))
|
||||
{
|
||||
if (!clear_saved_prints (dev, &error))
|
||||
{
|
||||
g_warning ("Clear saved prints from local storage failed: %s",
|
||||
error->message);
|
||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("Clear storage successful!\n");
|
||||
clear_storage_data->ret_value = EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
clear_storage_quit (dev, clear_storage_data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_warning ("Failed to clear storage: %s", error->message);
|
||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
||||
|
||||
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
|
||||
{
|
||||
g_autoptr(GError) clear_error = NULL;
|
||||
|
||||
if (clear_saved_prints (dev, &clear_error))
|
||||
clear_storage_data->ret_value = EXIT_SUCCESS;
|
||||
else
|
||||
g_warning ("Clear saved prints from local storage failed: %s",
|
||||
clear_error->message);
|
||||
}
|
||||
|
||||
clear_storage_quit (dev, clear_storage_data);
|
||||
}
|
||||
|
||||
static void
|
||||
start_clear_storage (FpDevice *dev, ClearStorageData *clear_storage_data)
|
||||
{
|
||||
char buffer[20];
|
||||
|
||||
g_print ("Clear device storage? [y/N]? ");
|
||||
if (fgets (buffer, sizeof (buffer), stdin) &&
|
||||
(buffer[0] == 'Y' || buffer[0] == 'y'))
|
||||
{
|
||||
fp_device_clear_storage (dev, clear_storage_data->cancellable,
|
||||
(GAsyncReadyCallback) on_clear_storage_completed,
|
||||
clear_storage_data);
|
||||
return;
|
||||
}
|
||||
|
||||
clear_storage_quit (dev, clear_storage_data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
ClearStorageData *clear_storage_data = user_data;
|
||||
|
||||
if (!fp_device_open_finish (dev, res, &error))
|
||||
{
|
||||
g_warning ("Failed to open device: %s", error->message);
|
||||
clear_storage_quit (dev, clear_storage_data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_print ("Opened device. ");
|
||||
|
||||
start_clear_storage (dev, clear_storage_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sigint_cb (void *user_data)
|
||||
{
|
||||
ClearStorageData *clear_storage_data = user_data;
|
||||
|
||||
g_cancellable_cancel (clear_storage_data->cancellable);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
g_autoptr(FpContext) ctx = NULL;
|
||||
g_autoptr(ClearStorageData) clear_storage_data = NULL;
|
||||
GPtrArray *devices;
|
||||
FpDevice *dev;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
ctx = fp_context_new ();
|
||||
|
||||
devices = fp_context_get_devices (ctx);
|
||||
if (!devices)
|
||||
{
|
||||
g_warning ("Impossible to get devices");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dev = discover_device (devices);
|
||||
if (!dev)
|
||||
{
|
||||
g_warning ("No devices detected.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
clear_storage_data = g_new0 (ClearStorageData, 1);
|
||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
||||
clear_storage_data->loop = g_main_loop_new (NULL, FALSE);
|
||||
clear_storage_data->cancellable = g_cancellable_new ();
|
||||
clear_storage_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
|
||||
SIGINT,
|
||||
sigint_cb,
|
||||
clear_storage_data,
|
||||
NULL);
|
||||
fp_device_open (dev, clear_storage_data->cancellable,
|
||||
(GAsyncReadyCallback) on_device_opened,
|
||||
clear_storage_data);
|
||||
|
||||
g_main_loop_run (clear_storage_data->loop);
|
||||
|
||||
return clear_storage_data->ret_value;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ examples = [
|
||||
'img-capture',
|
||||
'manage-prints',
|
||||
'verify',
|
||||
'clear-storage',
|
||||
]
|
||||
|
||||
foreach example: examples
|
||||
|
||||
+63
-5
@@ -26,6 +26,7 @@
|
||||
#include "storage.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -55,6 +56,18 @@ get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
|
||||
finger);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_print_prefix_for_device (FpDevice *dev)
|
||||
{
|
||||
const char *driver;
|
||||
const char *dev_id;
|
||||
|
||||
driver = fp_device_get_driver (dev);
|
||||
dev_id = fp_device_get_device_id (dev);
|
||||
|
||||
return g_strdup_printf ("%s/%s/", driver, dev_id);
|
||||
}
|
||||
|
||||
static GVariantDict *
|
||||
load_data (void)
|
||||
{
|
||||
@@ -169,8 +182,6 @@ gallery_data_load (FpDevice *dev)
|
||||
g_autoptr(GVariant) dict_variant = NULL;
|
||||
g_autofree char *dev_prefix = NULL;
|
||||
GPtrArray *gallery;
|
||||
const char *driver;
|
||||
const char *dev_id;
|
||||
GVariantIter iter;
|
||||
GVariant *value;
|
||||
gchar *key;
|
||||
@@ -178,9 +189,7 @@ gallery_data_load (FpDevice *dev)
|
||||
gallery = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
dict = load_data ();
|
||||
dict_variant = g_variant_dict_end (dict);
|
||||
driver = fp_device_get_driver (dev);
|
||||
dev_id = fp_device_get_device_id (dev);
|
||||
dev_prefix = g_strdup_printf ("%s/%s/", driver, dev_id);
|
||||
dev_prefix = get_print_prefix_for_device (dev);
|
||||
|
||||
g_variant_iter_init (&iter, dict_variant);
|
||||
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
||||
@@ -208,6 +217,55 @@ gallery_data_load (FpDevice *dev)
|
||||
return gallery;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clear_saved_prints (FpDevice *dev,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GVariantDict) dict = NULL;
|
||||
g_autoptr(GVariantDict) updated_dict = NULL;
|
||||
g_autoptr(GVariant) dict_variant = NULL;
|
||||
g_autofree char *dev_prefix = NULL;
|
||||
GPtrArray *print_keys;
|
||||
GVariantIter iter;
|
||||
GVariant *value;
|
||||
gchar *key;
|
||||
|
||||
print_keys = g_ptr_array_new_with_free_func (g_free);
|
||||
dict = load_data ();
|
||||
dict_variant = g_variant_dict_end (dict);
|
||||
dev_prefix = get_print_prefix_for_device (dev);
|
||||
|
||||
g_variant_iter_init (&iter, dict_variant);
|
||||
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
||||
{
|
||||
if (!g_str_has_prefix (key, dev_prefix))
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (print_keys, g_strdup (key));
|
||||
}
|
||||
|
||||
if (!print_keys->len)
|
||||
return TRUE;
|
||||
|
||||
updated_dict = load_data ();
|
||||
|
||||
for (guint i = 0; i < print_keys->len; ++i)
|
||||
{
|
||||
key = g_ptr_array_index (print_keys, i);
|
||||
if (!g_variant_dict_remove (updated_dict, key))
|
||||
{
|
||||
g_warning ("Print '%s' key not found!", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_debug ("Dropping print '%s' from gallery", key);
|
||||
}
|
||||
|
||||
save_data (g_variant_dict_end (updated_dict));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FpPrint *
|
||||
print_create_template (FpDevice *dev, FpFinger finger, gboolean load_existing)
|
||||
{
|
||||
|
||||
@@ -20,12 +20,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
int print_data_save (FpPrint *print,
|
||||
FpFinger finger,
|
||||
gboolean update_fingerprint);
|
||||
FpPrint * print_data_load (FpDevice *dev,
|
||||
FpFinger finger);
|
||||
GPtrArray * gallery_data_load (FpDevice *dev);
|
||||
gboolean clear_saved_prints (FpDevice *dev,
|
||||
GError **error);
|
||||
FpPrint * print_create_template (FpDevice *dev,
|
||||
FpFinger finger,
|
||||
const gboolean load_existing);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Driver for Egis Technology (LighTuning) Match-On-Chip sensors
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fpi-device.h"
|
||||
#include "fpi-ssm.h"
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FPI, DEVICE_EGIS_ETU905, FpDevice)
|
||||
|
||||
#define EGIS_ETU905_DRIVER_FULLNAME "Egis Technology (LighTuning) Match-on-Chip"
|
||||
|
||||
#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 (1 << 0)
|
||||
#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1)
|
||||
#define EGIS_ETU905_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2)
|
||||
|
||||
#define EGIS_ETU905_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT)
|
||||
#define EGIS_ETU905_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN)
|
||||
#define EGIS_ETU905_EP_CMD_INTERRUPT_IN 0x83
|
||||
|
||||
#define EGIS_ETU905_USB_CONTROL_TIMEOUT 5000
|
||||
#define EGIS_ETU905_USB_SEND_TIMEOUT 5000
|
||||
#define EGIS_ETU905_USB_RECV_TIMEOUT 5000
|
||||
#define EGIS_ETU905_USB_INTERRUPT_TIMEOUT 0 /* No timeout for waiting for finger down */
|
||||
|
||||
#define EGIS_ETU905_USB_IN_RECV_LENGTH 4096
|
||||
#define EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH 64
|
||||
|
||||
#define EGIS_ETU905_MAX_ENROLL_STAGES_DEFAULT 12
|
||||
#define EGIS_ETU905_MAX_ENROLL_NUM 12
|
||||
#define EGIS_ETU905_FINGERPRINT_DATA_SIZE 32
|
||||
#define EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE 14
|
||||
#define EGIS_ETU905_LIST_RESPONSE_SUFFIX_SIZE 2
|
||||
|
||||
#define EGIS_ETU905_PARA_4_SIZE 68
|
||||
|
||||
#define EGIS_ETU905_PARA_1_VALUE 0
|
||||
#define EGIS_ETU905_PARA_2_VALUE 0
|
||||
#define EGIS_ETU905_PARA_3_VALUE 32
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
guchar reserve_para_1;
|
||||
gushort reserve_para_2;
|
||||
gushort reserve_para_3;
|
||||
guchar reserve_para_4[EGIS_ETU905_PARA_4_SIZE];
|
||||
} EgismocSidData;
|
||||
#pragma pack(pop)
|
||||
|
||||
/* standard prefixes for all read/writes */
|
||||
|
||||
static const guchar egis_etu905_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01};
|
||||
static const gsize egis_etu905_write_prefix_len = sizeof (egis_etu905_write_prefix) / sizeof (egis_etu905_write_prefix[0]);
|
||||
|
||||
static const guchar egis_etu905_read_prefix[] = {'S', 'I', 'G', 'E', 0x00, 0x00, 0x00, 0x01};
|
||||
static const gsize egis_etu905_read_prefix_len = sizeof (egis_etu905_read_prefix) / sizeof (egis_etu905_read_prefix[0]);
|
||||
|
||||
|
||||
/* hard-coded command payloads */
|
||||
|
||||
static const guchar cmd_fw_version[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x0c};
|
||||
static const gsize cmd_fw_version_len = sizeof (cmd_fw_version) / sizeof (cmd_fw_version[0]);
|
||||
static const guchar rsp_fw_version_suffix[] = {0x90, 0x00};
|
||||
static const gsize rsp_fw_version_suffix_len = sizeof (rsp_fw_version_suffix) / sizeof (rsp_fw_version_suffix[0]);
|
||||
|
||||
static const guchar cmd_init[] = {0x00, 0x00, 0x00, 0x29, 0x50, 0x81, 0x80, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12, 0x00, 0x45, 0x67, 0x69, 0x73,
|
||||
0x46, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x51, 0xc6, 0xbd, 0x71};
|
||||
static const gsize cmd_init_len = sizeof (cmd_init) / sizeof (cmd_init[0]);
|
||||
|
||||
static const guchar cmd_list[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x19, 0x04, 0x00, 0x00, 0x01, 0x40};
|
||||
static const gsize cmd_list_len = sizeof (cmd_list) / sizeof (cmd_list[0]);
|
||||
|
||||
static const guchar cmd_sensor_reset[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x1a, 0x00, 0x00};
|
||||
static const gsize cmd_sensor_reset_len = sizeof (cmd_sensor_reset) / sizeof (cmd_sensor_reset[0]);
|
||||
|
||||
static const guchar cmd_sensor_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x02, 0x00};
|
||||
static const gsize cmd_sensor_check_len = sizeof (cmd_sensor_check) / sizeof (cmd_sensor_check[0]);
|
||||
|
||||
static const guchar cmd_sensor_identify[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x01, 0x01};
|
||||
static const gsize cmd_sensor_identify_len = sizeof (cmd_sensor_identify) / sizeof (cmd_sensor_identify[0]);
|
||||
|
||||
static const guchar rsp_identify_match_suffix[] = {0x90, 0x00};
|
||||
static const gsize rsp_identify_match_suffix_len = sizeof (rsp_identify_match_suffix) / sizeof (rsp_identify_match_suffix[0]);
|
||||
|
||||
static const guchar rsp_identify_notmatch_suffix[] = {0x90, 0x04};
|
||||
static const gsize rsp_identify_notmatch_suffix_len = sizeof (rsp_identify_notmatch_suffix) / sizeof (rsp_identify_notmatch_suffix[0]);
|
||||
|
||||
static const guchar cmd_enroll_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x01, 0x00, 0x00, 0x00, 0x20};
|
||||
static const gsize cmd_enroll_starting_len = sizeof (cmd_enroll_starting) / sizeof (cmd_enroll_starting[0]);
|
||||
|
||||
static const guchar cmd_sensor_start_capture[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x02, 0x01};
|
||||
static const gsize cmd_sensor_start_capture_len = sizeof (cmd_sensor_start_capture) / sizeof (cmd_sensor_start_capture[0]);
|
||||
|
||||
static const guchar cmd_read_capture[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x02, 0x02, 0x00, 0x00, 0x02};
|
||||
static const gsize cmd_read_capture_len = sizeof (cmd_read_capture) / sizeof (cmd_read_capture[0]);
|
||||
|
||||
static const guchar cmd_duplicate_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x05, 0x00};
|
||||
static const gsize cmd_duplicate_check_len = sizeof (cmd_duplicate_check) / sizeof (cmd_duplicate_check[0]);
|
||||
|
||||
static const guchar rsp_read_success_prefix[] = {0x00, 0x00, 0x00, 0x04};
|
||||
static const gsize rsp_read_success_prefix_len = sizeof (rsp_read_success_prefix) / sizeof (rsp_read_success_prefix[0]);
|
||||
static const guchar rsp_read_success_suffix[] = {0x90, 0x00};
|
||||
static const gsize rsp_read_success_suffix_len = sizeof (rsp_read_success_suffix) / sizeof (rsp_read_success_suffix[0]);
|
||||
static const guchar rsp_read_offcenter_prefix[] = {0x00, 0x00, 0x00, 0x04};
|
||||
static const gsize rsp_read_offcenter_prefix_len = sizeof (rsp_read_offcenter_prefix) / sizeof (rsp_read_offcenter_prefix[0]);
|
||||
static const guchar rsp_read_offcenter_suffix[] = {0x64, 0x91};
|
||||
static const gsize rsp_read_offcenter_suffix_len = sizeof (rsp_read_offcenter_suffix) / sizeof (rsp_read_offcenter_suffix[0]);
|
||||
static const guchar rsp_read_dirty_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x64};
|
||||
static const gsize rsp_read_dirty_prefix_len = sizeof (rsp_read_dirty_prefix) / sizeof (rsp_read_dirty_prefix[0]);
|
||||
|
||||
static const guchar cmd_commit_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x05, 0x00, 0x00, 0x00, 0x20};
|
||||
static const gsize cmd_commit_starting_len = sizeof (cmd_commit_starting) / sizeof (cmd_commit_starting[0]);
|
||||
|
||||
static const guchar cmd_enroll_discard[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x04, 0x00, 0x00, 0x00, 0x20};
|
||||
static const gsize cmd_enroll_discard_len = sizeof (cmd_enroll_discard) / sizeof (cmd_enroll_discard[0]);
|
||||
|
||||
static const guchar cmd_identify_cancel[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x01, 0x00};
|
||||
static const gsize cmd_identify_cancel_len = sizeof (cmd_identify_cancel) / sizeof (cmd_identify_cancel[0]);
|
||||
|
||||
static const guchar cmd_identify_cancel_result[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x02, 0x00};
|
||||
static const gsize cmd_identify_cancel_result_len = sizeof (cmd_identify_cancel_result) / sizeof (cmd_identify_cancel_result[0]);
|
||||
|
||||
/* prefixes/suffixes and other things for dynamically created command payloads */
|
||||
|
||||
#define EGIS_ETU905_CHECK_BYTES_LENGTH 2
|
||||
#define EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET 46
|
||||
#define EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH 32
|
||||
|
||||
static const guchar cmd_new_print_prefix_type2[] = {0x00, 0x00, 0x00, 0x50, 0x50, 0x16, 0x03, 0x00, 0x00, 0x00, 0x49};
|
||||
static const gsize cmd_new_print_prefix_type2_len = sizeof (cmd_new_print_prefix_type2) / sizeof (cmd_new_print_prefix_type2[0]);
|
||||
|
||||
static const guchar cmd_delete_prefix[] = {0x50, 0x18, 0x04, 0x00, 0x00};
|
||||
static const gsize cmd_delete_prefix_len = sizeof (cmd_delete_prefix) / sizeof (cmd_delete_prefix[0]);
|
||||
static const guchar rsp_delete_success_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x90, 0x00};
|
||||
static const gsize rsp_delete_success_prefix_len = sizeof (rsp_delete_success_prefix) / sizeof (rsp_delete_success_prefix[0]);
|
||||
|
||||
static const guchar cmd_check_prefix_type1[] = {0x50, 0x17, 0x03, 0x00, 0x00};
|
||||
static const gsize cmd_check_prefix_type1_len = sizeof (cmd_check_prefix_type1) / sizeof (cmd_check_prefix_type1[0]);
|
||||
static const guchar cmd_check_prefix_type2[] = {0x50, 0x17, 0x03, 0x80, 0x00};
|
||||
static const gsize cmd_check_prefix_type2_len = sizeof (cmd_check_prefix_type2) / sizeof (cmd_check_prefix_type2[0]);
|
||||
static const guchar cmd_check_suffix[] = {0x00, 0x40};
|
||||
static const gsize cmd_check_suffix_len = sizeof (cmd_check_suffix) / sizeof (cmd_check_suffix[0]);
|
||||
static const guchar rsp_check_not_yet_enrolled_suffix[] = {0x90, 0x04};
|
||||
static const gsize rsp_check_not_yet_enrolled_suffix_len = sizeof (rsp_check_not_yet_enrolled_suffix) / sizeof (rsp_check_not_yet_enrolled_suffix[0]);
|
||||
|
||||
|
||||
/* SSM task states and various status enums */
|
||||
|
||||
typedef enum {
|
||||
CMD_SEND,
|
||||
CMD_GET,
|
||||
CMD_STATES,
|
||||
} CommandStates;
|
||||
|
||||
typedef enum {
|
||||
DEV_GET_FW_VERSION,
|
||||
DEV_INIT_CONTROL,
|
||||
DEV_INIT_STATES,
|
||||
} DeviceInitStates;
|
||||
|
||||
typedef enum {
|
||||
IDENTIFY_GET_ENROLLED_IDS,
|
||||
IDENTIFY_CHECK_ENROLLED_NUM,
|
||||
IDENTIFY_SENSOR_RESET,
|
||||
IDENTIFY_SENSOR_IDENTIFY,
|
||||
IDENTIFY_WAIT_FINGER,
|
||||
IDENTIFY_SENSOR_CHECK,
|
||||
IDENTIFY_CHECK,
|
||||
IDENTIFY_SEND_CANCEL_RESULT,
|
||||
IDENTIFY_COMPLETE_SENSOR_RESET,
|
||||
IDENTIFY_COMPLETE,
|
||||
|
||||
/* Cleanup states follow */
|
||||
IDENTIFY_CANCEL,
|
||||
IDENTIFY_STATES,
|
||||
} IdentifyStates;
|
||||
|
||||
typedef enum {
|
||||
ENROLL_START,
|
||||
ENROLL_CAPTURE_SENSOR_RESET,
|
||||
ENROLL_CAPTURE_SENSOR_START_CAPTURE,
|
||||
ENROLL_CAPTURE_WAIT_FINGER,
|
||||
ENROLL_CAPTURE_READ_RESPONSE,
|
||||
ENROLL_DUPLICATE_CHECK,
|
||||
ENROLL_COMMIT_START,
|
||||
ENROLL_COMMIT,
|
||||
ENROLL_COMMIT_SENSOR_RESET,
|
||||
ENROLL_COMPLETE,
|
||||
|
||||
/* Cleanup states follow */
|
||||
ENROLL_CANCEL,
|
||||
ENROLL_STATES,
|
||||
} EnrollStates;
|
||||
|
||||
typedef enum {
|
||||
ENROLL_STATUS_DEVICE_FULL,
|
||||
ENROLL_STATUS_DUPLICATE,
|
||||
ENROLL_STATUS_PARTIAL_OK,
|
||||
ENROLL_STATUS_RETRY,
|
||||
ENROLL_STATUS_COMPLETE,
|
||||
} EnrollStatus;
|
||||
|
||||
typedef enum {
|
||||
LIST_GET_ENROLLED_IDS,
|
||||
LIST_RETURN_ENROLLED_PRINTS,
|
||||
LIST_STATES,
|
||||
} ListStates;
|
||||
|
||||
typedef enum {
|
||||
DELETE_GET_ENROLLED_IDS,
|
||||
DELETE_DELETE,
|
||||
DELETE_STATES,
|
||||
} DeleteStates;
|
||||
+242
-157
@@ -32,6 +32,7 @@
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "drivers_api.h"
|
||||
#include "fpi-byte-writer.h"
|
||||
|
||||
#include "egismoc.h"
|
||||
|
||||
@@ -42,15 +43,19 @@ struct _FpiDeviceEgisMoc
|
||||
FpiSsm *cmd_ssm;
|
||||
FpiUsbTransfer *cmd_transfer;
|
||||
GCancellable *interrupt_cancellable;
|
||||
|
||||
int enrolled_num;
|
||||
GPtrArray *enrolled_ids;
|
||||
gint max_enroll_stages;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FP_TYPE_DEVICE);
|
||||
|
||||
static const FpIdEntry egismoc_id_table[] = {
|
||||
{ .vid = 0x1c7a, .pid = 0x0582, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0583, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0584, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0586, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0587, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0588, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 },
|
||||
{ .vid = 0x1c7a, .pid = 0x05a1, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }
|
||||
};
|
||||
@@ -154,8 +159,6 @@ egismoc_task_ssm_done (FpiSsm *ssm,
|
||||
self->task_ssm = NULL;
|
||||
|
||||
g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref);
|
||||
self->enrolled_ids = NULL;
|
||||
self->enrolled_num = -1;
|
||||
|
||||
if (error)
|
||||
fpi_device_action_error (device, error);
|
||||
@@ -273,43 +276,24 @@ egismoc_cmd_ssm_done (FpiSsm *ssm,
|
||||
data->callback (device, NULL, 0, g_steal_pointer (&local_error));
|
||||
}
|
||||
|
||||
typedef union
|
||||
{
|
||||
guint16 check_value;
|
||||
guchar check_bytes[EGISMOC_CHECK_BYTES_LENGTH];
|
||||
} EgisMocCheckBytes;
|
||||
|
||||
G_STATIC_ASSERT (G_SIZEOF_MEMBER (EgisMocCheckBytes, check_value) ==
|
||||
sizeof (guint8) * EGISMOC_CHECK_BYTES_LENGTH);
|
||||
|
||||
/*
|
||||
* Derive the 2 "check bytes" for write payloads
|
||||
* 32-bit big-endian sum of all 16-bit words (including check bytes) MOD 0xFFFF
|
||||
* should be 0, otherwise the device will reject the payload
|
||||
*/
|
||||
static EgisMocCheckBytes
|
||||
egismoc_get_check_bytes (const guchar *value,
|
||||
const gsize value_length)
|
||||
static guint16
|
||||
egismoc_get_check_bytes (FpiByteReader *reader)
|
||||
{
|
||||
fp_dbg ("Get check bytes");
|
||||
EgisMocCheckBytes check_bytes;
|
||||
const size_t steps = (value_length + 1) / 2;
|
||||
guint16 values[steps];
|
||||
size_t sum_values = 0;
|
||||
guint16 val;
|
||||
|
||||
for (int i = 0, j = 0; i < value_length; i += 2, j++)
|
||||
{
|
||||
values[j] = (value[i] << 8 & 0xff00);
|
||||
fpi_byte_reader_set_pos (reader, 0);
|
||||
|
||||
if (i < value_length - 1)
|
||||
values[j] |= value[i + 1] & 0x00ff;
|
||||
}
|
||||
while (fpi_byte_reader_get_uint16_be (reader, &val))
|
||||
sum_values += val;
|
||||
|
||||
for (int i = 0; i < steps; i++)
|
||||
sum_values += values[i];
|
||||
|
||||
check_bytes.check_value = GUINT16_TO_BE (0xffff - (sum_values % 0xffff));
|
||||
return check_bytes;
|
||||
return G_MAXUINT16 - (sum_values % G_MAXUINT16);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -319,22 +303,15 @@ egismoc_exec_cmd (FpDevice *device,
|
||||
GDestroyNotify cmd_destroy,
|
||||
SynCmdMsgCallback callback)
|
||||
{
|
||||
fp_dbg ("Execute command and get response");
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
EgisMocCheckBytes check_bytes;
|
||||
g_autofree guchar *buffer_out = NULL;
|
||||
gsize buffer_out_length = 0;
|
||||
|
||||
g_auto(FpiByteWriter) writer = {0};
|
||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||
CommandData *data = g_new0 (CommandData, 1);
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
g_autofree CommandData *data = NULL;
|
||||
gsize buffer_out_length = 0;
|
||||
gboolean written = TRUE;
|
||||
guint16 check_value;
|
||||
|
||||
g_assert (self->cmd_ssm == NULL);
|
||||
self->cmd_ssm = fpi_ssm_new (device,
|
||||
egismoc_cmd_run_state,
|
||||
CMD_STATES);
|
||||
|
||||
transfer = fpi_usb_transfer_new (device);
|
||||
transfer->short_is_error = TRUE;
|
||||
fp_dbg ("Execute command and get response");
|
||||
|
||||
/*
|
||||
* buffer_out should be a fully composed command (with prefix, check bytes, etc)
|
||||
@@ -347,40 +324,60 @@ egismoc_exec_cmd (FpDevice *device,
|
||||
buffer_out_length = egismoc_write_prefix_len
|
||||
+ EGISMOC_CHECK_BYTES_LENGTH
|
||||
+ cmd_length;
|
||||
buffer_out = g_new0 (guchar, buffer_out_length);
|
||||
|
||||
fpi_byte_writer_init_with_size (&writer, buffer_out_length +
|
||||
(buffer_out_length % 2 ? 1 : 0), TRUE);
|
||||
|
||||
/* Prefix */
|
||||
memcpy (buffer_out, egismoc_write_prefix, egismoc_write_prefix_len);
|
||||
written &= fpi_byte_writer_put_data (&writer, egismoc_write_prefix,
|
||||
egismoc_write_prefix_len);
|
||||
|
||||
/* Check Bytes - leave them as 00 for now then later generate and copy over
|
||||
* the real ones */
|
||||
written &= fpi_byte_writer_change_pos (&writer, EGISMOC_CHECK_BYTES_LENGTH);
|
||||
|
||||
/* Command Payload */
|
||||
memcpy (buffer_out + egismoc_write_prefix_len + EGISMOC_CHECK_BYTES_LENGTH,
|
||||
cmd, cmd_length);
|
||||
|
||||
/* destroy cmd if requested */
|
||||
if (cmd_destroy)
|
||||
cmd_destroy (cmd);
|
||||
written &= fpi_byte_writer_put_data (&writer, cmd, cmd_length);
|
||||
|
||||
/* Now fetch and set the "real" check bytes based on the currently
|
||||
* assembled payload */
|
||||
check_bytes = egismoc_get_check_bytes (buffer_out, buffer_out_length);
|
||||
memcpy (buffer_out + egismoc_write_prefix_len, check_bytes.check_bytes,
|
||||
EGISMOC_CHECK_BYTES_LENGTH);
|
||||
check_value = egismoc_get_check_bytes (FPI_BYTE_READER (&writer));
|
||||
fpi_byte_writer_set_pos (&writer, egismoc_write_prefix_len);
|
||||
written &= fpi_byte_writer_put_uint16_be (&writer, check_value);
|
||||
|
||||
/* destroy cmd if requested */
|
||||
if (cmd_destroy)
|
||||
g_clear_pointer (&cmd, cmd_destroy);
|
||||
|
||||
g_assert (self->cmd_ssm == NULL);
|
||||
self->cmd_ssm = fpi_ssm_new (device,
|
||||
egismoc_cmd_run_state,
|
||||
CMD_STATES);
|
||||
|
||||
data = g_new0 (CommandData, 1);
|
||||
data->callback = callback;
|
||||
fpi_ssm_set_data (self->cmd_ssm, g_steal_pointer (&data), g_free);
|
||||
|
||||
if (!written)
|
||||
{
|
||||
fpi_ssm_start (self->cmd_ssm, egismoc_cmd_ssm_done);
|
||||
fpi_ssm_mark_failed (self->cmd_ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
return;
|
||||
}
|
||||
|
||||
transfer = fpi_usb_transfer_new (device);
|
||||
transfer->short_is_error = TRUE;
|
||||
transfer->ssm = self->cmd_ssm;
|
||||
|
||||
fpi_usb_transfer_fill_bulk_full (transfer,
|
||||
EGISMOC_EP_CMD_OUT,
|
||||
g_steal_pointer (&buffer_out),
|
||||
fpi_byte_writer_reset_and_get_data (&writer),
|
||||
buffer_out_length,
|
||||
g_free);
|
||||
transfer->ssm = self->cmd_ssm;
|
||||
|
||||
g_assert (self->cmd_transfer == NULL);
|
||||
self->cmd_transfer = g_steal_pointer (&transfer);
|
||||
data->callback = callback;
|
||||
|
||||
fpi_ssm_set_data (self->cmd_ssm, data, g_free);
|
||||
fpi_ssm_start (self->cmd_ssm, egismoc_cmd_ssm_done);
|
||||
}
|
||||
|
||||
@@ -419,11 +416,13 @@ egismoc_get_enrolled_prints (FpDevice *device)
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
|
||||
g_autoptr(GPtrArray) result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
FpPrint *print = NULL;
|
||||
|
||||
for (int i = 0; i < self->enrolled_num; i++)
|
||||
if (!self->enrolled_ids)
|
||||
return g_steal_pointer (&result);
|
||||
|
||||
for (guint i = 0; i < self->enrolled_ids->len; i++)
|
||||
{
|
||||
print = fp_print_new (device);
|
||||
FpPrint *print = fp_print_new (device);
|
||||
egismoc_set_print_data (print, g_ptr_array_index (self->enrolled_ids, i), NULL);
|
||||
g_ptr_array_add (result, g_object_ref_sink (print));
|
||||
}
|
||||
@@ -448,26 +447,37 @@ egismoc_list_fill_enrolled_ids_cb (FpDevice *device,
|
||||
|
||||
g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref);
|
||||
self->enrolled_ids = g_ptr_array_new_with_free_func (g_free);
|
||||
self->enrolled_num = 0;
|
||||
|
||||
FpiByteReader reader;
|
||||
gboolean read = TRUE;
|
||||
|
||||
fpi_byte_reader_init (&reader, buffer_in, length_in);
|
||||
|
||||
read &= fpi_byte_reader_set_pos (&reader, EGISMOC_LIST_RESPONSE_PREFIX_SIZE);
|
||||
|
||||
/*
|
||||
* Each fingerprint ID will be returned in this response as a 32 byte array
|
||||
* The other stuff in the payload is 16 bytes long, so if there is at least 1
|
||||
* print then the length should be at least 16+32=48 bytes long
|
||||
*/
|
||||
for (int pos = EGISMOC_LIST_RESPONSE_PREFIX_SIZE;
|
||||
pos < length_in - EGISMOC_LIST_RESPONSE_SUFFIX_SIZE;
|
||||
pos += EGISMOC_FINGERPRINT_DATA_SIZE, self->enrolled_num++)
|
||||
while (read)
|
||||
{
|
||||
g_autofree gchar *print_id = g_strndup ((gchar *) buffer_in + pos,
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
fp_dbg ("Device fingerprint %0d: %.*s", self->enrolled_num,
|
||||
const guint8 *data;
|
||||
g_autofree gchar *print_id = NULL;
|
||||
|
||||
read &= fpi_byte_reader_get_data (&reader, EGISMOC_FINGERPRINT_DATA_SIZE,
|
||||
&data);
|
||||
if (!read)
|
||||
break;
|
||||
|
||||
print_id = g_strndup ((gchar *) data, EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
fp_dbg ("Device fingerprint %0d: %.*s", self->enrolled_ids->len + 1,
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE, print_id);
|
||||
g_ptr_array_add (self->enrolled_ids, g_steal_pointer (&print_id));
|
||||
}
|
||||
|
||||
fp_info ("Number of currently enrolled fingerprints on the device is %d",
|
||||
self->enrolled_num);
|
||||
self->enrolled_ids->len);
|
||||
|
||||
if (self->task_ssm)
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
@@ -514,6 +524,7 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
{
|
||||
fp_dbg ("Get delete command");
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
g_auto(FpiByteWriter) writer = {0};
|
||||
g_autoptr(GVariant) print_data = NULL;
|
||||
g_autoptr(GVariant) print_data_id_var = NULL;
|
||||
const guchar *print_data_id = NULL;
|
||||
@@ -521,7 +532,7 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
g_autofree gchar *print_description = NULL;
|
||||
g_autofree guchar *enrolled_print_id = NULL;
|
||||
g_autofree guchar *result = NULL;
|
||||
gsize pos = 0;
|
||||
gboolean written = TRUE;
|
||||
|
||||
/*
|
||||
* The final command body should contain:
|
||||
@@ -537,7 +548,12 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
* identifiers (enrolled_list)
|
||||
*/
|
||||
|
||||
const int num_to_delete = (!delete_print) ? self->enrolled_num : 1;
|
||||
int num_to_delete = 0;
|
||||
if (delete_print)
|
||||
num_to_delete = 1;
|
||||
else if (self->enrolled_ids)
|
||||
num_to_delete = self->enrolled_ids->len;
|
||||
|
||||
const gsize body_length = sizeof (guchar) * EGISMOC_FINGERPRINT_DATA_SIZE *
|
||||
num_to_delete;
|
||||
/* total_length is the 6 various bytes plus prefix and body payload */
|
||||
@@ -545,10 +561,10 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
body_length;
|
||||
|
||||
/* pre-fill entire payload with 00s */
|
||||
result = g_new0 (guchar, total_length);
|
||||
fpi_byte_writer_init_with_size (&writer, total_length, TRUE);
|
||||
|
||||
/* start with 00 00 (just move starting offset up by 2) */
|
||||
pos = 2;
|
||||
written &= fpi_byte_writer_set_pos (&writer, 2);
|
||||
|
||||
/* Size Counter bytes */
|
||||
/* "easiest" way to handle 2-bytes size for counter is to hard-code logic for
|
||||
@@ -557,37 +573,31 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
* (assumed max is 10) */
|
||||
if (num_to_delete > 7)
|
||||
{
|
||||
memset (result + pos, 0x01, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, ((num_to_delete - 8) * 0x20) + 0x07, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, 0x01);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, ((num_to_delete - 8) * 0x20) + 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* first byte is 0x00, just skip it */
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, (num_to_delete * 0x20) + 0x07, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_change_pos (&writer, 1);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, (num_to_delete * 0x20) + 0x07);
|
||||
}
|
||||
|
||||
/* command prefix */
|
||||
memcpy (result + pos, cmd_delete_prefix, cmd_delete_prefix_len);
|
||||
pos += cmd_delete_prefix_len;
|
||||
written &= fpi_byte_writer_put_data (&writer, cmd_delete_prefix,
|
||||
cmd_delete_prefix_len);
|
||||
|
||||
/* 2-bytes size logic for counter again */
|
||||
if (num_to_delete > 7)
|
||||
{
|
||||
memset (result + pos, 0x01, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, ((num_to_delete - 8) * 0x20), sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, 0x01);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, (num_to_delete - 8) * 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* first byte is 0x00, just skip it */
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, (num_to_delete * 0x20), sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_change_pos (&writer, 1);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, num_to_delete * 0x20);
|
||||
}
|
||||
|
||||
/* append desired 32-byte fingerprint IDs */
|
||||
@@ -614,21 +624,26 @@ egismoc_get_delete_cmd (FpDevice *device,
|
||||
|
||||
fp_info ("Delete fingerprint %s (%s)", print_description, print_data_id);
|
||||
|
||||
memcpy (result + pos, print_data_id, EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
written &= fpi_byte_writer_put_data (&writer, print_data_id,
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
}
|
||||
/* Otherwise assume this is a "clear" - just loop through and append all enrolled IDs */
|
||||
else
|
||||
else if (self->enrolled_ids)
|
||||
{
|
||||
for (int i = 0; i < self->enrolled_ids->len; i++)
|
||||
memcpy (result + pos + (EGISMOC_FINGERPRINT_DATA_SIZE * i),
|
||||
g_ptr_array_index (self->enrolled_ids, i),
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
for (guint i = 0; i < self->enrolled_ids->len && written; i++)
|
||||
{
|
||||
written &= fpi_byte_writer_put_data (&writer,
|
||||
g_ptr_array_index (self->enrolled_ids, i),
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (written);
|
||||
|
||||
if (length_out)
|
||||
*length_out = total_length;
|
||||
|
||||
return g_steal_pointer (&result);
|
||||
return fpi_byte_writer_reset_and_get_data (&writer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -687,9 +702,7 @@ egismoc_delete_run_state (FpiSsm *ssm,
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case DELETE_GET_ENROLLED_IDS:
|
||||
/* get enrolled_ids and enrolled_num from device for use building
|
||||
* delete payload below
|
||||
*/
|
||||
/* get enrolled_ids from device for use building delete payload below */
|
||||
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL,
|
||||
egismoc_list_fill_enrolled_ids_cb);
|
||||
break;
|
||||
@@ -761,7 +774,7 @@ egismoc_enroll_status_report (FpDevice *device,
|
||||
enroll_print->stage++;
|
||||
fp_info ("Partial capture successful. Please touch the sensor again (%d/%d)",
|
||||
enroll_print->stage,
|
||||
EGISMOC_MAX_ENROLL_NUM);
|
||||
self->max_enroll_stages);
|
||||
fpi_device_enroll_progress (device, enroll_print->stage, enroll_print->print, NULL);
|
||||
break;
|
||||
|
||||
@@ -841,7 +854,7 @@ egismoc_read_capture_cb (FpDevice *device,
|
||||
egismoc_enroll_status_report (device, enroll_print, ENROLL_STATUS_RETRY, error);
|
||||
}
|
||||
|
||||
if (enroll_print->stage == EGISMOC_ENROLL_TIMES)
|
||||
if (enroll_print->stage == self->max_enroll_stages)
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
else
|
||||
fpi_ssm_jump_to_state (self->task_ssm, ENROLL_CAPTURE_SENSOR_RESET);
|
||||
@@ -884,26 +897,28 @@ egismoc_get_check_cmd (FpDevice *device,
|
||||
{
|
||||
fp_dbg ("Get check command");
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
g_auto(FpiByteWriter) writer = {0};
|
||||
g_autofree guchar *result = NULL;
|
||||
gsize pos = 0;
|
||||
gboolean written = TRUE;
|
||||
|
||||
/*
|
||||
* The final command body should contain:
|
||||
* 1) hard-coded 00 00
|
||||
* 2) 2-byte size indiciator, 20*Number enrolled identifiers plus 9 in form of:
|
||||
* (enrolled_num + 1) * 0x20 + 0x09
|
||||
* (enrolled_ids->len + 1) * 0x20 + 0x09
|
||||
* Since max prints can be higher than 7 then this goes up to 2 bytes
|
||||
* (e9 + 9 = 109)
|
||||
* 3) Hard-coded prefix (cmd_check_prefix)
|
||||
* 4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 9
|
||||
* ((enrolled_num + 1) * 0x20)
|
||||
* ((enrolled_ids->len + 1) * 0x20)
|
||||
* 5) Hard-coded 32 * 0x00 bytes
|
||||
* 6) All of the currently registered prints in their 32-byte device identifiers
|
||||
* (enrolled_list)
|
||||
* 7) Hard-coded suffix (cmd_check_suffix)
|
||||
*/
|
||||
|
||||
const gsize body_length = sizeof (guchar) * self->enrolled_num *
|
||||
g_assert (self->enrolled_ids);
|
||||
const gsize body_length = sizeof (guchar) * self->enrolled_ids->len *
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE;
|
||||
|
||||
/* prefix length can depend on the type */
|
||||
@@ -921,87 +936,82 @@ egismoc_get_check_cmd (FpDevice *device,
|
||||
+ cmd_check_suffix_len;
|
||||
|
||||
/* pre-fill entire payload with 00s */
|
||||
result = g_new0 (guchar, total_length);
|
||||
fpi_byte_writer_init_with_size (&writer, total_length, TRUE);
|
||||
|
||||
/* start with 00 00 (just move starting offset up by 2) */
|
||||
pos = 2;
|
||||
written &= fpi_byte_writer_set_pos (&writer, 2);
|
||||
|
||||
/* Size Counter bytes */
|
||||
/* "easiest" way to handle 2-bytes size for counter is to hard-code logic for
|
||||
* when we go to the 2nd byte
|
||||
* note this will not work in case any model ever supports more than 14 prints
|
||||
* (assumed max is 10) */
|
||||
if (self->enrolled_num > 6)
|
||||
if (self->enrolled_ids->len > 6)
|
||||
{
|
||||
memset (result + pos, 0x01, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, ((self->enrolled_num - 7) * 0x20) + 0x09,
|
||||
sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, 0x01);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer,
|
||||
((self->enrolled_ids->len - 7) * 0x20)
|
||||
+ 0x09);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* first byte is 0x00, just skip it */
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, ((self->enrolled_num + 1) * 0x20) + 0x09,
|
||||
sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_change_pos (&writer, 1);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer,
|
||||
((self->enrolled_ids->len + 1) * 0x20) +
|
||||
0x09);
|
||||
}
|
||||
|
||||
/* command prefix */
|
||||
if (fpi_device_get_driver_data (device) & EGISMOC_DRIVER_CHECK_PREFIX_TYPE2)
|
||||
{
|
||||
memcpy (result + pos, cmd_check_prefix_type2, cmd_check_prefix_type2_len);
|
||||
pos += cmd_check_prefix_type2_len;
|
||||
}
|
||||
written &= fpi_byte_writer_put_data (&writer, cmd_check_prefix_type2,
|
||||
cmd_check_prefix_type2_len);
|
||||
else
|
||||
{
|
||||
memcpy (result + pos, cmd_check_prefix_type1, cmd_check_prefix_type1_len);
|
||||
pos += cmd_check_prefix_type1_len;
|
||||
}
|
||||
written &= fpi_byte_writer_put_data (&writer, cmd_check_prefix_type1,
|
||||
cmd_check_prefix_type1_len);
|
||||
|
||||
/* 2-bytes size logic for counter again */
|
||||
if (self->enrolled_num > 6)
|
||||
if (self->enrolled_ids->len > 6)
|
||||
{
|
||||
memset (result + pos, 0x01, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, (self->enrolled_num - 7) * 0x20, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer, 0x01);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer,
|
||||
(self->enrolled_ids->len - 7) * 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* first byte is 0x00, just skip it */
|
||||
pos += sizeof (guchar);
|
||||
memset (result + pos, (self->enrolled_num + 1) * 0x20, sizeof (guchar));
|
||||
pos += sizeof (guchar);
|
||||
written &= fpi_byte_writer_change_pos (&writer, 1);
|
||||
written &= fpi_byte_writer_put_uint8 (&writer,
|
||||
(self->enrolled_ids->len + 1) * 0x20);
|
||||
}
|
||||
|
||||
/* add 00s "separator" to offset position */
|
||||
pos += EGISMOC_CMD_CHECK_SEPARATOR_LENGTH;
|
||||
written &= fpi_byte_writer_change_pos (&writer,
|
||||
EGISMOC_CMD_CHECK_SEPARATOR_LENGTH);
|
||||
|
||||
/* append all currently registered 32-byte fingerprint IDs */
|
||||
const gsize print_id_length = sizeof (guchar) * EGISMOC_FINGERPRINT_DATA_SIZE;
|
||||
|
||||
for (int i = 0; i < self->enrolled_num; i++)
|
||||
for (guint i = 0; i < self->enrolled_ids->len && written; i++)
|
||||
{
|
||||
gchar *device_print_id = g_ptr_array_index (self->enrolled_ids, i);
|
||||
memcpy (result + pos + (print_id_length * i), device_print_id, print_id_length);
|
||||
written &= fpi_byte_writer_put_data (&writer,
|
||||
g_ptr_array_index (self->enrolled_ids, i),
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
}
|
||||
pos += body_length;
|
||||
|
||||
/* command suffix */
|
||||
memcpy (result + pos, cmd_check_suffix, cmd_check_suffix_len);
|
||||
written &= fpi_byte_writer_put_data (&writer, cmd_check_suffix,
|
||||
cmd_check_suffix_len);
|
||||
g_assert (written);
|
||||
|
||||
if (length_out)
|
||||
*length_out = total_length;
|
||||
|
||||
return g_steal_pointer (&result);
|
||||
return fpi_byte_writer_reset_and_get_data (&writer);
|
||||
}
|
||||
|
||||
static void
|
||||
egismoc_enroll_run_state (FpiSsm *ssm,
|
||||
FpDevice *device)
|
||||
{
|
||||
g_auto(FpiByteWriter) writer = {0};
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
EnrollPrint *enroll_print = fpi_ssm_get_data (ssm);
|
||||
g_autofree guchar *payload = NULL;
|
||||
@@ -1012,13 +1022,13 @@ egismoc_enroll_run_state (FpiSsm *ssm,
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case ENROLL_GET_ENROLLED_IDS:
|
||||
/* get enrolled_ids and enrolled_num from device for use in check stages below */
|
||||
/* get enrolled_ids from device for use in check stages below */
|
||||
egismoc_exec_cmd (device, cmd_list, cmd_list_len,
|
||||
NULL, egismoc_list_fill_enrolled_ids_cb);
|
||||
break;
|
||||
|
||||
case ENROLL_CHECK_ENROLLED_NUM:
|
||||
if (self->enrolled_num >= EGISMOC_MAX_ENROLL_NUM)
|
||||
if (self->enrolled_ids->len >= EGISMOC_MAX_ENROLL_NUM)
|
||||
{
|
||||
egismoc_enroll_status_report (device, enroll_print, ENROLL_STATUS_DEVICE_FULL,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
|
||||
@@ -1089,14 +1099,23 @@ egismoc_enroll_run_state (FpiSsm *ssm,
|
||||
device_print_id = g_strndup (user_id, EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
egismoc_set_print_data (enroll_print->print, device_print_id, user_id);
|
||||
|
||||
/* create new dynamic payload of cmd_new_print_prefix + device_print_id */
|
||||
payload_length = cmd_new_print_prefix_len + EGISMOC_FINGERPRINT_DATA_SIZE;
|
||||
payload = g_new0 (guchar, payload_length);
|
||||
memcpy (payload, cmd_new_print_prefix, cmd_new_print_prefix_len);
|
||||
memcpy (payload + cmd_new_print_prefix_len, device_print_id,
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE);
|
||||
fpi_byte_writer_init (&writer);
|
||||
if (!fpi_byte_writer_put_data (&writer, cmd_new_print_prefix,
|
||||
cmd_new_print_prefix_len))
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
break;
|
||||
}
|
||||
if (!fpi_byte_writer_put_data (&writer, (guint8 *) device_print_id,
|
||||
EGISMOC_FINGERPRINT_DATA_SIZE))
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
break;
|
||||
}
|
||||
|
||||
egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length,
|
||||
payload_length = fpi_byte_writer_get_size (&writer);
|
||||
egismoc_exec_cmd (device, fpi_byte_writer_reset_and_get_data (&writer),
|
||||
payload_length,
|
||||
g_free, egismoc_task_ssm_next_state_cb);
|
||||
break;
|
||||
|
||||
@@ -1239,13 +1258,13 @@ egismoc_identify_run_state (FpiSsm *ssm,
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case IDENTIFY_GET_ENROLLED_IDS:
|
||||
/* get enrolled_ids and enrolled_num from device for use in check stages below */
|
||||
/* get enrolled_ids from device for use in check stages below */
|
||||
egismoc_exec_cmd (device, cmd_list, cmd_list_len,
|
||||
NULL, egismoc_list_fill_enrolled_ids_cb);
|
||||
break;
|
||||
|
||||
case IDENTIFY_CHECK_ENROLLED_NUM:
|
||||
if (self->enrolled_num == 0)
|
||||
if (self->enrolled_ids->len == 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (g_steal_pointer (&self->task_ssm),
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||
@@ -1446,6 +1465,71 @@ egismoc_dev_init_handler (FpiSsm *ssm,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
egismoc_probe (FpDevice *device)
|
||||
{
|
||||
GUsbDevice *usb_dev;
|
||||
GError *error = NULL;
|
||||
g_autofree gchar *serial = NULL;
|
||||
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
|
||||
|
||||
fp_dbg ("%s enter --> ", G_STRFUNC);
|
||||
|
||||
/* Claim usb interface */
|
||||
usb_dev = fpi_device_get_usb_device (device);
|
||||
if (!g_usb_device_open (usb_dev, &error))
|
||||
{
|
||||
fp_dbg ("%s g_usb_device_open failed %s", G_STRFUNC, error->message);
|
||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_usb_device_reset (usb_dev, &error))
|
||||
{
|
||||
fp_dbg ("%s g_usb_device_reset failed %s", G_STRFUNC, error->message);
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
||||
{
|
||||
fp_dbg ("%s g_usb_device_claim_interface failed %s", G_STRFUNC, error->message);
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (device)))
|
||||
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 (error)
|
||||
{
|
||||
fp_dbg ("%s g_usb_device_get_string_descriptor failed %s", G_STRFUNC, error->message);
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)),
|
||||
0, 0, NULL);
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fpi_device_get_driver_data (device) & EGISMOC_DRIVER_MAX_ENROLL_STAGES_20)
|
||||
self->max_enroll_stages = 20;
|
||||
else
|
||||
self->max_enroll_stages = EGISMOC_MAX_ENROLL_STAGES_DEFAULT;
|
||||
|
||||
fpi_device_set_nr_enroll_stages (device, self->max_enroll_stages);
|
||||
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)), 0, 0, NULL);
|
||||
g_usb_device_close (usb_dev, NULL);
|
||||
|
||||
fpi_device_probe_complete (device, serial, NULL, error);
|
||||
}
|
||||
|
||||
static void
|
||||
egismoc_open (FpDevice *device)
|
||||
{
|
||||
@@ -1526,10 +1610,11 @@ fpi_device_egismoc_class_init (FpiDeviceEgisMocClass *klass)
|
||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||
dev_class->id_table = egismoc_id_table;
|
||||
dev_class->nr_enroll_stages = EGISMOC_ENROLL_TIMES;
|
||||
dev_class->nr_enroll_stages = EGISMOC_MAX_ENROLL_STAGES_DEFAULT;
|
||||
/* device should be "always off" unless being used */
|
||||
dev_class->temp_hot_seconds = 0;
|
||||
|
||||
dev_class->probe = egismoc_probe;
|
||||
dev_class->open = egismoc_open;
|
||||
dev_class->cancel = egismoc_cancel;
|
||||
dev_class->suspend = egismoc_suspend;
|
||||
|
||||
@@ -36,6 +36,7 @@ G_DECLARE_FINAL_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FPI, DEVICE_EGISMOC,
|
||||
|
||||
#define EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 (1 << 0)
|
||||
#define EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1)
|
||||
#define EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2)
|
||||
|
||||
#define EGISMOC_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT)
|
||||
#define EGISMOC_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN)
|
||||
@@ -49,7 +50,7 @@ G_DECLARE_FINAL_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FPI, DEVICE_EGISMOC,
|
||||
#define EGISMOC_USB_IN_RECV_LENGTH 4096
|
||||
#define EGISMOC_USB_INTERRUPT_IN_RECV_LENGTH 64
|
||||
|
||||
#define EGISMOC_ENROLL_TIMES 10
|
||||
#define EGISMOC_MAX_ENROLL_STAGES_DEFAULT 10
|
||||
#define EGISMOC_MAX_ENROLL_NUM 10
|
||||
#define EGISMOC_FINGERPRINT_DATA_SIZE 32
|
||||
#define EGISMOC_LIST_RESPONSE_PREFIX_SIZE 14
|
||||
@@ -100,11 +101,11 @@ static guchar cmd_read_capture[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x02, 0x
|
||||
static gsize cmd_read_capture_len = sizeof (cmd_read_capture) / sizeof (cmd_read_capture[0]);
|
||||
static guchar rsp_read_success_prefix[] = {0x00, 0x00, 0x00, 0x04};
|
||||
static gsize rsp_read_success_prefix_len = sizeof (rsp_read_success_prefix) / sizeof (rsp_read_success_prefix[0]);
|
||||
static guchar rsp_read_success_suffix[] = {0x0a, 0x90, 0x00};
|
||||
static guchar rsp_read_success_suffix[] = {0x90, 0x00};
|
||||
static gsize rsp_read_success_suffix_len = sizeof (rsp_read_success_suffix) / sizeof (rsp_read_success_suffix[0]);
|
||||
static guchar rsp_read_offcenter_prefix[] = {0x00, 0x00, 0x00, 0x04};
|
||||
static gsize rsp_read_offcenter_prefix_len = sizeof (rsp_read_offcenter_prefix) / sizeof (rsp_read_offcenter_prefix[0]);
|
||||
static guchar rsp_read_offcenter_suffix[] = {0x0a, 0x64, 0x91};
|
||||
static guchar rsp_read_offcenter_suffix[] = {0x64, 0x91};
|
||||
static gsize rsp_read_offcenter_suffix_len = sizeof (rsp_read_offcenter_suffix) / sizeof (rsp_read_offcenter_suffix[0]);
|
||||
static guchar rsp_read_dirty_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x64};
|
||||
static gsize rsp_read_dirty_prefix_len = sizeof (rsp_read_dirty_prefix) / sizeof (rsp_read_dirty_prefix[0]);
|
||||
|
||||
@@ -547,10 +547,17 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
fpi_image_device_report_finger_status (idev, TRUE);
|
||||
elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT);
|
||||
}
|
||||
else if (self->dev_type == ELAN_0C58 && self->last_read &&
|
||||
(self->last_read[0] == 0x00 || self->last_read[0] == 0xaf))
|
||||
{
|
||||
/* 0x00 - not ready
|
||||
* 0xaf - finger removed or sensor busy (seen on 0x0c58) */
|
||||
fpi_ssm_jump_to_state_delayed (ssm, CAPTURE_WAIT_FINGER, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* XXX: The timeout is emulated incorrectly, resulting in a zero byte read. */
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
else
|
||||
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
@@ -795,7 +802,7 @@ elan_calibrate (FpiDeviceElan *self)
|
||||
|
||||
g_return_if_fail (!self->active);
|
||||
self->active = TRUE;
|
||||
self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS;
|
||||
self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS (self->dev_type);
|
||||
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (self), calibrate_run_state,
|
||||
CALIBRATE_NUM_STATES);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define ELAN_0907 (1 << 0)
|
||||
#define ELAN_0C03 (1 << 1)
|
||||
#define ELAN_0C42 (1 << 2)
|
||||
#define ELAN_0C58 (1 << 3)
|
||||
|
||||
/* devices which don't require frame rotation before assembling */
|
||||
#define ELAN_NOT_ROTATED ELAN_0C03
|
||||
@@ -44,7 +45,9 @@
|
||||
|
||||
/* times to retry reading calibration status during one session
|
||||
* generally prevents calibration from looping indefinitely */
|
||||
#define ELAN_CALIBRATION_ATTEMPTS 10
|
||||
#define ELAN_DEFAULT_CALIBRATION_ATTEMPTS 10
|
||||
#define ELAN_CALIBRATION_ATTEMPTS(dev_type) \
|
||||
((dev_type) == ELAN_0C58 ? 30 : ELAN_DEFAULT_CALIBRATION_ATTEMPTS)
|
||||
|
||||
/* min and max frames in a capture */
|
||||
#define ELAN_MIN_FRAMES 7
|
||||
@@ -220,7 +223,7 @@ static const FpIdEntry elan_id_table[] = {
|
||||
{.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV},
|
||||
{.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV},
|
||||
{.vid = ELAN_VEND_ID, .pid = 0x0c6e, .driver_data = ELAN_ALL_DEV},
|
||||
{.vid = ELAN_VEND_ID, .pid = 0x0c58, .driver_data = ELAN_ALL_DEV},
|
||||
{.vid = ELAN_VEND_ID, .pid = 0x0c58, .driver_data = ELAN_0C58},
|
||||
{.vid = 0, .pid = 0, .driver_data = 0},
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,16 @@ static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x04f3, .pid = 0x0c88, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c8c, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c8d, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c98, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c99, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c9c, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c9d, },
|
||||
{ .vid = 0x04f3, .pid = 0x0c9f, },
|
||||
{ .vid = 0x04f3, .pid = 0x0ca3, },
|
||||
{ .vid = 0x04f3, .pid = 0x0ca7, },
|
||||
{ .vid = 0x04f3, .pid = 0x0ca8, },
|
||||
{ .vid = 0x04f3, .pid = 0x0cb0, },
|
||||
{ .vid = 0x04f3, .pid = 0x0cb2, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
@@ -128,10 +137,10 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
FP_CMD_SEND = 0,
|
||||
FP_CMD_GET,
|
||||
FP_CMD_NUM_STATES,
|
||||
} FpCmdState;
|
||||
ELAN_MOC_CMD_SEND = 0,
|
||||
ELAN_MOC_CMD_GET,
|
||||
ELAN_MOC_CMD_NUM_STATES,
|
||||
} ElanMocCmdState;
|
||||
|
||||
static void
|
||||
fp_cmd_run_state (FpiSsm *ssm,
|
||||
@@ -142,7 +151,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_CMD_SEND:
|
||||
case ELAN_MOC_CMD_SEND:
|
||||
if (self->cmd_transfer)
|
||||
{
|
||||
self->cmd_transfer->ssm = ssm;
|
||||
@@ -158,7 +167,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_CMD_GET:
|
||||
case ELAN_MOC_CMD_GET:
|
||||
if (self->cmd_len_in == 0)
|
||||
{
|
||||
CommandData *data = fpi_ssm_get_data (ssm);
|
||||
@@ -225,7 +234,7 @@ elanmoc_get_cmd (FpDevice *device, guint8 *buffer_out,
|
||||
|
||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||
fp_cmd_run_state,
|
||||
FP_CMD_NUM_STATES);
|
||||
ELAN_MOC_CMD_NUM_STATES);
|
||||
|
||||
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ static void
|
||||
elanspi_do_hwreset (FpiDeviceElanSpi *self, GError **err)
|
||||
{
|
||||
/* Skip in emulation mode, since we don't mock hid devices */
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -485,7 +485,8 @@ elanspi_capture_old_handler (FpiSsm *ssm, FpDevice *dev)
|
||||
if (!(self->sensor_status & 4))
|
||||
{
|
||||
/* has the timeout expired? -- disabled in testing since valgrind is very slow */
|
||||
if (g_get_monotonic_time () > self->capture_timeout && g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") != 0)
|
||||
if (g_get_monotonic_time () > self->capture_timeout &&
|
||||
!fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
{
|
||||
/* end with a timeout */
|
||||
fpi_ssm_mark_failed (ssm, g_error_new (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "timed out waiting for new line"));
|
||||
|
||||
@@ -340,9 +340,11 @@ static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
|
||||
|
||||
// using checkargs ACPI:HIDPID
|
||||
static const FpIdEntry elanspi_id_table[] = {
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x2766}, .driver_data = ELANSPI_NO_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30c6}, .driver_data = ELANSPI_180_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3128}, .driver_data = ELANSPI_90LEFT_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3134}, .driver_data = ELANSPI_90LEFT_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3148}, .driver_data = ELANSPI_180_ROTATE},
|
||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
#define FP_COMPONENT "focaltech_moc"
|
||||
|
||||
#define FOCALTECH_QUIRK_SINGLE_SLOT 1
|
||||
#define FOCALTECH_MOC_STATIC_USER_ID "focaltech_moc_static_id"
|
||||
|
||||
#include "drivers_api.h"
|
||||
|
||||
G_DEFINE_TYPE (FpiDeviceFocaltechMoc, fpi_device_focaltech_moc, FP_TYPE_DEVICE)
|
||||
@@ -29,7 +32,17 @@ G_DEFINE_TYPE (FpiDeviceFocaltechMoc, fpi_device_focaltech_moc, FP_TYPE_DEVICE)
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x2808, .pid = 0x9e48, },
|
||||
{ .vid = 0x2808, .pid = 0xd979, },
|
||||
{ .vid = 0x2808, .pid = 0xa27a, },
|
||||
{ .vid = 0x2808, .pid = 0xa959, },
|
||||
{ .vid = 0x2808, .pid = 0xa99a, },
|
||||
{ .vid = 0x2808, .pid = 0xa57a, },
|
||||
{ .vid = 0x2808, .pid = 0xa78a, },
|
||||
{ .vid = 0x2808, .pid = 0xa97a, },
|
||||
{ .vid = 0x2808, .pid = 0x1579, },
|
||||
{ .vid = 0x2808, .pid = 0x077A, },
|
||||
{ .vid = 0x2808, .pid = 0x079A, },
|
||||
{ .vid = 0x2808, .pid = 0x5158, },
|
||||
{ .vid = 0x2808, .pid = 0x6553, .driver_data = FOCALTECH_QUIRK_SINGLE_SLOT, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
@@ -186,6 +199,22 @@ focaltech_moc_check_cmd (uint8_t *response_buf, uint16_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
focaltech_moc_require_response_len (FpiDeviceFocaltechMoc *self,
|
||||
gsize length_in,
|
||||
gsize minimum_length,
|
||||
const char *context)
|
||||
{
|
||||
if (length_in >= minimum_length)
|
||||
return TRUE;
|
||||
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"%s: short response (%zu < %zu)",
|
||||
context, length_in, minimum_length));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device,
|
||||
@@ -232,10 +261,10 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
FP_CMD_SEND = 0,
|
||||
FP_CMD_GET,
|
||||
FP_CMD_NUM_STATES,
|
||||
} FpCmdState;
|
||||
FOCALTECH_CMD_SEND = 0,
|
||||
FOCALTECH_CMD_GET,
|
||||
FOCALTECH_CMD_NUM_STATES,
|
||||
} FocaltechCmdState;
|
||||
|
||||
static void
|
||||
fp_cmd_run_state (FpiSsm *ssm,
|
||||
@@ -246,7 +275,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_CMD_SEND:
|
||||
case FOCALTECH_CMD_SEND:
|
||||
if (self->cmd_transfer)
|
||||
{
|
||||
self->cmd_transfer->ssm = ssm;
|
||||
@@ -263,7 +292,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
break;
|
||||
|
||||
case FP_CMD_GET:
|
||||
case FOCALTECH_CMD_GET:
|
||||
if (self->cmd_len_in == 0)
|
||||
{
|
||||
CommandData *data = fpi_ssm_get_data (ssm);
|
||||
@@ -331,7 +360,7 @@ focaltech_moc_get_cmd (FpDevice *device, guint8 *buffer_out,
|
||||
|
||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||
fp_cmd_run_state,
|
||||
FP_CMD_NUM_STATES);
|
||||
FOCALTECH_CMD_NUM_STATES);
|
||||
|
||||
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
||||
|
||||
@@ -1035,10 +1064,15 @@ focaltech_moc_get_enrolled_info_cb (FpiDeviceFocaltechMoc *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"get enrolled info"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
items = (struct EnrolledInfoItem *) (fp_cmd + 1);
|
||||
|
||||
if (fp_cmd->code != 0x04)
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -1046,8 +1080,25 @@ focaltech_moc_get_enrolled_info_cb (FpiDeviceFocaltechMoc *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (&data->enrolled_info->items[0], items,
|
||||
FOCALTECH_MOC_MAX_FINGERS * sizeof (struct EnrolledInfoItem));
|
||||
if (fp_cmd->code == 0x04)
|
||||
{
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) +
|
||||
FOCALTECH_MOC_MAX_FINGERS * sizeof (struct EnrolledInfoItem) +
|
||||
sizeof (uint8_t),
|
||||
"get enrolled info"))
|
||||
return;
|
||||
memcpy (&data->enrolled_info->items[0], items,
|
||||
FOCALTECH_MOC_MAX_FINGERS * sizeof (struct EnrolledInfoItem));
|
||||
|
||||
}
|
||||
else if (fp_cmd->code == 0x09)
|
||||
{
|
||||
memset (data->enrolled_info->actived, 0, FOCALTECH_MOC_MAX_FINGERS);
|
||||
memset (&data->enrolled_info->items[0], 0,
|
||||
FOCALTECH_MOC_MAX_FINGERS * sizeof (struct EnrolledInfoItem));
|
||||
}
|
||||
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
}
|
||||
@@ -1099,10 +1150,15 @@ focaltech_moc_get_enrolled_list_cb (FpiDeviceFocaltechMoc *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"get enrolled list"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
uid_list = (struct UidList *) (fp_cmd + 1);
|
||||
|
||||
if (fp_cmd->code != 0x04)
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -1111,46 +1167,57 @@ focaltech_moc_get_enrolled_list_cb (FpiDeviceFocaltechMoc *self,
|
||||
else
|
||||
{
|
||||
FpActionData *data = fpi_ssm_get_data (self->task_ssm);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FOCALTECH_MOC_MAX_FINGERS; i++)
|
||||
if (fp_cmd->code == 0x04)
|
||||
{
|
||||
if (uid_list->actived[i] != 0)
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) +
|
||||
sizeof (struct UidList) +
|
||||
sizeof (uint8_t),
|
||||
"get enrolled list"))
|
||||
return;
|
||||
for (size_t i = 0; i < FOCALTECH_MOC_MAX_FINGERS; i++)
|
||||
{
|
||||
struct UserId *user_id = &uid_list->uid[i];
|
||||
FpPrint *print = fp_print_new (FP_DEVICE (self));
|
||||
struct EnrolledInfoItem *item = NULL;
|
||||
int index;
|
||||
|
||||
fp_info ("focaltechmoc add slot: %d", i);
|
||||
|
||||
fprint_set_uid (print, user_id->uid, sizeof (user_id->uid));
|
||||
|
||||
if (focaltech_moc_get_enrolled_info_item (self, user_id->uid, &item, &index) == 0)
|
||||
if (uid_list->actived[i] != 0)
|
||||
{
|
||||
g_autofree gchar *userid_safe = NULL;
|
||||
const gchar *username;
|
||||
userid_safe = g_strndup ((const char *) &item->user_id, FOCALTECH_MOC_USER_ID_LENGTH);
|
||||
fp_dbg ("%s", userid_safe);
|
||||
fpi_print_fill_from_user_id (print, userid_safe);
|
||||
memcpy (data->enrolled_info->user_id[index].uid, user_id->uid, 32);
|
||||
data->enrolled_info->user_des[index].finger = fp_print_get_finger (print);
|
||||
username = fp_print_get_username (print);
|
||||
struct UserId *user_id = &uid_list->uid[i];
|
||||
FpPrint *print = fp_print_new (FP_DEVICE (self));
|
||||
struct EnrolledInfoItem *item = NULL;
|
||||
int index;
|
||||
|
||||
if (username != NULL)
|
||||
strncpy (data->enrolled_info->user_des[index].username, username, 64);
|
||||
fp_info ("focaltechmoc add slot: %zu", i);
|
||||
|
||||
fprint_set_uid (print, user_id->uid, sizeof (user_id->uid));
|
||||
|
||||
if (focaltech_moc_get_enrolled_info_item (self, user_id->uid, &item, &index) == 0)
|
||||
{
|
||||
g_autofree gchar *userid_safe = NULL;
|
||||
const gchar *username;
|
||||
|
||||
userid_safe = g_strndup ((const char *) &item->user_id, FOCALTECH_MOC_USER_ID_LENGTH);
|
||||
fp_dbg ("%s", userid_safe);
|
||||
fpi_print_fill_from_user_id (print, userid_safe);
|
||||
memcpy (data->enrolled_info->user_id[index].uid, user_id->uid, 32);
|
||||
data->enrolled_info->user_des[index].finger = fp_print_get_finger (print);
|
||||
username = fp_print_get_username (print);
|
||||
|
||||
if (username != NULL)
|
||||
g_strlcpy (data->enrolled_info->user_des[index].username,
|
||||
username,
|
||||
sizeof (data->enrolled_info->user_des[index].username));
|
||||
}
|
||||
|
||||
g_ptr_array_add (data->list_result, g_object_ref_sink (print));
|
||||
}
|
||||
|
||||
g_ptr_array_add (data->list_result, g_object_ref_sink (print));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FOCALTECH_MOC_MAX_FINGERS; i++)
|
||||
{
|
||||
struct EnrolledInfoItem *item = &data->enrolled_info->items[i];
|
||||
for (size_t i = 0; i < FOCALTECH_MOC_MAX_FINGERS; i++)
|
||||
{
|
||||
struct EnrolledInfoItem *item = &data->enrolled_info->items[i];
|
||||
|
||||
if (data->enrolled_info->actived[i] == 0)
|
||||
memset (item, 0, sizeof (struct EnrolledInfoItem));
|
||||
if (data->enrolled_info->actived[i] == 0)
|
||||
memset (item, 0, sizeof (struct EnrolledInfoItem));
|
||||
}
|
||||
}
|
||||
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
@@ -1272,9 +1339,21 @@ focaltech_moc_start_enroll_cb (FpiDeviceFocaltechMoc *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
guint64 quirk = fpi_device_get_driver_data (FP_DEVICE (self));
|
||||
|
||||
fpi_device_get_enroll_data (FP_DEVICE (self), &print);
|
||||
fprint_set_uid (print, user_id->uid, sizeof (user_id->uid));
|
||||
userid_safe = fpi_print_generate_user_id (print);
|
||||
|
||||
if (quirk == FOCALTECH_QUIRK_SINGLE_SLOT)
|
||||
{
|
||||
fp_info ("Applying SINGLE_SLOT quirk: Forcing static User ID");
|
||||
userid_safe = g_strdup (FOCALTECH_MOC_STATIC_USER_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
userid_safe = fpi_print_generate_user_id (print);
|
||||
}
|
||||
|
||||
userid_len = strlen (userid_safe);
|
||||
userid_len = MIN (FOCALTECH_MOC_USER_ID_LENGTH, userid_len);
|
||||
fp_info ("focaltechmoc user id: %s", userid_safe);
|
||||
@@ -1343,9 +1422,14 @@ focaltech_moc_set_enrolled_info_cb (FpiDeviceFocaltechMoc *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"set enrolled info"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
|
||||
if (fp_cmd->code != 0x04)
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -1370,9 +1454,14 @@ focaltech_moc_commit_cb (FpiDeviceFocaltechMoc *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"commit"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
|
||||
if (fp_cmd->code != 0x04)
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -1565,9 +1654,14 @@ focaltech_moc_delete_cb (FpiDeviceFocaltechMoc *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"delete"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
|
||||
if (fp_cmd->code != 0x04)
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -1762,8 +1856,9 @@ static void
|
||||
focaltech_moc_delete_print (FpDevice *device)
|
||||
{
|
||||
FpiDeviceFocaltechMoc *self = FPI_DEVICE_FOCALTECH_MOC (device);
|
||||
FpActionData *data = g_new0 (FpActionData, 1);
|
||||
FpActionData *data = NULL;
|
||||
|
||||
data = g_new0 (FpActionData, 1);
|
||||
data->enrolled_info = g_new0 (struct EnrolledInfo, 1);
|
||||
data->list_result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
@@ -1774,6 +1869,87 @@ focaltech_moc_delete_print (FpDevice *device)
|
||||
fpi_ssm_start (self->task_ssm, task_ssm_done);
|
||||
}
|
||||
|
||||
enum moc_clear_storage_states {
|
||||
MOC_CLEAR_STORAGE_SEND,
|
||||
MOC_CLEAR_STORAGE_NUM_STATES,
|
||||
};
|
||||
|
||||
static void
|
||||
focaltech_moc_clear_storage_cb (FpiDeviceFocaltechMoc *self,
|
||||
uint8_t *buffer_in,
|
||||
gsize length_in,
|
||||
GError *error)
|
||||
{
|
||||
FpCmd *fp_cmd = NULL;
|
||||
|
||||
if (error)
|
||||
{
|
||||
fp_warn ("Mass erase command completed with warning: %s", error->message);
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (length_in == 0)
|
||||
{
|
||||
fpi_device_clear_storage_complete (FP_DEVICE (self), NULL);
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!focaltech_moc_require_response_len (self, length_in,
|
||||
sizeof (FpCmd) + sizeof (uint8_t),
|
||||
"clear storage"))
|
||||
return;
|
||||
|
||||
fp_cmd = (FpCmd *) buffer_in;
|
||||
|
||||
if (fp_cmd->code != 0x04 && fp_cmd->code != 0x09)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Clear storage failed: unexpected response code 0x%02x",
|
||||
fp_cmd->code));
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_clear_storage_complete (FP_DEVICE (self), NULL);
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
focaltech_clear_storage_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
{
|
||||
guint64 quirk = fpi_device_get_driver_data (device);
|
||||
guint8 *cmd_buf = NULL;
|
||||
uint16_t cmd_len = 0;
|
||||
uint16_t resp_len = 0;
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case MOC_CLEAR_STORAGE_SEND:
|
||||
resp_len = quirk == FOCALTECH_QUIRK_SINGLE_SLOT ? 0 : sizeof (uint8_t);
|
||||
cmd_buf = focaltech_moc_compose_cmd (0xac, NULL, cmd_len);
|
||||
|
||||
focaltech_moc_get_cmd (device, cmd_buf,
|
||||
sizeof (FpCmd) + cmd_len + sizeof (uint8_t),
|
||||
sizeof (FpCmd) + resp_len + sizeof (uint8_t),
|
||||
FALSE,
|
||||
focaltech_moc_clear_storage_cb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
focaltech_moc_clear_storage (FpDevice *device)
|
||||
{
|
||||
FpiDeviceFocaltechMoc *self = FPI_DEVICE_FOCALTECH_MOC (device);
|
||||
|
||||
self->task_ssm = fpi_ssm_new (device,
|
||||
focaltech_clear_storage_run_state,
|
||||
MOC_CLEAR_STORAGE_NUM_STATES);
|
||||
fpi_ssm_start (self->task_ssm, task_ssm_done);
|
||||
}
|
||||
|
||||
enum moc_list_states {
|
||||
MOC_LIST_GET_ENROLLED_INFO,
|
||||
MOC_LIST_GET_ENROLLED_LIST,
|
||||
@@ -1849,6 +2025,17 @@ fpi_device_focaltech_moc_init (FpiDeviceFocaltechMoc *self)
|
||||
G_DEBUG_HERE ();
|
||||
}
|
||||
|
||||
static void
|
||||
focaltech_moc_probe (FpDevice *device)
|
||||
{
|
||||
guint64 quirk = fpi_device_get_driver_data (device);
|
||||
|
||||
if (quirk == FOCALTECH_QUIRK_SINGLE_SLOT)
|
||||
fpi_device_update_features (device, FP_DEVICE_FEATURE_STORAGE_DELETE, 0);
|
||||
|
||||
fpi_device_probe_complete (device, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_focaltech_moc_class_init (FpiDeviceFocaltechMocClass *klass)
|
||||
{
|
||||
@@ -1863,12 +2050,14 @@ fpi_device_focaltech_moc_class_init (FpiDeviceFocaltechMocClass *klass)
|
||||
dev_class->nr_enroll_stages = FOCALTECH_MOC_MAX_FINGERS;
|
||||
dev_class->temp_hot_seconds = -1;
|
||||
|
||||
dev_class->probe = focaltech_moc_probe;
|
||||
dev_class->open = focaltech_moc_open;
|
||||
dev_class->close = focaltech_moc_close;
|
||||
dev_class->verify = focaltech_moc_identify;
|
||||
dev_class->enroll = focaltech_moc_enroll;
|
||||
dev_class->identify = focaltech_moc_identify;
|
||||
dev_class->delete = focaltech_moc_delete_print;
|
||||
dev_class->clear_storage = focaltech_moc_clear_storage;
|
||||
dev_class->list = focaltech_moc_list;
|
||||
|
||||
fpi_device_class_auto_initialize_features (dev_class);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#define FP_COMPONENT "fpcmoc"
|
||||
#define MAX_ENROLL_SAMPLES (25)
|
||||
#define CTRL_TIMEOUT (1000)
|
||||
#define CTRL_TIMEOUT (2000)
|
||||
#define DATA_TIMEOUT (5000)
|
||||
|
||||
/* Usb port setting */
|
||||
@@ -65,9 +65,14 @@ typedef struct
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x10A5, .pid = 0xFFE0, },
|
||||
{ .vid = 0x10A5, .pid = 0xA305, },
|
||||
{ .vid = 0x10A5, .pid = 0xA306, },
|
||||
{ .vid = 0x10A5, .pid = 0xDA04, },
|
||||
{ .vid = 0x10A5, .pid = 0xD805, },
|
||||
{ .vid = 0x10A5, .pid = 0xD205, },
|
||||
{ .vid = 0x10A5, .pid = 0x9524, },
|
||||
{ .vid = 0x10A5, .pid = 0x9544, },
|
||||
{ .vid = 0x10A5, .pid = 0xC844, },
|
||||
{ .vid = 0x10A5, .pid = 0x9B24, },
|
||||
/* terminating entry */
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||
};
|
||||
@@ -82,7 +87,7 @@ fpc_suspend_resume_cb (FpiUsbTransfer *transfer,
|
||||
|
||||
fp_dbg ("%s current ssm state: %d", G_STRFUNC, ssm_state);
|
||||
|
||||
if (ssm_state == FP_CMD_SUSPENDED)
|
||||
if (ssm_state == FPC_CMD_SUSPENDED)
|
||||
{
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
@@ -90,12 +95,12 @@ fpc_suspend_resume_cb (FpiUsbTransfer *transfer,
|
||||
fpi_device_suspend_complete (device, error);
|
||||
/* The resume handler continues to the next state! */
|
||||
}
|
||||
else if (ssm_state == FP_CMD_RESUME)
|
||||
else if (ssm_state == FPC_CMD_RESUME)
|
||||
{
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
else
|
||||
fpi_ssm_jump_to_state (transfer->ssm, FP_CMD_GET_DATA);
|
||||
fpi_ssm_jump_to_state (transfer->ssm, FPC_CMD_GET_DATA);
|
||||
|
||||
fpi_device_resume_complete (device, error);
|
||||
}
|
||||
@@ -114,7 +119,7 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && (self->cmd_suspended))
|
||||
{
|
||||
g_error_free (error);
|
||||
fpi_ssm_jump_to_state (transfer->ssm, FP_CMD_SUSPENDED);
|
||||
fpi_ssm_jump_to_state (transfer->ssm, FPC_CMD_SUSPENDED);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -135,7 +140,7 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
fp_dbg ("%s current ssm request: %d state: %d", G_STRFUNC, data->request, ssm_state);
|
||||
|
||||
/* clean cmd_ssm except capture command for suspend/resume case */
|
||||
if (ssm_state != FP_CMD_SEND || data->request != FPC_CMD_ARM)
|
||||
if (ssm_state != FPC_CMD_SEND || data->request != FPC_CMD_ARM)
|
||||
self->cmd_ssm = NULL;
|
||||
|
||||
if (data->cmdtype == FPC_CMDTYPE_TO_DEVICE)
|
||||
@@ -149,13 +154,13 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
}
|
||||
else if (data->cmdtype == FPC_CMDTYPE_TO_DEVICE_EVTDATA)
|
||||
{
|
||||
if (ssm_state == FP_CMD_SEND)
|
||||
if (ssm_state == FPC_CMD_SEND)
|
||||
{
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssm_state == FP_CMD_GET_DATA)
|
||||
if (ssm_state == FPC_CMD_GET_DATA)
|
||||
{
|
||||
fpc_cmd_response_t evt_data = {0};
|
||||
fp_dbg ("%s recv evt data length: %ld", G_STRFUNC, transfer->actual_length);
|
||||
@@ -267,17 +272,17 @@ static void
|
||||
fpc_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev);
|
||||
CommandData *data = fpi_ssm_get_data (ssm);
|
||||
CommandData *data;
|
||||
|
||||
self->cmd_ssm = NULL;
|
||||
/* Notify about the SSM failure from here instead. */
|
||||
if (error)
|
||||
{
|
||||
fp_err ("%s error: %s ", G_STRFUNC, error->message);
|
||||
data = fpi_ssm_get_data (ssm);
|
||||
if (data->callback)
|
||||
data->callback (self, NULL, error);
|
||||
}
|
||||
|
||||
self->cmd_ssm = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -289,11 +294,11 @@ fpc_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_CMD_SEND:
|
||||
case FPC_CMD_SEND:
|
||||
fpc_send_ctrl_cmd (dev);
|
||||
break;
|
||||
|
||||
case FP_CMD_GET_DATA:
|
||||
case FPC_CMD_GET_DATA:
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
||||
@@ -304,7 +309,7 @@ fpc_cmd_run_state (FpiSsm *ssm,
|
||||
fpi_ssm_get_data (ssm));
|
||||
break;
|
||||
|
||||
case FP_CMD_SUSPENDED:
|
||||
case FPC_CMD_SUSPENDED:
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_fill_control (transfer,
|
||||
@@ -320,7 +325,7 @@ fpc_cmd_run_state (FpiSsm *ssm,
|
||||
fpc_suspend_resume_cb, NULL);
|
||||
break;
|
||||
|
||||
case FP_CMD_RESUME:
|
||||
case FPC_CMD_RESUME:
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_fill_control (transfer,
|
||||
@@ -351,21 +356,22 @@ fpc_sensor_cmd (FpiDeviceFpcMoc *self,
|
||||
|
||||
data = g_memdup2 (cmd_data, sizeof (CommandData));
|
||||
|
||||
g_clear_object (&self->interrupt_cancellable);
|
||||
|
||||
if (wait_data_delay)
|
||||
{
|
||||
self->cmd_data_timeout = 0;
|
||||
g_set_object (&self->interrupt_cancellable, g_cancellable_new ());
|
||||
self->interrupt_cancellable = g_cancellable_new ();
|
||||
}
|
||||
else
|
||||
{
|
||||
self->cmd_data_timeout = DATA_TIMEOUT;
|
||||
g_clear_object (&self->interrupt_cancellable);
|
||||
}
|
||||
|
||||
g_assert (self->cmd_ssm == NULL);
|
||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||
fpc_cmd_run_state,
|
||||
FP_CMD_NUM_STATES);
|
||||
FPC_CMD_NUM_STATES);
|
||||
|
||||
fpi_ssm_set_data (self->cmd_ssm, data, g_free);
|
||||
fpi_ssm_start (self->cmd_ssm, fpc_cmd_ssm_done);
|
||||
@@ -388,7 +394,7 @@ fpc_dev_release_interface (FpiDeviceFpcMoc *self,
|
||||
}
|
||||
|
||||
/* Notify close complete */
|
||||
fpi_device_close_complete (FP_DEVICE (self), release_error);
|
||||
fpi_device_close_complete (FP_DEVICE (self), g_steal_pointer (&release_error));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -446,10 +452,16 @@ fpc_evt_cb (FpiDeviceFpcMoc *self,
|
||||
break;
|
||||
|
||||
case FPC_EVT_FINGER_DWN:
|
||||
fp_dbg ("%s Got finger down event", G_STRFUNC);
|
||||
fp_dbg ("%s Got finger down event (%d)", G_STRFUNC, presp->evt_hdr.status);
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_PRESENT,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
if (presp->evt_hdr.status != 0)
|
||||
{
|
||||
/* Redo the current task state if capture failed */
|
||||
fpi_ssm_jump_to_state (self->task_ssm, fpi_ssm_get_cur_state (self->task_ssm));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case FPC_EVT_IMG:
|
||||
@@ -734,7 +746,7 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
|
||||
case FPC_ENROL_STATUS_COMPLETED:
|
||||
self->enroll_stage++;
|
||||
fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_COMPLETE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
|
||||
return;
|
||||
|
||||
case FPC_ENROL_STATUS_IMAGE_TOO_SIMILAR:
|
||||
@@ -742,15 +754,22 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
|
||||
/* here should tips remove finger and try again */
|
||||
if (self->max_immobile_stage)
|
||||
{
|
||||
if (self->immobile_stage >= self->max_immobile_stage)
|
||||
self->immobile_stage++;
|
||||
if (self->immobile_stage > self->max_immobile_stage)
|
||||
{
|
||||
fp_dbg ("Skip similar handle due to customer enrollment %d(%d)",
|
||||
self->immobile_stage, self->max_immobile_stage);
|
||||
/* Skip too similar handle, treat as normal enroll progress. */
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROL_STATUS_PROGRESS);
|
||||
self->enroll_stage++;
|
||||
fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
|
||||
/* Used for customer enrollment scheme */
|
||||
if (self->enroll_stage >= (self->max_enroll_stage - self->max_immobile_stage))
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
self->immobile_stage++;
|
||||
}
|
||||
fpi_device_enroll_progress (FP_DEVICE (self),
|
||||
self->enroll_stage,
|
||||
@@ -763,7 +782,10 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
|
||||
fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL);
|
||||
/* Used for customer enrollment scheme */
|
||||
if (self->enroll_stage >= (self->max_enroll_stage - self->max_immobile_stage))
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_COMPLETE);
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_COMPLETE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case FPC_ENROL_STATUS_IMAGE_LOW_COVERAGE:
|
||||
@@ -796,7 +818,7 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FPC_ENROLL_CAPTURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,7 +946,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_ENROLL_ENUM:
|
||||
case FPC_ENROLL_ENUM:
|
||||
{
|
||||
FPC_FID_DATA pquery_data = {0};
|
||||
gsize query_data_len = 0;
|
||||
@@ -949,7 +971,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CREATE:
|
||||
case FPC_ENROLL_CREATE:
|
||||
{
|
||||
recv_data_len = sizeof (FPC_BEGIN_ENROL);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -964,7 +986,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CAPTURE:
|
||||
case FPC_ENROLL_CAPTURE:
|
||||
{
|
||||
guint32 capture_id = FPC_CAPTUREID_RESERVED;
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
@@ -982,7 +1004,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_GET_IMG:
|
||||
case FPC_ENROLL_GET_IMG:
|
||||
{
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
|
||||
cmd_data.request = FPC_CMD_GET_IMG;
|
||||
@@ -996,7 +1018,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_UPDATE:
|
||||
case FPC_ENROLL_UPDATE:
|
||||
{
|
||||
recv_data_len = sizeof (FPC_ENROL);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1011,7 +1033,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_COMPLETE:
|
||||
case FPC_ENROLL_COMPLETE:
|
||||
{
|
||||
recv_data_len = sizeof (FPC_END_ENROL);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1026,7 +1048,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CHECK_DUPLICATE:
|
||||
case FPC_ENROLL_CHECK_DUPLICATE:
|
||||
{
|
||||
recv_data_len = sizeof (FPC_IDENTIFY);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1041,7 +1063,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_BINDID:
|
||||
case FPC_ENROLL_BINDID:
|
||||
{
|
||||
FPC_FID_DATA data = {0};
|
||||
gsize data_len = 0;
|
||||
@@ -1095,7 +1117,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_COMMIT:
|
||||
case FPC_ENROLL_COMMIT:
|
||||
{
|
||||
recv_data_len = sizeof (gint32);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1110,7 +1132,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_DICARD:
|
||||
case FPC_ENROLL_DICARD:
|
||||
{
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
|
||||
cmd_data.request = FPC_CMD_ABORT;
|
||||
@@ -1123,7 +1145,7 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CLEANUP:
|
||||
case FPC_ENROLL_CLEANUP:
|
||||
{
|
||||
if (self->do_cleanup == TRUE)
|
||||
{
|
||||
@@ -1268,7 +1290,7 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_VERIFY_CAPTURE:
|
||||
case FPC_VERIFY_CAPTURE:
|
||||
{
|
||||
guint32 capture_id = FPC_CAPTUREID_RESERVED;
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
@@ -1286,7 +1308,7 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_VERIFY_GET_IMG:
|
||||
case FPC_VERIFY_GET_IMG:
|
||||
{
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
|
||||
cmd_data.request = FPC_CMD_GET_IMG;
|
||||
@@ -1300,7 +1322,7 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_VERIFY_IDENTIFY:
|
||||
case FPC_VERIFY_IDENTIFY:
|
||||
{
|
||||
gsize recv_data_len = sizeof (FPC_IDENTIFY);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1315,7 +1337,7 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_VERIFY_CANCEL:
|
||||
case FPC_VERIFY_CANCEL:
|
||||
{
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
|
||||
cmd_data.request = FPC_CMD_ABORT;
|
||||
@@ -1385,7 +1407,7 @@ fpc_clear_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_CLEAR_DELETE_DB:
|
||||
case FPC_CLEAR_DELETE_DB:
|
||||
{
|
||||
if (self->dbid)
|
||||
{
|
||||
@@ -1412,7 +1434,7 @@ fpc_clear_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_CLEAR_CREATE_DB:
|
||||
case FPC_CLEAR_CREATE_DB:
|
||||
{
|
||||
if (self->dbid)
|
||||
{
|
||||
@@ -1517,7 +1539,7 @@ fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_INIT:
|
||||
case FPC_INIT:
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
|
||||
cmd_data.request = FPC_CMD_INIT;
|
||||
cmd_data.value = 0x1;
|
||||
@@ -1529,7 +1551,7 @@ fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fpc_sensor_cmd (self, FALSE, &cmd_data);
|
||||
break;
|
||||
|
||||
case FP_LOAD_DB:
|
||||
case FPC_INIT_LOAD_DB:
|
||||
{
|
||||
gsize recv_data_len = sizeof (FPC_LOAD_DB);
|
||||
cmd_data.cmdtype = FPC_CMDTYPE_FROM_DEVICE;
|
||||
@@ -1620,9 +1642,13 @@ fpc_dev_probe (FpDevice *device)
|
||||
{
|
||||
case 0xFFE0:
|
||||
case 0xA305:
|
||||
case 0xA306:
|
||||
case 0xD805:
|
||||
case 0xDA04:
|
||||
case 0xD205:
|
||||
case 0x9524:
|
||||
case 0x9544:
|
||||
case 0xC844:
|
||||
self->max_enroll_stage = MAX_ENROLL_SAMPLES;
|
||||
break;
|
||||
|
||||
@@ -1659,7 +1685,7 @@ fpc_dev_open (FpDevice *device)
|
||||
}
|
||||
|
||||
self->task_ssm = fpi_ssm_new (device, fpc_init_sm_run_state,
|
||||
FP_INIT_NUM_STATES);
|
||||
FPC_INIT_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fpc_init_ssm_done);
|
||||
}
|
||||
@@ -1671,6 +1697,7 @@ fpc_dev_close (FpDevice *device)
|
||||
|
||||
fp_dbg ("%s enter -->", G_STRFUNC);
|
||||
g_clear_pointer (&self->dbid, g_free);
|
||||
g_cancellable_cancel (self->interrupt_cancellable);
|
||||
g_clear_object (&self->interrupt_cancellable);
|
||||
fpc_dev_release_interface (self, NULL);
|
||||
}
|
||||
@@ -1682,8 +1709,8 @@ fpc_dev_verify_identify (FpDevice *device)
|
||||
|
||||
fp_dbg ("%s enter -->", G_STRFUNC);
|
||||
self->task_ssm = fpi_ssm_new_full (device, fpc_verify_sm_run_state,
|
||||
FP_VERIFY_NUM_STATES,
|
||||
FP_VERIFY_CANCEL,
|
||||
FPC_VERIFY_NUM_STATES,
|
||||
FPC_VERIFY_CANCEL,
|
||||
"verify_identify");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fpc_verify_ssm_done);
|
||||
@@ -1699,8 +1726,8 @@ fpc_dev_enroll (FpDevice *device)
|
||||
self->enroll_stage = 0;
|
||||
self->immobile_stage = 0;
|
||||
self->task_ssm = fpi_ssm_new_full (device, fpc_enroll_sm_run_state,
|
||||
FP_ENROLL_NUM_STATES,
|
||||
FP_ENROLL_DICARD,
|
||||
FPC_ENROLL_NUM_STATES,
|
||||
FPC_ENROLL_DICARD,
|
||||
"enroll");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fpc_enroll_ssm_done);
|
||||
@@ -1751,7 +1778,7 @@ fpc_dev_suspend (FpDevice *device)
|
||||
}
|
||||
|
||||
g_assert (self->cmd_ssm);
|
||||
g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FP_CMD_GET_DATA);
|
||||
g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FPC_CMD_GET_DATA);
|
||||
self->cmd_suspended = TRUE;
|
||||
g_cancellable_cancel (self->interrupt_cancellable);
|
||||
}
|
||||
@@ -1773,10 +1800,12 @@ fpc_dev_resume (FpDevice *device)
|
||||
|
||||
g_assert (self->cmd_ssm);
|
||||
g_assert (self->cmd_suspended);
|
||||
g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FP_CMD_SUSPENDED);
|
||||
g_assert (fpi_ssm_get_cur_state (self->cmd_ssm) == FPC_CMD_SUSPENDED);
|
||||
self->cmd_suspended = FALSE;
|
||||
g_set_object (&self->interrupt_cancellable, g_cancellable_new ());
|
||||
fpi_ssm_jump_to_state (self->cmd_ssm, FP_CMD_RESUME);
|
||||
|
||||
g_clear_object (&self->interrupt_cancellable);
|
||||
self->interrupt_cancellable = g_cancellable_new ();
|
||||
fpi_ssm_jump_to_state (self->cmd_ssm, FPC_CMD_RESUME);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1840,8 +1869,8 @@ fpc_dev_clear_storage (FpDevice *device)
|
||||
|
||||
fp_dbg ("%s enter -->", G_STRFUNC);
|
||||
self->task_ssm = fpi_ssm_new_full (device, fpc_clear_sm_run_state,
|
||||
FP_CLEAR_NUM_STATES,
|
||||
FP_CLEAR_NUM_STATES,
|
||||
FPC_CLEAR_NUM_STATES,
|
||||
FPC_CLEAR_NUM_STATES,
|
||||
"Clear storage");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fpc_clear_ssm_done);
|
||||
|
||||
@@ -178,44 +178,44 @@ typedef enum {
|
||||
} FpcCmdType;
|
||||
|
||||
typedef enum {
|
||||
FP_CMD_SEND = 0,
|
||||
FP_CMD_GET_DATA,
|
||||
FP_CMD_SUSPENDED,
|
||||
FP_CMD_RESUME,
|
||||
FP_CMD_NUM_STATES,
|
||||
} FpCmdState;
|
||||
FPC_CMD_SEND = 0,
|
||||
FPC_CMD_GET_DATA,
|
||||
FPC_CMD_SUSPENDED,
|
||||
FPC_CMD_RESUME,
|
||||
FPC_CMD_NUM_STATES,
|
||||
} FpcCmdState;
|
||||
|
||||
typedef enum {
|
||||
FP_INIT = 0,
|
||||
FP_LOAD_DB,
|
||||
FP_INIT_NUM_STATES,
|
||||
} FpInitState;
|
||||
FPC_INIT = 0,
|
||||
FPC_INIT_LOAD_DB,
|
||||
FPC_INIT_NUM_STATES,
|
||||
} FpcInitState;
|
||||
|
||||
typedef enum {
|
||||
FP_ENROLL_ENUM = 0,
|
||||
FP_ENROLL_CREATE,
|
||||
FP_ENROLL_CAPTURE,
|
||||
FP_ENROLL_GET_IMG,
|
||||
FP_ENROLL_UPDATE,
|
||||
FP_ENROLL_COMPLETE,
|
||||
FP_ENROLL_CHECK_DUPLICATE,
|
||||
FP_ENROLL_BINDID,
|
||||
FP_ENROLL_COMMIT,
|
||||
FP_ENROLL_DICARD,
|
||||
FP_ENROLL_CLEANUP,
|
||||
FP_ENROLL_NUM_STATES,
|
||||
} FpEnrollState;
|
||||
FPC_ENROLL_ENUM = 0,
|
||||
FPC_ENROLL_CREATE,
|
||||
FPC_ENROLL_CAPTURE,
|
||||
FPC_ENROLL_GET_IMG,
|
||||
FPC_ENROLL_UPDATE,
|
||||
FPC_ENROLL_COMPLETE,
|
||||
FPC_ENROLL_CHECK_DUPLICATE,
|
||||
FPC_ENROLL_BINDID,
|
||||
FPC_ENROLL_COMMIT,
|
||||
FPC_ENROLL_DICARD,
|
||||
FPC_ENROLL_CLEANUP,
|
||||
FPC_ENROLL_NUM_STATES,
|
||||
} FpcEnrollState;
|
||||
|
||||
typedef enum {
|
||||
FP_VERIFY_CAPTURE = 0,
|
||||
FP_VERIFY_GET_IMG,
|
||||
FP_VERIFY_IDENTIFY,
|
||||
FP_VERIFY_CANCEL,
|
||||
FP_VERIFY_NUM_STATES,
|
||||
} FpVerifyState;
|
||||
FPC_VERIFY_CAPTURE = 0,
|
||||
FPC_VERIFY_GET_IMG,
|
||||
FPC_VERIFY_IDENTIFY,
|
||||
FPC_VERIFY_CANCEL,
|
||||
FPC_VERIFY_NUM_STATES,
|
||||
} FpcVerifyState;
|
||||
|
||||
typedef enum {
|
||||
FP_CLEAR_DELETE_DB = 0,
|
||||
FP_CLEAR_CREATE_DB,
|
||||
FP_CLEAR_NUM_STATES,
|
||||
FPC_CLEAR_DELETE_DB = 0,
|
||||
FPC_CLEAR_CREATE_DB,
|
||||
FPC_CLEAR_NUM_STATES,
|
||||
} FpClearState;
|
||||
|
||||
@@ -128,11 +128,13 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
GError *error)
|
||||
{
|
||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||
FpiByteReader reader = {0};
|
||||
CommandData *data = user_data;
|
||||
int ret = -1, ssm_state = 0;
|
||||
int ssm_state = 0;
|
||||
gxfp_cmd_response_t cmd_reponse = {0, };
|
||||
pack_header header;
|
||||
guint32 crc32_calc = 0;
|
||||
guint32 crc32 = 0;
|
||||
guint16 cmd = 0;
|
||||
|
||||
if (error)
|
||||
@@ -154,8 +156,10 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
return;
|
||||
}
|
||||
|
||||
ret = gx_proto_parse_header (transfer->buffer, transfer->actual_length, &header);
|
||||
if (ret != 0)
|
||||
reader.data = transfer->buffer;
|
||||
reader.size = transfer->actual_length;
|
||||
|
||||
if (gx_proto_parse_header (&reader, &header) != 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -163,8 +167,17 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fpi_byte_reader_set_pos (&reader, PACKAGE_HEADER_SIZE + header.len))
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Package crc read failed"));
|
||||
}
|
||||
|
||||
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
|
||||
if(crc32_calc != GUINT32_FROM_LE (*(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)))
|
||||
|
||||
if (!fpi_byte_reader_get_uint32_le (&reader, &crc32) ||
|
||||
crc32_calc != crc32)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -174,8 +187,11 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
|
||||
cmd = MAKE_CMD_EX (header.cmd0, header.cmd1);
|
||||
|
||||
ret = gx_proto_parse_body (cmd, &transfer->buffer[PACKAGE_HEADER_SIZE], header.len, &cmd_reponse);
|
||||
if (ret != 0)
|
||||
fpi_byte_reader_set_pos (&reader, 0);
|
||||
reader.data = &transfer->buffer[PACKAGE_HEADER_SIZE];
|
||||
reader.size = header.len;
|
||||
|
||||
if (gx_proto_parse_body (cmd, &reader, &cmd_reponse) != 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
@@ -222,7 +238,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_CMD_SEND:
|
||||
case GOODIX_CMD_SEND:
|
||||
if (self->cmd_transfer)
|
||||
{
|
||||
self->cmd_transfer->ssm = ssm;
|
||||
@@ -238,7 +254,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_CMD_GET_ACK:
|
||||
case GOODIX_CMD_GET_ACK:
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
||||
@@ -250,7 +266,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||
|
||||
break;
|
||||
|
||||
case FP_CMD_GET_DATA:
|
||||
case GOODIX_CMD_GET_DATA:
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
||||
@@ -338,7 +354,7 @@ goodix_sensor_cmd (FpiDeviceGoodixMoc *self,
|
||||
|
||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||
fp_cmd_run_state,
|
||||
FP_CMD_NUM_STATES);
|
||||
GOODIX_CMD_NUM_STATES);
|
||||
|
||||
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
||||
|
||||
@@ -464,6 +480,35 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fp_verify_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||
gxfp_cmd_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
/* if reach max timeout(5sec) finger not up, try again */
|
||||
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_VERIFY_WAIT_FINGER_UP);
|
||||
return;
|
||||
}
|
||||
else if (resp->finger_status.status != GX_SUCCESS)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Switch finger mode failed"));
|
||||
return;
|
||||
}
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
FP_FINGER_STATUS_NONE,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
{
|
||||
@@ -477,7 +522,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_VERIFY_PWR_BTN_SHIELD_ON:
|
||||
case GOODIX_VERIFY_PWR_BTN_SHIELD_ON:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||
false,
|
||||
NULL,
|
||||
@@ -485,7 +530,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_pwr_btn_shield_cb);
|
||||
break;
|
||||
|
||||
case FP_VERIFY_CAPTURE:
|
||||
case GOODIX_VERIFY_CAPTURE:
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
@@ -496,7 +541,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_verify_capture_cb);
|
||||
break;
|
||||
|
||||
case FP_VERIFY_IDENTIFY:
|
||||
case GOODIX_VERIFY_IDENTIFY:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT,
|
||||
false,
|
||||
(const guint8 *) nonce,
|
||||
@@ -504,7 +549,18 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_verify_cb);
|
||||
break;
|
||||
|
||||
case FP_VERIFY_PWR_BTN_SHIELD_OFF:
|
||||
case GOODIX_VERIFY_WAIT_FINGER_UP:
|
||||
{
|
||||
guint8 dummy = 0;
|
||||
goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP,
|
||||
true,
|
||||
&dummy,
|
||||
1,
|
||||
fp_verify_finger_mode_cb);
|
||||
}
|
||||
break;
|
||||
|
||||
case GOODIX_VERIFY_PWR_BTN_SHIELD_OFF:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||
false,
|
||||
NULL,
|
||||
@@ -666,7 +722,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||
self->enroll_stage,
|
||||
NULL,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
||||
return;
|
||||
}
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
@@ -684,7 +740,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||
self->enroll_stage,
|
||||
NULL,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -715,7 +771,7 @@ fp_enroll_update_cb (FpiDeviceGoodixMoc *self,
|
||||
NULL,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER));
|
||||
}
|
||||
else if (resp->enroll_update.rollback)
|
||||
else if (resp->enroll_update.rollback || resp->result == 0x73)
|
||||
{
|
||||
fpi_device_enroll_progress (FP_DEVICE (self),
|
||||
self->enroll_stage,
|
||||
@@ -730,7 +786,7 @@ fp_enroll_update_cb (FpiDeviceGoodixMoc *self,
|
||||
/* if enroll complete, no need to wait finger up */
|
||||
if (self->enroll_stage >= self->max_enroll_stage)
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CHECK_DUPLICATE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CHECK_DUPLICATE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -796,7 +852,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||
/* 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);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_WAIT_FINGER_UP);
|
||||
return;
|
||||
}
|
||||
else if (resp->finger_status.status != GX_SUCCESS)
|
||||
@@ -811,7 +867,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||
FP_FINGER_STATUS_PRESENT);
|
||||
if (self->enroll_stage < self->max_enroll_stage)
|
||||
{
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
||||
return;
|
||||
}
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
@@ -837,7 +893,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_ENROLL_PWR_BTN_SHIELD_ON:
|
||||
case GOODIX_ENROLL_PWR_BTN_SHIELD_ON:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||
false,
|
||||
@@ -847,7 +903,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_ENUM:
|
||||
case GOODIX_ENROLL_ENUM:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT,
|
||||
false,
|
||||
@@ -857,7 +913,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CREATE:
|
||||
case GOODIX_ENROLL_CREATE:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_ENROLL_INIT, MOC_CMD1_DEFAULT,
|
||||
false,
|
||||
@@ -867,7 +923,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CAPTURE:
|
||||
case GOODIX_ENROLL_CAPTURE:
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
@@ -878,7 +934,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_enroll_capture_cb);
|
||||
break;
|
||||
|
||||
case FP_ENROLL_UPDATE:
|
||||
case GOODIX_ENROLL_UPDATE:
|
||||
dummy[0] = 1;
|
||||
dummy[1] = self->sensorcfg->config[2];
|
||||
dummy[2] = self->sensorcfg->config[3];
|
||||
@@ -889,7 +945,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_enroll_update_cb);
|
||||
break;
|
||||
|
||||
case FP_ENROLL_WAIT_FINGER_UP:
|
||||
case GOODIX_ENROLL_WAIT_FINGER_UP:
|
||||
dummy[0] = 0;
|
||||
goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP,
|
||||
true,
|
||||
@@ -898,7 +954,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_finger_mode_cb);
|
||||
break;
|
||||
|
||||
case FP_ENROLL_CHECK_DUPLICATE:
|
||||
case GOODIX_ENROLL_CHECK_DUPLICATE:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_CHECK4DUPLICATE, MOC_CMD1_DEFAULT,
|
||||
false,
|
||||
(const guint8 *) &dummy,
|
||||
@@ -906,7 +962,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_enroll_check_duplicate_cb);
|
||||
break;
|
||||
|
||||
case FP_ENROLL_COMMIT:
|
||||
case GOODIX_ENROLL_COMMIT:
|
||||
{
|
||||
fpi_device_get_enroll_data (device, &print);
|
||||
user_id = fpi_print_generate_user_id (print);
|
||||
@@ -914,7 +970,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
user_id_len = MIN (100, user_id_len);
|
||||
finger = 1;
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
memset (self->template_id, 0, TEMPLATE_ID_SIZE);
|
||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
user_id,
|
||||
@@ -959,7 +1015,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
}
|
||||
break;
|
||||
|
||||
case FP_ENROLL_PWR_BTN_SHIELD_OFF:
|
||||
case GOODIX_ENROLL_PWR_BTN_SHIELD_OFF:
|
||||
{
|
||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||
false,
|
||||
@@ -1050,7 +1106,7 @@ fp_init_cb_reset_or_complete (FpiDeviceGoodixMoc *self,
|
||||
{
|
||||
fp_warn ("Template storage appears to have been corrupted! Error was: %s", error->message);
|
||||
fp_warn ("A known reason for this to happen is a firmware bug triggered by another storage area being initialized.");
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_INIT_RESET_DEVICE);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_INIT_RESET_DEVICE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1091,7 +1147,7 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_INIT_VERSION:
|
||||
case GOODIX_INIT_VERSION:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_GET_VERSION, MOC_CMD1_DEFAULT,
|
||||
false,
|
||||
&dummy,
|
||||
@@ -1099,7 +1155,7 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_init_version_cb);
|
||||
break;
|
||||
|
||||
case FP_INIT_CONFIG:
|
||||
case GOODIX_INIT_CONFIG:
|
||||
goodix_sensor_cmd (self, MOC_CMD0_UPDATE_CONFIG, MOC_CMD1_WRITE_CFG_TO_FLASH,
|
||||
false,
|
||||
(guint8 *) self->sensorcfg,
|
||||
@@ -1107,7 +1163,7 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_init_config_cb);
|
||||
break;
|
||||
|
||||
case FP_INIT_TEMPLATE_LIST:
|
||||
case GOODIX_INIT_TEMPLATE_LIST:
|
||||
/* List prints to check whether the template DB was corrupted.
|
||||
* As of 2022-06-13 there is a known firmware issue that can cause the
|
||||
* stored templates for Linux to be corrupted when the Windows storage
|
||||
@@ -1122,7 +1178,7 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
fp_init_cb_reset_or_complete);
|
||||
break;
|
||||
|
||||
case FP_INIT_RESET_DEVICE:
|
||||
case GOODIX_INIT_RESET_DEVICE:
|
||||
fp_warn ("Resetting device storage, you will need to enroll all prints again!");
|
||||
goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DELETE_ALL,
|
||||
FALSE,
|
||||
@@ -1334,7 +1390,7 @@ gx_fp_probe (FpDevice *device)
|
||||
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
||||
goto err_close;
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
{
|
||||
|
||||
serial = g_strdup ("emulated-device");
|
||||
@@ -1361,10 +1417,13 @@ gx_fp_probe (FpDevice *device)
|
||||
case 0x60A2:
|
||||
case 0x60A4:
|
||||
case 0x6014:
|
||||
case 0x6090:
|
||||
case 0x6092:
|
||||
case 0x6094:
|
||||
case 0x609A:
|
||||
case 0x609C:
|
||||
case 0x60BC:
|
||||
case 0x60C2:
|
||||
case 0x6304:
|
||||
case 0x631C:
|
||||
case 0x633C:
|
||||
@@ -1374,9 +1433,13 @@ gx_fp_probe (FpDevice *device)
|
||||
case 0x63AC:
|
||||
case 0x63BC:
|
||||
case 0x63CC:
|
||||
case 0x650A:
|
||||
case 0x650C:
|
||||
case 0x6582:
|
||||
case 0x6A94:
|
||||
case 0x659A:
|
||||
case 0x6890:
|
||||
case 0x6984:
|
||||
self->max_enroll_stage = 12;
|
||||
break;
|
||||
|
||||
@@ -1432,7 +1495,7 @@ gx_fp_init (FpDevice *device)
|
||||
}
|
||||
|
||||
self->task_ssm = fpi_ssm_new (device, fp_init_sm_run_state,
|
||||
FP_INIT_NUM_STATES);
|
||||
GOODIX_INIT_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fp_init_ssm_done);
|
||||
|
||||
@@ -1463,9 +1526,7 @@ gx_fp_exit_cb (FpiDeviceGoodixMoc *self,
|
||||
gxfp_cmd_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
|
||||
|
||||
if (resp->result >= GX_FAILED)
|
||||
if (resp && 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);
|
||||
@@ -1500,8 +1561,8 @@ gx_fp_verify_identify (FpDevice *device)
|
||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||
|
||||
self->task_ssm = fpi_ssm_new_full (device, fp_verify_sm_run_state,
|
||||
FP_VERIFY_NUM_STATES,
|
||||
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||
GOODIX_VERIFY_NUM_STATES,
|
||||
GOODIX_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||
"verify");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fp_verify_ssm_done);
|
||||
@@ -1517,8 +1578,8 @@ gx_fp_enroll (FpDevice *device)
|
||||
self->enroll_stage = 0;
|
||||
|
||||
self->task_ssm = fpi_ssm_new_full (device, fp_enroll_sm_run_state,
|
||||
FP_ENROLL_NUM_STATES,
|
||||
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||
GOODIX_ENROLL_NUM_STATES,
|
||||
GOODIX_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||
"enroll");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
|
||||
@@ -1608,12 +1669,15 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x27c6, .pid = 0x5840, },
|
||||
{ .vid = 0x27c6, .pid = 0x6014, },
|
||||
{ .vid = 0x27c6, .pid = 0x6090, },
|
||||
{ .vid = 0x27c6, .pid = 0x6092, },
|
||||
{ .vid = 0x27c6, .pid = 0x6094, },
|
||||
{ .vid = 0x27c6, .pid = 0x609A, },
|
||||
{ .vid = 0x27c6, .pid = 0x609C, },
|
||||
{ .vid = 0x27c6, .pid = 0x60A2, },
|
||||
{ .vid = 0x27c6, .pid = 0x60A4, },
|
||||
{ .vid = 0x27c6, .pid = 0x60BC, },
|
||||
{ .vid = 0x27c6, .pid = 0x60C2, },
|
||||
{ .vid = 0x27c6, .pid = 0x6304, },
|
||||
{ .vid = 0x27c6, .pid = 0x631C, },
|
||||
{ .vid = 0x27c6, .pid = 0x633C, },
|
||||
@@ -1624,6 +1688,8 @@ static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x27c6, .pid = 0x63BC, },
|
||||
{ .vid = 0x27c6, .pid = 0x63CC, },
|
||||
{ .vid = 0x27c6, .pid = 0x6496, },
|
||||
{ .vid = 0x27c6, .pid = 0x650A, },
|
||||
{ .vid = 0x27c6, .pid = 0x650C, },
|
||||
{ .vid = 0x27c6, .pid = 0x6582, },
|
||||
{ .vid = 0x27c6, .pid = 0x6584, },
|
||||
{ .vid = 0x27c6, .pid = 0x658C, },
|
||||
@@ -1632,6 +1698,11 @@ static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x27c6, .pid = 0x659A, },
|
||||
{ .vid = 0x27c6, .pid = 0x659C, },
|
||||
{ .vid = 0x27c6, .pid = 0x6A94, },
|
||||
{ .vid = 0x27c6, .pid = 0x6512, },
|
||||
{ .vid = 0x27c6, .pid = 0x6890, },
|
||||
{ .vid = 0x27c6, .pid = 0x689A, },
|
||||
{ .vid = 0x27c6, .pid = 0x66A9, },
|
||||
{ .vid = 0x27c6, .pid = 0x6984, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
|
||||
@@ -25,39 +25,40 @@
|
||||
G_DECLARE_FINAL_TYPE (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FPI, DEVICE_GOODIXMOC, FpDevice)
|
||||
|
||||
typedef enum {
|
||||
FP_CMD_SEND = 0,
|
||||
FP_CMD_GET_ACK,
|
||||
FP_CMD_GET_DATA,
|
||||
FP_CMD_NUM_STATES,
|
||||
} FpCmdState;
|
||||
GOODIX_CMD_SEND = 0,
|
||||
GOODIX_CMD_GET_ACK,
|
||||
GOODIX_CMD_GET_DATA,
|
||||
GOODIX_CMD_NUM_STATES,
|
||||
} GoodixCmdState;
|
||||
|
||||
|
||||
typedef enum {
|
||||
FP_INIT_VERSION = 0,
|
||||
FP_INIT_CONFIG,
|
||||
FP_INIT_TEMPLATE_LIST,
|
||||
FP_INIT_RESET_DEVICE,
|
||||
FP_INIT_NUM_STATES,
|
||||
} FpInitState;
|
||||
GOODIX_INIT_VERSION = 0,
|
||||
GOODIX_INIT_CONFIG,
|
||||
GOODIX_INIT_TEMPLATE_LIST,
|
||||
GOODIX_INIT_RESET_DEVICE,
|
||||
GOODIX_INIT_NUM_STATES,
|
||||
} GoodixInitState;
|
||||
|
||||
|
||||
typedef enum {
|
||||
FP_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||
FP_ENROLL_ENUM,
|
||||
FP_ENROLL_CREATE,
|
||||
FP_ENROLL_CAPTURE,
|
||||
FP_ENROLL_UPDATE,
|
||||
FP_ENROLL_WAIT_FINGER_UP,
|
||||
FP_ENROLL_CHECK_DUPLICATE,
|
||||
FP_ENROLL_COMMIT,
|
||||
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||
FP_ENROLL_NUM_STATES,
|
||||
} FpEnrollState;
|
||||
GOODIX_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||
GOODIX_ENROLL_ENUM,
|
||||
GOODIX_ENROLL_CREATE,
|
||||
GOODIX_ENROLL_CAPTURE,
|
||||
GOODIX_ENROLL_UPDATE,
|
||||
GOODIX_ENROLL_WAIT_FINGER_UP,
|
||||
GOODIX_ENROLL_CHECK_DUPLICATE,
|
||||
GOODIX_ENROLL_COMMIT,
|
||||
GOODIX_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||
GOODIX_ENROLL_NUM_STATES,
|
||||
} GoodixEnrollState;
|
||||
|
||||
typedef enum {
|
||||
FP_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||
FP_VERIFY_CAPTURE,
|
||||
FP_VERIFY_IDENTIFY,
|
||||
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||
FP_VERIFY_NUM_STATES,
|
||||
} FpVerifyState;
|
||||
GOODIX_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||
GOODIX_VERIFY_CAPTURE,
|
||||
GOODIX_VERIFY_IDENTIFY,
|
||||
GOODIX_VERIFY_WAIT_FINGER_UP,
|
||||
GOODIX_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||
GOODIX_VERIFY_NUM_STATES,
|
||||
} GoodixVerifyState;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "goodix_proto.h"
|
||||
|
||||
/*
|
||||
@@ -107,7 +109,7 @@ reflect (uint32_t data, uint8_t n_bits)
|
||||
* If the LSB bit is set, set the reflection of it.
|
||||
*/
|
||||
if (data & 0x01)
|
||||
reflection |= (1 << ((n_bits - 1) - bit));
|
||||
reflection |= (1LU << ((n_bits - 1) - bit));
|
||||
|
||||
data = (data >> 1);
|
||||
}
|
||||
@@ -211,7 +213,11 @@ gx_proto_build_package (uint8_t *ppackage,
|
||||
init_pack_header (&header, payload_size, cmd, 0);
|
||||
|
||||
memcpy (ppackage, &header, PACKAGE_HEADER_SIZE);
|
||||
memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
|
||||
|
||||
if (payload)
|
||||
memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
|
||||
else
|
||||
ppackage[PACKAGE_HEADER_SIZE] = 0;
|
||||
|
||||
gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size);
|
||||
|
||||
@@ -220,94 +226,108 @@ gx_proto_build_package (uint8_t *ppackage,
|
||||
|
||||
|
||||
int
|
||||
gx_proto_parse_header (
|
||||
uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
pack_header *pheader)
|
||||
gx_proto_parse_header (FpiByteReader *reader,
|
||||
pack_header *pheader)
|
||||
{
|
||||
if (!buffer || !pheader)
|
||||
return -1;
|
||||
if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
|
||||
if (!pheader)
|
||||
return -1;
|
||||
|
||||
memcpy (pheader, buffer, sizeof (pack_header));
|
||||
pheader->len = GUINT16_FROM_LE (pheader->len);
|
||||
if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
|
||||
return -1;
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->cmd0))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->cmd1))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->packagenum))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->reserved))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint16_le (reader, &pheader->len))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->crc8))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->rev_crc8))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
pheader->len -= PACKAGE_CRC_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gx_proto_parse_fingerid (
|
||||
uint8_t * fid_buffer,
|
||||
uint16_t fid_buffer_size,
|
||||
ptemplate_format_t template
|
||||
)
|
||||
gx_proto_parse_fingerid (FpiByteReader *reader,
|
||||
ptemplate_format_t template)
|
||||
{
|
||||
uint8_t * buffer = NULL;
|
||||
uint16_t Offset = 0;
|
||||
uint8_t byte;
|
||||
const uint8_t *buffer;
|
||||
|
||||
if (!template || !fid_buffer)
|
||||
if (!template)
|
||||
return -1;
|
||||
|
||||
if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
|
||||
return -1;
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &byte) || byte != 67)
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
buffer = fid_buffer;
|
||||
Offset = 0;
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &template->type))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (buffer[Offset++] != 67)
|
||||
return -1;
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &template->finger_index))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
template->type = buffer[Offset++];
|
||||
template->finger_index = buffer[Offset++];
|
||||
Offset++;
|
||||
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++];
|
||||
if (template->payload.size > sizeof (template->payload.data))
|
||||
return -1;
|
||||
if (template->payload.size + Offset > fid_buffer_size)
|
||||
return -1;
|
||||
memset (template->payload.data, 0, template->payload.size);
|
||||
memcpy (template->payload.data, &buffer[Offset], template->payload.size);
|
||||
if (!fpi_byte_reader_skip (reader, 1))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_data (reader, sizeof (template->accountid), &buffer))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
memcpy (template->accountid, buffer, sizeof (template->accountid));
|
||||
|
||||
if (!fpi_byte_reader_get_data (reader, sizeof (template->tid), &buffer))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
memcpy (template->tid, buffer, sizeof (template->tid));
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (reader, &template->payload.size))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_data (reader, template->payload.size, &buffer))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
memcpy (template->payload.data, buffer, template->payload.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
|
||||
gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_response_t presp)
|
||||
{
|
||||
uint16_t offset = 0;
|
||||
uint8_t *fingerlist = NULL;
|
||||
if (!presp)
|
||||
return -1;
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->result))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!buffer || !presp)
|
||||
return -1;
|
||||
if (buffer_len < 1)
|
||||
return -1;
|
||||
presp->result = buffer[0];
|
||||
switch (HIBYTE (cmd))
|
||||
{
|
||||
case RESPONSE_PACKAGE_CMD:
|
||||
{
|
||||
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
|
||||
return -1;
|
||||
presp->parse_msg.ack_cmd = buffer[1];
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->parse_msg.ack_cmd))
|
||||
g_return_val_if_reached (-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;
|
||||
presp->finger_config.status = presp->result;
|
||||
/* to compatiable old version firmware */
|
||||
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
|
||||
|
||||
if (fpi_byte_reader_skip (byte_reader, 1))
|
||||
fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->finger_config.max_stored_prints);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -318,85 +338,99 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
|
||||
|
||||
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");
|
||||
}
|
||||
uint8_t support_pwr_shield;
|
||||
|
||||
if (fpi_byte_reader_get_uint8 (byte_reader, &support_pwr_shield) &&
|
||||
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));
|
||||
const uint8_t *version_info;
|
||||
|
||||
if (!fpi_byte_reader_get_data (byte_reader, sizeof (gxfp_version_info_t), &version_info))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
memcpy (&presp->version_info, version_info, 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];
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->capture_data_resp.img_quality))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->capture_data_resp.img_coverage))
|
||||
g_return_val_if_reached (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_ENROLL_INIT:
|
||||
if (buffer_len < sizeof (gxfp_enroll_create_t) + 1)
|
||||
return -1;
|
||||
if (presp->result == GX_SUCCESS)
|
||||
memcpy (&presp->enroll_create.tid, &buffer[1], TEMPLATE_ID_SIZE);
|
||||
if (presp->result != GX_SUCCESS)
|
||||
break;
|
||||
const uint8_t *tid;
|
||||
if (!fpi_byte_reader_get_data (byte_reader, TEMPLATE_ID_SIZE, &tid))
|
||||
g_return_val_if_reached (-1);
|
||||
memcpy (presp->enroll_create.tid, tid, 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];
|
||||
presp->enroll_update.rollback = (presp->result < 0x80) ? false : true;
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->enroll_update.img_overlay))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->enroll_update.img_preoverlay))
|
||||
g_return_val_if_reached (-1);
|
||||
break;
|
||||
|
||||
case MOC_CMD0_CHECK4DUPLICATE:
|
||||
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
|
||||
if (presp->check_duplicate_resp.duplicate)
|
||||
{
|
||||
if (buffer_len < 3)
|
||||
return -1;
|
||||
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
|
||||
offset += 3;
|
||||
uint16_t tid_size;
|
||||
FpiByteReader tid_reader;
|
||||
|
||||
if (buffer_len < tid_size + offset)
|
||||
return -1;
|
||||
if (gx_proto_parse_fingerid (buffer + offset, tid_size, &presp->check_duplicate_resp.template) != 0)
|
||||
return -1;
|
||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &tid_size))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &tid_reader, tid_size))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (gx_proto_parse_fingerid (&tid_reader, &presp->check_duplicate_resp.template) != 0)
|
||||
g_return_val_if_reached (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOC_CMD0_GETFINGERLIST:
|
||||
if (presp->result != GX_SUCCESS)
|
||||
break;
|
||||
if (buffer_len < 2)
|
||||
return -1;
|
||||
presp->finger_list_resp.finger_num = buffer[1];
|
||||
fingerlist = buffer + 2;
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
||||
&presp->finger_list_resp.finger_num))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
|
||||
{
|
||||
uint16_t fingerid_length;
|
||||
if (buffer_len < offset + 2)
|
||||
return -1;
|
||||
fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
|
||||
offset += 2;
|
||||
if (buffer_len < fingerid_length + offset)
|
||||
return -1;
|
||||
if (gx_proto_parse_fingerid (fingerlist + offset,
|
||||
fingerid_length,
|
||||
FpiByteReader fingerid_reader;
|
||||
|
||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_length))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &fingerid_reader,
|
||||
fingerid_length))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (gx_proto_parse_fingerid (&fingerid_reader,
|
||||
&presp->finger_list_resp.finger_list[num]) != 0)
|
||||
{
|
||||
g_warning ("Failed to parse finger list");
|
||||
return -1;
|
||||
g_return_val_if_reached (-1);
|
||||
}
|
||||
offset += fingerid_length;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -405,23 +439,32 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
|
||||
uint32_t score = 0;
|
||||
uint8_t study = 0;
|
||||
uint16_t fingerid_size = 0;
|
||||
presp->verify.match = (buffer[0] == 0) ? true : false;
|
||||
|
||||
presp->verify.match = (presp->result == 0) ? true : false;
|
||||
|
||||
if (presp->verify.match)
|
||||
{
|
||||
if (buffer_len < 10)
|
||||
return -1;
|
||||
offset += 1;
|
||||
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||
offset += 2;
|
||||
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
|
||||
offset += 4;
|
||||
study = buffer[offset];
|
||||
offset += 1;
|
||||
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||
offset += 2;
|
||||
if (buffer_len < fingerid_size + offset)
|
||||
return -1;
|
||||
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
|
||||
FpiByteReader finger_reader;
|
||||
|
||||
if (!fpi_byte_reader_get_uint16_le (byte_reader,
|
||||
&presp->verify.rejectdetail))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint32_le (byte_reader, &score))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &study))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_size))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &finger_reader,
|
||||
fingerid_size))
|
||||
g_return_val_if_reached (-1);
|
||||
|
||||
if (gx_proto_parse_fingerid (&finger_reader,
|
||||
&presp->verify.template) != 0)
|
||||
{
|
||||
presp->result = GX_FAILED;
|
||||
break;
|
||||
@@ -432,7 +475,7 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c
|
||||
break;
|
||||
|
||||
case MOC_CMD0_FINGER_MODE:
|
||||
presp->finger_status.status = buffer[0];
|
||||
presp->finger_status.status = presp->result;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fpi-byte-reader.h"
|
||||
|
||||
#define PACKAGE_CRC_SIZE (4)
|
||||
#define PACKAGE_HEADER_SIZE (8)
|
||||
|
||||
@@ -133,7 +135,7 @@ typedef struct _template_format
|
||||
typedef struct _gxfp_verify
|
||||
{
|
||||
bool match;
|
||||
uint32_t rejectdetail;
|
||||
uint16_t rejectdetail;
|
||||
template_format_t template;
|
||||
} gxfp_verify_t, *pgxfp_verify_t;
|
||||
|
||||
@@ -232,13 +234,11 @@ int gx_proto_build_package (uint8_t *ppackage,
|
||||
const uint8_t *payload,
|
||||
uint32_t payload_size);
|
||||
|
||||
int gx_proto_parse_header (uint8_t *buffer,
|
||||
uint32_t buffer_len,
|
||||
pack_header *pheader);
|
||||
int gx_proto_parse_header (FpiByteReader *reader,
|
||||
pack_header *pheader);
|
||||
|
||||
int gx_proto_parse_body (uint16_t cmd,
|
||||
uint8_t *buffer,
|
||||
uint16_t buffer_len,
|
||||
FpiByteReader *byte_reader,
|
||||
pgxfp_cmd_response_t presponse);
|
||||
|
||||
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
#include "fpi-device.h"
|
||||
#include "fpi-ssm.h"
|
||||
#include "pwd.h"
|
||||
#include <sys/utsname.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpiDeviceMafpmoc, fpi_device_mafpmoc, FPI, DEVICE_MAFPMOC, FpDevice)
|
||||
|
||||
#define PRINT_CMD 0
|
||||
#define PRINT_SSM_DEBUG 0
|
||||
|
||||
#define MAFP_INTERFACE_CLASS G_USB_DEVICE_CLASS_VENDOR_SPECIFIC
|
||||
#define MAFP_INTERFACE_SUB_CLASS 0x01
|
||||
#define MAFP_INTERFACE_PROTOCOL 0x01
|
||||
|
||||
/* Usb port setting */
|
||||
#define MAFP_EP_BULK_OUT 0x03
|
||||
#define MAFP_EP_BULK_IN 0x83
|
||||
#define MAFP_EP_INT_IN 0x82
|
||||
|
||||
/* Command transfer timeout: ms */
|
||||
#define CMD_TIMEOUT 5000
|
||||
#define DATA_TIMEOUT 5000
|
||||
#define CTRL_TIMEOUT 200
|
||||
|
||||
#define MAFP_USB_BUFFER_SIZE 512
|
||||
#define PACKAGE_CRC_SIZE 2
|
||||
#define PACKAGE_HEADER_SIZE 9
|
||||
#define PACKAGE_DATA_SIZE_MAX (MAFP_USB_BUFFER_SIZE - PACKAGE_HEADER_SIZE - PACKAGE_CRC_SIZE)
|
||||
|
||||
#define TEMPLATE_ID_SIZE 2
|
||||
#define TEMPLATE_UID_SIZE 128
|
||||
#define DEVICE_SN_SIZE 32
|
||||
#define MAX_FINGER_NUM 10
|
||||
#define MAX_USER_NUM 3
|
||||
#define MAX_NOTEPAD_PAGE 16
|
||||
|
||||
#define MOC_CMD_GET_IMAGE 0x01
|
||||
#define MOC_CMD_GEN_FEATURE 0x02
|
||||
#define MOC_CMD_SEARCH 0x04
|
||||
#define MOC_CMD_GEN_TEMPLATE 0x05
|
||||
#define MOC_CMD_SAVE_TEMPLATE 0x06
|
||||
#define MOC_CMD_READ_TEMPLATE 0x07
|
||||
#define MOC_CMD_DELETE_TEMPLATE 0x0C
|
||||
#define MOC_CMD_EMPTY 0x0D
|
||||
#define MOC_CMD_WRITE_NOTEPAD 0x18
|
||||
#define MOC_CMD_READ_NOTEPAD 0x19
|
||||
#define MOC_CMD_GET_TEMPLATE_NUM 0x1D
|
||||
#define MOC_CMD_GET_TEMPLATE_TABLE 0x1F
|
||||
#define MOC_CMD_CANCEL 0x30
|
||||
#define MOC_CMD_SLEEP 0x33
|
||||
#define MOC_CMD_HANDSHAKE 0x35
|
||||
#define MOC_CMD_CALIBRATE 0x36
|
||||
#define MOC_CMD_FACTORY_RESET 0x3B
|
||||
#define MOC_CMD_FACTORY_TEST 0x56
|
||||
#define MOC_CMD_MATCH_WITHFID 0x66
|
||||
#define MOC_CMD_GET_MAX_ID 0x6d
|
||||
#define MOC_CMD_DUPAREA_TEST 0x6f
|
||||
#define MOC_CMD_SAVE_TEMPLATE_INFO 0x86
|
||||
#define MOC_CMD_GET_TEMPLATE_INFO 0x87
|
||||
#define MOC_CMD_GET_INIT_STATUS 0x88
|
||||
|
||||
#define MAFP_SUCCESS 0
|
||||
#define MAFP_RE_TPL_NUM_OVERSIZE 0x0B
|
||||
#define MAFP_RE_GET_IMAGE_SUCCESS 0x00
|
||||
#define MAFP_RE_GET_IMAGE_NONE 0x02
|
||||
/* calibrate error (un-calibrate or calibrate failed) */
|
||||
#define MAFP_RE_CALIBRATE_ERROR 0x02
|
||||
|
||||
#define MAFP_HANDSHAKE_CODE1 'M'
|
||||
#define MAFP_HANDSHAKE_CODE2 'A'
|
||||
|
||||
/* Default enroll stages number */
|
||||
#define DEFAULT_ENROLL_SAMPLES 12
|
||||
#define MAFP_ENV_ENROLL_SAMPLES "MAFP_ENROLL_SAMPLES"
|
||||
|
||||
#define MAFP_ENROLL_IDENTIFY_DISABLED 0
|
||||
#define MAFP_ENROLL_IDENTIFY_ENABLED 1
|
||||
#define MAFP_ENROLL_IDENTIFY_ONCE 2
|
||||
#define MAFP_ENROLL_DUPLICATE_DELETE_DISABLED 0
|
||||
#define MAFP_ENROLL_DUPLICATE_DELETE_ENABLED 1
|
||||
#define MAFP_ENROLL_DUPLICATE_AREA_DENY 0
|
||||
#define MAFP_ENROLL_DUPLICATE_AREA_ALLOW 1
|
||||
|
||||
#define MAFP_SLEEP_INT_WAIT 0
|
||||
#define MAFP_SLEEP_INT_CHECK 1
|
||||
#define MAFP_SLEEP_INT_REFRESH 2
|
||||
|
||||
#define MAFP_PRESS_WAIT_UP 0
|
||||
#define MAFP_PRESS_WAIT_DOWN 1
|
||||
|
||||
#define MAFP_IMAGE_ERR_TRRIGER 30
|
||||
|
||||
typedef enum {
|
||||
MAPF_CMD_SEND = 0,
|
||||
MAPF_CMD_RECEIVE,
|
||||
MAPF_CMD_DATA_RECEIVE,
|
||||
MAPF_CMD_TRANSFER_STATES,
|
||||
} MapfCmdState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_INIT_CLEAN_EPIN = 0,
|
||||
MAPF_INIT_CLEAN_EPOUT,
|
||||
MAPF_INIT_CLEAN_EPIN2,
|
||||
MAPF_INIT_HANDSHAKE,
|
||||
MAPF_INIT_MODULE_STATUS,
|
||||
MAPF_INIT_STATES,
|
||||
} MapfInitState;
|
||||
|
||||
typedef enum {
|
||||
MAFP_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||
MAFP_ENROLL_CHECK_EMPTY,
|
||||
MAFP_ENROLL_TEMPLATE_TABLE,
|
||||
MAFP_ENROLL_READ_TEMPLATE,
|
||||
MAFP_ENROLL_VERIFY_GET_IMAGE,
|
||||
MAFP_ENROLL_CHECK_INT_PARA,
|
||||
MAFP_ENROLL_DETECT_MODE,
|
||||
MAFP_ENROLL_ENABLE_INT,
|
||||
MAFP_ENROLL_WAIT_INT,
|
||||
MAFP_ENROLL_DISBALE_INT,
|
||||
MAFP_ENROLL_REFRESH_INT_PARA,
|
||||
MAFP_ENROLL_VERIFY_GENERATE_FEATURE,
|
||||
MAFP_ENROLL_VERIFY_DUPLICATE_AREA,
|
||||
MAFP_ENROLL_VERIFY_SEARCH,
|
||||
MAFP_ENROLL_VERIFY_SEARCH_STEP, //match assigned id
|
||||
MAFP_ENROLL_GET_TEMPLATE_INFO,
|
||||
MAFP_ENROLL_SAVE_TEMPLATE_INFO,
|
||||
MAFP_ENROLL_SAVE_TEMPLATE,
|
||||
MAFP_ENROLL_DELETE_TEMPLATE_INFO_IF_FAILED,
|
||||
MAFP_ENROLL_EXIT,
|
||||
MAFP_ENROLL_STATES,
|
||||
} MapfEnrollState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||
MAPF_VERIFY_TEMPLATE_TABLE,
|
||||
MAPF_VERIFY_GET_STARTUP_RESULT,
|
||||
MAPF_VERIFY_GET_IMAGE,
|
||||
MAPF_VERIFY_CHECK_INT_PARA,
|
||||
MAPF_VERIFY_DETECT_MODE,
|
||||
MAPF_VERIFY_ENABLE_INT,
|
||||
MAPF_VERIFY_WAIT_INT,
|
||||
MAPF_VERIFY_DISBALE_INT,
|
||||
MAPF_VERIFY_REFRESH_INT_PARA,
|
||||
MAPF_VERIFY_GENERATE_FEATURE,
|
||||
MAPF_VERIFY_SEARCH_STEP, //match assigned id
|
||||
MAPF_VERIFY_GET_TEMPLATE_INFO,
|
||||
MAPF_VERIFY_EXIT,
|
||||
MAPF_VERIFY_STATES,
|
||||
} MapfVerifyState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_LIST_TEMPLATE_TABLE = 0,
|
||||
MAPF_LIST_GET_TEMPLATE_INFO,
|
||||
MAPF_LIST_STATES,
|
||||
} MapfListState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_DELETE_TEMPLATE_TABLE = 0,
|
||||
MAPF_DELETE_GET_TEMPLATE_INFO,
|
||||
MAPF_DELETE_CLEAR_TEMPLATE_INFO,
|
||||
MAPF_DELETE_TEMPLATE,
|
||||
MAPF_DELETE_STATES,
|
||||
} MapfDeleteState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_EMPTY_TEMPLATE = 0,
|
||||
MAPF_EMPTY_STATES,
|
||||
} MapfDeleteAllState;
|
||||
|
||||
typedef enum {
|
||||
MAPF_PACK_CMD = 0x01, //cmd packet
|
||||
MAPF_PACK_DATA = 0x02, //data packet, with more data packets later, must follow cmd or answer packet
|
||||
MAPF_PACK_ANSWER = 0x07, //answer packet for cmd packet
|
||||
MAPF_PACK_END = 0x08, //last data packet
|
||||
MAPF_PACK_DATA_ANDSWER = 0x09, //answer packet for data packet
|
||||
} MapfPackMark;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct _mafp_handshake
|
||||
{
|
||||
uint8_t code[2];
|
||||
/*uint8_t state;
|
||||
uint8_t desc[16];
|
||||
uint8_t ver[4];*/
|
||||
} mafp_handshake_t, *pmafp_handshake_t;
|
||||
|
||||
typedef struct _mafp_search
|
||||
{
|
||||
uint8_t id[2];
|
||||
uint8_t score[2];
|
||||
} mafp_search_t, *pmafp_search_t;
|
||||
|
||||
typedef struct _mafp_tpl_table
|
||||
{
|
||||
uint8_t used_num;
|
||||
uint8_t list[256];
|
||||
} mafp_tpl_table_t, *pmafp_tpl_table_t;
|
||||
|
||||
typedef struct _mafp_tpl_info
|
||||
{
|
||||
char uid[128];
|
||||
} mafp_tpl_info_t, *pmafp_tpl_info_t;
|
||||
|
||||
typedef struct _mafp_boot_handshake
|
||||
{
|
||||
char code[2];
|
||||
uint8_t state;
|
||||
char descrip[16];
|
||||
uint32_t version;
|
||||
} mafp_boot_handshake_t, *pmafp_boot_handshake_t;
|
||||
|
||||
typedef struct _mafp_template
|
||||
{
|
||||
char sn[32];
|
||||
uint16_t id;
|
||||
char uid[128];
|
||||
} mafp_template_t, *pmafp_template_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct _mafp_templates
|
||||
{
|
||||
uint16_t index;
|
||||
uint16_t total_num;
|
||||
uint16_t priv_num;
|
||||
mafp_template_t total_list[256];
|
||||
mafp_template_t priv_list[MAX_FINGER_NUM];
|
||||
GPtrArray *list;
|
||||
} mafp_templates_t, *pmafp_templates_t;
|
||||
|
||||
typedef struct _fp_cmd_response
|
||||
{
|
||||
uint8_t result;
|
||||
union
|
||||
{
|
||||
mafp_handshake_t handshake;
|
||||
mafp_search_t search;
|
||||
mafp_tpl_table_t tpl_table;
|
||||
mafp_tpl_info_t tpl_info;
|
||||
mafp_boot_handshake_t boot_handshake;
|
||||
};
|
||||
} mafp_cmd_response_t, *pmafp_cmd_response_t;
|
||||
|
||||
typedef struct _pack_header
|
||||
{
|
||||
uint8_t head0;
|
||||
uint8_t head1;
|
||||
uint8_t addr0;
|
||||
uint8_t addr1;
|
||||
uint8_t addr2;
|
||||
uint8_t addr3;
|
||||
uint8_t flag;
|
||||
uint8_t frame_len0;
|
||||
uint8_t frame_len1;
|
||||
} pack_header, *ppack_header;
|
||||
@@ -28,6 +28,9 @@ G_DEFINE_TYPE (FpiDeviceRealtek, fpi_device_realtek, FP_TYPE_DEVICE)
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x0bda, .pid = 0x5813, },
|
||||
{ .vid = 0x0bda, .pid = 0x5816, },
|
||||
{ .vid = 0x2541, .pid = 0xfa03, },
|
||||
{ .vid = 0x3274, .pid = 0x9003, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
@@ -92,6 +95,50 @@ fp_task_ssm_generic_cb (FpiDeviceRealtek *self,
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_get_device_info_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
self->template_len = TEMPLATE_LEN_COMMON;
|
||||
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_update_template_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_VERIFY_NUM_STATES);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_enroll_commit_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_ENROLL_NUM_STATES);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_finish_capture_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
@@ -103,8 +150,17 @@ fp_finish_capture_cb (FpiDeviceRealtek *self,
|
||||
return;
|
||||
}
|
||||
|
||||
gint capture_status = buffer_in[0];
|
||||
/* We hope this polling CMD can be completed before the action is cancelled */
|
||||
GCancellable *cancellable = fpi_device_get_cancellable (FP_DEVICE (self));
|
||||
if (g_cancellable_is_cancelled (cancellable))
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Action is cancelled!"));
|
||||
return;
|
||||
}
|
||||
|
||||
gint capture_status = buffer_in[0];
|
||||
if (capture_status == 0)
|
||||
{
|
||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||
@@ -238,7 +294,6 @@ fp_identify_feature_cb (FpiDeviceRealtek *self,
|
||||
}
|
||||
|
||||
gint in_status = buffer_in[0];
|
||||
|
||||
if (in_status == FP_RTK_CMD_ERR)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
@@ -291,7 +346,7 @@ fp_identify_feature_cb (FpiDeviceRealtek *self,
|
||||
else
|
||||
{
|
||||
fpi_device_identify_report (device, print, match, error);
|
||||
fpi_ssm_mark_completed (self->task_ssm);
|
||||
fpi_ssm_jump_to_state (self->task_ssm, FP_RTK_VERIFY_NUM_STATES);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -340,9 +395,9 @@ fp_get_delete_pos_cb (FpiDeviceRealtek *self,
|
||||
|
||||
for (gint i = 0; i < self->template_num; i++)
|
||||
{
|
||||
if (buffer_in[i * TEMPLATE_LEN] != 0)
|
||||
if (buffer_in[i * self->template_len] != 0)
|
||||
{
|
||||
memcpy (temp_userid, buffer_in + i * TEMPLATE_LEN + UID_OFFSET, DEFAULT_UID_LEN);
|
||||
memcpy (temp_userid, buffer_in + i * self->template_len + UID_OFFSET, DEFAULT_UID_LEN);
|
||||
if (g_strcmp0 (fp_print_get_description (print), (const char *) temp_userid) == 0)
|
||||
{
|
||||
self->pos_index = i;
|
||||
@@ -380,10 +435,25 @@ fp_get_enroll_num_cb (FpiDeviceRealtek *self,
|
||||
}
|
||||
|
||||
static void
|
||||
fp_get_template_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
fp_verify_get_template_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_ssm_next_state (self->task_ssm);
|
||||
}
|
||||
|
||||
static void
|
||||
fp_enroll_get_template_cb (FpiDeviceRealtek *self,
|
||||
uint8_t *buffer_in,
|
||||
GError *error)
|
||||
{
|
||||
g_autofree guchar *seq_list = NULL;
|
||||
gboolean found = FALSE;
|
||||
|
||||
if (error)
|
||||
@@ -394,7 +464,7 @@ fp_get_template_cb (FpiDeviceRealtek *self,
|
||||
|
||||
for (gint i = 0; i < self->template_num; i++)
|
||||
{
|
||||
if (buffer_in[i * TEMPLATE_LEN] == 0)
|
||||
if (buffer_in[i * self->template_len] == 0)
|
||||
{
|
||||
self->pos_index = i;
|
||||
found = TRUE;
|
||||
@@ -425,7 +495,6 @@ fp_check_duplicate_cb (FpiDeviceRealtek *self,
|
||||
}
|
||||
|
||||
gint in_status = buffer_in[0];
|
||||
|
||||
if (in_status == FP_RTK_CMD_ERR)
|
||||
{
|
||||
fpi_ssm_mark_failed (self->task_ssm,
|
||||
@@ -471,10 +540,10 @@ fp_list_cb (FpiDeviceRealtek *self,
|
||||
|
||||
for (gint i = 0; i < self->template_num; i++)
|
||||
{
|
||||
if (buffer_in[i * TEMPLATE_LEN] != 0)
|
||||
if (buffer_in[i * self->template_len] != 0)
|
||||
{
|
||||
FpPrint *print = NULL;
|
||||
print = fp_print_from_data (self, buffer_in + i * TEMPLATE_LEN + SUBFACTOR_OFFSET);
|
||||
print = fp_print_from_data (self, buffer_in + i * self->template_len + SUBFACTOR_OFFSET);
|
||||
g_ptr_array_add (list_result, g_object_ref_sink (print));
|
||||
found = TRUE;
|
||||
}
|
||||
@@ -518,11 +587,11 @@ parse_status (guint8 *buffer, gint status_type)
|
||||
{
|
||||
switch (status_type)
|
||||
{
|
||||
case FP_RTK_MSG_PLAINTEXT_NO_STATUS:
|
||||
case FP_RTK_MSG_NO_STATUS:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case FP_RTK_MSG_PLAINTEXT:
|
||||
case FP_RTK_MSG_DEFAULT:
|
||||
return buffer[0];
|
||||
break;
|
||||
|
||||
@@ -621,13 +690,13 @@ fp_cmd_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
break;
|
||||
|
||||
case FP_RTK_CMD_TRANS_DATA:
|
||||
if (self->cmd_type == FP_RTK_CMD_ONLY)
|
||||
if (self->cmd_type == FP_RTK_CMD_BULK_ONLY)
|
||||
{
|
||||
fpi_ssm_jump_to_state (ssm, FP_RTK_CMD_GET_STATUS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (self->cmd_type == FP_RTK_CMD_WRITE)
|
||||
if (self->cmd_type == FP_RTK_CMD_BULK_WRITE)
|
||||
{
|
||||
if (self->data_transfer)
|
||||
{
|
||||
@@ -688,10 +757,10 @@ fp_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
}
|
||||
|
||||
static FpiUsbTransfer *
|
||||
prepare_transfer (FpDevice *dev,
|
||||
guint8 *data,
|
||||
gsize data_len,
|
||||
GDestroyNotify free_func)
|
||||
prepare_bulk_transfer (FpDevice *dev,
|
||||
guint8 *data,
|
||||
gsize data_len,
|
||||
GDestroyNotify free_func)
|
||||
{
|
||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||
|
||||
@@ -708,29 +777,100 @@ prepare_transfer (FpDevice *dev,
|
||||
return g_steal_pointer (&transfer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
realtek_sensor_cmd (FpiDeviceRealtek *self,
|
||||
guint8 *cmd,
|
||||
guint8 *trans_data,
|
||||
FpRtkMsgType message_type,
|
||||
gboolean bwait_data_delay,
|
||||
SynCmdMsgCallback callback)
|
||||
fp_ctrl_cmd_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device,
|
||||
gpointer user_data,
|
||||
GError *error)
|
||||
{
|
||||
FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
|
||||
g_autofree CommandData *data = g_steal_pointer (&user_data);
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (transfer->direction == G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE)
|
||||
{
|
||||
if (data->callback)
|
||||
data->callback (self, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transfer->actual_length == 0)
|
||||
{
|
||||
fp_info ("Control transfer receive data failed!");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->callback)
|
||||
data->callback (self, transfer->buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtk_send_ctrl_cmd (FpiDeviceRealtek *self,
|
||||
struct rtk_cmd_ctrl *ctrl_cmd,
|
||||
guint8 *cmd_data,
|
||||
SynCmdMsgCallback callback)
|
||||
{
|
||||
FpiUsbTransfer *transfer = NULL;
|
||||
g_autofree CommandData *data = g_new0 (CommandData, 1);
|
||||
|
||||
data->callback = callback;
|
||||
|
||||
transfer = fpi_usb_transfer_new (FP_DEVICE (self));
|
||||
fpi_usb_transfer_fill_control (transfer,
|
||||
ctrl_cmd->direction,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
ctrl_cmd->request,
|
||||
ctrl_cmd->value,
|
||||
ctrl_cmd->index,
|
||||
ctrl_cmd->len);
|
||||
|
||||
transfer->ssm = self->task_ssm;
|
||||
if (ctrl_cmd->direction == G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST &&
|
||||
cmd_data != NULL && ctrl_cmd->len != 0)
|
||||
memcpy (transfer->buffer, cmd_data, ctrl_cmd->len);
|
||||
|
||||
fpi_usb_transfer_submit (transfer,
|
||||
CMD_TIMEOUT,
|
||||
NULL,
|
||||
fp_ctrl_cmd_cb,
|
||||
g_steal_pointer (&data));
|
||||
}
|
||||
|
||||
static void
|
||||
rtk_sensor_bulk_cmd (FpiDeviceRealtek *self,
|
||||
guint8 *cmd,
|
||||
guint8 *trans_data,
|
||||
FpRtkMsgType message_type,
|
||||
gboolean bwait_data_delay,
|
||||
SynCmdMsgCallback callback)
|
||||
{
|
||||
g_autoptr(FpiUsbTransfer) cmd_transfer = NULL;
|
||||
g_autoptr(FpiUsbTransfer) data_transfer = NULL;
|
||||
CommandData *data = g_new0 (CommandData, 1);
|
||||
|
||||
self->cmd_type = GET_CMD_TYPE (cmd[0]);
|
||||
self->cmd_type = GET_BULK_CMD_TYPE (cmd[0]);
|
||||
self->message_type = message_type;
|
||||
self->trans_data_len = GET_TRANS_DATA_LEN (cmd[11], cmd[10]);
|
||||
self->cmd_cancellable = bwait_data_delay;
|
||||
|
||||
cmd_transfer = prepare_transfer (FP_DEVICE (self), cmd, FP_RTK_CMD_TOTAL_LEN, NULL);
|
||||
cmd_transfer = prepare_bulk_transfer (FP_DEVICE (self), cmd, FP_RTK_CMD_BULK_TOTAL_LEN, NULL);
|
||||
self->cmd_transfer = g_steal_pointer (&cmd_transfer);
|
||||
|
||||
if ((self->cmd_type == FP_RTK_CMD_WRITE) && trans_data)
|
||||
if ((self->cmd_type == FP_RTK_CMD_BULK_WRITE) && trans_data)
|
||||
{
|
||||
data_transfer = prepare_transfer (FP_DEVICE (self), trans_data, self->trans_data_len, g_free);
|
||||
data_transfer = prepare_bulk_transfer (FP_DEVICE (self), trans_data, self->trans_data_len, g_free);
|
||||
self->data_transfer = g_steal_pointer (&data_transfer);
|
||||
}
|
||||
|
||||
@@ -829,34 +969,49 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_RTK_VERIFY_GET_TEMPLATE:
|
||||
g_assert (self->template_num > 0);
|
||||
|
||||
co_get_template.data_len[0] = GET_LEN_L (self->template_len * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (self->template_len * self->template_num);
|
||||
cmd_buf = (guint8 *) &co_get_template;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_verify_get_template_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_CAPTURE:
|
||||
fpi_device_report_finger_status_changes (device,
|
||||
FP_FINGER_STATUS_NEEDED,
|
||||
FP_FINGER_STATUS_NONE);
|
||||
|
||||
cmd_buf = (guint8 *) &co_start_capture;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_task_ssm_generic_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_FINISH_CAPTURE:
|
||||
cmd_buf = (guint8 *) &co_finish_capture;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_finish_capture_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_finish_capture_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_ACCEPT_SAMPLE:
|
||||
co_accept_sample.param[0] = self->fp_purpose;
|
||||
cmd_buf = (guint8 *) &co_accept_sample;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_accept_sample_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_NO_STATUS, 0, fp_accept_sample_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_INDENTIFY_FEATURE:
|
||||
cmd_buf = (guint8 *) &tls_identify_feature;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 0, fp_identify_feature_cb);
|
||||
cmd_buf = (guint8 *) &nor_identify_feature;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_NO_STATUS, 0, fp_identify_feature_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_UPDATE_TEMPLATE:
|
||||
cmd_buf = (guint8 *) &co_update_template;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_update_template_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_VERIFY_CANCEL_CAPTURE:
|
||||
co_cancel_capture.param[0] = self->fp_purpose;
|
||||
cmd_buf = (guint8 *) &co_cancel_capture;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -869,7 +1024,6 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
FpiDeviceRealtek *self = FPI_DEVICE_REALTEK (device);
|
||||
FpPrint *print = NULL;
|
||||
guint8 *cmd_buf = NULL;
|
||||
guint8 *trans_id = NULL;
|
||||
GVariant *uid = NULL;
|
||||
GVariant *data = NULL;
|
||||
gsize user_id_len;
|
||||
@@ -880,17 +1034,17 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
case FP_RTK_ENROLL_GET_TEMPLATE:
|
||||
g_assert (self->template_num > 0);
|
||||
|
||||
co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[0] = GET_LEN_L (self->template_len * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (self->template_len * self->template_num);
|
||||
|
||||
cmd_buf = (guint8 *) &co_get_template;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_template_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_enroll_get_template_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_BEGIN_POS:
|
||||
tls_enroll_begin.param[0] = self->pos_index;
|
||||
cmd_buf = (guint8 *) &tls_enroll_begin;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
|
||||
nor_enroll_begin.param[0] = self->pos_index;
|
||||
cmd_buf = (guint8 *) &nor_enroll_begin;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_CAPTURE:
|
||||
@@ -899,39 +1053,42 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
FP_FINGER_STATUS_NONE);
|
||||
|
||||
cmd_buf = (guint8 *) &co_start_capture;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_task_ssm_generic_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_FINISH_CAPTURE:
|
||||
cmd_buf = (guint8 *) &co_finish_capture;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_finish_capture_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_finish_capture_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_ACCEPT_SAMPLE:
|
||||
co_accept_sample.param[0] = self->fp_purpose;
|
||||
cmd_buf = (guint8 *) &co_accept_sample;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_accept_sample_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_NO_STATUS, 0, fp_accept_sample_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_CHECK_DUPLICATE:
|
||||
cmd_buf = (guint8 *) &co_check_duplicate;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT_NO_STATUS, 1, fp_check_duplicate_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_NO_STATUS, 0, fp_check_duplicate_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_COMMIT:
|
||||
gchar *valid_uid = NULL;
|
||||
gint payload_len;
|
||||
|
||||
payload_len = UID_PAYLOAD_LEN_DEFAULT;
|
||||
|
||||
fpi_device_get_enroll_data (device, &print);
|
||||
user_id = fpi_print_generate_user_id (print);
|
||||
user_id_len = strlen (user_id);
|
||||
user_id_len = MIN (DEFAULT_UID_LEN, user_id_len);
|
||||
user_id_len = MIN (DEFAULT_UID_LEN, strlen (user_id));
|
||||
|
||||
payload = g_malloc0 (UID_PAYLOAD_LEN);
|
||||
payload = g_malloc0 (payload_len);
|
||||
memcpy (payload, user_id, user_id_len);
|
||||
|
||||
trans_id = g_steal_pointer (&payload);
|
||||
valid_uid = (gchar *) payload;
|
||||
|
||||
finger = SUB_FINGER_01;
|
||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
user_id,
|
||||
valid_uid,
|
||||
user_id_len,
|
||||
1);
|
||||
data = g_variant_new ("(y@ay)",
|
||||
@@ -941,14 +1098,23 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
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, NULL);
|
||||
g_object_set (print, "description", valid_uid, NULL);
|
||||
|
||||
g_debug ("user_id: %s, finger: 0x%x", user_id, finger);
|
||||
|
||||
tls_enroll_commit.param[0] = SUB_FINGER_01;
|
||||
cmd_buf = (guint8 *) &tls_enroll_commit;
|
||||
realtek_sensor_cmd (self, cmd_buf, trans_id, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
|
||||
nor_enroll_commit.param[0] = SUB_FINGER_01;
|
||||
nor_enroll_commit.data_len[0] = GET_LEN_L (payload_len);
|
||||
nor_enroll_commit.data_len[1] = GET_LEN_H (payload_len);
|
||||
|
||||
cmd_buf = (guint8 *) &nor_enroll_commit;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, g_steal_pointer (&payload),
|
||||
FP_RTK_MSG_DEFAULT, 1, fp_enroll_commit_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_ENROLL_CANCEL_CAPTURE:
|
||||
co_cancel_capture.param[0] = self->fp_purpose;
|
||||
cmd_buf = (guint8 *) &co_cancel_capture;
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,15 +1126,19 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case FP_RTK_INIT_GET_DEVICE_INFO:
|
||||
rtk_send_ctrl_cmd (self, &get_device_info, NULL, fp_get_device_info_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_INIT_SELECT_OS:
|
||||
co_select_system.param[0] = 0x01;
|
||||
cmd_buf = (guint8 *) &co_select_system;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_INIT_GET_ENROLL_NUM:
|
||||
cmd_buf = (guint8 *) &co_get_enroll_num;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_enroll_num_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_get_enroll_num_cb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -984,17 +1154,17 @@ fp_delete_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||
case FP_RTK_DELETE_GET_POS:
|
||||
g_assert (self->template_num > 0);
|
||||
|
||||
co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[0] = GET_LEN_L (self->template_len * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (self->template_len * self->template_num);
|
||||
|
||||
cmd_buf = (guint8 *) &co_get_template;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_get_delete_pos_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_get_delete_pos_cb);
|
||||
break;
|
||||
|
||||
case FP_RTK_DELETE_PRINT:
|
||||
co_delete_record.param[0] = self->pos_index;
|
||||
cmd_buf = (guint8 *) &co_delete_record;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_task_ssm_generic_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_task_ssm_generic_cb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1012,17 +1182,14 @@ identify_verify (FpDevice *device)
|
||||
g_assert (current_action == FPI_DEVICE_ACTION_VERIFY ||
|
||||
current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
||||
|
||||
if (current_action == FPI_DEVICE_ACTION_IDENTIFY)
|
||||
self->fp_purpose = FP_RTK_PURPOSE_IDENTIFY;
|
||||
else
|
||||
self->fp_purpose = FP_RTK_PURPOSE_VERIFY;
|
||||
self->fp_purpose = FP_RTK_PURPOSE_IDENTIFY;
|
||||
|
||||
g_assert (!self->task_ssm);
|
||||
|
||||
self->task_ssm = fpi_ssm_new_full (device,
|
||||
fp_verify_sm_run_state,
|
||||
FP_RTK_VERIFY_NUM_STATES,
|
||||
FP_RTK_VERIFY_NUM_STATES,
|
||||
FP_RTK_VERIFY_CANCEL_CAPTURE,
|
||||
"Verify & Identify");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fp_verify_ssm_done);
|
||||
@@ -1042,7 +1209,7 @@ enroll (FpDevice *device)
|
||||
self->task_ssm = fpi_ssm_new_full (device,
|
||||
fp_enroll_sm_run_state,
|
||||
FP_RTK_ENROLL_NUM_STATES,
|
||||
FP_RTK_ENROLL_NUM_STATES,
|
||||
FP_RTK_ENROLL_CANCEL_CAPTURE,
|
||||
"Enroll");
|
||||
|
||||
fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
|
||||
@@ -1167,7 +1334,7 @@ clear_storage (FpDevice *device)
|
||||
G_DEBUG_HERE ();
|
||||
co_delete_record.param[0] = 0xff;
|
||||
cmd_buf = (guint8 *) &co_delete_record;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 0, fp_clear_storage_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 0, fp_clear_storage_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1179,11 +1346,11 @@ list_print (FpDevice *device)
|
||||
G_DEBUG_HERE ();
|
||||
g_assert (self->template_num > 0);
|
||||
|
||||
co_get_template.data_len[0] = GET_LEN_L (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (TEMPLATE_LEN * self->template_num);
|
||||
co_get_template.data_len[0] = GET_LEN_L (self->template_len * self->template_num);
|
||||
co_get_template.data_len[1] = GET_LEN_H (self->template_len * self->template_num);
|
||||
|
||||
cmd_buf = (guint8 *) &co_get_template;
|
||||
realtek_sensor_cmd (self, cmd_buf, NULL, FP_RTK_MSG_PLAINTEXT, 1, fp_list_cb);
|
||||
rtk_sensor_bulk_cmd (self, cmd_buf, NULL, FP_RTK_MSG_DEFAULT, 1, fp_list_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -30,16 +30,17 @@
|
||||
|
||||
#define EP_IN_MAX_BUF_SIZE 2048
|
||||
|
||||
#define FP_RTK_CMD_TOTAL_LEN 12
|
||||
#define FP_RTK_CMD_LEN 2
|
||||
#define FP_RTK_CMD_PARAM_LEN 4
|
||||
#define FP_RTK_CMD_ADDR_LEN 4
|
||||
#define FP_RTK_CMD_DATA_LEN 2
|
||||
#define FP_RTK_CMD_BULK_TOTAL_LEN 12
|
||||
#define FP_RTK_CMD_BULK_LEN 2
|
||||
#define FP_RTK_CMD_BULK_PARAM_LEN 4
|
||||
#define FP_RTK_CMD_BULK_ADDR_LEN 4
|
||||
#define FP_RTK_CMD_BULK_DATA_LEN 2
|
||||
|
||||
#define TEMPLATE_LEN_COMMON 35
|
||||
|
||||
#define TEMPLATE_LEN 35
|
||||
#define SUBFACTOR_OFFSET 2
|
||||
#define UID_OFFSET 3
|
||||
#define UID_PAYLOAD_LEN 32
|
||||
#define UID_PAYLOAD_LEN_DEFAULT 32
|
||||
|
||||
/* Command transfer timeout :ms*/
|
||||
#define CMD_TIMEOUT 1000
|
||||
@@ -50,7 +51,7 @@
|
||||
#define DEFAULT_UID_LEN 28
|
||||
#define SUB_FINGER_01 0xFF
|
||||
|
||||
#define GET_CMD_TYPE(val) ((val & 0xC0) >> 6)
|
||||
#define GET_BULK_CMD_TYPE(val) ((val & 0xC0) >> 6)
|
||||
#define GET_TRANS_DATA_LEN(len_h, len_l) ((len_h << 8) | len_l)
|
||||
#define GET_LEN_L(total_data_len) ((total_data_len) & 0xff)
|
||||
#define GET_LEN_H(total_data_len) ((total_data_len) >> 8)
|
||||
@@ -67,19 +68,19 @@ typedef struct
|
||||
} CommandData;
|
||||
|
||||
typedef enum {
|
||||
FP_RTK_CMD_ONLY = 0,
|
||||
FP_RTK_CMD_READ,
|
||||
FP_RTK_CMD_WRITE,
|
||||
FP_RTK_CMD_BULK_ONLY = 0,
|
||||
FP_RTK_CMD_BULK_READ,
|
||||
FP_RTK_CMD_BULK_WRITE,
|
||||
} FpRtkCmdType;
|
||||
|
||||
typedef enum {
|
||||
FP_RTK_MSG_PLAINTEXT = 0,
|
||||
FP_RTK_MSG_PLAINTEXT_NO_STATUS,
|
||||
FP_RTK_MSG_DEFAULT = 0,
|
||||
FP_RTK_MSG_NO_STATUS,
|
||||
} FpRtkMsgType;
|
||||
|
||||
typedef enum {
|
||||
FP_RTK_PURPOSE_IDENTIFY = 0x01, /* identify before enroll */
|
||||
FP_RTK_PURPOSE_VERIFY = 0x02,
|
||||
FP_RTK_PURPOSE_VERIFY = 0x01,
|
||||
FP_RTK_PURPOSE_IDENTIFY = 0x02,
|
||||
FP_RTK_PURPOSE_ENROLL = 0x04,
|
||||
} FpRtkPurpose;
|
||||
|
||||
@@ -107,15 +108,18 @@ typedef enum {
|
||||
FP_RTK_ENROLL_ACCEPT_SAMPLE,
|
||||
FP_RTK_ENROLL_CHECK_DUPLICATE,
|
||||
FP_RTK_ENROLL_COMMIT,
|
||||
FP_RTK_ENROLL_CANCEL_CAPTURE,
|
||||
FP_RTK_ENROLL_NUM_STATES,
|
||||
} FpRtkEnrollState;
|
||||
|
||||
typedef enum {
|
||||
FP_RTK_VERIFY_CAPTURE = 0,
|
||||
FP_RTK_VERIFY_GET_TEMPLATE = 0,
|
||||
FP_RTK_VERIFY_CAPTURE,
|
||||
FP_RTK_VERIFY_FINISH_CAPTURE,
|
||||
FP_RTK_VERIFY_ACCEPT_SAMPLE,
|
||||
FP_RTK_VERIFY_INDENTIFY_FEATURE,
|
||||
FP_RTK_VERIFY_UPDATE_TEMPLATE,
|
||||
FP_RTK_VERIFY_CANCEL_CAPTURE,
|
||||
FP_RTK_VERIFY_NUM_STATES,
|
||||
} FpRtkVerifyState;
|
||||
|
||||
@@ -126,7 +130,8 @@ typedef enum {
|
||||
} FpRtkDeleteState;
|
||||
|
||||
typedef enum {
|
||||
FP_RTK_INIT_SELECT_OS = 0,
|
||||
FP_RTK_INIT_GET_DEVICE_INFO = 0,
|
||||
FP_RTK_INIT_SELECT_OS,
|
||||
FP_RTK_INIT_GET_ENROLL_NUM,
|
||||
FP_RTK_INIT_NUM_STATES,
|
||||
} FpRtkInitState;
|
||||
@@ -155,66 +160,87 @@ struct _FpiDeviceRealtek
|
||||
FpRtkPurpose fp_purpose;
|
||||
gint pos_index;
|
||||
gint template_num;
|
||||
gint template_len;
|
||||
};
|
||||
|
||||
struct realtek_fp_cmd
|
||||
struct rtk_cmd_bulk
|
||||
{
|
||||
uint8_t cmd[FP_RTK_CMD_LEN];
|
||||
uint8_t param[FP_RTK_CMD_PARAM_LEN];
|
||||
uint8_t addr[FP_RTK_CMD_ADDR_LEN];
|
||||
uint8_t data_len[FP_RTK_CMD_DATA_LEN];
|
||||
uint8_t cmd[FP_RTK_CMD_BULK_LEN];
|
||||
uint8_t param[FP_RTK_CMD_BULK_PARAM_LEN];
|
||||
uint8_t addr[FP_RTK_CMD_BULK_ADDR_LEN];
|
||||
uint8_t data_len[FP_RTK_CMD_BULK_DATA_LEN];
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_start_capture = {
|
||||
struct rtk_cmd_ctrl
|
||||
{
|
||||
int direction;
|
||||
uint8_t request;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
static struct rtk_cmd_ctrl get_device_info = {
|
||||
.direction = G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
||||
.request = 0x07,
|
||||
.value = 0x000D,
|
||||
.index = 0x0000,
|
||||
.len = 0x0008,
|
||||
};
|
||||
|
||||
static struct rtk_cmd_bulk co_start_capture = {
|
||||
.cmd = {0x05, 0x05},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_finish_capture = {
|
||||
static struct rtk_cmd_bulk co_finish_capture = {
|
||||
.cmd = {0x45, 0x06},
|
||||
.data_len = {0x05},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_accept_sample = {
|
||||
static struct rtk_cmd_bulk co_accept_sample = {
|
||||
.cmd = {0x45, 0x08},
|
||||
.data_len = {0x09},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd tls_identify_feature = {
|
||||
static struct rtk_cmd_bulk nor_identify_feature = {
|
||||
.cmd = {0x45, 0x22},
|
||||
.data_len = {0x2A},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_get_enroll_num = {
|
||||
static struct rtk_cmd_bulk co_get_enroll_num = {
|
||||
.cmd = {0x45, 0x0d},
|
||||
.data_len = {0x02},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_get_template = {
|
||||
static struct rtk_cmd_bulk co_get_template = {
|
||||
.cmd = {0x45, 0x0E},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd tls_enroll_begin = {
|
||||
static struct rtk_cmd_bulk nor_enroll_begin = {
|
||||
.cmd = {0x05, 0x20},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_check_duplicate = {
|
||||
static struct rtk_cmd_bulk co_check_duplicate = {
|
||||
.cmd = {0x45, 0x10},
|
||||
.data_len = {0x22},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd tls_enroll_commit = {
|
||||
static struct rtk_cmd_bulk nor_enroll_commit = {
|
||||
.cmd = {0x85, 0x21},
|
||||
.data_len = {0x20},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_update_template = {
|
||||
static struct rtk_cmd_bulk co_update_template = {
|
||||
.cmd = {0x05, 0x11},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_delete_record = {
|
||||
static struct rtk_cmd_bulk co_delete_record = {
|
||||
.cmd = {0x05, 0x0F},
|
||||
};
|
||||
|
||||
static struct realtek_fp_cmd co_select_system = {
|
||||
static struct rtk_cmd_bulk co_select_system = {
|
||||
.cmd = {0x05, 0x13},
|
||||
};
|
||||
|
||||
static struct rtk_cmd_bulk co_cancel_capture = {
|
||||
.cmd = {0x05, 0x07},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -256,7 +256,8 @@ bmkt_compose_message (uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_nu
|
||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
||||
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
||||
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
||||
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
||||
if (payload_size > 0)
|
||||
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
||||
|
||||
*cmd_len = message_len;
|
||||
|
||||
|
||||
@@ -32,22 +32,36 @@ static void compose_and_send_identify_msg (FpDevice *device);
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00BD, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C2, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C4, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C6, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00DF, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00E9, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F0, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F9, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FC, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C2, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0100, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F0, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0103, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0104, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0106, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0107, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0108, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0109, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x010A, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0123, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0124, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x015F, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0104, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0169, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x016C, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0173, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0106, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0174, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x019D, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x019F, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x01A0, },
|
||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x01A4, },
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||
};
|
||||
|
||||
@@ -1197,7 +1211,7 @@ prob_msg_cb (FpiDeviceSynaptics *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (self)))
|
||||
serial = g_strdup ("emulated-device");
|
||||
else
|
||||
serial = g_usb_device_get_string_descriptor (usb_dev,
|
||||
@@ -1247,6 +1261,12 @@ dev_probe (FpDevice *device)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_usb_device_reset (usb_dev, &error))
|
||||
{
|
||||
fp_dbg ("%s g_usb_device_reset failed %s", G_STRFUNC, error->message);
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
||||
goto err_close;
|
||||
|
||||
|
||||
@@ -196,8 +196,9 @@ struct read_msg_data
|
||||
static void __read_msg_async (FpDevice *dev,
|
||||
struct read_msg_data *udata);
|
||||
|
||||
#define READ_MSG_DATA_CB_ERR(dev, udata, error) (udata)->callback (dev, \
|
||||
READ_MSG_CMD, 0, 0, NULL, 0, (udata)->user_data, error)
|
||||
#define READ_MSG_DATA_CB_ERR(dev, udata, error) \
|
||||
(udata)->callback (dev, \
|
||||
READ_MSG_CMD, 0, 0, NULL, 0, (udata)->user_data, error)
|
||||
|
||||
static void
|
||||
busy_ack_sent_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
@@ -1243,7 +1244,7 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
|
||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||
|
||||
/* Report the error immediately if possible, otherwise delay it. */
|
||||
if (error && error->domain == FP_DEVICE_RETRY)
|
||||
if (!error || error->domain == FP_DEVICE_RETRY)
|
||||
fpi_device_verify_report (dev, res, NULL, error);
|
||||
else
|
||||
data->error = error;
|
||||
@@ -1295,7 +1296,7 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
memcpy (msg, verify_hdr, sizeof (verify_hdr));
|
||||
memcpy (msg + sizeof (verify_hdr), data, data_len);
|
||||
|
||||
transfer = alloc_send_cmd28_transfer (dev, 0x03, data, data_len);
|
||||
transfer = alloc_send_cmd28_transfer (dev, 0x03, msg, msg_len);
|
||||
|
||||
g_free (msg);
|
||||
|
||||
@@ -1341,7 +1342,6 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data,
|
||||
fp_dbg ("good image");
|
||||
break;
|
||||
|
||||
case 0x1c: /* FIXME what does this one mean? */
|
||||
case 0x0b: /* FIXME what does this one mean? */
|
||||
case 0x23: /* FIXME what does this one mean? */
|
||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
||||
@@ -1351,6 +1351,14 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data,
|
||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER);
|
||||
break;
|
||||
|
||||
case 0x1c: /* swipe too fast */
|
||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_FAST);
|
||||
break;
|
||||
|
||||
case 0x1d: /* too much horizontal movement */
|
||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER);
|
||||
break;
|
||||
|
||||
case 0x1e: /* swipe too short */
|
||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
|
||||
break;
|
||||
@@ -1439,7 +1447,7 @@ verify_rd2800_cb (FpDevice *dev, enum read_msg_type msgtype,
|
||||
do_verify_stop (dev,
|
||||
FPI_MATCH_ERROR,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Response hat wrong command sequence"));
|
||||
"Response had wrong command sequence"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+60
-66
@@ -20,8 +20,8 @@
|
||||
|
||||
#define FP_COMPONENT "uru4000"
|
||||
|
||||
#include <nss.h>
|
||||
#include <pk11pub.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "drivers_api.h"
|
||||
|
||||
@@ -148,10 +148,7 @@ struct _FpiDeviceUru4000
|
||||
int fwfixer_offset;
|
||||
unsigned char fwfixer_value;
|
||||
|
||||
CK_MECHANISM_TYPE cipher;
|
||||
PK11SlotInfo *slot;
|
||||
PK11SymKey *symkey;
|
||||
SECItem *param;
|
||||
EVP_CIPHER_CTX *cipher_ctx;
|
||||
};
|
||||
G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000,
|
||||
FpImageDevice);
|
||||
@@ -246,13 +243,29 @@ response_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *e
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
}
|
||||
|
||||
static GError *
|
||||
openssl_device_error (void)
|
||||
{
|
||||
char buf[256];
|
||||
unsigned long e;
|
||||
|
||||
e = ERR_get_error ();
|
||||
if (e == 0)
|
||||
return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"unexpected OpenSSL error");
|
||||
|
||||
ERR_error_string_n (e, buf, G_N_ELEMENTS (buf));
|
||||
|
||||
return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "OpenSSL error: %s",
|
||||
buf);
|
||||
}
|
||||
|
||||
static void
|
||||
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
unsigned char respdata[CR_LENGTH];
|
||||
PK11Context *ctx;
|
||||
unsigned char respdata[CR_LENGTH * 2];
|
||||
int outlen;
|
||||
|
||||
if (error)
|
||||
@@ -261,17 +274,39 @@ challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *
|
||||
return;
|
||||
}
|
||||
|
||||
if (transfer->actual_length != CR_LENGTH)
|
||||
{
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Unexpected buffer length (%" G_GSIZE_FORMAT
|
||||
"instead of %d)",
|
||||
transfer->actual_length, CR_LENGTH);
|
||||
fpi_ssm_mark_failed (ssm, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* submit response */
|
||||
/* produce response from challenge */
|
||||
ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT,
|
||||
self->symkey, self->param);
|
||||
if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess ||
|
||||
PK11_Finalize (ctx) != SECSuccess)
|
||||
if (!EVP_EncryptUpdate (self->cipher_ctx, respdata, &outlen, transfer->buffer, CR_LENGTH))
|
||||
{
|
||||
fp_err ("Failed to encrypt challenge data");
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data");
|
||||
fpi_ssm_mark_failed (ssm, openssl_device_error ());
|
||||
return;
|
||||
}
|
||||
|
||||
if (outlen != CR_LENGTH)
|
||||
{
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Unexpected encrypted buffer length (%d"
|
||||
"instead of %d)",
|
||||
outlen, CR_LENGTH);
|
||||
fpi_ssm_mark_failed (ssm, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EVP_EncryptFinal_ex (self->cipher_ctx, respdata + outlen, &outlen))
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, openssl_device_error ());
|
||||
return;
|
||||
}
|
||||
PK11_DestroyContext (ctx, PR_TRUE);
|
||||
|
||||
if (!error)
|
||||
write_regs (FP_IMAGE_DEVICE (dev), REG_RESPONSE, CR_LENGTH, respdata, response_cb, ssm);
|
||||
@@ -703,9 +738,9 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||
|
||||
case IMAGING_DECODE:
|
||||
key = self->last_reg_rd[0];
|
||||
key |= self->last_reg_rd[1] << 8;
|
||||
key |= self->last_reg_rd[2] << 16;
|
||||
key |= self->last_reg_rd[3] << 24;
|
||||
key |= (uint32_t) self->last_reg_rd[1] << 8;
|
||||
key |= (uint32_t) self->last_reg_rd[2] << 16;
|
||||
key |= (uint32_t) self->last_reg_rd[3] << 24;
|
||||
key ^= self->img_enc_seed;
|
||||
|
||||
fp_dbg ("encryption id %02x -> key %08x", img->key_number, key);
|
||||
@@ -1270,8 +1305,6 @@ dev_init (FpImageDevice *dev)
|
||||
g_autoptr(GPtrArray) interfaces = NULL;
|
||||
GUsbInterface *iface = NULL;
|
||||
guint64 driver_data;
|
||||
SECStatus rv;
|
||||
SECItem item;
|
||||
int i;
|
||||
|
||||
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
|
||||
@@ -1343,25 +1376,11 @@ dev_init (FpImageDevice *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable loading p11-kit's user configuration */
|
||||
g_setenv ("P11_KIT_NO_USER_CONFIG", "1", TRUE);
|
||||
|
||||
/* Initialise NSS early */
|
||||
rv = NSS_NoDB_Init (".");
|
||||
if (rv != SECSuccess)
|
||||
{
|
||||
fp_err ("could not initialise NSS");
|
||||
fpi_image_device_open_complete (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Could not initialise NSS"));
|
||||
return;
|
||||
}
|
||||
|
||||
self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
g_clear_pointer (&self->rand, g_rand_free);
|
||||
self->rand = g_rand_new ();
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (FP_DEVICE (dev)))
|
||||
g_rand_set_seed (self->rand, 0xFACADE);
|
||||
|
||||
driver_data = fpi_device_get_driver_data (FP_DEVICE (dev));
|
||||
@@ -1369,35 +1388,17 @@ dev_init (FpImageDevice *dev)
|
||||
self->interface = g_usb_interface_get_number (iface);
|
||||
|
||||
/* Set up encryption */
|
||||
self->cipher = CKM_AES_ECB;
|
||||
self->slot = PK11_GetBestSlot (self->cipher, NULL);
|
||||
if (self->slot == NULL)
|
||||
if (!(self->cipher_ctx = EVP_CIPHER_CTX_new ()))
|
||||
{
|
||||
fp_err ("could not get encryption slot");
|
||||
fpi_image_device_open_complete (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Could not get encryption slot"));
|
||||
fpi_image_device_open_complete (dev, openssl_device_error ());
|
||||
return;
|
||||
}
|
||||
item.type = siBuffer;
|
||||
item.data = (unsigned char *) crkey;
|
||||
item.len = sizeof (crkey);
|
||||
self->symkey = PK11_ImportSymKey (self->slot,
|
||||
self->cipher,
|
||||
PK11_OriginUnwrap,
|
||||
CKA_ENCRYPT,
|
||||
&item, NULL);
|
||||
if (self->symkey == NULL)
|
||||
|
||||
if (!EVP_EncryptInit_ex (self->cipher_ctx, EVP_aes_128_ecb (), NULL, crkey, NULL))
|
||||
{
|
||||
fp_err ("failed to import key into NSS");
|
||||
PK11_FreeSlot (self->slot);
|
||||
self->slot = NULL;
|
||||
fpi_image_device_open_complete (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Failed to import key into NSS"));
|
||||
fpi_image_device_open_complete (dev, openssl_device_error ());
|
||||
return;
|
||||
}
|
||||
self->param = PK11_ParamFromIV (self->cipher, NULL);
|
||||
|
||||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
@@ -1408,14 +1409,7 @@ dev_deinit (FpImageDevice *dev)
|
||||
GError *error = NULL;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (self->symkey)
|
||||
PK11_FreeSymKey (self->symkey);
|
||||
if (self->param)
|
||||
SECITEM_FreeItem (self->param, PR_TRUE);
|
||||
if (self->slot)
|
||||
PK11_FreeSlot (self->slot);
|
||||
|
||||
NSS_Shutdown ();
|
||||
g_clear_pointer (&self->cipher_ctx, EVP_CIPHER_CTX_free);
|
||||
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||
self->interface, 0, &error);
|
||||
|
||||
@@ -119,7 +119,7 @@ async_abort_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
|
||||
/* In normal case endpoint is empty */
|
||||
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) ||
|
||||
(g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0 && transfer->actual_length == 0))
|
||||
(fpi_device_emulation_mode_enabled (device) && transfer->actual_length == 0))
|
||||
{
|
||||
g_clear_error (&error);
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
|
||||
@@ -162,9 +162,9 @@ enum {
|
||||
|
||||
/* Dump buffer for debug */
|
||||
#define dump_buffer(buf) \
|
||||
fp_dbg ("%02x %02x %02x %02x %02x %02x %02x %02x", \
|
||||
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13] \
|
||||
)
|
||||
fp_dbg ("%02x %02x %02x %02x %02x %02x %02x %02x", \
|
||||
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13] \
|
||||
)
|
||||
|
||||
/* Callback of asynchronous send */
|
||||
static void
|
||||
|
||||
@@ -157,7 +157,7 @@ vfs301_proto_generate_0B (int subtype, gssize *len)
|
||||
}
|
||||
|
||||
#define HEX_TO_INT(c) \
|
||||
(((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10))
|
||||
(((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10))
|
||||
|
||||
static guint8 *
|
||||
translate_str (const char **srcL, gssize *len)
|
||||
@@ -422,15 +422,15 @@ img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int l
|
||||
/************************** PROTOCOL STUFF ************************************/
|
||||
|
||||
#define USB_RECV(from, len) \
|
||||
usb_recv (dev, from, len, NULL, NULL)
|
||||
usb_recv (dev, from, len, NULL, NULL)
|
||||
|
||||
#define USB_SEND(type, subtype) \
|
||||
{ \
|
||||
const guint8 *data; \
|
||||
gssize len; \
|
||||
data = vfs301_proto_generate (type, subtype, &len); \
|
||||
usb_send (dev, data, len, NULL); \
|
||||
}
|
||||
{ \
|
||||
const guint8 *data; \
|
||||
gssize len; \
|
||||
data = vfs301_proto_generate (type, subtype, &len); \
|
||||
usb_send (dev, data, len, NULL); \
|
||||
}
|
||||
|
||||
#define RAW_DATA(x) g_memdup2 (x, sizeof (x)), sizeof (x)
|
||||
|
||||
@@ -489,13 +489,13 @@ vfs301_proto_peek_event (FpDeviceVfs301 *dev)
|
||||
* we will run into timeouts randomly and need to then try again.
|
||||
*/
|
||||
#define PARALLEL_RECEIVE(e1, l1, e2, l2) \
|
||||
{ \
|
||||
g_autoptr(GError) error = NULL; \
|
||||
usb_recv (dev, e1, l1, NULL, &error); \
|
||||
usb_recv (dev, e2, l2, NULL, NULL); \
|
||||
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
|
||||
usb_recv (dev, e1, l1, NULL, NULL); \
|
||||
}
|
||||
{ \
|
||||
g_autoptr(GError) error = NULL; \
|
||||
usb_recv (dev, e1, l1, NULL, &error); \
|
||||
usb_recv (dev, e2, l2, NULL, NULL); \
|
||||
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
|
||||
usb_recv (dev, e1, l1, NULL, NULL); \
|
||||
}
|
||||
|
||||
static void
|
||||
vfs301_proto_process_event_cb (FpiUsbTransfer *transfer,
|
||||
|
||||
+20
-20
@@ -41,30 +41,30 @@ struct usb_action
|
||||
};
|
||||
|
||||
#define SEND(ENDPOINT, COMMAND) \
|
||||
{ \
|
||||
.type = ACTION_SEND, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.name = #COMMAND, \
|
||||
.size = sizeof (COMMAND), \
|
||||
.data = COMMAND \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_SEND, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.name = #COMMAND, \
|
||||
.size = sizeof (COMMAND), \
|
||||
.data = COMMAND \
|
||||
},
|
||||
|
||||
#define RECV(ENDPOINT, SIZE) \
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL \
|
||||
},
|
||||
|
||||
#define RECV_CHECK(ENDPOINT, SIZE, EXPECTED) \
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = EXPECTED, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = EXPECTED, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
|
||||
struct usbexchange_data
|
||||
{
|
||||
|
||||
+27
-27
@@ -51,39 +51,39 @@ struct usb_action
|
||||
};
|
||||
|
||||
#define SEND(ENDPOINT, COMMAND) \
|
||||
{ \
|
||||
.type = ACTION_SEND, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.name = #COMMAND, \
|
||||
.size = sizeof (COMMAND), \
|
||||
.data = COMMAND \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_SEND, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.name = #COMMAND, \
|
||||
.size = sizeof (COMMAND), \
|
||||
.data = COMMAND \
|
||||
},
|
||||
|
||||
#define RECV(ENDPOINT, SIZE) \
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL \
|
||||
},
|
||||
|
||||
#define RECV_CHECK(ENDPOINT, SIZE, EXPECTED) \
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = EXPECTED, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = EXPECTED, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
|
||||
#define RECV_CHECK_SIZE(ENDPOINT, SIZE, EXPECTED) \
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
{ \
|
||||
.type = ACTION_RECEIVE, \
|
||||
.endpoint = ENDPOINT, \
|
||||
.size = SIZE, \
|
||||
.data = NULL, \
|
||||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
|
||||
struct usbexchange_data
|
||||
{
|
||||
|
||||
@@ -77,6 +77,7 @@ dev_identify (FpDevice *dev)
|
||||
&idx))
|
||||
{
|
||||
match = g_ptr_array_index (prints, idx);
|
||||
fp_print_set_finger (new_scan, fp_print_get_finger (match));
|
||||
}
|
||||
|
||||
if (!self->match_reported)
|
||||
|
||||
@@ -165,11 +165,7 @@ process_cmds (FpDeviceVirtualDevice * self,
|
||||
{
|
||||
g_autofree gchar *cmd = NULL;
|
||||
|
||||
/* TODO: g_ptr_array_steal_index requires GLib 2.58, we depend on 2.56 */
|
||||
cmd = g_ptr_array_index (self->pending_commands, 0);
|
||||
g_ptr_array_index (self->pending_commands, 0) = NULL;
|
||||
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||
|
||||
cmd = g_ptr_array_steal_index (self->pending_commands, 0);
|
||||
g_debug ("Processing command %s", cmd);
|
||||
|
||||
/* These are always processed. */
|
||||
@@ -549,6 +545,9 @@ dev_verify (FpDevice *dev)
|
||||
else
|
||||
{
|
||||
success = fp_print_equal (print, new_scan);
|
||||
|
||||
if (success)
|
||||
fp_print_set_finger (new_scan, fp_print_get_finger (print));
|
||||
}
|
||||
|
||||
if (!self->match_reported)
|
||||
@@ -772,6 +771,7 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
const char *hot_seconds;
|
||||
|
||||
object_class->finalize = fpi_device_virtual_device_finalize;
|
||||
|
||||
@@ -787,5 +787,18 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||
dev_class->enroll = dev_enroll;
|
||||
dev_class->cancel = dev_cancel;
|
||||
|
||||
if ((hot_seconds = g_getenv ("FP_VIRTUAL_DEVICE_HOT_SECONDS")) &&
|
||||
*hot_seconds != '\0')
|
||||
{
|
||||
gint64 hot_seconds_value;
|
||||
|
||||
hot_seconds_value = g_ascii_strtoll (hot_seconds, NULL, 10);
|
||||
if (hot_seconds_value >= G_MAXINT32 || hot_seconds_value < 0)
|
||||
hot_seconds_value = -1;
|
||||
|
||||
dev_class->temp_hot_seconds = hot_seconds_value;
|
||||
g_debug ("device hot seconds set to %d", dev_class->temp_hot_seconds);
|
||||
}
|
||||
|
||||
fpi_device_class_auto_initialize_features (dev_class);
|
||||
}
|
||||
|
||||
@@ -191,12 +191,12 @@ on_listener_connected (FpiDeviceVirtualListener *listener,
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||
recv_image (self);
|
||||
|
||||
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
||||
case FPI_IMAGE_DEVICE_STATE_ACTIVATING:
|
||||
case FPI_IMAGE_DEVICE_STATE_DEACTIVATING:
|
||||
@@ -310,6 +310,7 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
const char *hot_seconds;
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual image device for debugging";
|
||||
@@ -321,4 +322,17 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||
|
||||
img_class->activate = dev_activate;
|
||||
img_class->deactivate = dev_deactivate;
|
||||
|
||||
if ((hot_seconds = g_getenv ("FP_VIRTUAL_IMAGE_HOT_SECONDS")) &&
|
||||
*hot_seconds != '\0')
|
||||
{
|
||||
gint64 hot_seconds_value;
|
||||
|
||||
hot_seconds_value = g_ascii_strtoll (hot_seconds, NULL, 10);
|
||||
if (hot_seconds_value >= G_MAXINT32 || hot_seconds_value < 0)
|
||||
hot_seconds_value = -1;
|
||||
|
||||
dev_class->temp_hot_seconds = hot_seconds_value;
|
||||
g_debug ("device hot seconds set to %d", dev_class->temp_hot_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "fpi-compat.h"
|
||||
#include "fpi-enums.h"
|
||||
#include "fpi-assembling.h"
|
||||
#include "fpi-device.h"
|
||||
#include "fpi-image-device.h"
|
||||
|
||||
+15
-12
@@ -292,14 +292,14 @@ fp_device_get_property (GObject *object,
|
||||
|
||||
case PROP_FPI_UDEV_DATA_SPIDEV:
|
||||
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||
g_value_set_string (value, g_strdup (priv->udev_data.spidev_path));
|
||||
g_value_set_string (value, priv->udev_data.spidev_path);
|
||||
else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
|
||||
case PROP_FPI_UDEV_DATA_HIDRAW:
|
||||
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||
g_value_set_string (value, g_strdup (priv->udev_data.hidraw_path));
|
||||
g_value_set_string (value, priv->udev_data.hidraw_path);
|
||||
else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
@@ -483,6 +483,9 @@ fp_device_class_init (FpDeviceClass *klass)
|
||||
NULL,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* FpDevice:open: (getter is_open):
|
||||
*/
|
||||
properties[PROP_OPEN] =
|
||||
g_param_spec_boolean ("open",
|
||||
"Opened",
|
||||
@@ -1103,8 +1106,8 @@ enroll_data_free (FpEnrollData *data)
|
||||
* @device: a #FpDevice
|
||||
* @template_print: (transfer floating): a #FpPrint
|
||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||
* @progress_cb: (nullable) (scope notified): progress reporting callback
|
||||
* @progress_data: (closure progress_cb): user data for @progress_cb
|
||||
* @progress_cb: (nullable) (closure progress_data) (scope notified): progress reporting callback
|
||||
* @progress_data: user data for @progress_cb
|
||||
* @progress_destroy: (destroy progress_data): Destroy notify for @progress_data
|
||||
* @callback: (scope async): the function to call on completion
|
||||
* @user_data: the data to pass to @callback
|
||||
@@ -1248,8 +1251,8 @@ match_data_free (FpMatchData *data)
|
||||
* @device: a #FpDevice
|
||||
* @enrolled_print: a #FpPrint to verify
|
||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||
* @match_data: (closure match_cb): user data for @match_cb
|
||||
* @match_cb: (nullable) (scope notified) (closure match_data): match reporting callback
|
||||
* @match_data: user data for @match_cb
|
||||
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||
* @callback: the function to call on completion
|
||||
* @user_data: the data to pass to @callback
|
||||
@@ -1374,8 +1377,8 @@ fp_device_verify_finish (FpDevice *device,
|
||||
* @device: a #FpDevice
|
||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||
* @match_data: (closure match_cb): user data for @match_cb
|
||||
* @match_cb: (nullable) (scope notified) (closure match_data): match reporting callback
|
||||
* @match_data: user data for @match_cb
|
||||
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||
* @callback: the function to call on completion
|
||||
* @user_data: the data to pass to @callback
|
||||
@@ -1943,8 +1946,8 @@ fp_device_enroll_sync (FpDevice *device,
|
||||
* @device: a #FpDevice
|
||||
* @enrolled_print: a #FpPrint to verify
|
||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||
* @match_cb: (nullable) (scope call): match reporting callback
|
||||
* @match_data: (closure match_cb): user data for @match_cb
|
||||
* @match_cb: (nullable) (scope call) (closure match_data): match reporting callback
|
||||
* @match_data: user data for @match_cb
|
||||
* @match: (out): Whether the user presented the correct finger
|
||||
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
|
||||
* @error: Return location for errors, or %NULL to ignore
|
||||
@@ -1983,8 +1986,8 @@ fp_device_verify_sync (FpDevice *device,
|
||||
* @device: a #FpDevice
|
||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||
* @match_cb: (nullable) (scope call): match reporting callback
|
||||
* @match_data: (closure match_cb): user data for @match_cb
|
||||
* @match_cb: (nullable) (scope call) (closure match_data): match reporting callback
|
||||
* @match_data: user data for @match_cb
|
||||
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
|
||||
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
|
||||
* @error: Return location for errors, or %NULL to ignore
|
||||
|
||||
@@ -113,6 +113,8 @@ typedef enum {
|
||||
* @FP_DEVICE_RETRY_REMOVE_FINGER: The scan did not succeed due to quality or
|
||||
* pressure problems; the user should remove their finger from the scanner
|
||||
* before retrying.
|
||||
* @FP_DEVICE_RETRY_TOO_FAST: The scan did not succeed because the finger
|
||||
* swipe or touch was too fast.
|
||||
*
|
||||
* Error codes representing scan failures resulting in the user needing to
|
||||
* retry.
|
||||
@@ -122,6 +124,7 @@ typedef enum {
|
||||
FP_DEVICE_RETRY_TOO_SHORT,
|
||||
FP_DEVICE_RETRY_CENTER_FINGER,
|
||||
FP_DEVICE_RETRY_REMOVE_FINGER,
|
||||
FP_DEVICE_RETRY_TOO_FAST,
|
||||
} FpDeviceRetry;
|
||||
|
||||
/**
|
||||
|
||||
+77
-73
@@ -605,18 +605,16 @@ fp_print_equal (FpPrint *self, FpPrint *other)
|
||||
if (g_strcmp0 (self->device_id, other->device_id))
|
||||
return FALSE;
|
||||
|
||||
if (self->type == FPI_PRINT_RAW)
|
||||
switch (self->type)
|
||||
{
|
||||
case FPI_PRINT_RAW:
|
||||
return g_variant_equal (self->data, other->data);
|
||||
}
|
||||
else if (self->type == FPI_PRINT_NBIS)
|
||||
{
|
||||
guint i;
|
||||
|
||||
case FPI_PRINT_NBIS:
|
||||
if (self->prints->len != other->prints->len)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < self->prints->len; i++)
|
||||
for (guint i = 0; i < self->prints->len; i++)
|
||||
{
|
||||
struct xyt_struct *a = g_ptr_array_index (self->prints, i);
|
||||
struct xyt_struct *b = g_ptr_array_index (other->prints, i);
|
||||
@@ -626,11 +624,12 @@ fp_print_equal (FpPrint *self, FpPrint *other)
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
case FPI_PRINT_UNDEFINED:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
#define FPI_PRINT_VARIANT_TYPE G_VARIANT_TYPE ("(issbymsmsia{sv}v)")
|
||||
@@ -765,7 +764,7 @@ fp_print_deserialize (const guchar *data,
|
||||
g_autoptr(GVariant) value = NULL;
|
||||
g_autoptr(GVariant) print_data = NULL;
|
||||
g_autoptr(GDate) date = NULL;
|
||||
guchar *aligned_data = NULL;
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
guint8 finger_int8;
|
||||
FpFinger finger;
|
||||
g_autofree gchar *username = NULL;
|
||||
@@ -787,14 +786,10 @@ fp_print_deserialize (const guchar *data,
|
||||
* of this function (meaning we don't need to keep the data around.
|
||||
*/
|
||||
|
||||
/* To support GLIB < 2.60 we need to make sure that the memory is aligned correctly.
|
||||
* We also need to copy the backing store for the raw data that we may keep for
|
||||
* longer. */
|
||||
aligned_data = g_malloc (length - 3);
|
||||
memcpy (aligned_data, data + 3, length - 3);
|
||||
raw_value = g_variant_new_from_data (FPI_PRINT_VARIANT_TYPE,
|
||||
aligned_data, length - 3,
|
||||
FALSE, g_free, aligned_data);
|
||||
/* We need to copy the backing store for the raw data that we may keep for
|
||||
* longer. Using a GBytes also ensures the data is correctly aligned. */
|
||||
bytes = g_bytes_new (data + 3, length - 3);
|
||||
raw_value = g_variant_new_from_bytes (FPI_PRINT_VARIANT_TYPE, bytes, FALSE);
|
||||
|
||||
if (!raw_value)
|
||||
goto invalid_format;
|
||||
@@ -821,72 +816,81 @@ fp_print_deserialize (const guchar *data,
|
||||
finger = finger_int8;
|
||||
|
||||
/* Assume data is valid at this point if the values are somewhat sane. */
|
||||
if (type == FPI_PRINT_NBIS)
|
||||
switch (type)
|
||||
{
|
||||
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
|
||||
guint i;
|
||||
case FPI_PRINT_NBIS:
|
||||
{
|
||||
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
|
||||
guint i;
|
||||
|
||||
result = g_object_new (FP_TYPE_PRINT,
|
||||
"driver", driver,
|
||||
"device-id", device_id,
|
||||
"device-stored", device_stored,
|
||||
NULL);
|
||||
g_object_ref_sink (result);
|
||||
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
||||
for (i = 0; i < g_variant_n_children (prints); i++)
|
||||
{
|
||||
g_autofree struct xyt_struct *xyt = NULL;
|
||||
const gint32 *xcol, *ycol, *thetacol;
|
||||
gsize xlen, ylen, thetalen;
|
||||
g_autoptr(GVariant) xyt_data = NULL;
|
||||
GVariant *child;
|
||||
result = g_object_new (FP_TYPE_PRINT,
|
||||
"driver", driver,
|
||||
"device-id", device_id,
|
||||
"device-stored", device_stored,
|
||||
NULL);
|
||||
g_object_ref_sink (result);
|
||||
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
||||
for (i = 0; i < g_variant_n_children (prints); i++)
|
||||
{
|
||||
g_autofree struct xyt_struct *xyt = NULL;
|
||||
const gint32 *xcol, *ycol, *thetacol;
|
||||
gsize xlen, ylen, thetalen;
|
||||
g_autoptr(GVariant) xyt_data = NULL;
|
||||
GVariant *child;
|
||||
|
||||
xyt_data = g_variant_get_child_value (prints, i);
|
||||
xyt_data = g_variant_get_child_value (prints, i);
|
||||
|
||||
child = g_variant_get_child_value (xyt_data, 0);
|
||||
xcol = g_variant_get_fixed_array (child, &xlen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
child = g_variant_get_child_value (xyt_data, 0);
|
||||
xcol = g_variant_get_fixed_array (child, &xlen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
|
||||
child = g_variant_get_child_value (xyt_data, 1);
|
||||
ycol = g_variant_get_fixed_array (child, &ylen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
child = g_variant_get_child_value (xyt_data, 1);
|
||||
ycol = g_variant_get_fixed_array (child, &ylen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
|
||||
child = g_variant_get_child_value (xyt_data, 2);
|
||||
thetacol = g_variant_get_fixed_array (child, &thetalen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
child = g_variant_get_child_value (xyt_data, 2);
|
||||
thetacol = g_variant_get_fixed_array (child, &thetalen, sizeof (gint32));
|
||||
g_variant_unref (child);
|
||||
|
||||
if (xlen != ylen || xlen != thetalen)
|
||||
goto invalid_format;
|
||||
if (xlen != ylen || xlen != thetalen)
|
||||
goto invalid_format;
|
||||
|
||||
if (xlen > G_N_ELEMENTS (xyt->xcol))
|
||||
goto invalid_format;
|
||||
if (xlen > G_N_ELEMENTS (xyt->xcol))
|
||||
goto invalid_format;
|
||||
|
||||
xyt = g_new0 (struct xyt_struct, 1);
|
||||
xyt->nrows = xlen;
|
||||
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
|
||||
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
|
||||
memcpy (xyt->thetacol, thetacol, sizeof (xcol[0]) * xlen);
|
||||
xyt = g_new0 (struct xyt_struct, 1);
|
||||
xyt->nrows = xlen;
|
||||
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
|
||||
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
|
||||
memcpy (xyt->thetacol, thetacol, sizeof (xcol[0]) * xlen);
|
||||
|
||||
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
|
||||
}
|
||||
}
|
||||
else if (type == FPI_PRINT_RAW)
|
||||
{
|
||||
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
|
||||
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
result = g_object_new (FP_TYPE_PRINT,
|
||||
"fpi-type", type,
|
||||
"driver", driver,
|
||||
"device-id", device_id,
|
||||
"device-stored", device_stored,
|
||||
"fpi-data", fp_data,
|
||||
NULL);
|
||||
g_object_ref_sink (result);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Invalid print type: 0x%X", type);
|
||||
goto invalid_format;
|
||||
case FPI_PRINT_RAW:
|
||||
{
|
||||
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
|
||||
|
||||
result = g_object_new (FP_TYPE_PRINT,
|
||||
"fpi-type", type,
|
||||
"driver", driver,
|
||||
"device-id", device_id,
|
||||
"device-stored", device_stored,
|
||||
"fpi-data", fp_data,
|
||||
NULL);
|
||||
g_object_ref_sink (result);
|
||||
}
|
||||
break;
|
||||
|
||||
case FPI_PRINT_UNDEFINED:
|
||||
{
|
||||
g_autofree char *type_str = g_enum_to_string (fpi_print_type_get_type (), type);
|
||||
g_warning ("Invalid print type: 0x%X (%s)", type, type_str);
|
||||
|
||||
goto invalid_format;
|
||||
}
|
||||
}
|
||||
|
||||
date = g_date_new_julian (julian_date);
|
||||
|
||||
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (FpPrint, fp_print, FP, PRINT, GInitiallyUnowned)
|
||||
|
||||
#define FP_FINGER_IS_VALID(finger) \
|
||||
((finger) >= FP_FINGER_FIRST && (finger) <= FP_FINGER_LAST)
|
||||
((finger) >= FP_FINGER_FIRST && (finger) <= FP_FINGER_LAST)
|
||||
|
||||
#include "fp-device.h"
|
||||
|
||||
|
||||
@@ -65,6 +65,31 @@ fpi_byte_reader_new (const guint8 * data, guint size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_new_bytes: (skip)
|
||||
* @bytes: (in) (transfer none): a #GBytes instance from which the
|
||||
* #FpiByteReader should read
|
||||
*
|
||||
* Create a new #FpiByteReader instance, which will read from @bytes.
|
||||
*
|
||||
* Free-function: fpi_byte_reader_free
|
||||
*
|
||||
* Returns: (transfer full): a new #FpiByteReader instance
|
||||
*/
|
||||
FpiByteReader *
|
||||
fpi_byte_reader_new_bytes (GBytes * bytes)
|
||||
{
|
||||
const guint8 *data;
|
||||
gsize size = 0;
|
||||
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
|
||||
data = g_bytes_get_data (bytes, &size);
|
||||
g_return_val_if_fail (size <= G_MAXUINT, NULL);
|
||||
|
||||
return fpi_byte_reader_new (data, (guint) size);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_free:
|
||||
* @reader: (in) (transfer full): a #FpiByteReader instance
|
||||
@@ -100,6 +125,30 @@ fpi_byte_reader_init (FpiByteReader * reader, const guint8 * data, guint size)
|
||||
reader->byte = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_init_bytes:
|
||||
* @reader: a #FpiByteReader instance
|
||||
* @bytes: (in) (transfer none): a #GBytes instance from which
|
||||
* the #FpiByteReader should read
|
||||
*
|
||||
* Initializes a #FpiByteReader instance to read from @bytes. This function
|
||||
* can be called on already initialized instances.
|
||||
*/
|
||||
FpiByteReader *
|
||||
fpi_byte_reader_init_bytes (FpiByteReader * reader, GBytes * bytes)
|
||||
{
|
||||
g_return_val_if_fail (reader != NULL, NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
|
||||
gsize size = 0;
|
||||
const guint8 *data = g_bytes_get_data (bytes, &size);
|
||||
|
||||
g_return_val_if_fail (size <= G_MAXUINT, NULL);
|
||||
fpi_byte_reader_init (reader, data, (guint) size);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_peek_sub_reader: (skip)
|
||||
* @reader: an existing and initialized #FpiByteReader instance
|
||||
@@ -799,6 +848,41 @@ fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size,
|
||||
return fpi_byte_reader_peek_data_inline (reader, size, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_get_data_fixed:
|
||||
* @reader: a #FpiByteReader instance
|
||||
* @size: Size in bytes
|
||||
* @val: (out) (array length=size): address of a buffer to copy data into
|
||||
*
|
||||
* Copies @size bytes from the current data position into @val if at
|
||||
* least @size bytes are left, and updates the current position.
|
||||
*
|
||||
* Returns: %TRUE if successful, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
(fpi_byte_reader_get_data_static) (FpiByteReader * reader, guint size,
|
||||
const guint8 * val)
|
||||
{
|
||||
return (fpi_byte_reader_get_data_inline_static) (reader, size, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_peek_data_fixed:
|
||||
* @reader: a #FpiByteReader instance
|
||||
* @size: Size in bytes
|
||||
* @val: (out) (array length=size): address of a buffer to copy data into
|
||||
*
|
||||
* Like fpi_byte_reader_get_data_fixed() but does not advance the position.
|
||||
*
|
||||
* Returns: %TRUE if successful, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
(fpi_byte_reader_peek_data_static) (const FpiByteReader * reader, guint size,
|
||||
guint8 * val)
|
||||
{
|
||||
return (fpi_byte_reader_peek_data_inline_static) (reader, size, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_dup_data:
|
||||
* @reader: a #FpiByteReader instance
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef struct {
|
||||
|
||||
FpiByteReader * fpi_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
|
||||
|
||||
FpiByteReader * fpi_byte_reader_new_bytes (GBytes *bytes) G_GNUC_MALLOC;
|
||||
|
||||
void fpi_byte_reader_free (FpiByteReader *reader);
|
||||
|
||||
@@ -57,6 +58,9 @@ void fpi_byte_reader_free (FpiByteReader *reader);
|
||||
void fpi_byte_reader_init (FpiByteReader *reader, const guint8 *data, guint size);
|
||||
|
||||
|
||||
FpiByteReader * fpi_byte_reader_init_bytes (FpiByteReader *reader, GBytes *bytes);
|
||||
|
||||
|
||||
gboolean fpi_byte_reader_peek_sub_reader (FpiByteReader * reader,
|
||||
FpiByteReader * sub_reader,
|
||||
guint size);
|
||||
@@ -218,8 +222,21 @@ gboolean fpi_byte_reader_dup_data (FpiByteReader * reader, guint s
|
||||
gboolean fpi_byte_reader_get_data (FpiByteReader * reader, guint size, const guint8 ** val);
|
||||
|
||||
|
||||
gboolean fpi_byte_reader_get_data_static (FpiByteReader * reader, guint size, const guint8 * val);
|
||||
|
||||
|
||||
gboolean fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, const guint8 ** val);
|
||||
|
||||
|
||||
gboolean fpi_byte_reader_peek_data_static (const FpiByteReader * reader, guint size, guint8 * val);
|
||||
|
||||
|
||||
GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size);
|
||||
|
||||
|
||||
GBytes * fpi_byte_reader_peek_bytes (const FpiByteReader *reader, guint size);
|
||||
|
||||
|
||||
#define fpi_byte_reader_dup_string(reader,str) \
|
||||
fpi_byte_reader_dup_string_utf8(reader,str)
|
||||
|
||||
@@ -642,6 +659,60 @@ fpi_byte_reader_peek_data_inline (const FpiByteReader * reader, guint size, cons
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline GBytes *
|
||||
fpi_byte_reader_peek_bytes_inline (const FpiByteReader *reader, guint size)
|
||||
{
|
||||
const guint8 *data;
|
||||
|
||||
g_return_val_if_fail (reader != NULL, NULL);
|
||||
|
||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
||||
return NULL;
|
||||
|
||||
data = fpi_byte_reader_peek_data_unchecked (reader);
|
||||
return g_bytes_new_static (data, size);
|
||||
}
|
||||
|
||||
static inline GBytes *
|
||||
fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size)
|
||||
{
|
||||
const guint8 *data;
|
||||
|
||||
g_return_val_if_fail (reader != NULL, NULL);
|
||||
|
||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
||||
return NULL;
|
||||
|
||||
data = fpi_byte_reader_get_data_unchecked (reader, size);
|
||||
return g_bytes_new_static (data, size);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
(fpi_byte_reader_get_data_inline_static) (FpiByteReader * reader, guint size, const guint8 * val)
|
||||
{
|
||||
g_return_val_if_fail (reader != NULL, FALSE);
|
||||
g_return_val_if_fail (val != NULL, FALSE);
|
||||
|
||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
||||
return FALSE;
|
||||
|
||||
memcpy ((void *) val, fpi_byte_reader_get_data_unchecked (reader, size), size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
(fpi_byte_reader_peek_data_inline_static) (const FpiByteReader * reader, guint size, guint8 * val)
|
||||
{
|
||||
g_return_val_if_fail (reader != NULL, FALSE);
|
||||
g_return_val_if_fail (val != NULL, FALSE);
|
||||
|
||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
||||
return FALSE;
|
||||
|
||||
memcpy (val, fpi_byte_reader_peek_data_unchecked (reader), size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline guint
|
||||
fpi_byte_reader_get_pos_inline (const FpiByteReader * reader)
|
||||
{
|
||||
@@ -672,7 +743,38 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes)
|
||||
G_LIKELY(fpi_byte_reader_peek_data_inline(reader,size,val))
|
||||
#define fpi_byte_reader_skip(reader,nbytes) \
|
||||
G_LIKELY(fpi_byte_reader_skip_inline(reader,nbytes))
|
||||
#define fpi_byte_reader_get_bytes(reader,size) \
|
||||
fpi_byte_reader_get_bytes_inline(reader,size)
|
||||
#define fpi_byte_reader_peek_bytes(reader,size) \
|
||||
fpi_byte_reader_peek_bytes_inline(reader,size)
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_get_data_static:
|
||||
* @reader: a #FpiByteReader
|
||||
* @val: fixed-size array (e.g. `uint8_t buf[32]`)
|
||||
*
|
||||
* Reads @size bytes from @reader directly into @val, where @size is
|
||||
* deduced via `sizeof()` - only safe with true C arrays.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE otherwise.
|
||||
*/
|
||||
#define fpi_byte_reader_get_data_static(reader,val) \
|
||||
(fpi_byte_reader_get_data_static) (reader,sizeof(val),val)
|
||||
|
||||
/**
|
||||
* fpi_byte_reader_peek_data_static:
|
||||
* @reader: a #FpiByteReader
|
||||
* @val: fixed-size array (e.g. `uint8_t buf[32]`)
|
||||
*
|
||||
* Like fpi_byte_reader_get_data_static() but does not advance the position.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE otherwise.
|
||||
*/
|
||||
#define fpi_byte_reader_peek_data_static(reader,val) \
|
||||
(fpi_byte_reader_peek_data_static) (reader,sizeof(val),val)
|
||||
|
||||
#endif /* FPI_BYTE_READER_DISABLE_INLINES */
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteReader, fpi_byte_reader_free);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -75,7 +75,8 @@ fpi_byte_writer_new_with_size (guint size, gboolean fixed)
|
||||
FpiByteWriter *ret = fpi_byte_writer_new ();
|
||||
|
||||
ret->alloc_size = size;
|
||||
ret->parent.data = g_malloc (ret->alloc_size);
|
||||
ret->parent.data = g_malloc0 (ret->alloc_size);
|
||||
ret->parent.size = size;
|
||||
ret->fixed = fixed;
|
||||
ret->owned = TRUE;
|
||||
|
||||
@@ -142,7 +143,8 @@ fpi_byte_writer_init_with_size (FpiByteWriter * writer, guint size,
|
||||
|
||||
fpi_byte_writer_init (writer);
|
||||
|
||||
writer->parent.data = g_malloc (size);
|
||||
writer->parent.data = g_malloc0 (size);
|
||||
writer->parent.size = size;
|
||||
writer->alloc_size = size;
|
||||
writer->fixed = fixed;
|
||||
writer->owned = TRUE;
|
||||
@@ -209,15 +211,44 @@ fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer)
|
||||
|
||||
g_return_val_if_fail (writer != NULL, NULL);
|
||||
|
||||
data = (guint8 *) writer->parent.data;
|
||||
data = (guint8 *) g_steal_pointer (&writer->parent.data);
|
||||
if (!writer->owned)
|
||||
data = g_memdup2 (data, writer->parent.size);
|
||||
writer->parent.data = NULL;
|
||||
fpi_byte_writer_reset (writer);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_writer_reset_and_get_bytes:
|
||||
* @writer: #FpiByteWriter instance
|
||||
*
|
||||
* Resets @writer and returns the current data as a #GBytes.
|
||||
*
|
||||
* Returns: (transfer full): the current data as a #GBytes.
|
||||
*/
|
||||
GBytes *
|
||||
fpi_byte_writer_reset_and_get_bytes (FpiByteWriter * writer)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (writer != NULL, NULL);
|
||||
|
||||
if (!writer->owned)
|
||||
{
|
||||
bytes = g_bytes_new (g_steal_pointer (&writer->parent.data),
|
||||
writer->parent.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = g_bytes_new_take ((gpointer) g_steal_pointer (&writer->parent.data),
|
||||
writer->parent.size);
|
||||
}
|
||||
|
||||
fpi_byte_writer_reset (writer);
|
||||
return g_steal_pointer (&bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_byte_writer_free:
|
||||
* @writer: (in) (transfer full): #FpiByteWriter instance
|
||||
@@ -601,6 +632,15 @@ CREATE_WRITE_STRING_FUNC (32, guint32);
|
||||
*
|
||||
* Returns: %TRUE if the value could be written
|
||||
*/
|
||||
/**
|
||||
* fpi_byte_writer_put_bytes:
|
||||
* @writer: #FpiByteWriter instance
|
||||
* @bytes: (transfer none): Data to write
|
||||
*
|
||||
* Writes the contents of @bytes to @writer.
|
||||
*
|
||||
* Returns: %TRUE if the value could be written
|
||||
*/
|
||||
/**
|
||||
* fpi_byte_writer_fill:
|
||||
* @writer: #FpiByteWriter instance
|
||||
|
||||
@@ -77,6 +77,9 @@ void fpi_byte_writer_reset (FpiByteWriter *writer);
|
||||
|
||||
guint8 * fpi_byte_writer_reset_and_get_data (FpiByteWriter *writer);
|
||||
|
||||
|
||||
GBytes * fpi_byte_writer_reset_and_get_bytes (FpiByteWriter *writer);
|
||||
|
||||
/**
|
||||
* fpi_byte_writer_get_pos:
|
||||
* @writer: #FpiByteWriter instance
|
||||
@@ -111,6 +114,17 @@ fpi_byte_writer_set_pos (FpiByteWriter *writer, guint pos)
|
||||
return fpi_byte_reader_set_pos (FPI_BYTE_READER (writer), pos);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
fpi_byte_writer_change_pos (FpiByteWriter *writer, gint pos)
|
||||
{
|
||||
pos = fpi_byte_writer_get_pos (writer) + pos;
|
||||
|
||||
if (pos < 0)
|
||||
return FALSE;
|
||||
|
||||
return fpi_byte_reader_set_pos (FPI_BYTE_READER (writer), pos);
|
||||
}
|
||||
|
||||
static inline guint
|
||||
fpi_byte_writer_get_size (const FpiByteWriter *writer)
|
||||
{
|
||||
@@ -193,6 +207,9 @@ gboolean fpi_byte_writer_put_float64_le (FpiByteWriter *writer, gdoubl
|
||||
gboolean fpi_byte_writer_put_data (FpiByteWriter *writer, const guint8 *data, guint size);
|
||||
|
||||
|
||||
gboolean fpi_byte_writer_put_bytes (FpiByteWriter *writer, const GBytes *bytes);
|
||||
|
||||
|
||||
gboolean fpi_byte_writer_fill (FpiByteWriter *writer, guint8 value, guint size);
|
||||
|
||||
|
||||
@@ -327,6 +344,18 @@ fpi_byte_writer_put_data_inline (FpiByteWriter * writer, const guint8 * data,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
fpi_byte_writer_put_bytes_inline (FpiByteWriter * writer, const GBytes * bytes)
|
||||
{
|
||||
g_return_val_if_fail (writer != NULL, FALSE);
|
||||
g_return_val_if_fail (bytes != NULL, FALSE);
|
||||
const guint8 *data;
|
||||
gsize size;
|
||||
|
||||
data = g_bytes_get_data ((GBytes *) bytes, &size);
|
||||
return fpi_byte_writer_put_data_inline (writer, data, size);
|
||||
}
|
||||
|
||||
static inline void
|
||||
fpi_byte_writer_fill_unchecked (FpiByteWriter * writer, guint8 value, guint size)
|
||||
{
|
||||
@@ -402,9 +431,16 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint size)
|
||||
|
||||
#define fpi_byte_writer_put_data(writer, data, size) \
|
||||
G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, size))
|
||||
#define fpi_byte_writer_put_data_static(writer, data) \
|
||||
G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, sizeof (data)))
|
||||
#define fpi_byte_writer_put_bytes(writer, bytes) \
|
||||
G_LIKELY (fpi_byte_writer_put_bytes_inline (writer, bytes))
|
||||
#define fpi_byte_writer_fill(writer, val, size) \
|
||||
G_LIKELY (fpi_byte_writer_fill_inline (writer, val, size))
|
||||
|
||||
#endif
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteWriter, fpi_byte_writer_free);
|
||||
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (FpiByteWriter, fpi_byte_writer_reset);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+100
-31
@@ -22,10 +22,12 @@
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "fp-device-private.h"
|
||||
#include "tests/fpi-test-emulation.h"
|
||||
|
||||
/**
|
||||
* SECTION: fpi-device
|
||||
@@ -50,8 +52,64 @@ fp_device_get_instance_private (FpDevice *self)
|
||||
g_type_class_get_instance_private_offset (dev_class));
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GModule, g_module_close)
|
||||
|
||||
/**
|
||||
* fpi_device_emulation_mode_enabled:
|
||||
* @device: The #FpDevice to check
|
||||
*
|
||||
* Checks if the device is running in emulation mode, which is enabled by
|
||||
* setting the FP_DEVICE_EMULATION environment variable to a '1' value but
|
||||
* only when the test emulation library is loaded.
|
||||
* This is used by some drivers to enable special behavior for testing
|
||||
* and development purposes.
|
||||
*/
|
||||
gboolean
|
||||
(fpi_device_emulation_mode_enabled) (FpDevice *device)
|
||||
{
|
||||
static gboolean (*real_fn)(FpDevice *) = NULL;
|
||||
static gsize emulation_mode = 0;
|
||||
|
||||
if (g_once_init_enter (&emulation_mode))
|
||||
{
|
||||
if (g_strcmp0 (g_getenv (FPI_EMULATION_ENV_VAR), "1") == 0)
|
||||
{
|
||||
const char *dirs[] = {
|
||||
FPI_EMULATION_HELPER_BUILDDIR,
|
||||
FPI_EMULATION_HELPER_INSTALLDIR,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (dirs); ++i)
|
||||
{
|
||||
g_autofree char *path = NULL;
|
||||
g_autoptr(GModule) mod = NULL;
|
||||
gpointer sym;
|
||||
|
||||
path = g_build_filename (dirs[i], FPI_EMULATION_HELPER_MODULE, NULL);
|
||||
if (!(mod = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL)))
|
||||
continue;
|
||||
|
||||
if (!g_module_symbol (mod, "fpi_device_emulation_mode_enabled", &sym))
|
||||
continue;
|
||||
|
||||
real_fn = (gboolean (*)(FpDevice *)) sym;
|
||||
g_steal_pointer (&mod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_once_init_leave (&emulation_mode, real_fn ? TRUE : G_MAXSIZE);
|
||||
}
|
||||
|
||||
if (real_fn)
|
||||
return real_fn (device);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_device_class_auto_initialize_features:
|
||||
* @device_class: An #FpDeviceClass to initialize
|
||||
*
|
||||
* Initializes the #FpDeviceClass @features flags checking what device vfuncs
|
||||
* are implemented.
|
||||
@@ -117,6 +175,10 @@ fpi_device_retry_new (FpDeviceRetry error)
|
||||
msg = "Please try again after removing the finger first.";
|
||||
break;
|
||||
|
||||
case FP_DEVICE_RETRY_TOO_FAST:
|
||||
msg = "The swipe was too fast, please try again.";
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Unsupported error, returning general error instead!");
|
||||
error = FP_DEVICE_RETRY_GENERAL;
|
||||
@@ -1042,34 +1104,41 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
||||
static void
|
||||
fpi_device_task_return_data_free (FpDeviceTaskReturnData *data)
|
||||
{
|
||||
if (data->result)
|
||||
switch (data->type)
|
||||
{
|
||||
switch (data->type)
|
||||
{
|
||||
case FP_DEVICE_TASK_RETURN_INT:
|
||||
case FP_DEVICE_TASK_RETURN_BOOL:
|
||||
break;
|
||||
case FP_DEVICE_TASK_RETURN_INT:
|
||||
case FP_DEVICE_TASK_RETURN_BOOL:
|
||||
break;
|
||||
|
||||
case FP_DEVICE_TASK_RETURN_OBJECT:
|
||||
g_clear_object ((GObject **) &data->result);
|
||||
break;
|
||||
case FP_DEVICE_TASK_RETURN_OBJECT:
|
||||
g_clear_object ((GObject **) &data->result);
|
||||
break;
|
||||
|
||||
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
||||
g_clear_pointer ((GPtrArray **) &data->result, g_ptr_array_unref);
|
||||
break;
|
||||
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
||||
g_clear_pointer ((GPtrArray **) &data->result, g_ptr_array_unref);
|
||||
break;
|
||||
|
||||
case FP_DEVICE_TASK_RETURN_ERROR:
|
||||
g_clear_error ((GError **) &data->result);
|
||||
break;
|
||||
case FP_DEVICE_TASK_RETURN_ERROR:
|
||||
g_clear_error ((GError **) &data->result);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_object_unref (data->device);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_device_return_task_in_idle:
|
||||
* @device: The #FpDevice
|
||||
* @return_type: The #FpDeviceTaskReturnType of @return_data
|
||||
* @return_data: (nullable) (transfer full): The data to return.
|
||||
*
|
||||
* Completes a #FpDevice task in an idle source, stealing the ownership of
|
||||
* the passed @returned_data.
|
||||
*/
|
||||
static void
|
||||
fpi_device_return_task_in_idle (FpDevice *device,
|
||||
FpDeviceTaskReturnType return_type,
|
||||
@@ -1101,7 +1170,7 @@ fpi_device_return_task_in_idle (FpDevice *device,
|
||||
* @device: The #FpDevice
|
||||
* @device_id: Unique ID for the device or %NULL
|
||||
* @device_name: Human readable name or %NULL for driver name
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing probe operation. If error is %NULL success is assumed.
|
||||
*/
|
||||
@@ -1147,7 +1216,7 @@ fpi_device_probe_complete (FpDevice *device,
|
||||
/**
|
||||
* fpi_device_open_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing open operation. If error is %NULL success is assumed.
|
||||
*/
|
||||
@@ -1174,7 +1243,7 @@ fpi_device_open_complete (FpDevice *device, GError *error)
|
||||
/**
|
||||
* fpi_device_close_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing close operation. If error is %NULL success is assumed.
|
||||
*/
|
||||
@@ -1226,7 +1295,7 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
||||
* fpi_device_enroll_complete:
|
||||
* @device: The #FpDevice
|
||||
* @print: (nullable) (transfer full): The #FpPrint or %NULL on failure
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing enroll operation. The #FpPrint can be stored by the
|
||||
* caller for later verification.
|
||||
@@ -1355,7 +1424,7 @@ fpi_device_verify_complete (FpDevice *device,
|
||||
/**
|
||||
* fpi_device_identify_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing identify operation.
|
||||
*
|
||||
@@ -1421,7 +1490,7 @@ fpi_device_identify_complete (FpDevice *device,
|
||||
* fpi_device_capture_complete:
|
||||
* @device: The #FpDevice
|
||||
* @image: The #FpImage, or %NULL on error
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing capture operation.
|
||||
*/
|
||||
@@ -1468,7 +1537,7 @@ fpi_device_capture_complete (FpDevice *device,
|
||||
/**
|
||||
* fpi_device_delete_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing delete operation.
|
||||
*/
|
||||
@@ -1497,7 +1566,7 @@ fpi_device_delete_complete (FpDevice *device,
|
||||
* fpi_device_list_complete:
|
||||
* @device: The #FpDevice
|
||||
* @prints: (element-type FpPrint) (transfer container): Possibly empty array of prints or %NULL on error
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing list operation.
|
||||
*
|
||||
@@ -1775,7 +1844,7 @@ fpi_device_suspend_completed (FpDevice *device)
|
||||
/**
|
||||
* fpi_device_suspend_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish a suspend request. Only return a %NULL error if suspend has been
|
||||
* correctly configured and the current action as returned by
|
||||
@@ -1785,7 +1854,7 @@ fpi_device_suspend_completed (FpDevice *device)
|
||||
* current action will be cancelled before the error is forwarded to the
|
||||
* application.
|
||||
*
|
||||
* It is recommended to set @error to #FP_ERROR_NOT_IMPLEMENTED.
|
||||
* It is recommended to set @error to #FP_DEVICE_ERROR_NOT_SUPPORTED.
|
||||
*/
|
||||
void
|
||||
fpi_device_suspend_complete (FpDevice *device,
|
||||
@@ -1826,7 +1895,7 @@ fpi_device_suspend_complete (FpDevice *device,
|
||||
/**
|
||||
* fpi_device_resume_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish a resume request.
|
||||
*/
|
||||
@@ -1854,7 +1923,7 @@ fpi_device_resume_complete (FpDevice *device,
|
||||
/**
|
||||
* fpi_device_clear_storage_complete:
|
||||
* @device: The #FpDevice
|
||||
* @error: The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Finish an ongoing clear_storage operation.
|
||||
*/
|
||||
@@ -1885,7 +1954,7 @@ fpi_device_clear_storage_complete (FpDevice *device,
|
||||
* @device: The #FpDevice
|
||||
* @completed_stages: The number of stages that are completed at this point
|
||||
* @print: (transfer floating): The #FpPrint for the newly completed stage or %NULL on failure
|
||||
* @error: (transfer full): The #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Notify about the progress of the enroll operation. This is important for UI interaction.
|
||||
* The passed error may be used if a scan needs to be retried, use fpi_device_retry_new().
|
||||
|
||||
@@ -38,6 +38,13 @@ typedef enum {
|
||||
|
||||
/**
|
||||
* FpIdEntry:
|
||||
* @pid: The USB product ID (for USB devices)
|
||||
* @vid: The USB vendor ID (for USB devices)
|
||||
* @virtual_envvar: Environment variable name (for virtual devices)
|
||||
* @driver_data: Optional driver-specific data, defaults to 0
|
||||
* @udev_types: Subtypes for udev-based devices
|
||||
* @spi_acpi_id: ACPI ID (for SPI devices)
|
||||
* @hid_id: HID device identifier (for HID devices)
|
||||
*
|
||||
* An entry in the table of supported hardware. For USB devices, the product ID
|
||||
* and vendor ID should be provided. The optional @driver_data field defaults
|
||||
@@ -325,4 +332,11 @@ gboolean fpi_device_report_finger_status_changes (FpDevice *device,
|
||||
FpFingerStatusFlags added_status,
|
||||
FpFingerStatusFlags removed_status);
|
||||
|
||||
/* Debugging utilities */
|
||||
|
||||
#define fpi_device_emulation_mode_enabled(dev) \
|
||||
G_UNLIKELY ((fpi_device_emulation_mode_enabled) ((dev)))
|
||||
|
||||
gboolean (fpi_device_emulation_mode_enabled) (FpDevice *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -565,7 +565,7 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
|
||||
/**
|
||||
* fpi_image_device_session_error:
|
||||
* @self: a #FpImageDevice imaging fingerprint device
|
||||
* @error: The #GError to report
|
||||
* @error: (nullable) (transfer full): The #GError to report.
|
||||
*
|
||||
* Report an error while interacting with the device. This effectively
|
||||
* aborts the current ongoing action. Note that doing so will result in
|
||||
@@ -624,7 +624,7 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
||||
/**
|
||||
* fpi_image_device_activate_complete:
|
||||
* @self: a #FpImageDevice imaging fingerprint device
|
||||
* @error: A #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Reports completion of device activation.
|
||||
*/
|
||||
@@ -663,7 +663,7 @@ fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
|
||||
/**
|
||||
* fpi_image_device_deactivate_complete:
|
||||
* @self: a #FpImageDevice imaging fingerprint device
|
||||
* @error: A #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Reports completion of device deactivation.
|
||||
*/
|
||||
@@ -690,7 +690,7 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
|
||||
/**
|
||||
* fpi_image_device_open_complete:
|
||||
* @self: a #FpImageDevice imaging fingerprint device
|
||||
* @error: A #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Reports completion of open operation.
|
||||
*/
|
||||
@@ -718,7 +718,7 @@ fpi_image_device_open_complete (FpImageDevice *self, GError *error)
|
||||
/**
|
||||
* fpi_image_device_close_complete:
|
||||
* @self: a #FpImageDevice imaging fingerprint device
|
||||
* @error: A #GError or %NULL on success
|
||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
||||
*
|
||||
* Reports completion of close operation.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
* @FPI_IMAGE_V_FLIPPED: the image is vertically flipped
|
||||
* @FPI_IMAGE_H_FLIPPED: the image is horizontally flipped
|
||||
* @FPI_IMAGE_COLORS_INVERTED: the colours are inverted
|
||||
* @FPI_IMAGE_PARTIAL: the image is a partial scan
|
||||
*
|
||||
* Flags used in an #FpImage structure to describe the contained image.
|
||||
* This is useful for image drivers as they can simply set these flags and
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* FpiLog - Internal logging functions
|
||||
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
* Copyright (C) 2026 Marco Trevisan (Treviño) <mail@3v1n0.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
|
||||
*/
|
||||
|
||||
#include "fpi-log.h"
|
||||
|
||||
/**
|
||||
* fpi_log_is_debug_transfer_enabled:
|
||||
*
|
||||
* Checks if the %FP_DEBUG_TRANSFER environment variable is set.
|
||||
*
|
||||
* Returns: %TRUE if %FP_DEBUG_TRANSFER is set, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
fpi_log_is_debug_transfer_enabled (void)
|
||||
{
|
||||
static gsize debug_transfer_enabled = 0;
|
||||
|
||||
if (g_once_init_enter (&debug_transfer_enabled))
|
||||
{
|
||||
gsize enabled = g_getenv ("FP_DEBUG_TRANSFER") != NULL ? TRUE : G_MAXSIZE;
|
||||
g_once_init_leave (&debug_transfer_enabled, enabled);
|
||||
}
|
||||
|
||||
return debug_transfer_enabled == TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_dbg_hex_dump_data:
|
||||
* @buf: Bytes buffer to dump
|
||||
* @len: Length of @buf to dump
|
||||
*
|
||||
* Prints hex dump of @buf to fp_dbg()
|
||||
*/
|
||||
void
|
||||
(fpi_dbg_hex_dump_data) (const gchar *log_domain,
|
||||
const guint8 *buf,
|
||||
gsize len)
|
||||
{
|
||||
g_autoptr(GString) line = NULL;
|
||||
|
||||
if (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, log_domain))
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (len == 0 || !buf))
|
||||
return;
|
||||
|
||||
line = g_string_new ("");
|
||||
|
||||
for (gint i = 0; i < len; i++)
|
||||
g_string_append_printf (line, "%02x", buf[i]);
|
||||
|
||||
if (line->len)
|
||||
g_log (log_domain, G_LOG_LEVEL_DEBUG, "%s", line->str);
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_dbg_hex_dump_bytes:
|
||||
* @bytes: #GBytes to dump
|
||||
*
|
||||
* Prints hex dump of @bytes to fp_dbg()
|
||||
*/
|
||||
void
|
||||
(fpi_dbg_hex_dump_bytes) (const gchar *log_domain,
|
||||
GBytes *bytes)
|
||||
{
|
||||
gsize length = 0;
|
||||
const guint8 *data = g_bytes_get_data (bytes, &length);
|
||||
|
||||
(fpi_dbg_hex_dump_data) (log_domain, data, length);
|
||||
}
|
||||
+40
-7
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
||||
* Copyright (C) 2026 Marco Trevisan (Treviño) <mail@3v1n0.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -79,13 +80,16 @@
|
||||
*
|
||||
* Uses fp_err() to print an error if the @condition is true.
|
||||
*/
|
||||
#define BUG_ON(condition) G_STMT_START \
|
||||
if (condition) { \
|
||||
char *s; \
|
||||
s = g_strconcat ("BUG: (", #condition, ")", NULL); \
|
||||
fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \
|
||||
g_free (s); \
|
||||
} G_STMT_END
|
||||
#define BUG_ON(condition) \
|
||||
G_STMT_START \
|
||||
if (condition) \
|
||||
{ \
|
||||
char *s; \
|
||||
s = g_strconcat ("BUG: (", #condition, ")", NULL); \
|
||||
fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \
|
||||
g_free (s); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/**
|
||||
* BUG:
|
||||
@@ -93,3 +97,32 @@
|
||||
* Same as BUG_ON() but is always true.
|
||||
*/
|
||||
#define BUG() BUG_ON (1)
|
||||
|
||||
void (fpi_dbg_hex_dump_data) (const gchar *log_domain,
|
||||
const guint8 *buf,
|
||||
gsize len);
|
||||
|
||||
/**
|
||||
* fp_dbg_hex_dump_data:
|
||||
* @buf: Bytes buffer to dump
|
||||
* @len: Length of @buf to dump
|
||||
*
|
||||
* Prints hex dump of @buf to fp_dbg()
|
||||
*/
|
||||
#define fp_dbg_hex_dump_data(buf, len) \
|
||||
(fpi_dbg_hex_dump_data) (G_LOG_DOMAIN, (buf), (len))
|
||||
|
||||
void (fpi_dbg_hex_dump_bytes) (const gchar *log_domain,
|
||||
GBytes *bytes);
|
||||
|
||||
/**
|
||||
* fp_dbg_hex_dump_bytes:
|
||||
* @bytes: #GBytes to dump
|
||||
*
|
||||
* Prints hex dump of @bytes to fp_dbg()
|
||||
*/
|
||||
#define fp_dbg_hex_dump_bytes(bytes) \
|
||||
(fpi_dbg_hex_dump_bytes) \
|
||||
(G_LOG_DOMAIN, (bytes))
|
||||
|
||||
gboolean fpi_log_is_debug_transfer_enabled (void);
|
||||
|
||||
@@ -196,7 +196,7 @@ fpi_print_add_from_image (FpPrint *print,
|
||||
|
||||
/**
|
||||
* fpi_print_bz3_match:
|
||||
* @template: A #FpPrint containing one or more prints
|
||||
* @print_template: A #FpPrint containing one or more prints
|
||||
* @print: A newly scanned #FpPrint to test
|
||||
* @bz3_threshold: The BZ3 match threshold
|
||||
* @error: Return location for error
|
||||
@@ -210,14 +210,17 @@ fpi_print_add_from_image (FpPrint *print,
|
||||
* Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned
|
||||
*/
|
||||
FpiMatchResult
|
||||
fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GError **error)
|
||||
fpi_print_bz3_match (FpPrint *print_template,
|
||||
FpPrint *print,
|
||||
gint bz3_threshold,
|
||||
GError **error)
|
||||
{
|
||||
struct xyt_struct *pstruct;
|
||||
gint probe_len;
|
||||
gint i;
|
||||
|
||||
/* XXX: Use a different error type? */
|
||||
if (template->type != FPI_PRINT_NBIS || print->type != FPI_PRINT_NBIS)
|
||||
if (print_template->type != FPI_PRINT_NBIS || print->type != FPI_PRINT_NBIS)
|
||||
{
|
||||
*error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||
"It is only possible to match NBIS type print data");
|
||||
@@ -234,11 +237,11 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
|
||||
pstruct = g_ptr_array_index (print->prints, 0);
|
||||
probe_len = bozorth_probe_init (pstruct);
|
||||
|
||||
for (i = 0; i < template->prints->len; i++)
|
||||
for (i = 0; i < print_template->prints->len; i++)
|
||||
{
|
||||
struct xyt_struct *gstruct;
|
||||
gint score;
|
||||
gstruct = g_ptr_array_index (template->prints, i);
|
||||
gstruct = g_ptr_array_index (print_template->prints, i);
|
||||
score = bozorth_to_gallery (probe_len, pstruct, gstruct);
|
||||
fp_dbg ("score %d/%d", score, bz3_threshold);
|
||||
|
||||
@@ -292,7 +295,7 @@ fpi_print_generate_user_id (FpPrint *print)
|
||||
if (!username)
|
||||
username = "nobody";
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
if (fpi_device_emulation_mode_enabled (NULL))
|
||||
rand_id = 0;
|
||||
else
|
||||
rand_id = g_random_int ();
|
||||
|
||||
@@ -42,7 +42,7 @@ gboolean fpi_print_add_from_image (FpPrint *print,
|
||||
FpImage *image,
|
||||
GError **error);
|
||||
|
||||
FpiMatchResult fpi_print_bz3_match (FpPrint *temp,
|
||||
FpiMatchResult fpi_print_bz3_match (FpPrint *print_template,
|
||||
FpPrint *print,
|
||||
gint bz3_threshold,
|
||||
GError **error);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "fpi-spi-transfer.h"
|
||||
#include "fpi-log.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <errno.h>
|
||||
@@ -41,38 +42,17 @@ static gsize block_size = 0;
|
||||
* Drivers should always use this API rather than calling read/write/ioctl on
|
||||
* the spidev device.
|
||||
*
|
||||
* Setting G_MESSAGES_DEBUG and FP_DEBUG_TRANSFER will result in the message
|
||||
* Setting %G_MESSAGES_DEBUG and %FP_DEBUG_TRANSFER will result in the message
|
||||
* content to be dumped.
|
||||
*/
|
||||
|
||||
|
||||
G_DEFINE_BOXED_TYPE (FpiSpiTransfer, fpi_spi_transfer, fpi_spi_transfer_ref, fpi_spi_transfer_unref)
|
||||
|
||||
static void
|
||||
dump_buffer (guchar *buf, gssize dump_len)
|
||||
{
|
||||
g_autoptr(GString) line = NULL;
|
||||
|
||||
line = g_string_new ("");
|
||||
/* Dump the buffer. */
|
||||
for (gssize i = 0; i < dump_len; i++)
|
||||
{
|
||||
g_string_append_printf (line, "%02x ", buf[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
{
|
||||
g_debug ("%s", line->str);
|
||||
g_string_set_size (line, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (line->len)
|
||||
g_debug ("%s", line->str);
|
||||
}
|
||||
|
||||
static void
|
||||
log_transfer (FpiSpiTransfer *transfer, gboolean submit, GError *error)
|
||||
{
|
||||
if (g_getenv ("FP_DEBUG_TRANSFER"))
|
||||
if (fpi_log_is_debug_transfer_enabled ())
|
||||
{
|
||||
if (submit)
|
||||
{
|
||||
@@ -82,7 +62,7 @@ log_transfer (FpiSpiTransfer *transfer, gboolean submit, GError *error)
|
||||
transfer->length_rd);
|
||||
|
||||
if (transfer->buffer_wr)
|
||||
dump_buffer (transfer->buffer_wr, transfer->length_wr);
|
||||
fp_dbg_hex_dump_data (transfer->buffer_wr, transfer->length_wr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -98,7 +78,7 @@ log_transfer (FpiSpiTransfer *transfer, gboolean submit, GError *error)
|
||||
transfer->length_wr,
|
||||
transfer->length_rd);
|
||||
if (transfer->buffer_rd)
|
||||
dump_buffer (transfer->buffer_rd, transfer->length_rd);
|
||||
fp_dbg_hex_dump_data (transfer->buffer_rd, transfer->length_rd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-14
@@ -615,7 +615,7 @@ fpi_ssm_get_cur_state (FpiSsm *machine)
|
||||
*
|
||||
* Returns the error code set by fpi_ssm_mark_failed().
|
||||
*
|
||||
* Returns: (transfer none): a error code
|
||||
* Returns: (transfer none): a #GError or %NULL if not set.
|
||||
*/
|
||||
GError *
|
||||
fpi_ssm_get_error (FpiSsm *machine)
|
||||
@@ -631,7 +631,7 @@ fpi_ssm_get_error (FpiSsm *machine)
|
||||
*
|
||||
* Returns the error code set by fpi_ssm_mark_failed().
|
||||
*
|
||||
* Returns: (transfer full): a error code
|
||||
* Returns: (transfer full): a #GError or %NULL if not set.
|
||||
*/
|
||||
GError *
|
||||
fpi_ssm_dup_error (FpiSsm *machine)
|
||||
@@ -657,6 +657,8 @@ fpi_ssm_dup_error (FpiSsm *machine)
|
||||
void
|
||||
fpi_ssm_silence_debug (FpiSsm *machine)
|
||||
{
|
||||
g_return_if_fail (machine != NULL);
|
||||
|
||||
machine->silence = TRUE;
|
||||
}
|
||||
|
||||
@@ -665,10 +667,10 @@ fpi_ssm_silence_debug (FpiSsm *machine)
|
||||
* @transfer: a #FpiUsbTransfer
|
||||
* @device: a #FpDevice
|
||||
* @unused_data: User data (unused)
|
||||
* @error: The #GError or %NULL
|
||||
* @error: (transfer full): a #GError or %NULL.
|
||||
*
|
||||
* Can be used in as a #FpiUsbTransfer callback handler to automatically
|
||||
* advance or fail a statemachine on transfer completion.
|
||||
* advance or fail a state machine on transfer completion.
|
||||
*
|
||||
* Make sure to set the #FpiSsm on the transfer.
|
||||
*/
|
||||
@@ -676,10 +678,11 @@ void
|
||||
fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer unused_data, GError *error)
|
||||
{
|
||||
g_return_if_fail (transfer != NULL);
|
||||
g_return_if_fail (transfer->ssm);
|
||||
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
|
||||
else
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
}
|
||||
@@ -691,10 +694,10 @@ fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
* @weak_ptr: A #gpointer pointer to nullify. You can pass a pointer to any
|
||||
* #gpointer to nullify when the callback is completed. I.e a
|
||||
* pointer to the current #FpiUsbTransfer.
|
||||
* @error: The #GError or %NULL
|
||||
* @error: (transfer full): a #GError or %NULL.
|
||||
*
|
||||
* Can be used in as a #FpiUsbTransfer callback handler to automatically
|
||||
* advance or fail a statemachine on transfer completion.
|
||||
* advance or fail a state machine on transfer completion.
|
||||
* Passing a #gpointer* as @weak_ptr permits to nullify it once we're done
|
||||
* with the transfer.
|
||||
*
|
||||
@@ -705,12 +708,13 @@ fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device, gpointer weak_ptr,
|
||||
GError *error)
|
||||
{
|
||||
g_return_if_fail (transfer != NULL);
|
||||
g_return_if_fail (transfer->ssm);
|
||||
|
||||
if (weak_ptr)
|
||||
g_nullify_pointer ((gpointer *) weak_ptr);
|
||||
|
||||
fpi_ssm_usb_transfer_cb (transfer, device, weak_ptr, error);
|
||||
fpi_ssm_usb_transfer_cb (transfer, device, weak_ptr, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -718,10 +722,10 @@ fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
|
||||
* @transfer: a #FpiSpiTransfer
|
||||
* @device: a #FpDevice
|
||||
* @unused_data: User data (unused)
|
||||
* @error: The #GError or %NULL
|
||||
* @error: (transfer full): a #GError or %NULL.
|
||||
*
|
||||
* Can be used in as a #FpiSpiTransfer callback handler to automatically
|
||||
* advance or fail a statemachine on transfer completion.
|
||||
* advance or fail a state machine on transfer completion.
|
||||
*
|
||||
* Make sure to set the #FpiSsm on the transfer.
|
||||
*/
|
||||
@@ -729,10 +733,11 @@ void
|
||||
fpi_ssm_spi_transfer_cb (FpiSpiTransfer *transfer, FpDevice *device,
|
||||
gpointer unused_data, GError *error)
|
||||
{
|
||||
g_return_if_fail (transfer != NULL);
|
||||
g_return_if_fail (transfer->ssm);
|
||||
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
fpi_ssm_mark_failed (transfer->ssm, g_steal_pointer (&error));
|
||||
else
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
}
|
||||
@@ -744,10 +749,10 @@ fpi_ssm_spi_transfer_cb (FpiSpiTransfer *transfer, FpDevice *device,
|
||||
* @weak_ptr: A #gpointer pointer to nullify. You can pass a pointer to any
|
||||
* #gpointer to nullify when the callback is completed. I.e a
|
||||
* pointer to the current #FpiSpiTransfer.
|
||||
* @error: The #GError or %NULL
|
||||
* @error: (transfer full): a #GError or %NULL.
|
||||
*
|
||||
* Can be used in as a #FpiSpiTransfer callback handler to automatically
|
||||
* advance or fail a statemachine on transfer completion.
|
||||
* advance or fail a state machine on transfer completion.
|
||||
* Passing a #gpointer* as @weak_ptr permits to nullify it once we're done
|
||||
* with the transfer.
|
||||
*
|
||||
@@ -758,10 +763,11 @@ fpi_ssm_spi_transfer_with_weak_pointer_cb (FpiSpiTransfer *transfer,
|
||||
FpDevice *device, gpointer weak_ptr,
|
||||
GError *error)
|
||||
{
|
||||
g_return_if_fail (transfer != NULL);
|
||||
g_return_if_fail (transfer->ssm);
|
||||
|
||||
if (weak_ptr)
|
||||
g_nullify_pointer ((gpointer *) weak_ptr);
|
||||
|
||||
fpi_ssm_spi_transfer_cb (transfer, device, weak_ptr, error);
|
||||
fpi_ssm_spi_transfer_cb (transfer, device, weak_ptr, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ typedef void (*FpiSsmHandlerCallback)(FpiSsm *ssm,
|
||||
|
||||
/* for library and drivers */
|
||||
#define fpi_ssm_new(dev, handler, nr_states) \
|
||||
fpi_ssm_new_full (dev, handler, nr_states, nr_states, #nr_states)
|
||||
fpi_ssm_new_full (dev, handler, nr_states, nr_states, #nr_states)
|
||||
FpiSsm *fpi_ssm_new_full (FpDevice *dev,
|
||||
FpiSsmHandlerCallback handler,
|
||||
int nr_states,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "fpi-usb-transfer.h"
|
||||
#include "fpi-log.h"
|
||||
|
||||
/**
|
||||
* SECTION:fpi-usb-transfer
|
||||
@@ -30,6 +31,9 @@
|
||||
*
|
||||
* Drivers should use this API only rather than accessing the GUsbDevice
|
||||
* directly in most cases.
|
||||
*
|
||||
* Setting %G_MESSAGES_DEBUG and %FP_DEBUG_TRANSFER will result in the message
|
||||
* content to be dumped.
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,7 +42,7 @@ G_DEFINE_BOXED_TYPE (FpiUsbTransfer, fpi_usb_transfer, fpi_usb_transfer_ref, fpi
|
||||
static void
|
||||
log_transfer (FpiUsbTransfer *transfer, gboolean submit, GError *error)
|
||||
{
|
||||
if (g_getenv ("FP_DEBUG_TRANSFER"))
|
||||
if (fpi_log_is_debug_transfer_enabled ())
|
||||
{
|
||||
if (!submit)
|
||||
{
|
||||
@@ -65,25 +69,9 @@ log_transfer (FpiUsbTransfer *transfer, gboolean submit, GError *error)
|
||||
|
||||
if (!submit == !!(transfer->endpoint & FPI_USB_ENDPOINT_IN))
|
||||
{
|
||||
g_autoptr(GString) line = NULL;
|
||||
gssize dump_len;
|
||||
|
||||
dump_len = (transfer->endpoint & FPI_USB_ENDPOINT_IN) ? transfer->actual_length : transfer->length;
|
||||
|
||||
line = g_string_new ("");
|
||||
/* Dump the buffer. */
|
||||
for (gint i = 0; i < dump_len; i++)
|
||||
{
|
||||
g_string_append_printf (line, "%02x ", transfer->buffer[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
{
|
||||
g_debug ("%s", line->str);
|
||||
g_string_set_size (line, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (line->len)
|
||||
g_debug ("%s", line->str);
|
||||
fp_dbg_hex_dump_data (transfer->buffer,
|
||||
(transfer->endpoint & FPI_USB_ENDPOINT_IN) ?
|
||||
transfer->actual_length : transfer->length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,7 +332,8 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
|
||||
{
|
||||
error = g_error_new (G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_IO,
|
||||
"Unexpected short error of %zd size (expected %zd)", transfer->actual_length, transfer->length);
|
||||
"Unexpected short error of %zd size (expected %zd)",
|
||||
transfer->actual_length, transfer->length);
|
||||
}
|
||||
|
||||
callback = transfer->callback;
|
||||
@@ -548,3 +537,23 @@ fpi_usb_transfer_submit_sync (FpiUsbTransfer *transfer,
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_usb_transfer_set_short_error:
|
||||
* @transfer: The transfer to submit, must have been filled.
|
||||
* @short_is_error: Whether a short transfer should be considered an error
|
||||
*
|
||||
* Sets whether a short transfer (a transfer in which the transferred length
|
||||
* does not match the expected length) should be considered an error
|
||||
*
|
||||
* By default, short transfers are not considered an error, but
|
||||
* drivers can enforce a further check by setting this flag.
|
||||
*/
|
||||
void
|
||||
fpi_usb_transfer_set_short_error (FpiUsbTransfer *transfer,
|
||||
gboolean short_is_error)
|
||||
{
|
||||
g_return_if_fail (transfer);
|
||||
|
||||
transfer->short_is_error = short_is_error;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include "fpi-context.h"
|
||||
#include "fpi-device.h"
|
||||
|
||||
#define METAINFO_BASE \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
|
||||
"<component>\n" \
|
||||
" <id>org.freedesktop.libfprint</id>\n" \
|
||||
" <name>libfprint</name>\n" \
|
||||
" <metadata_license>CC0-1.0</metadata_license>\n" \
|
||||
" <project_license>LGPL-2.1-or-later</project_license>\n" \
|
||||
" <url type=\"homepage\">https://fprint.freedesktop.org</url>\n" \
|
||||
" <url type=\"vcs-browser\">https://gitlab.freedesktop.org/libfprint/libfprint</url>\n" \
|
||||
" <url type=\"help\">https://fprint.freedesktop.org/libfprint-dev</url>\n" \
|
||||
" <url type=\"bugtracker\">https://gitlab.freedesktop.org/libfprint/libfprint/-/work_items</url>\n" \
|
||||
" <summary>Async fingerprint readers library</summary>\n" \
|
||||
" <description>\n" \
|
||||
" <p>\n" \
|
||||
" The fprint project aims to support for consumer fingerprint reader devices.\n" \
|
||||
" </p>\n" \
|
||||
" </description>\n" \
|
||||
" <provides>\n" \
|
||||
"%s\n" \
|
||||
" </provides>\n" \
|
||||
"</component>\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);
|
||||
}
|
||||
|
||||
static void
|
||||
usb_driver_devices_append (GPtrArray *devices_list,
|
||||
const FpDeviceClass *cls)
|
||||
{
|
||||
const FpIdEntry *entry;
|
||||
|
||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
return;
|
||||
|
||||
for (entry = cls->id_table; entry->vid != 0; entry++)
|
||||
{
|
||||
if (entry->vid == 0 || entry->pid == 0)
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (devices_list,
|
||||
g_strdup_printf ("v%04xp%04x", entry->vid, entry->pid));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
g_autoptr(GPtrArray) devices_list = g_ptr_array_new_with_free_func (g_free);
|
||||
g_autoptr(GArray) drivers = fpi_get_driver_types ();
|
||||
g_autoptr(GString) provided_modules = g_string_new (NULL);
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_log_writer_default_set_use_stderr (TRUE);
|
||||
|
||||
g_array_sort (drivers, driver_compare);
|
||||
|
||||
for (guint i = 0; i < drivers->len; ++i)
|
||||
{
|
||||
GType driver = g_array_index (drivers, GType, i);
|
||||
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||
|
||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
continue;
|
||||
|
||||
usb_driver_devices_append (devices_list, cls);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < devices_list->len; ++i)
|
||||
{
|
||||
const char *device_id = g_ptr_array_index (devices_list, i);
|
||||
|
||||
g_string_append (provided_modules, " ");
|
||||
g_string_append_printf (provided_modules, "<modalias>usb:%s*</modalias>",
|
||||
device_id);
|
||||
|
||||
if (i < devices_list->len - 1)
|
||||
g_string_append_c (provided_modules, '\n');
|
||||
}
|
||||
|
||||
g_print (METAINFO_BASE, provided_modules->str);
|
||||
}
|
||||
@@ -29,7 +29,10 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
* You can generate this list from the wiki page using e.g.:
|
||||
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
|
||||
*/
|
||||
{ .vid = 0x0a5c, .pid = 0x5802 },
|
||||
{ .vid = 0x047d, .pid = 0x00f2 },
|
||||
{ .vid = 0x047d, .pid = 0x8054 },
|
||||
{ .vid = 0x047d, .pid = 0x8055 },
|
||||
{ .vid = 0x04e8, .pid = 0x730b },
|
||||
{ .vid = 0x04f3, .pid = 0x036b },
|
||||
{ .vid = 0x04f3, .pid = 0x0c00 },
|
||||
@@ -37,27 +40,37 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
{ .vid = 0x04f3, .pid = 0x0c57 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c5e },
|
||||
{ .vid = 0x04f3, .pid = 0x0c5a },
|
||||
{ .vid = 0x04f3, .pid = 0x0c60 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c6c },
|
||||
{ .vid = 0x04f3, .pid = 0x0c70 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c72 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c77 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c7c },
|
||||
{ .vid = 0x04f3, .pid = 0x0c7f },
|
||||
{ .vid = 0x04f3, .pid = 0x0c80 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c85 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c90 },
|
||||
{ .vid = 0x04f3, .pid = 0x2706 },
|
||||
{ .vid = 0x04f3, .pid = 0x3032 },
|
||||
{ .vid = 0x04f3, .pid = 0x3057 },
|
||||
{ .vid = 0x04f3, .pid = 0x3104 },
|
||||
{ .vid = 0x04f3, .pid = 0x310d },
|
||||
{ .vid = 0x04f3, .pid = 0x3128 },
|
||||
{ .vid = 0x04f3, .pid = 0x0c8a },
|
||||
{ .vid = 0x05ba, .pid = 0x000e },
|
||||
{ .vid = 0x06cb, .pid = 0x0051 },
|
||||
{ .vid = 0x06cb, .pid = 0x0081 },
|
||||
{ .vid = 0x06cb, .pid = 0x0088 },
|
||||
{ .vid = 0x06cb, .pid = 0x008a },
|
||||
{ .vid = 0x06cb, .pid = 0x009a },
|
||||
{ .vid = 0x06cb, .pid = 0x009b },
|
||||
{ .vid = 0x06cb, .pid = 0x00a1 },
|
||||
{ .vid = 0x06cb, .pid = 0x00a2 },
|
||||
{ .vid = 0x06cb, .pid = 0x00a8 },
|
||||
{ .vid = 0x06cb, .pid = 0x00b7 },
|
||||
{ .vid = 0x06cb, .pid = 0x00bb },
|
||||
{ .vid = 0x06cb, .pid = 0x00bc },
|
||||
{ .vid = 0x06cb, .pid = 0x00be },
|
||||
{ .vid = 0x06cb, .pid = 0x00c4 },
|
||||
{ .vid = 0x06cb, .pid = 0x00cb },
|
||||
{ .vid = 0x06cb, .pid = 0x00c9 },
|
||||
{ .vid = 0x06cb, .pid = 0x00d8 },
|
||||
@@ -65,8 +78,8 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
{ .vid = 0x06cb, .pid = 0x00dc },
|
||||
{ .vid = 0x06cb, .pid = 0x00e4 },
|
||||
{ .vid = 0x06cb, .pid = 0x00e7 },
|
||||
{ .vid = 0x06cb, .pid = 0x00e9 },
|
||||
{ .vid = 0x06cb, .pid = 0x00fd },
|
||||
{ .vid = 0x06cb, .pid = 0x00ff },
|
||||
{ .vid = 0x0a5c, .pid = 0x5801 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5805 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5834 },
|
||||
@@ -76,10 +89,20 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
{ .vid = 0x0a5c, .pid = 0x5843 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5844 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5845 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5860 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5863 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5864 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5865 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5866 },
|
||||
{ .vid = 0x0a5c, .pid = 0x5867 },
|
||||
{ .vid = 0x0bda, .pid = 0x5812 },
|
||||
{ .vid = 0x10a5, .pid = 0x0007 },
|
||||
{ .vid = 0x10a5, .pid = 0x9200 },
|
||||
{ .vid = 0x10a5, .pid = 0x9201 },
|
||||
{ .vid = 0x10a5, .pid = 0x9800 },
|
||||
{ .vid = 0x10a5, .pid = 0xa120 },
|
||||
{ .vid = 0x10a5, .pid = 0xa900 },
|
||||
{ .vid = 0x10a5, .pid = 0xa921 },
|
||||
{ .vid = 0x10a5, .pid = 0xe340 },
|
||||
{ .vid = 0x1188, .pid = 0x9545 },
|
||||
{ .vid = 0x138a, .pid = 0x0007 },
|
||||
@@ -101,6 +124,9 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
{ .vid = 0x1c7a, .pid = 0x0575 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0576 },
|
||||
{ .vid = 0x1c7a, .pid = 0x0577 },
|
||||
{ .vid = 0x1c7a, .pid = 0x057e },
|
||||
{ .vid = 0x2541, .pid = 0x0236 },
|
||||
{ .vid = 0x2541, .pid = 0x9711 },
|
||||
{ .vid = 0x27c6, .pid = 0x5042 },
|
||||
{ .vid = 0x27c6, .pid = 0x5110 },
|
||||
{ .vid = 0x27c6, .pid = 0x5117 },
|
||||
@@ -129,11 +155,18 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||
{ .vid = 0x27c6, .pid = 0x5e0a },
|
||||
{ .vid = 0x27c6, .pid = 0x581a },
|
||||
{ .vid = 0x27c6, .pid = 0x589a },
|
||||
{ .vid = 0x27c6, .pid = 0x5f10 },
|
||||
{ .vid = 0x27c6, .pid = 0x5f91 },
|
||||
{ .vid = 0x27c6, .pid = 0x6382 },
|
||||
{ .vid = 0x2808, .pid = 0x9338 },
|
||||
{ .vid = 0x2808, .pid = 0x9348 },
|
||||
{ .vid = 0x2808, .pid = 0x93a9 },
|
||||
{ .vid = 0x2808, .pid = 0xa658 },
|
||||
{ .vid = 0x2808, .pid = 0xc652 },
|
||||
{ .vid = 0x2808, .pid = 0xa553 },
|
||||
{ .vid = 0x298d, .pid = 0x2020 },
|
||||
{ .vid = 0x298d, .pid = 0x2033 },
|
||||
{ .vid = 0x2df0, .pid = 0x0003 },
|
||||
{ .vid = 0x3538, .pid = 0x0930 },
|
||||
{ .vid = 0 },
|
||||
};
|
||||
|
||||
+101
-86
@@ -1,3 +1,11 @@
|
||||
spi_sources = []
|
||||
spi_headers = []
|
||||
|
||||
if enabled_spi_drivers.length() > 0
|
||||
spi_headers = ['fpi-spi-transfer.h']
|
||||
spi_sources = ['fpi-spi-transfer.c']
|
||||
endif
|
||||
|
||||
libfprint_sources = [
|
||||
'fp-context.c',
|
||||
'fp-device.c',
|
||||
@@ -13,11 +21,11 @@ libfprint_private_sources = [
|
||||
'fpi-device.c',
|
||||
'fpi-image-device.c',
|
||||
'fpi-image.c',
|
||||
'fpi-log.c',
|
||||
'fpi-print.c',
|
||||
'fpi-ssm.c',
|
||||
'fpi-usb-transfer.c',
|
||||
'fpi-spi-transfer.c',
|
||||
]
|
||||
] + spi_sources
|
||||
|
||||
libfprint_public_headers = [
|
||||
'fp-context.h',
|
||||
@@ -41,9 +49,8 @@ libfprint_private_headers = [
|
||||
'fpi-minutiae.h',
|
||||
'fpi-print.h',
|
||||
'fpi-usb-transfer.h',
|
||||
'fpi-spi-transfer.h',
|
||||
'fpi-ssm.h',
|
||||
]
|
||||
] + spi_headers
|
||||
|
||||
nbis_sources = [
|
||||
'nbis/bozorth3/bozorth3.c',
|
||||
@@ -81,87 +88,66 @@ nbis_sources = [
|
||||
]
|
||||
|
||||
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' ],
|
||||
'vfs7552' :
|
||||
[ 'drivers/vfs7552.c' ],
|
||||
'upektc_img' :
|
||||
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
|
||||
'etes603' :
|
||||
[ 'drivers/etes603.c' ],
|
||||
'egis0570' :
|
||||
[ 'drivers/egis0570.c' ],
|
||||
'egismoc' :
|
||||
[ 'drivers/egismoc/egismoc.c' ],
|
||||
'vfs0050' :
|
||||
[ 'drivers/vfs0050.c' ],
|
||||
'elan' :
|
||||
[ 'drivers/elan.c' ],
|
||||
'elanmoc' :
|
||||
[ 'drivers/elanmoc/elanmoc.c' ],
|
||||
'elanspi' :
|
||||
[ 'drivers/elanspi.c' ],
|
||||
'nb1010' :
|
||||
[ 'drivers/nb1010.c' ],
|
||||
'virtual_image' :
|
||||
[ 'drivers/virtual-image.c' ],
|
||||
'virtual_device' :
|
||||
[ 'drivers/virtual-device.c' ],
|
||||
'virtual_device_storage' :
|
||||
[ 'drivers/virtual-device-storage.c' ],
|
||||
'synaptics' :
|
||||
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
|
||||
'goodixmoc' :
|
||||
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
|
||||
'fpcmoc' :
|
||||
[ 'drivers/fpcmoc/fpc.c' ],
|
||||
'realtek' :
|
||||
[ 'drivers/realtek/realtek.c' ],
|
||||
'focaltech_moc' :
|
||||
[ 'drivers/focaltech_moc/focaltech_moc.c' ],
|
||||
'upekts' : files(
|
||||
'drivers/upekts.c',
|
||||
'drivers/upek_proto.c',
|
||||
),
|
||||
'upektc' : files('drivers/upektc.c'),
|
||||
'upeksonly' : files('drivers/upeksonly.c'),
|
||||
'uru4000' : files('drivers/uru4000.c'),
|
||||
'aes1610' : files('drivers/aes1610.c'),
|
||||
'aes1660' : files('drivers/aes1660.c'),
|
||||
'aes2501' : files('drivers/aes2501.c'),
|
||||
'aes2550' : files('drivers/aes2550.c'),
|
||||
'aes2660' : files('drivers/aes2660.c'),
|
||||
'aes3500' : files('drivers/aes3500.c'),
|
||||
'aes4000' : files('drivers/aes4000.c'),
|
||||
'vcom5s' : files('drivers/vcom5s.c'),
|
||||
'vfs101' : files('drivers/vfs101.c'),
|
||||
'vfs301' : files(
|
||||
'drivers/vfs301.c',
|
||||
'drivers/vfs301_proto.c',
|
||||
),
|
||||
'vfs5011' : files('drivers/vfs5011.c'),
|
||||
'vfs7552' : files('drivers/vfs7552.c'),
|
||||
'upektc_img' : files(
|
||||
'drivers/upektc_img.c',
|
||||
'drivers/upek_proto.c',
|
||||
),
|
||||
'etes603' : files('drivers/etes603.c'),
|
||||
'egis0570' : files('drivers/egis0570.c'),
|
||||
'egismoc' : files('drivers/egismoc/egismoc.c'),
|
||||
'egis_etu905' : files('drivers/egismoc/egis_etu905.c'),
|
||||
'vfs0050' : files('drivers/vfs0050.c'),
|
||||
'elan' : files('drivers/elan.c'),
|
||||
'elanmoc' : files('drivers/elanmoc/elanmoc.c'),
|
||||
'elanspi' : files('drivers/elanspi.c'),
|
||||
'nb1010' : files('drivers/nb1010.c'),
|
||||
'virtual_image' : files('drivers/virtual-image.c'),
|
||||
'virtual_device' : files('drivers/virtual-device.c'),
|
||||
'virtual_device_storage' : files('drivers/virtual-device-storage.c'),
|
||||
'synaptics' : files(
|
||||
'drivers/synaptics/synaptics.c',
|
||||
'drivers/synaptics/bmkt_message.c',
|
||||
),
|
||||
'goodixmoc' : files(
|
||||
'drivers/goodixmoc/goodix.c',
|
||||
'drivers/goodixmoc/goodix_proto.c',
|
||||
),
|
||||
'fpcmoc' : files('drivers/fpcmoc/fpc.c'),
|
||||
'realtek' : files('drivers/realtek/realtek.c'),
|
||||
'focaltech_moc' : files('drivers/focaltech_moc/focaltech_moc.c'),
|
||||
'mafpmoc' : files('drivers/mafpmoc/mafpmoc.c'),
|
||||
'secugen' : files('drivers/secugen.c'),
|
||||
}
|
||||
|
||||
helper_sources = {
|
||||
'aeslib' :
|
||||
[ 'drivers/aeslib.c' ],
|
||||
'aesx660' :
|
||||
[ 'drivers/aesx660.c' ],
|
||||
'aes3k' :
|
||||
[ 'drivers/aes3k.c' ],
|
||||
'nss' :
|
||||
[ ],
|
||||
'udev' :
|
||||
[ ],
|
||||
'virtual' :
|
||||
[ 'drivers/virtual-device-listener.c' ],
|
||||
'aeslib': files('drivers/aeslib.c'),
|
||||
'aesx660': files('drivers/aesx660.c'),
|
||||
'aes3k': files('drivers/aes3k.c'),
|
||||
'openssl': files(),
|
||||
'udev': files(),
|
||||
'virtual': files('drivers/virtual-device-listener.c'),
|
||||
}
|
||||
|
||||
drivers_sources = []
|
||||
@@ -225,6 +211,7 @@ deps = [
|
||||
enums_dep,
|
||||
gio_dep,
|
||||
glib_dep,
|
||||
gmodule_dep,
|
||||
gobject_dep,
|
||||
gusb_dep,
|
||||
mathlib_dep,
|
||||
@@ -249,6 +236,7 @@ libnbis = static_library('nbis',
|
||||
'-Wno-discarded-qualifiers',
|
||||
'-Wno-array-bounds',
|
||||
'-Wno-array-parameter',
|
||||
'-Wno-unused-but-set-variable',
|
||||
]),
|
||||
install: false)
|
||||
|
||||
@@ -268,8 +256,13 @@ libfprint_drivers = static_library('fprint-drivers',
|
||||
link_with: libfprint_private,
|
||||
install: false)
|
||||
|
||||
mapfile = files('libfprint.ver')
|
||||
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.project_source_root(), mapfile[0])
|
||||
mapfile = files('libfprint.ver')[0]
|
||||
if meson.version().version_compare('>=1.4')
|
||||
mapfile_path = mapfile.full_path()
|
||||
else
|
||||
mapfile_path = meson.project_source_root() / '@0@'.format(mapfile)
|
||||
endif
|
||||
vflag = '-Wl,--version-script,@0@'.format(mapfile_path)
|
||||
|
||||
libfprint = shared_library(versioned_libname.split('lib')[1],
|
||||
sources: [
|
||||
@@ -311,7 +304,9 @@ udev_hwdb = executable('fprint-list-udev-hwdb',
|
||||
'fprint-list-udev-hwdb.c',
|
||||
dependencies: libfprint_private_dep,
|
||||
link_with: libfprint_drivers,
|
||||
install: false)
|
||||
install: false,
|
||||
link_args: ['-Wl,--disable-new-dtags'],
|
||||
)
|
||||
|
||||
udev_hwdb_generator = custom_target('udev-hwdb',
|
||||
output: 'autosuspend.hwdb',
|
||||
@@ -321,12 +316,31 @@ udev_hwdb_generator = custom_target('udev-hwdb',
|
||||
install: false,
|
||||
)
|
||||
|
||||
metainfo = executable('fprint-list-metainfo',
|
||||
'fprint-list-metainfo.c',
|
||||
dependencies: libfprint_private_dep,
|
||||
link_with: libfprint_drivers,
|
||||
install: false,
|
||||
link_args: ['-Wl,--disable-new-dtags'],
|
||||
)
|
||||
|
||||
metainfo_generator = custom_target('metainfo',
|
||||
output: 'org.freedesktop.libfprint.metainfo.xml',
|
||||
depend_files: drivers_sources,
|
||||
capture: true,
|
||||
command: [ metainfo ],
|
||||
install: true,
|
||||
install_dir: datadir / 'metainfo'
|
||||
)
|
||||
|
||||
if install_udev_rules
|
||||
udev_rules = executable('fprint-list-udev-rules',
|
||||
'fprint-list-udev-rules.c',
|
||||
dependencies: libfprint_private_dep,
|
||||
link_with: libfprint_drivers,
|
||||
install: false)
|
||||
install: false,
|
||||
link_args: ['-Wl,--disable-new-dtags'],
|
||||
)
|
||||
|
||||
custom_target('udev-rules',
|
||||
output: '70-@0@.rules'.format(versioned_libname),
|
||||
@@ -384,6 +398,7 @@ if get_option('introspection')
|
||||
'GObject-2.0',
|
||||
'GUsb-1.0',
|
||||
],
|
||||
fatal_warnings: true,
|
||||
install : true)
|
||||
libfprint_gir = libfprint_girtarget[0]
|
||||
libfprint_typelib = libfprint_girtarget[1]
|
||||
|
||||
+43
-12
@@ -1,13 +1,14 @@
|
||||
project('libfprint', [ 'c', 'cpp' ],
|
||||
version: '1.94.7',
|
||||
version: '1.94.10',
|
||||
license: 'LGPLv2.1+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
'warning_level=1',
|
||||
'c_std=gnu99',
|
||||
],
|
||||
meson_version: '>= 0.56.0')
|
||||
meson_version: '>= 0.59.0')
|
||||
|
||||
fs = import('fs')
|
||||
gnome = import('gnome')
|
||||
|
||||
libfprint_conf = configuration_data()
|
||||
@@ -21,12 +22,17 @@ datadir = prefix / get_option('datadir')
|
||||
cc = meson.get_compiler('c')
|
||||
cpp = meson.get_compiler('cpp')
|
||||
host_system = host_machine.system()
|
||||
|
||||
libfprint_sanitizers = get_option('b_sanitize').split(',')
|
||||
if libfprint_sanitizers == ['none']
|
||||
libfprint_sanitizers = []
|
||||
endif
|
||||
|
||||
glib_min_version = '2.68'
|
||||
|
||||
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
|
||||
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
|
||||
common_cflags = cc.get_supported_arguments([
|
||||
'-Wall',
|
||||
'-Wcast-align',
|
||||
'-Wformat-nonliteral',
|
||||
'-Wformat-security',
|
||||
@@ -87,15 +93,20 @@ versioned_libname = meson.project_name() + '-' + soversion.to_string()
|
||||
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
||||
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
|
||||
gmodule_dep = dependency('gmodule-2.0', version: '>=' + glib_min_version)
|
||||
gusb_dep = dependency('gusb', version: '>= 0.2.0')
|
||||
mathlib_dep = cc.find_library('m', required: false)
|
||||
|
||||
# The following dependencies are only used for tests
|
||||
sh = find_program('sh', required: true)
|
||||
cairo_dep = dependency('cairo', required: false)
|
||||
|
||||
# introspection scanning and Gio-2.0.gir
|
||||
gobject_introspection = dependency('gobject-introspection-1.0', required: get_option('introspection'))
|
||||
|
||||
# SPI
|
||||
have_spi = host_machine.system() == 'linux'
|
||||
|
||||
# Drivers
|
||||
drivers = get_option('drivers').split(',')
|
||||
virtual_drivers = [
|
||||
@@ -121,6 +132,7 @@ default_drivers = [
|
||||
'etes603',
|
||||
'egis0570',
|
||||
'egismoc',
|
||||
'egis_etu905',
|
||||
'vcom5s',
|
||||
'synaptics',
|
||||
'elan',
|
||||
@@ -134,11 +146,18 @@ default_drivers = [
|
||||
'fpcmoc',
|
||||
'realtek',
|
||||
'focaltech_moc',
|
||||
|
||||
# SPI
|
||||
'elanspi',
|
||||
'mafpmoc',
|
||||
'secugen',
|
||||
]
|
||||
|
||||
spi_drivers = [
|
||||
'elanspi'
|
||||
]
|
||||
|
||||
if have_spi
|
||||
default_drivers += spi_drivers
|
||||
endif
|
||||
|
||||
# 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 + [
|
||||
@@ -150,6 +169,7 @@ endian_independent_drivers = virtual_drivers + [
|
||||
'aes4000',
|
||||
'egis0570',
|
||||
'egismoc',
|
||||
'egis_etu905',
|
||||
'elanmoc',
|
||||
'etes603',
|
||||
'focaltech_moc',
|
||||
@@ -175,6 +195,17 @@ if drivers == [ 'default' ]
|
||||
drivers = default_drivers
|
||||
endif
|
||||
|
||||
enabled_spi_drivers = []
|
||||
foreach driver : spi_drivers
|
||||
if driver in drivers
|
||||
enabled_spi_drivers += driver
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if enabled_spi_drivers.length() > 0 and not have_spi
|
||||
error('SPI drivers @0@ are not supported'.format(enabled_spi_drivers))
|
||||
endif
|
||||
|
||||
driver_helper_mapping = {
|
||||
'aes1610' : [ 'aeslib' ],
|
||||
'aes1660' : [ 'aeslib', 'aesx660' ],
|
||||
@@ -183,7 +214,7 @@ driver_helper_mapping = {
|
||||
'aes2660' : [ 'aeslib', 'aesx660' ],
|
||||
'aes3500' : [ 'aeslib', 'aes3k' ],
|
||||
'aes4000' : [ 'aeslib', 'aes3k' ],
|
||||
'uru4000' : [ 'nss' ],
|
||||
'uru4000' : [ 'openssl' ],
|
||||
'elanspi' : [ 'udev' ],
|
||||
'virtual_image' : [ 'virtual' ],
|
||||
'virtual_device' : [ 'virtual' ],
|
||||
@@ -240,13 +271,13 @@ foreach i : driver_helpers
|
||||
|
||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||
optional_deps += imaging_dep
|
||||
elif i == 'nss'
|
||||
nss_dep = dependency('nss', required: false)
|
||||
if not nss_dep.found()
|
||||
error('nss is required for @0@ and possibly others'.format(driver))
|
||||
elif i == 'openssl'
|
||||
openssl_dep = dependency('openssl', version: '>= 3.0', required: false)
|
||||
if not openssl_dep.found()
|
||||
error('OpenSSL is required for @0@ and possibly others'.format(driver))
|
||||
endif
|
||||
|
||||
optional_deps += nss_dep
|
||||
optional_deps += openssl_dep
|
||||
elif i == 'udev'
|
||||
install_udev_rules = true
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ indent_func_proto_param false
|
||||
indent_switch_case 0
|
||||
indent_case_brace 2
|
||||
indent_paren_close 1
|
||||
pp_multiline_define_body_indent 2
|
||||
|
||||
# spacing
|
||||
sp_arith Add
|
||||
@@ -114,6 +115,7 @@ nl_create_for_one_liner False
|
||||
nl_create_while_one_liner False
|
||||
nl_after_semicolon True
|
||||
nl_multi_line_cond true
|
||||
nl_multi_line_define true
|
||||
|
||||
# mod
|
||||
# I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import cairo
|
||||
import sys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
BUILDDIR='@BUILDDIR@'
|
||||
SRCDIR='@SRCDIR@'
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/python3
|
||||
import traceback
|
||||
|
||||
import sys
|
||||
import gi
|
||||
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib, Gio
|
||||
|
||||
# Exit with error on any exception, included those happening in async callbacks
|
||||
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
c = FPrint.Context()
|
||||
c.enumerate()
|
||||
devices = c.get_devices()
|
||||
|
||||
d = devices[0]
|
||||
del devices
|
||||
|
||||
assert d.get_driver() == "egis_etu905"
|
||||
assert not d.has_feature(FPrint.DeviceFeature.CAPTURE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.VERIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
|
||||
d.open_sync()
|
||||
|
||||
def enroll_progress(*args):
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.PRESENT
|
||||
print("enroll progress stage: " + str(args[1]))
|
||||
|
||||
def identify_done(dev, res):
|
||||
global identified
|
||||
identified = True
|
||||
identify_match, identify_print = dev.identify_finish(res)
|
||||
print("MATCH FOUND!" if identify_match else "NO MATCH FOUND")
|
||||
assert identify_match.equal(identify_print)
|
||||
|
||||
# List
|
||||
print("--- LISTING ---")
|
||||
stored = d.list_prints_sync()
|
||||
prints1 = len(stored)
|
||||
print(f"--- LIST DONE: Found {prints1} prints before enroll---")
|
||||
|
||||
# Enroll
|
||||
print("--- ENROLLING ---")
|
||||
template = FPrint.Print.new(d)
|
||||
|
||||
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 ---")
|
||||
del template
|
||||
|
||||
# List
|
||||
print("--- LISTING ---")
|
||||
stored = d.list_prints_sync()
|
||||
prints2 = len(stored)
|
||||
print(f"--- LIST DONE: Found {prints2} prints after enroll---")
|
||||
assert (prints2 - prints1) == 1
|
||||
|
||||
# Cancel test - start async identify and cancel it
|
||||
print("--- TESTING CANCELLATION ---")
|
||||
deserialized_prints = []
|
||||
for sp in stored:
|
||||
deserialized_prints.append(FPrint.Print.deserialize(sp.serialize()))
|
||||
|
||||
cancellable = Gio.Cancellable()
|
||||
identify_cancelled = False
|
||||
cancel_result = None
|
||||
|
||||
def identify_cancelled_cb(dev, res):
|
||||
global identify_cancelled, cancel_result
|
||||
identify_cancelled = True
|
||||
try:
|
||||
result = dev.identify_finish(res)
|
||||
cancel_result = result
|
||||
except Exception as e:
|
||||
cancel_result = e
|
||||
print(f"Identify cancelled with error: {e}")
|
||||
|
||||
d.identify(deserialized_prints, cancellable=cancellable, callback=identify_cancelled_cb)
|
||||
cancellable.cancel()
|
||||
|
||||
while not identify_cancelled:
|
||||
ctx.iteration(True)
|
||||
print(f"--- CANCELLATION TEST DONE, result: {cancel_result} ---")
|
||||
del deserialized_prints
|
||||
|
||||
# Verify
|
||||
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(f"--- VERIFY DONE: Result {verify_res} ---")
|
||||
|
||||
# Identify
|
||||
print("--- ASYNC IDENTIFYING ---")
|
||||
identified = False
|
||||
deserialized_prints = []
|
||||
for p in stored:
|
||||
deserialized_prints.append(FPrint.Print.deserialize(p.serialize()))
|
||||
assert deserialized_prints[-1].equal(p)
|
||||
|
||||
d.identify(deserialized_prints, callback=identify_done)
|
||||
del deserialized_prints
|
||||
|
||||
while not identified:
|
||||
ctx.iteration(True)
|
||||
print("--- IDENTIFY DONE ---")
|
||||
|
||||
# Delete
|
||||
print("--- DELETING ---")
|
||||
p_to_delete = next((sp for sp in stored if sp.equal(p)), None)
|
||||
if p_to_delete:
|
||||
d.delete_print_sync(p_to_delete)
|
||||
print("--- DELETE DONE ---")
|
||||
del p_to_delete
|
||||
del p
|
||||
|
||||
# List
|
||||
print("--- LISTING ---")
|
||||
stored = d.list_prints_sync()
|
||||
prints3 = len(stored)
|
||||
print(f"--- LIST DONE: Found {prints3} prints after deleting---")
|
||||
assert (prints2 - prints3) == 1
|
||||
del stored
|
||||
|
||||
d.close_sync()
|
||||
|
||||
del d
|
||||
del c
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import time
|
||||
import gi
|
||||
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib
|
||||
|
||||
# Exit with error on any exception, included those happening in async callbacks
|
||||
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
c = FPrint.Context()
|
||||
c.enumerate()
|
||||
devices = c.get_devices()
|
||||
|
||||
d = devices[0]
|
||||
del devices
|
||||
|
||||
d.open_sync()
|
||||
|
||||
assert d.get_driver() == "egismoc"
|
||||
assert not d.has_feature(FPrint.DeviceFeature.CAPTURE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.VERIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
|
||||
def enroll_progress(*args):
|
||||
print("finger status: ", d.get_finger_status())
|
||||
print('enroll progress: ' + str(args))
|
||||
|
||||
def identify_done(dev, res):
|
||||
global identified
|
||||
identified = True
|
||||
identify_match, identify_print = dev.identify_finish(res)
|
||||
print('indentification_done: ', identify_match, identify_print)
|
||||
assert identify_match.equal(identify_print)
|
||||
|
||||
# Beginning with list and clear assumes you begin with >0 prints enrolled before capturing
|
||||
|
||||
print("listing - device should have prints")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) > 0
|
||||
del stored
|
||||
|
||||
print("clear device storage")
|
||||
d.clear_storage_sync()
|
||||
print("clear done")
|
||||
|
||||
print("listing - device should be empty")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 0
|
||||
del stored
|
||||
|
||||
print("enrolling")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.LEFT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
p1 = d.enroll_sync(template, None, enroll_progress, None)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("enroll done")
|
||||
del template
|
||||
|
||||
print("listing - device should have 1 print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p1)
|
||||
|
||||
print("verifying")
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
verify_res, verify_print = d.verify_sync(p1)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("verify done")
|
||||
assert verify_res == True
|
||||
|
||||
identified = False
|
||||
deserialized_prints = []
|
||||
for p in stored:
|
||||
deserialized_prints.append(FPrint.Print.deserialize(p.serialize()))
|
||||
assert deserialized_prints[-1].equal(p)
|
||||
del stored
|
||||
|
||||
print('async identifying')
|
||||
d.identify(deserialized_prints, callback=identify_done)
|
||||
del deserialized_prints
|
||||
|
||||
while not identified:
|
||||
ctx.iteration(True)
|
||||
|
||||
print("try to enroll duplicate")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.RIGHT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
try:
|
||||
d.enroll_sync(template, None, enroll_progress, None)
|
||||
except GLib.Error as error:
|
||||
assert error.matches(FPrint.DeviceError.quark(),
|
||||
FPrint.DeviceError.DATA_DUPLICATE)
|
||||
except Exception as exc:
|
||||
raise
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("duplicate enroll attempt done")
|
||||
|
||||
print("listing - device should still only have 1 print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p1)
|
||||
del stored
|
||||
|
||||
print("enroll new finger")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.RIGHT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
p2 = d.enroll_sync(template, None, enroll_progress, None)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("enroll new finger done")
|
||||
del template
|
||||
|
||||
print("listing - device should have 2 prints")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 2
|
||||
assert (stored[0].equal(p1) and stored[1].equal(p2)) or (stored[0].equal(p2) and stored[1].equal(p1))
|
||||
del stored
|
||||
|
||||
print("deleting first print")
|
||||
d.delete_print_sync(p1)
|
||||
print("delete done")
|
||||
del p1
|
||||
|
||||
print("listing - device should only have second print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p2)
|
||||
del stored
|
||||
del p2
|
||||
|
||||
print("clear device storage")
|
||||
d.clear_storage_sync()
|
||||
print("clear done")
|
||||
|
||||
print("listing - device should be empty")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 0
|
||||
del stored
|
||||
|
||||
d.close_sync()
|
||||
|
||||
del d
|
||||
del c
|
||||
@@ -0,0 +1,255 @@
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb1/1-7
|
||||
N: bus/usb/001/021=12010002FF0000407A1C860556620102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
E: BUSNUM=001
|
||||
E: DEVNAME=/dev/bus/usb/001/021
|
||||
E: DEVNUM=021
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_MODEL=ETU905A88-E
|
||||
E: ID_MODEL_ENC=ETU905A88-E
|
||||
E: ID_MODEL_ID=0586
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:7
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_7
|
||||
E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:7
|
||||
E: ID_PERSIST=0
|
||||
E: ID_REVISION=6256
|
||||
E: ID_SERIAL=EGIS_ETU905A88-E_0A5743PCU834
|
||||
E: ID_SERIAL_SHORT=0A5743PCU834
|
||||
E: ID_USB_INTERFACES=:ff0000:
|
||||
E: ID_USB_MODEL=ETU905A88-E
|
||||
E: ID_USB_MODEL_ENC=ETU905A88-E
|
||||
E: ID_USB_MODEL_ID=0586
|
||||
E: ID_USB_REVISION=6256
|
||||
E: ID_USB_SERIAL=EGIS_ETU905A88-E_0A5743PCU834
|
||||
E: ID_USB_SERIAL_SHORT=0A5743PCU834
|
||||
E: ID_USB_VENDOR=EGIS
|
||||
E: ID_USB_VENDOR_ENC=EGIS
|
||||
E: ID_USB_VENDOR_ID=1c7a
|
||||
E: ID_VENDOR=EGIS
|
||||
E: ID_VENDOR_ENC=EGIS
|
||||
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
|
||||
E: ID_VENDOR_ID=1c7a
|
||||
E: MAJOR=189
|
||||
E: MINOR=20
|
||||
E: PRODUCT=1c7a/586/6256
|
||||
E: SUBSYSTEM=usb
|
||||
E: TYPE=255/0/0
|
||||
A: authorized=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=ff\n
|
||||
A: bDeviceProtocol=00\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=100mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=6256\n
|
||||
A: bmAttributes=a0\n
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002FF0000407A1C860556620102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
A: dev=189:20\n
|
||||
A: devnum=21\n
|
||||
A: devpath=7\n
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e/device:4f/device:56
|
||||
A: idProduct=0586\n
|
||||
A: idVendor=1c7a\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=EGIS\n
|
||||
A: maxchild=0\n
|
||||
A: physical_location/dock=no\n
|
||||
A: physical_location/horizontal_position=center\n
|
||||
A: physical_location/lid=no\n
|
||||
A: physical_location/panel=front\n
|
||||
A: physical_location/vertical_position=center\n
|
||||
L: port=../1-0:1.0/usb1-port7
|
||||
A: power/active_duration=12644\n
|
||||
A: power/autosuspend=2\n
|
||||
A: power/autosuspend_delay_ms=2000\n
|
||||
A: power/connected_duration=230907\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/persist=0\n
|
||||
A: power/runtime_active_time=12929\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=217715\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=ETU905A88-E\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=fixed\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=0A5743PCU834\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=18\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb1
|
||||
N: bus/usb/001/001=12010002090001406B1D020008060302010109021900010100E0000904000001090000000705810304000C
|
||||
E: BUSNUM=001
|
||||
E: CURRENT_TAGS=:seat:
|
||||
E: DEVNAME=/dev/bus/usb/001/001
|
||||
E: DEVNUM=001
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
||||
E: ID_MODEL=xHCI_Host_Controller
|
||||
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||
E: ID_MODEL_ID=0002
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_REVISION=0608
|
||||
E: ID_SERIAL=Linux_6.8.5-arch1-1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_INTERFACES=:090000:
|
||||
E: ID_USB_MODEL=xHCI_Host_Controller
|
||||
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_USB_MODEL_ID=0002
|
||||
E: ID_USB_REVISION=0608
|
||||
E: ID_USB_SERIAL=Linux_6.8.5-arch1-1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_USB_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_VENDOR=Linux_6.8.5-arch1-1_xhci-hcd
|
||||
E: ID_USB_VENDOR_ENC=Linux\x206.8.5-arch1-1\x20xhci-hcd
|
||||
E: ID_USB_VENDOR_ID=1d6b
|
||||
E: ID_VENDOR=Linux_6.8.5-arch1-1_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x206.8.5-arch1-1\x20xhci-hcd
|
||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||
E: ID_VENDOR_ID=1d6b
|
||||
E: MAJOR=189
|
||||
E: MINOR=0
|
||||
E: PRODUCT=1d6b/2/608
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:seat:
|
||||
E: TYPE=9/0/1
|
||||
A: authorized=1\n
|
||||
A: authorized_default=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=09\n
|
||||
A: bDeviceProtocol=01\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=0mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=0608\n
|
||||
A: bmAttributes=e0\n
|
||||
A: busnum=1\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020008060302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:0\n
|
||||
A: devnum=1\n
|
||||
A: devpath=0\n
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e/device:4f
|
||||
A: idProduct=0002\n
|
||||
A: idVendor=1d6b\n
|
||||
A: interface_authorized_default=1\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=Linux 6.8.5-arch1-1 xhci-hcd\n
|
||||
A: maxchild=12\n
|
||||
A: power/active_duration=73066477\n
|
||||
A: power/autosuspend=0\n
|
||||
A: power/autosuspend_delay_ms=0\n
|
||||
A: power/connected_duration=73071614\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/runtime_active_time=73070027\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=0\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=xHCI Host Controller\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=unknown\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=0000:00:14.0\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=1111\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0
|
||||
E: DRIVER=xhci_hcd
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_MODEL_FROM_DATABASE=Alder Lake PCH USB 3.2 xHCI Host Controller
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||
E: MODALIAS=pci:v00008086d000051EDsv00001043sd0000201Fbc0Csc03i30
|
||||
E: PCI_CLASS=C0330
|
||||
E: PCI_ID=8086:51ED
|
||||
E: PCI_SLOT_NAME=0000:00:14.0
|
||||
E: PCI_SUBSYS_ID=1043:201F
|
||||
E: SUBSYSTEM=pci
|
||||
A: ari_enabled=0\n
|
||||
A: broken_parity_status=0\n
|
||||
A: class=0x0c0330\n
|
||||
H: config=8680ED51060490020130030C000080000400220560000000000000000000000000000000000000000000000043101F20000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C10800000000000000000000000590B7001805E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F110112000000
|
||||
A: consistent_dma_mask_bits=64\n
|
||||
A: d3cold_allowed=1\n
|
||||
A: device=0x51ed\n
|
||||
A: dma_mask_bits=64\n
|
||||
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||
A: driver_override=(null)\n
|
||||
A: enable=1\n
|
||||
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e
|
||||
A: irq=143\n
|
||||
A: local_cpulist=0-15\n
|
||||
A: local_cpus=ffff\n
|
||||
A: modalias=pci:v00008086d000051EDsv00001043sd0000201Fbc0Csc03i30\n
|
||||
A: msi_bus=1\n
|
||||
A: msi_irqs/143=msi\n
|
||||
A: msi_irqs/144=msi\n
|
||||
A: msi_irqs/145=msi\n
|
||||
A: msi_irqs/146=msi\n
|
||||
A: msi_irqs/147=msi\n
|
||||
A: msi_irqs/148=msi\n
|
||||
A: msi_irqs/149=msi\n
|
||||
A: msi_irqs/150=msi\n
|
||||
A: numa_node=-1\n
|
||||
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 8 9 2112 9\nxHCI ring segments 43 53 4096 53\nbuffer-2048 0 16 2048 8\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 128 32 1\n
|
||||
A: power/control=auto\n
|
||||
A: power/runtime_active_time=73070690\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=0\n
|
||||
A: power/wakeup=enabled\n
|
||||
A: power/wakeup_abort_count=0\n
|
||||
A: power/wakeup_active=0\n
|
||||
A: power/wakeup_active_count=0\n
|
||||
A: power/wakeup_count=0\n
|
||||
A: power/wakeup_expire_count=0\n
|
||||
A: power/wakeup_last_time_ms=0\n
|
||||
A: power/wakeup_max_time_ms=0\n
|
||||
A: power/wakeup_total_time_ms=0\n
|
||||
A: power_state=D0\n
|
||||
A: resource=0x0000006005220000 0x000000600522ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
|
||||
A: revision=0x01\n
|
||||
A: subsystem_device=0x201f\n
|
||||
A: subsystem_vendor=0x1043\n
|
||||
A: vendor=0x8086\n
|
||||
Binary file not shown.
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import time
|
||||
import gi
|
||||
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib
|
||||
|
||||
# Exit with error on any exception, included those happening in async callbacks
|
||||
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
c = FPrint.Context()
|
||||
c.enumerate()
|
||||
devices = c.get_devices()
|
||||
|
||||
d = devices[0]
|
||||
del devices
|
||||
|
||||
d.open_sync()
|
||||
|
||||
assert d.get_driver() == "egismoc"
|
||||
assert not d.has_feature(FPrint.DeviceFeature.CAPTURE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.VERIFY)
|
||||
assert d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
|
||||
def enroll_progress(*args):
|
||||
print("finger status: ", d.get_finger_status())
|
||||
print('enroll progress: ' + str(args))
|
||||
|
||||
def identify_done(dev, res):
|
||||
global identified
|
||||
identified = True
|
||||
identify_match, identify_print = dev.identify_finish(res)
|
||||
print('indentification_done: ', identify_match, identify_print)
|
||||
assert identify_match.equal(identify_print)
|
||||
|
||||
# Beginning with list and clear assumes you begin with >0 prints enrolled before capturing
|
||||
|
||||
print("listing - device should have prints")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) > 0
|
||||
del stored
|
||||
|
||||
print("clear device storage")
|
||||
d.clear_storage_sync()
|
||||
print("clear done")
|
||||
|
||||
print("listing - device should be empty")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 0
|
||||
del stored
|
||||
|
||||
print("enrolling")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.LEFT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
p1 = d.enroll_sync(template, None, enroll_progress, None)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("enroll done")
|
||||
del template
|
||||
|
||||
print("listing - device should have 1 print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p1)
|
||||
|
||||
print("verifying")
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
verify_res, verify_print = d.verify_sync(p1)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("verify done")
|
||||
assert verify_res == True
|
||||
|
||||
identified = False
|
||||
deserialized_prints = []
|
||||
for p in stored:
|
||||
deserialized_prints.append(FPrint.Print.deserialize(p.serialize()))
|
||||
assert deserialized_prints[-1].equal(p)
|
||||
del stored
|
||||
|
||||
print('async identifying')
|
||||
d.identify(deserialized_prints, callback=identify_done)
|
||||
del deserialized_prints
|
||||
|
||||
while not identified:
|
||||
ctx.iteration(True)
|
||||
|
||||
print("try to enroll duplicate")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.RIGHT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
try:
|
||||
d.enroll_sync(template, None, enroll_progress, None)
|
||||
except GLib.Error as error:
|
||||
assert error.matches(FPrint.DeviceError.quark(),
|
||||
FPrint.DeviceError.DATA_DUPLICATE)
|
||||
except Exception as exc:
|
||||
raise
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("duplicate enroll attempt done")
|
||||
|
||||
print("listing - device should still only have 1 print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p1)
|
||||
del stored
|
||||
|
||||
print("enroll new finger")
|
||||
template = FPrint.Print.new(d)
|
||||
template.set_finger(FPrint.Finger.RIGHT_INDEX)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
p2 = d.enroll_sync(template, None, enroll_progress, None)
|
||||
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
|
||||
print("enroll new finger done")
|
||||
del template
|
||||
|
||||
print("listing - device should have 2 prints")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 2
|
||||
assert (stored[0].equal(p1) and stored[1].equal(p2)) or (stored[0].equal(p2) and stored[1].equal(p1))
|
||||
del stored
|
||||
|
||||
print("deleting first print")
|
||||
d.delete_print_sync(p1)
|
||||
print("delete done")
|
||||
del p1
|
||||
|
||||
print("listing - device should only have second print")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p2)
|
||||
del stored
|
||||
del p2
|
||||
|
||||
print("clear device storage")
|
||||
d.clear_storage_sync()
|
||||
print("clear done")
|
||||
|
||||
print("listing - device should be empty")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 0
|
||||
del stored
|
||||
|
||||
d.close_sync()
|
||||
|
||||
del d
|
||||
del c
|
||||
@@ -0,0 +1,270 @@
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3/3-5
|
||||
N: bus/usb/003/009=12010002FF0000407A1C870567640102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
E: BUSNUM=003
|
||||
E: DEVNAME=/dev/bus/usb/003/009
|
||||
E: DEVNUM=009
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_MODEL=ETU905A88-E
|
||||
E: ID_MODEL_ENC=ETU905A88-E
|
||||
E: ID_MODEL_ID=0587
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:5
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_5
|
||||
E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:5
|
||||
E: ID_PERSIST=0
|
||||
E: ID_REVISION=6467
|
||||
E: ID_SERIAL=EGIS_ETU905A88-E_198427PCU834
|
||||
E: ID_SERIAL_SHORT=198427PCU834
|
||||
E: ID_USB_INTERFACES=:ff0000:
|
||||
E: ID_USB_MODEL=ETU905A88-E
|
||||
E: ID_USB_MODEL_ENC=ETU905A88-E
|
||||
E: ID_USB_MODEL_ID=0587
|
||||
E: ID_USB_REVISION=6467
|
||||
E: ID_USB_SERIAL=EGIS_ETU905A88-E_198427PCU834
|
||||
E: ID_USB_SERIAL_SHORT=198427PCU834
|
||||
E: ID_USB_VENDOR=EGIS
|
||||
E: ID_USB_VENDOR_ENC=EGIS
|
||||
E: ID_USB_VENDOR_ID=1c7a
|
||||
E: ID_VENDOR=EGIS
|
||||
E: ID_VENDOR_ENC=EGIS
|
||||
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
|
||||
E: ID_VENDOR_ID=1c7a
|
||||
E: MAJOR=189
|
||||
E: MINOR=264
|
||||
E: PRODUCT=1c7a/587/6467
|
||||
E: SUBSYSTEM=usb
|
||||
E: TYPE=255/0/0
|
||||
A: authorized=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=ff\n
|
||||
A: bDeviceProtocol=00\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=100mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=6467\n
|
||||
A: bmAttributes=a0\n
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002FF0000407A1C870567640102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
A: dev=189:264\n
|
||||
A: devnum=9\n
|
||||
A: devpath=5\n
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e/device:4f/device:54
|
||||
A: idProduct=0587\n
|
||||
A: idVendor=1c7a\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=EGIS\n
|
||||
A: maxchild=0\n
|
||||
A: physical_location/dock=no\n
|
||||
A: physical_location/horizontal_position=left\n
|
||||
A: physical_location/lid=no\n
|
||||
A: physical_location/panel=top\n
|
||||
A: physical_location/vertical_position=upper\n
|
||||
L: port=../3-0:1.0/usb3-port5
|
||||
A: power/active_duration=58096\n
|
||||
A: power/async=enabled\n
|
||||
A: power/autosuspend=2\n
|
||||
A: power/autosuspend_delay_ms=2000\n
|
||||
A: power/connected_duration=183928\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/persist=0\n
|
||||
A: power/runtime_active_kids=0\n
|
||||
A: power/runtime_active_time=58510\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=125136\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=ETU905A88-E\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=fixed\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=198427PCU834\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=547\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3
|
||||
N: bus/usb/003/001=12010002090001406B1D020006060302010109021900010100E0000904000001090000000705810304000C
|
||||
E: BUSNUM=003
|
||||
E: CURRENT_TAGS=:seat:
|
||||
E: DEVNAME=/dev/bus/usb/003/001
|
||||
E: DEVNUM=001
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
||||
E: ID_MODEL=xHCI_Host_Controller
|
||||
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||
E: ID_MODEL_ID=0002
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_REVISION=0606
|
||||
E: ID_SERIAL=Linux_6.6.0-14-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_INTERFACES=:090000:
|
||||
E: ID_USB_MODEL=xHCI_Host_Controller
|
||||
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_USB_MODEL_ID=0002
|
||||
E: ID_USB_REVISION=0606
|
||||
E: ID_USB_SERIAL=Linux_6.6.0-14-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_USB_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_VENDOR=Linux_6.6.0-14-generic_xhci-hcd
|
||||
E: ID_USB_VENDOR_ENC=Linux\x206.6.0-14-generic\x20xhci-hcd
|
||||
E: ID_USB_VENDOR_ID=1d6b
|
||||
E: ID_VENDOR=Linux_6.6.0-14-generic_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x206.6.0-14-generic\x20xhci-hcd
|
||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||
E: ID_VENDOR_ID=1d6b
|
||||
E: MAJOR=189
|
||||
E: MINOR=256
|
||||
E: PRODUCT=1d6b/2/606
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:seat:
|
||||
E: TYPE=9/0/1
|
||||
A: authorized=1\n
|
||||
A: authorized_default=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=09\n
|
||||
A: bDeviceProtocol=01\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=0mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=0606\n
|
||||
A: bmAttributes=e0\n
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020006060302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:256\n
|
||||
A: devnum=1\n
|
||||
A: devpath=0\n
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e/device:4f
|
||||
A: idProduct=0002\n
|
||||
A: idVendor=1d6b\n
|
||||
A: interface_authorized_default=1\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=Linux 6.6.0-14-generic xhci-hcd\n
|
||||
A: maxchild=12\n
|
||||
A: power/active_duration=5145268\n
|
||||
A: power/async=enabled\n
|
||||
A: power/autosuspend=0\n
|
||||
A: power/autosuspend_delay_ms=0\n
|
||||
A: power/connected_duration=5191200\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/runtime_active_kids=2\n
|
||||
A: power/runtime_active_time=5145262\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=45937\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=xHCI Host Controller\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=unknown\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=0000:00:14.0\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=637\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0
|
||||
E: DRIVER=xhci_hcd
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_MODEL_FROM_DATABASE=Alder Lake PCH USB 3.2 xHCI Host Controller
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||
E: MODALIAS=pci:v00008086d000051EDsv00001043sd0000201Fbc0Csc03i30
|
||||
E: PCI_CLASS=C0330
|
||||
E: PCI_ID=8086:51ED
|
||||
E: PCI_SLOT_NAME=0000:00:14.0
|
||||
E: PCI_SUBSYS_ID=1043:201F
|
||||
E: SUBSYSTEM=pci
|
||||
A: ari_enabled=0\n
|
||||
A: broken_parity_status=0\n
|
||||
A: class=0x0c0330\n
|
||||
H: config=8680ED51060490020130030C000080000400262F62000000000000000000000000000000000000000000000043101F20000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C1080000000000000000000000059087001805E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F110112000000
|
||||
A: consistent_dma_mask_bits=64\n
|
||||
A: d3cold_allowed=1\n
|
||||
A: dbc=disabled\n
|
||||
A: dbc_bInterfaceProtocol=01\n
|
||||
A: dbc_bcdDevice=0010\n
|
||||
A: dbc_idProduct=0010\n
|
||||
A: dbc_idVendor=1d6b\n
|
||||
A: device=0x51ed\n
|
||||
A: dma_mask_bits=64\n
|
||||
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||
A: driver_override=(null)\n
|
||||
A: enable=1\n
|
||||
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4e
|
||||
A: index=10\n
|
||||
L: iommu=../../virtual/iommu/dmar1
|
||||
L: iommu_group=../../../kernel/iommu_groups/11
|
||||
A: irq=145\n
|
||||
A: label=Onboard - Other\n
|
||||
A: local_cpulist=0-19\n
|
||||
A: local_cpus=fffff\n
|
||||
A: modalias=pci:v00008086d000051EDsv00001043sd0000201Fbc0Csc03i30\n
|
||||
A: msi_bus=1\n
|
||||
A: msi_irqs/145=msi\n
|
||||
A: numa_node=-1\n
|
||||
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 1 32 128 1\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 10 11 2112 11\nxHCI ring segments 38 38 4096 38\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n
|
||||
A: power/async=enabled\n
|
||||
A: power/control=auto\n
|
||||
A: power/runtime_active_kids=2\n
|
||||
A: power/runtime_active_time=5192072\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=0\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=enabled\n
|
||||
A: power/wakeup_abort_count=0\n
|
||||
A: power/wakeup_active=0\n
|
||||
A: power/wakeup_active_count=0\n
|
||||
A: power/wakeup_count=0\n
|
||||
A: power/wakeup_expire_count=0\n
|
||||
A: power/wakeup_last_time_ms=0\n
|
||||
A: power/wakeup_max_time_ms=0\n
|
||||
A: power/wakeup_total_time_ms=0\n
|
||||
A: power_state=D0\n
|
||||
A: resource=0x000000622f260000 0x000000622f26ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
|
||||
A: revision=0x01\n
|
||||
A: subsystem_device=0x201f\n
|
||||
A: subsystem_vendor=0x1043\n
|
||||
A: vendor=0x8086\n
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import gi
|
||||
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib
|
||||
|
||||
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
c = FPrint.Context()
|
||||
c.enumerate()
|
||||
devices = c.get_devices()
|
||||
|
||||
d = next((dev for dev in devices if dev.get_driver() == "focaltech_moc"), None)
|
||||
|
||||
if d is None:
|
||||
print("Error: Focaltech driver not loaded for any discovered device.")
|
||||
sys.exit(1)
|
||||
|
||||
del devices
|
||||
|
||||
d.open_sync()
|
||||
assert d.get_driver() == "focaltech_moc"
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST)
|
||||
assert not d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
|
||||
|
||||
print("Clearing storage (0xAC)...")
|
||||
d.clear_storage_sync()
|
||||
|
||||
template = FPrint.Print.new(d)
|
||||
|
||||
def enroll_progress(*args):
|
||||
print('Enroll progress: ' + str(args))
|
||||
|
||||
print("Enrolling (Perform 12 taps now)...")
|
||||
p = d.enroll_sync(template, None, enroll_progress, None)
|
||||
print("Enroll done.")
|
||||
|
||||
print("Listing prints...")
|
||||
stored = d.list_prints_sync()
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p)
|
||||
print("List verified.")
|
||||
|
||||
print("Verifying...")
|
||||
verify_res, verify_print = d.verify_sync(p)
|
||||
assert verify_res == True
|
||||
print("Verify done.")
|
||||
|
||||
print("Delete is a no-op here")
|
||||
d.delete_print_sync(p)
|
||||
|
||||
print('Identifying...')
|
||||
match, identify_print = d.identify_sync(stored, None, None, None)
|
||||
|
||||
print('Identification SUCCESS')
|
||||
assert match.equal(identify_print)
|
||||
assert match.equal(p)
|
||||
|
||||
print("Clearing storage...")
|
||||
d.clear_storage_sync()
|
||||
|
||||
final_list = d.list_prints_sync()
|
||||
assert len(final_list) == 0
|
||||
print("Cleanup verified.")
|
||||
|
||||
d.close_sync()
|
||||
@@ -0,0 +1,267 @@
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3/3-2
|
||||
N: bus/usb/003/002=12010102000000400828536501210301020109022000010104A0FA0904000002DCA0B0000705010240000007058202400000
|
||||
E: BUSNUM=003
|
||||
E: CURRENT_TAGS=:seat:
|
||||
E: DEVNAME=/dev/bus/usb/003/002
|
||||
E: DEVNUM=002
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_2
|
||||
E: ID_MODEL=Focaltech_FT9365_ESS
|
||||
E: ID_MODEL_ENC=Focaltech\x20FT9365\x20ESS
|
||||
E: ID_MODEL_ID=6553
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:2
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2
|
||||
E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:2
|
||||
E: ID_PERSIST=0
|
||||
E: ID_REVISION=2101
|
||||
E: ID_SERIAL=Generic_Focaltech_FT9365_ESS_201801010001
|
||||
E: ID_SERIAL_SHORT=201801010001
|
||||
E: ID_USB_INTERFACES=:dca0b0:
|
||||
E: ID_USB_MODEL=Focaltech_FT9365_ESS
|
||||
E: ID_USB_MODEL_ENC=Focaltech\x20FT9365\x20ESS
|
||||
E: ID_USB_MODEL_ID=6553
|
||||
E: ID_USB_REVISION=2101
|
||||
E: ID_USB_SERIAL=Generic_Focaltech_FT9365_ESS_201801010001
|
||||
E: ID_USB_SERIAL_SHORT=201801010001
|
||||
E: ID_USB_VENDOR=Generic
|
||||
E: ID_USB_VENDOR_ENC=Generic
|
||||
E: ID_USB_VENDOR_ID=2808
|
||||
E: ID_VENDOR=Generic
|
||||
E: ID_VENDOR_ENC=Generic
|
||||
E: ID_VENDOR_ID=2808
|
||||
E: MAJOR=189
|
||||
E: MINOR=257
|
||||
E: PRODUCT=2808/6553/2101
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:seat:
|
||||
E: TYPE=0/0/0
|
||||
A: authorized=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=00\n
|
||||
A: bDeviceProtocol=00\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=500mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=2101\n
|
||||
A: bmAttributes=a0\n
|
||||
H: bos_descriptors=050F2900021C100500DF60DDD88945C74C9CD2659D9E648A9F000003066E0315000810110103000000
|
||||
A: busnum=3\n
|
||||
A: configuration=Focaltech FT9365 ESS\n
|
||||
H: descriptors=12010102000000400828536501210301020109022000010104A0FA0904000002DCA0B0000705010240000007058202400000
|
||||
A: dev=189:257\n
|
||||
A: devnum=2\n
|
||||
A: devpath=2\n
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:56/device:57/device:59
|
||||
A: idProduct=6553\n
|
||||
A: idVendor=2808\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=Generic\n
|
||||
A: maxchild=0\n
|
||||
A: physical_location/dock=no\n
|
||||
A: physical_location/horizontal_position=left\n
|
||||
A: physical_location/lid=no\n
|
||||
A: physical_location/panel=top\n
|
||||
A: physical_location/vertical_position=upper\n
|
||||
L: port=../3-0:1.0/usb3-port2
|
||||
A: power/active_duration=886464\n
|
||||
A: power/autosuspend=2\n
|
||||
A: power/autosuspend_delay_ms=2000\n
|
||||
A: power/connected_duration=15109711\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/persist=0\n
|
||||
A: power/runtime_active_time=894614\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=14214859\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=Focaltech FT9365 ESS\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=fixed\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=201801010001\n
|
||||
A: speed=12\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=12224\n
|
||||
A: version= 2.01\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3
|
||||
N: bus/usb/003/001=12010002090001406B1D020018060302010109021900010100E0000904000001090000000705810304000C
|
||||
E: BUSNUM=003
|
||||
E: CURRENT_TAGS=:seat:
|
||||
E: DEVNAME=/dev/bus/usb/003/001
|
||||
E: DEVNUM=001
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
||||
E: ID_MODEL=xHCI_Host_Controller
|
||||
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||
E: ID_MODEL_ID=0002
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_REVISION=0618
|
||||
E: ID_SERIAL=Linux_6.18.9-arch1-2_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_INTERFACES=:090000:
|
||||
E: ID_USB_MODEL=xHCI_Host_Controller
|
||||
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_USB_MODEL_ID=0002
|
||||
E: ID_USB_REVISION=0618
|
||||
E: ID_USB_SERIAL=Linux_6.18.9-arch1-2_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_USB_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_VENDOR=Linux_6.18.9-arch1-2_xhci-hcd
|
||||
E: ID_USB_VENDOR_ENC=Linux\x206.18.9-arch1-2\x20xhci-hcd
|
||||
E: ID_USB_VENDOR_ID=1d6b
|
||||
E: ID_VENDOR=Linux_6.18.9-arch1-2_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x206.18.9-arch1-2\x20xhci-hcd
|
||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||
E: ID_VENDOR_ID=1d6b
|
||||
E: MAJOR=189
|
||||
E: MINOR=256
|
||||
E: PRODUCT=1d6b/2/618
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:seat:
|
||||
E: TYPE=9/0/1
|
||||
A: authorized=1\n
|
||||
A: authorized_default=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
A: bConfigurationValue=1\n
|
||||
A: bDeviceClass=09\n
|
||||
A: bDeviceProtocol=01\n
|
||||
A: bDeviceSubClass=00\n
|
||||
A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=0mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=0618\n
|
||||
A: bmAttributes=e0\n
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020018060302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:256\n
|
||||
A: devnum=1\n
|
||||
A: devpath=0\n
|
||||
L: driver=../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:56/device:57
|
||||
A: idProduct=0002\n
|
||||
A: idVendor=1d6b\n
|
||||
A: interface_authorized_default=1\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=Linux 6.18.9-arch1-2 xhci-hcd\n
|
||||
A: maxchild=12\n
|
||||
A: power/active_duration=7247968\n
|
||||
A: power/autosuspend=0\n
|
||||
A: power/autosuspend_delay_ms=0\n
|
||||
A: power/connected_duration=15109854\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/runtime_active_time=7247962\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=7861889\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
A: power/wakeup_active_count=\n
|
||||
A: power/wakeup_count=\n
|
||||
A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=xHCI Host Controller\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=unknown\n
|
||||
A: rx_lanes=1\n
|
||||
A: serial=0000:00:14.0\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=1929\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0
|
||||
E: DRIVER=xhci_hcd
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_MODEL_FROM_DATABASE=Alder Lake PCH USB 3.2 xHCI Host Controller
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||
E: MODALIAS=pci:v00008086d000051EDsv0000144Dsd0000C1D9bc0Csc03i30
|
||||
E: PCI_CLASS=C0330
|
||||
E: PCI_ID=8086:51ED
|
||||
E: PCI_SLOT_NAME=0000:00:14.0
|
||||
E: PCI_SUBSYS_ID=144D:C1D9
|
||||
E: SUBSYSTEM=pci
|
||||
A: ari_enabled=0\n
|
||||
A: broken_parity_status=0\n
|
||||
A: class=0x0c0330\n
|
||||
H: config=8680ED51060490020130030C00008000040012016000000000000000000000000000000000000000000000004D14D9C1000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C10800000000000000000000000590B7001804E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F110112000000
|
||||
A: consistent_dma_mask_bits=64\n
|
||||
A: d3cold_allowed=1\n
|
||||
A: dbc=disabled\n
|
||||
A: dbc_bInterfaceProtocol=01\n
|
||||
A: dbc_bcdDevice=0010\n
|
||||
A: dbc_idProduct=0010\n
|
||||
A: dbc_idVendor=1d6b\n
|
||||
A: dbc_poll_interval_ms=64\n
|
||||
A: device=0x51ed\n
|
||||
A: dma_mask_bits=64\n
|
||||
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||
A: driver_override=(null)\n
|
||||
A: enable=1\n
|
||||
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:56
|
||||
A: index=5\n
|
||||
A: irq=131\n
|
||||
A: label=Onboard - Other\n
|
||||
A: local_cpulist=0-11\n
|
||||
A: local_cpus=fff\n
|
||||
A: modalias=pci:v00008086d000051EDsv0000144Dsd0000C1D9bc0Csc03i30\n
|
||||
A: msi_bus=1\n
|
||||
A: msi_irqs/131=msi\n
|
||||
A: msi_irqs/132=msi\n
|
||||
A: msi_irqs/133=msi\n
|
||||
A: msi_irqs/134=msi\n
|
||||
A: msi_irqs/135=msi\n
|
||||
A: msi_irqs/136=msi\n
|
||||
A: msi_irqs/137=msi\n
|
||||
A: msi_irqs/138=msi\n
|
||||
A: numa_node=-1\n
|
||||
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 256 port bw ctx arrays 0 0 256 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 8 9 2112 9\nxHCI ring segments 33 33 4096 33\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
|
||||
A: power/control=auto\n
|
||||
A: power/runtime_active_time=7261537\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=7861354\n
|
||||
A: power/wakeup=enabled\n
|
||||
A: power/wakeup_abort_count=0\n
|
||||
A: power/wakeup_active=0\n
|
||||
A: power/wakeup_active_count=0\n
|
||||
A: power/wakeup_count=0\n
|
||||
A: power/wakeup_expire_count=0\n
|
||||
A: power/wakeup_last_time_ms=0\n
|
||||
A: power/wakeup_max_time_ms=0\n
|
||||
A: power/wakeup_total_time_ms=0\n
|
||||
A: power_state=D0\n
|
||||
A: resource=0x0000006001120000 0x000000600112ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
|
||||
A: revision=0x01\n
|
||||
A: subsystem_device=0xc1d9\n
|
||||
A: subsystem_vendor=0x144d\n
|
||||
A: vendor=0x8086\n
|
||||
|
||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
@@ -27,10 +27,14 @@ assert not d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)
|
||||
assert not d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)
|
||||
|
||||
d.open_sync()
|
||||
|
||||
print("Clear")
|
||||
d.clear_storage_sync()
|
||||
print("Clear done")
|
||||
|
||||
template = FPrint.Print.new(d)
|
||||
|
||||
def enroll_progress(*args):
|
||||
|
||||
+249
-361
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
+7
-7
@@ -3,7 +3,7 @@ N: bus/usb/001/019=1201000200000040A510E0FF10000102000109021900010104A0320904000
|
||||
E: DEVNAME=/dev/bus/usb/001/019
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: PRODUCT=10a5/ffe0/10
|
||||
E: PRODUCT=10a5/a306/10
|
||||
E: TYPE=0/0/0
|
||||
E: BUSNUM=001
|
||||
E: DEVNUM=019
|
||||
@@ -13,11 +13,11 @@ E: SUBSYSTEM=usb
|
||||
E: ID_VENDOR=FPC
|
||||
E: ID_VENDOR_ENC=FPC
|
||||
E: ID_VENDOR_ID=10a5
|
||||
E: ID_MODEL=FPC_L:0001_FW:127010
|
||||
E: ID_MODEL_ENC=FPC\x20L:0001\x20FW:127010
|
||||
E: ID_MODEL_ID=ffe0
|
||||
E: ID_MODEL=FPC_L:0001_FW:222709
|
||||
E: ID_MODEL_ENC=FPC\x20L:0001\x20FW:222709
|
||||
E: ID_MODEL_ID=a306
|
||||
E: ID_REVISION=0010
|
||||
E: ID_SERIAL=FPC_FPC_L:0001_FW:127010
|
||||
E: ID_SERIAL=FPC_FPC_L:0001_FW:222709
|
||||
E: ID_BUS=usb
|
||||
E: ID_USB_INTERFACES=:ffffff:
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:1
|
||||
@@ -45,7 +45,7 @@ A: devnum=19\n
|
||||
A: devpath=1\n
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:1e
|
||||
A: idProduct=ffe0\n
|
||||
A: idProduct=a306\n
|
||||
A: idVendor=10a5\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=FPC\n
|
||||
@@ -74,7 +74,7 @@ A: power/wakeup_expire_count=\n
|
||||
A: power/wakeup_last_time_ms=\n
|
||||
A: power/wakeup_max_time_ms=\n
|
||||
A: power/wakeup_total_time_ms=\n
|
||||
A: product=FPC L:0001 FW:127010\n
|
||||
A: product=FPC L:0001 FW:222709\n
|
||||
A: quirks=0x0\n
|
||||
A: removable=removable\n
|
||||
A: rx_lanes=1\n
|
||||
|
||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
@@ -53,17 +53,20 @@ 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")
|
||||
assert p.get_description() == 'FP1-00000000-0-00000000-nobody'
|
||||
|
||||
print("listing")
|
||||
stored = d.list_prints_sync()
|
||||
print("listing done")
|
||||
assert len(stored) == 1
|
||||
assert stored[0].equal(p)
|
||||
assert stored[0].get_description() == 'FP1-00000000-0-00000000-nobody'
|
||||
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")
|
||||
assert verify_print.get_description() == 'FP1-00000000-0-00000000-nobody'
|
||||
del p
|
||||
assert verify_res == True
|
||||
|
||||
|
||||
+315
-103
File diff suppressed because one or more lines are too long
@@ -24,3 +24,12 @@
|
||||
...
|
||||
fun:g_thread_new
|
||||
}
|
||||
|
||||
{
|
||||
<ignore-libusb-context>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: possible
|
||||
fun:calloc
|
||||
...
|
||||
fun:libusb_init_context
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user