diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07d7399 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.swp +_build diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 71f5582..4f9afac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ default: variables: extends: .libfprint_common_variables FDO_DISTRIBUTION_TAG: $LIBFPRINT_IMAGE_TAG - FDO_DISTRIBUTION_VERSION: rawhide + FDO_DISTRIBUTION_VERSION: 41 FDO_UPSTREAM_REPO: "libfprint/$CI_PROJECT_NAME" FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG" LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546" @@ -28,6 +28,8 @@ 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 +37,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 +59,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,9 +83,8 @@ 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 @@ -99,9 +106,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 +122,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 +164,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 +180,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 +216,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 +237,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 +247,8 @@ flatpak: libudev-devel FDO_DISTRIBUTION_EXEC: | $LIBFPRINT_EXEC + rules: + - when: never .container_fedora_build_forced: variables: @@ -234,25 +258,39 @@ 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 + script: + - mkdir public + - mv _build/meson-logs/coveragereport public/coverage + artifacts: + paths: + - public + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH diff --git a/.gitlab-ci/libfprint-image-variables.yaml b/.gitlab-ci/libfprint-image-variables.yaml index e568839..03525b4 100644 --- a/.gitlab-ci/libfprint-image-variables.yaml +++ b/.gitlab-ci/libfprint-image-variables.yaml @@ -1,2 +1,2 @@ variables: - LIBFPRINT_IMAGE_TAG: v3 + LIBFPRINT_IMAGE_TAG: v6 diff --git a/.gitlab-ci/libfprint-templates.yaml b/.gitlab-ci/libfprint-templates.yaml index 9c8de1c..6401cfa 100644 --- a/.gitlab-ci/libfprint-templates.yaml +++ b/.gitlab-ci/libfprint-templates.yaml @@ -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,5 @@ glibc \ libgusb \ libusb \ - nss \ + openssl \ pixman - - git clone https://github.com/martinpitt/umockdev.git && \ - cd umockdev && \ - meson _build --prefix=/usr && \ - ninja -C _build && ninja -C _build install diff --git a/.gitlab-ci/scan-build b/.gitlab-ci/scan-build index 0aa8c99..da24849 100755 --- a/.gitlab-ci/scan-build +++ b/.gitlab-ci/scan-build @@ -1,4 +1,4 @@ #!/bin/sh # This wrapper just disables the malloc checker -exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc "$@" \ No newline at end of file +exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc --exclude "_build/meson-private" "$@" diff --git a/NEWS b/NEWS index 44a048f..b945e9f 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,35 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +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: diff --git a/README.md b/README.md index 2e52403..34ad811 100644 --- a/README.md +++ b/README.md @@ -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 +
@@ -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 diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index 74ac65b..9115fb0 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -79,6 +79,9 @@ usb:v1C7Ap0571* # Supported by libfprint driver egismoc usb:v1C7Ap0582* +usb:v1C7Ap0583* +usb:v1C7Ap0586* +usb:v1C7Ap0587* usb:v1C7Ap05A1* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -155,7 +158,11 @@ usb:v04F3p0C82* usb:v04F3p0C88* usb:v04F3p0C8C* usb:v04F3p0C8D* +usb:v04F3p0C98* usb:v04F3p0C99* +usb:v04F3p0C9D* +usb:v04F3p0C9F* +usb:v04F3p0CA3* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -168,6 +175,9 @@ usb:v1C7Ap0603* usb:v2808p9E48* usb:v2808pD979* usb:v2808pA959* +usb:v2808pA99A* +usb:v2808pA57A* +usb:v2808pA78A* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -177,6 +187,9 @@ usb:v10A5pA305* usb:v10A5pDA04* usb:v10A5pD805* usb:v10A5pD205* +usb:v10A5p9524* +usb:v10A5p9544* +usb:v10A5pC844* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -185,10 +198,12 @@ usb:v27C6p5840* usb:v27C6p6014* usb:v27C6p6092* usb:v27C6p6094* +usb:v27C6p609A* usb:v27C6p609C* usb:v27C6p60A2* usb:v27C6p60A4* usb:v27C6p60BC* +usb:v27C6p60C2* usb:v27C6p6304* usb:v27C6p631C* usb:v27C6p633C* @@ -199,6 +214,8 @@ usb:v27C6p63AC* usb:v27C6p63BC* usb:v27C6p63CC* usb:v27C6p6496* +usb:v27C6p650A* +usb:v27C6p650C* usb:v27C6p6582* usb:v27C6p6584* usb:v27C6p658C* @@ -207,6 +224,8 @@ usb:v27C6p6594* usb:v27C6p659A* usb:v27C6p659C* usb:v27C6p6A94* +usb:v27C6p6512* +usb:v27C6p689A* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -217,27 +236,35 @@ usb:v298Dp1010* # Supported by libfprint driver realtek usb:v0BDAp5813* +usb:v0BDAp5816* ID_AUTOSUSPEND=1 ID_PERSIST=0 # Supported by libfprint driver synaptics usb:v06CBp00BD* +usb:v06CBp00C2* +usb:v06CBp00C4* +usb:v06CBp00C6* usb:v06CBp00DF* +usb:v06CBp00F0* usb:v06CBp00F9* usb:v06CBp00FC* -usb:v06CBp00C2* usb:v06CBp0100* -usb:v06CBp00F0* usb:v06CBp0103* +usb:v06CBp0104* +usb:v06CBp0106* +usb:v06CBp0107* +usb:v06CBp0108* usb:v06CBp0123* usb:v06CBp0124* usb:v06CBp0126* usb:v06CBp0129* -usb:v06CBp0168* usb:v06CBp015F* -usb:v06CBp0104* +usb:v06CBp0168* +usb:v06CBp016C* usb:v06CBp0173* -usb:v06CBp0106* +usb:v06CBp0174* +usb:v06CBp019D* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -306,7 +333,10 @@ usb:v138Ap0091* ID_PERSIST=0 # Known unsupported devices +usb:v0A5Cp5802* usb:v047Dp00F2* +usb:v047Dp8054* +usb:v047Dp8055* usb:v04E8p730B* usb:v04F3p036B* usb:v04F3p0C00* @@ -314,16 +344,25 @@ 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* @@ -334,7 +373,6 @@ usb:v06CBp00A8* usb:v06CBp00B7* usb:v06CBp00BB* usb:v06CBp00BE* -usb:v06CBp00C4* usb:v06CBp00CB* usb:v06CBp00C9* usb:v06CBp00D8* @@ -344,6 +382,7 @@ usb:v06CBp00E4* usb:v06CBp00E7* usb:v06CBp00E9* usb:v06CBp00FD* +usb:v06CBp00FF* usb:v0A5Cp5801* usb:v0A5Cp5805* usb:v0A5Cp5834* @@ -353,10 +392,18 @@ 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:v10A5p9800* +usb:v10A5pA120* +usb:v10A5pA900* usb:v10A5pE340* usb:v1188p9545* usb:v138Ap0007* @@ -377,7 +424,11 @@ usb:v16D1p1027* usb:v1C7Ap0300* usb:v1C7Ap0575* usb:v1C7Ap0576* +usb:v1C7Ap0584* usb:v1C7Ap0577* +usb:v1C7Ap057E* +usb:v2541p0236* +usb:v2541p9711* usb:v27C6p5042* usb:v27C6p5110* usb:v27C6p5117* @@ -406,11 +457,17 @@ usb:v27C6p5740* usb:v27C6p5E0A* usb:v27C6p581A* usb:v27C6p589A* +usb:v27C6p5F10* usb:v27C6p6382* usb:v2808p9338* +usb:v2808p9348* usb:v2808p93A9* +usb:v2808pA658* +usb:v2808pC652* usb:v298Dp2020* usb:v298Dp2033* +usb:v2DF0p0003* +usb:v3274p8012* usb:v3538p0930* ID_AUTOSUSPEND=1 ID_PERSIST=0 diff --git a/debian/changelog b/debian/changelog index fd019b2..9425bd0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,44 @@ -libfprint (1:1.94.7-2deepin2) unstable; urgency=medium +libfprint (1:1.94.9-1deepin2) unstable; urgency=medium - * add uru4000 suspend/resume. + * Add riscv64 timeout multiplier support in debian/rules - -- lichenggang Thu, 27 Nov 2025 13:46:41 +0800 + -- lichenggang Wed, 11 Mar 2026 14:30:00 +0800 -libfprint (1:1.94.7-2deepin1) unstable; urgency=medium +libfprint (1:1.94.9-1deepin1) unstable; urgency=medium - * Disable ut synaptice and focaltech_moc + * Apply deepin patches: + - Disable synaptics and focaltech_moc tests + - Add uru4000 suspend/resume support + - Add error handling for fpi_device_suspend_complete + - Skip fpi-device tests - -- xiangzelong Thu, 30 May 2024 15:15:32 +0800 + -- lichenggang Wed, 11 Mar 2026 14:10:00 +0800 + +libfprint (1:1.94.9-1) unstable; urgency=medium + + * New upstream release + * debian/libfprint-2-2.postinst: Devices triggers updated + * debian/libfprint-2-2.install: Install metainfo data + * debian/control: Replace NSS build dependency with OpenSSL + * debian/control: Add b-d on GLib and Gio gir dev packages + + -- Marco Trevisan (Treviño) Thu, 20 Feb 2025 19:01:13 +0100 + +libfprint (1:1.94.8-2) unstable; urgency=medium + + * debian/control: Build-Depend on dh-sequence-gir + + -- Marco Trevisan (Treviño) Tue, 03 Sep 2024 06:02:52 +0200 + +libfprint (1:1.94.8-1) unstable; urgency=medium + + * New upstream release + * debian/watch: Update + * debian/libfprint-2-2.postinst: Devices triggers updated + * debian/patches: Drop, applied upstream + * debian/control: Update Standards Version (no change required) + + -- Marco Trevisan (Treviño) Tue, 03 Sep 2024 05:41:34 +0200 libfprint (1:1.94.7-2) unstable; urgency=medium diff --git a/debian/control b/debian/control index 77ee6a3..7102656 100644 --- a/debian/control +++ b/debian/control @@ -5,17 +5,17 @@ Maintainer: FingerForce Team Uploaders: Ulises Vitulli , Marco Trevisan Build-Depends: debhelper-compat (= 13), - gir1.2-gobject-2.0-dev , - gir1.2-gio-2.0-dev , - gobject-introspection, + dh-sequence-gir, + gir1.2-gobject-2.0-dev, + gir1.2-gio-2.0-dev, gtk-doc-tools, libcairo-dev , libgirepository1.0-dev, libglib2.0-dev, libgudev-1.0-dev, libgusb-dev, - libnss3-dev, libpixman-1-dev, + libssl-dev, meson, python3 , python3-cairo , @@ -23,7 +23,7 @@ Build-Depends: debhelper-compat (= 13), systemd-dev, umockdev Build-Depends-Indep: libglib2.0-doc , libgusb-doc -Standards-Version: 4.6.2 +Standards-Version: 4.7.0 Homepage: https://www.freedesktop.org/wiki/Software/fprint/libfprint Vcs-Browser: https://salsa.debian.org/debian/libfprint Vcs-Git: https://salsa.debian.org/debian/libfprint.git diff --git a/debian/libfprint-2-2.install b/debian/libfprint-2-2.install index 8dd1e0a..1f88c0e 100644 --- a/debian/libfprint-2-2.install +++ b/debian/libfprint-2-2.install @@ -1,3 +1,4 @@ usr/lib/udev/hwdb.d/ usr/lib/udev/rules.d/ usr/lib/${DEB_HOST_MULTIARCH}/libfprint-[0-9].so.* +usr/share/metainfo/org.freedesktop.libfprint.metainfo.xml diff --git a/debian/libfprint-2-2.postinst b/debian/libfprint-2-2.postinst index d77fb5d..36e4e28 100644 --- a/debian/libfprint-2-2.postinst +++ b/debian/libfprint-2-2.postinst @@ -56,6 +56,9 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0570 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0571 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0582 || true + udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0583 || true + udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0586 || true + udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0587 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=05a1 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0903 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0907 || true @@ -124,24 +127,36 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c88 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c8c || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c8d || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c98 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c99 || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c9d || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c9f || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0ca3 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0603 || true udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=9e48 || true udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=d979 || true udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=a959 || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=a99a || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=a57a || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=a78a || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=ffe0 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=a305 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=da04 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=d805 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=d205 || true + udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=9524 || true + udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=9544 || true + udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=c844 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5840 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6014 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6092 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6094 || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=609a || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=609c || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=60a2 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=60a4 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=60bc || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=60c2 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6304 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=631c || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=633c || true @@ -152,6 +167,8 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=63bc || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=63cc || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6496 || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=650a || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=650c || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6582 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6584 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=658c || true @@ -160,25 +177,35 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=659a || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=659c || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6a94 || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6512 || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=689a || true udevadm trigger --action=add --attr-match=idVendor=298d --attr-match=idProduct=1010 || true udevadm trigger --action=add --attr-match=idVendor=0bda --attr-match=idProduct=5813 || true + udevadm trigger --action=add --attr-match=idVendor=0bda --attr-match=idProduct=5816 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00bd || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c2 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c4 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c6 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00df || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00f0 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00f9 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00fc || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c2 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0100 || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00f0 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0103 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0104 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0106 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0107 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0108 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0123 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0124 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0126 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0129 || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0168 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=015f || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0104 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0168 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=016c || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0173 || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0106 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0174 || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=019d || true udevadm trigger --action=add --attr-match=idVendor=147e --attr-match=idProduct=2016 || true udevadm trigger --action=add --attr-match=idVendor=147e --attr-match=idProduct=1000 || true udevadm trigger --action=add --attr-match=idVendor=147e --attr-match=idProduct=1001 || true @@ -203,7 +230,10 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=138a --attr-match=idProduct=0017 || true udevadm trigger --action=add --attr-match=idVendor=138a --attr-match=idProduct=0018 || true udevadm trigger --action=add --attr-match=idVendor=138a --attr-match=idProduct=0091 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5802 || true udevadm trigger --action=add --attr-match=idVendor=047d --attr-match=idProduct=00f2 || true + udevadm trigger --action=add --attr-match=idVendor=047d --attr-match=idProduct=8054 || true + udevadm trigger --action=add --attr-match=idVendor=047d --attr-match=idProduct=8055 || true udevadm trigger --action=add --attr-match=idVendor=04e8 --attr-match=idProduct=730b || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=036b || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c00 || true @@ -211,16 +241,25 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c57 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c5e || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c5a || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c60 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c6c || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c70 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c72 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c77 || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c7c || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c7f || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c80 || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c85 || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c90 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=2706 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=3032 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=3057 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=3104 || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=310d || true udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=3128 || true + udevadm trigger --action=add --attr-match=idVendor=04f3 --attr-match=idProduct=0c8a || true + udevadm trigger --action=add --attr-match=idVendor=05ba --attr-match=idProduct=000e || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0051 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0081 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=0088 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=008a || true @@ -231,7 +270,6 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00b7 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00bb || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00be || true - udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c4 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00cb || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00c9 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00d8 || true @@ -241,6 +279,7 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00e7 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00e9 || true udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00fd || true + udevadm trigger --action=add --attr-match=idVendor=06cb --attr-match=idProduct=00ff || true udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5801 || true udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5805 || true udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5834 || true @@ -250,10 +289,18 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5843 || true udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5844 || true udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5845 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5860 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5863 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5864 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5865 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5866 || true + udevadm trigger --action=add --attr-match=idVendor=0a5c --attr-match=idProduct=5867 || true udevadm trigger --action=add --attr-match=idVendor=0bda --attr-match=idProduct=5812 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=0007 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=9200 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=9800 || true + udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=a120 || true + udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=a900 || true udevadm trigger --action=add --attr-match=idVendor=10a5 --attr-match=idProduct=e340 || true udevadm trigger --action=add --attr-match=idVendor=1188 --attr-match=idProduct=9545 || true udevadm trigger --action=add --attr-match=idVendor=138a --attr-match=idProduct=0007 || true @@ -274,7 +321,11 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0300 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0575 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0576 || true + udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0584 || true udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=0577 || true + udevadm trigger --action=add --attr-match=idVendor=1c7a --attr-match=idProduct=057e || true + udevadm trigger --action=add --attr-match=idVendor=2541 --attr-match=idProduct=0236 || true + udevadm trigger --action=add --attr-match=idVendor=2541 --attr-match=idProduct=9711 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5042 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5110 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5117 || true @@ -303,11 +354,17 @@ if [ "$1" = "configure" -o "$1" = "upgrade" ] && command -V udevadm >/dev/null 2 udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5e0a || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=581a || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=589a || true + udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=5f10 || true udevadm trigger --action=add --attr-match=idVendor=27c6 --attr-match=idProduct=6382 || true udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=9338 || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=9348 || true udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=93a9 || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=a658 || true + udevadm trigger --action=add --attr-match=idVendor=2808 --attr-match=idProduct=c652 || true udevadm trigger --action=add --attr-match=idVendor=298d --attr-match=idProduct=2020 || true udevadm trigger --action=add --attr-match=idVendor=298d --attr-match=idProduct=2033 || true + udevadm trigger --action=add --attr-match=idVendor=2df0 --attr-match=idProduct=0003 || true + udevadm trigger --action=add --attr-match=idVendor=3274 --attr-match=idProduct=8012 || true udevadm trigger --action=add --attr-match=idVendor=3538 --attr-match=idProduct=0930 || true fi diff --git a/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch b/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch index 98dcc4c..8cf4541 100644 --- a/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch +++ b/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch @@ -34,4 +34,3 @@ index 1b9fa8f..d383998 100644 -- 2.47.2 - diff --git a/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch b/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch index bc45600..5118854 100644 --- a/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch +++ b/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch @@ -1,16 +1,5 @@ -From b8fd038b6fa2fbf95e31ef1474e33335a4827eee Mon Sep 17 00:00:00 2001 -From: xzl -Date: Thu, 30 May 2024 15:13:02 +0800 -Subject: [PATCH 1/1] Disable synaptics and focaltech_moc - ---- - tests/meson.build | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/meson.build b/tests/meson.build -index dc3b70e..44e3bb8 100644 ---- a/tests/meson.build -+++ b/tests/meson.build +--- libfprint-1.94.9.orig/tests/meson.build ++++ libfprint-1.94.9/tests/meson.build @@ -39,7 +39,7 @@ drivers_tests = [ 'elan-cobo', 'elanmoc', @@ -20,15 +9,12 @@ index dc3b70e..44e3bb8 100644 'upektc_img', 'upektc_img-tcs1s', 'uru4000-msv2', -@@ -55,7 +55,7 @@ drivers_tests = [ - 'egismoc-05a1', +@@ -58,7 +58,7 @@ drivers_tests = [ 'fpcmoc', - 'realtek', + 'realtek', + 'realtek-5816', - 'focaltech_moc', +# 'focaltech_moc', ] if get_option('introspection') --- -2.43.4 - diff --git a/debian/patches/0001-skip-tests-fpi-device.patch b/debian/patches/0001-skip-tests-fpi-device.patch index f7a630e..afbbe9a 100644 --- a/debian/patches/0001-skip-tests-fpi-device.patch +++ b/debian/patches/0001-skip-tests-fpi-device.patch @@ -21,4 +21,3 @@ index f68ed40..19691ce 100644 ] -- 2.47.2 - diff --git a/debian/patches/build-Look-for-sh-just-once.patch b/debian/patches/build-Look-for-sh-just-once.patch deleted file mode 100644 index 2dadcd6..0000000 --- a/debian/patches/build-Look-for-sh-just-once.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= -Date: Tue, 20 Feb 2024 08:22:42 +0100 -Subject: build: Look for sh just once - -Origin: https://gitlab.freedesktop.org/libfprint/libfprint/commit/4b72f27d -Forwarded: yes ---- - meson.build | 1 + - tests/meson.build | 10 +++++----- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/meson.build b/meson.build -index 435827c..28ee27a 100644 ---- a/meson.build -+++ b/meson.build -@@ -91,6 +91,7 @@ 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 -diff --git a/tests/meson.build b/tests/meson.build -index f68ed40..8c8f5d0 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -151,7 +151,7 @@ if get_option('introspection') - endif - else - test(vdtest, -- find_program('sh'), -+ sh, - args: ['-c', 'exit 77'] - ) - endif -@@ -205,7 +205,7 @@ if get_option('introspection') - endif - else - test(driver_test, -- find_program('sh'), -+ sh, - args: ['-c', 'exit 77'] - ) - endif -@@ -224,13 +224,13 @@ if get_option('introspection') - else - warning('Skipping all driver tests as introspection bindings are missing') - test('virtual-image', -- find_program('sh'), -+ sh, - args: ['-c', 'exit 77'] - ) - - foreach driver_test: drivers_tests - test(driver_test, -- find_program('sh'), -+ sh, - args: ['-c', 'exit 77'] - ) - endforeach -@@ -273,7 +273,7 @@ foreach test_name: unit_tests - # Create a dummy test that always skips instead - warning('Test @0@ cannot be compiled due to missing dependencies'.format(test_name)) - test(test_name, -- find_program('sh'), -+ sh, - suite: ['unit-tests'], - args: ['-c', 'exit 77'], - ) diff --git a/debian/patches/build-tests-Skip-a-test-if-the-test-requires-it-during-in.patch b/debian/patches/build-tests-Skip-a-test-if-the-test-requires-it-during-in.patch deleted file mode 100644 index ad36306..0000000 --- a/debian/patches/build-tests-Skip-a-test-if-the-test-requires-it-during-in.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= -Date: Tue, 20 Feb 2024 08:24:12 +0100 -Subject: build/tests: Skip a test if the test requires it during inspection - -In case we don't have dependencies, we should skip the test, otherwise -we can just fail at test time - -Origin: https://gitlab.freedesktop.org/libfprint/libfprint/commit/7dbb21e7 -Forwarded: yes ---- - tests/meson.build | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/tests/meson.build b/tests/meson.build -index 8c8f5d0..dc3b70e 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -100,11 +100,17 @@ if get_option('introspection') - base_args = files(vdtest + '.py') - suite = ['virtual-driver'] - -- r = run_command(unittest_inspector, files(vdtest + '.py'), check: true) -+ r = run_command(unittest_inspector, files(vdtest + '.py'), check: false) - unit_tests = r.stdout().strip().split('\n') - - if r.returncode() == 0 and unit_tests.length() > 0 - suite += vdtest -+ elif r.returncode() == 77 -+ test(vdtest, -+ sh, -+ args: ['-c', 'exit 77'] -+ ) -+ continue - else - unit_tests = [vdtest] - endif diff --git a/debian/patches/series b/debian/patches/series index 52caa3d..b5caf0d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,5 +1,3 @@ -build-Look-for-sh-just-once.patch -build-tests-Skip-a-test-if-the-test-requires-it-during-in.patch 0001-Disable-synaptics-and-focaltech_moc.patch add-uru4000-suspend-resume.patch 0001-Add-error-handling-for-fpi_device_suspend_complete.patch diff --git a/debian/rules b/debian/rules index f32921a..5340736 100755 --- a/debian/rules +++ b/debian/rules @@ -2,6 +2,7 @@ include /usr/share/dpkg/default.mk DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) + export DPKG_GENSYMBOLS_CHECK_LEVEL = 2 TIMEOUT_MULTIPLIER = 5 @@ -19,7 +20,7 @@ CONFIG_ARGS = \ -Dgtk-examples=false %: - dh $@ --with gir + dh $@ override_dh_auto_configure: dh_auto_configure -- $(CONFIG_ARGS) diff --git a/debian/watch b/debian/watch index 46a0137..907dd99 100644 --- a/debian/watch +++ b/debian/watch @@ -1,4 +1,6 @@ version=4 +opts="searchmode=plain" \ https://gitlab.freedesktop.org/libfprint/@PACKAGE@/tags?sort=updated_desc \ - archive/v(?:[^/]*)/@PACKAGE@-v(\d\S*)@ARCHIVE_EXT@ + -/archive/v?\d[\d.]+/@PACKAGE@-@ANY_VERSION@@ARCHIVE_EXT@ + diff --git a/demo/gtk-libfprint-test.c b/demo/gtk-libfprint-test.c index 30e91ef..d914c12 100644 --- a/demo/gtk-libfprint-test.c +++ b/demo/gtk-libfprint-test.c @@ -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++) { diff --git a/examples/clear-storage.c b/examples/clear-storage.c new file mode 100644 index 0000000..4886348 --- /dev/null +++ b/examples/clear-storage.c @@ -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 + * Copyright (C) 2024 Abhinav Baid + * + * 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 +#include +#include +#include + +#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; +} diff --git a/examples/meson.build b/examples/meson.build index f28a2d4..250c055 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -5,6 +5,7 @@ examples = [ 'img-capture', 'manage-prints', 'verify', + 'clear-storage', ] foreach example: examples diff --git a/examples/storage.c b/examples/storage.c index b84c72d..cc513bc 100644 --- a/examples/storage.c +++ b/examples/storage.c @@ -26,6 +26,7 @@ #include "storage.h" #include +#include #include #include #include @@ -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) { diff --git a/examples/storage.h b/examples/storage.h index 0922b90..fc3bf8a 100644 --- a/examples/storage.h +++ b/examples/storage.h @@ -20,12 +20,17 @@ #pragma once +#include +#include + 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); diff --git a/libfprint/drivers/egismoc/egismoc.c b/libfprint/drivers/egismoc/egismoc.c index 0b5e8d2..8f35a67 100644 --- a/libfprint/drivers/egismoc/egismoc.c +++ b/libfprint/drivers/egismoc/egismoc.c @@ -32,6 +32,7 @@ #include #include "drivers_api.h" +#include "fpi-byte-writer.h" #include "egismoc.h" @@ -42,15 +43,17 @@ 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 = 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 = 0x05a1, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 }, { .vid = 0, .pid = 0, .driver_data = 0 } }; @@ -154,8 +157,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 +274,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); - - if (i < value_length - 1) - values[j] |= value[i + 1] & 0x00ff; - } + fpi_byte_reader_set_pos (reader, 0); - for (int i = 0; i < steps; i++) - sum_values += values[i]; + while (fpi_byte_reader_get_uint16_be (reader, &val)) + sum_values += val; - 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 +301,15 @@ egismoc_exec_cmd (FpDevice *device, GDestroyNotify cmd_destroy, SynCmdMsgCallback callback) { - fp_dbg ("Execute command and get response"); + g_auto(FpiByteWriter) writer = {0}; + g_autoptr(FpiUsbTransfer) transfer = NULL; FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device); - EgisMocCheckBytes check_bytes; - g_autofree guchar *buffer_out = NULL; + g_autofree CommandData *data = NULL; gsize buffer_out_length = 0; + gboolean written = TRUE; + guint16 check_value; - g_autoptr(FpiUsbTransfer) transfer = NULL; - CommandData *data = g_new0 (CommandData, 1); - - 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 +322,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); + 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_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) - cmd_destroy (cmd); + g_clear_pointer (&cmd, cmd_destroy); - /* 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); + 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 +414,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 +445,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 +522,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 +530,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 +546,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 +559,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 +571,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 +622,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 +700,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 +772,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 +852,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 +895,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 +934,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; - - /* append all currently registered 32-byte fingerprint IDs */ - const gsize print_id_length = sizeof (guchar) * EGISMOC_FINGERPRINT_DATA_SIZE; + written &= fpi_byte_writer_change_pos (&writer, + EGISMOC_CMD_CHECK_SEPARATOR_LENGTH); - 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 +1020,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 +1097,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 +1256,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 +1463,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 (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) + serial = g_strdup ("emulated-device"); + else + serial = g_usb_device_get_string_descriptor (usb_dev, + g_usb_device_get_serial_number_index (usb_dev), + &error); + + if (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 +1608,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; diff --git a/libfprint/drivers/egismoc/egismoc.h b/libfprint/drivers/egismoc/egismoc.h index f027ea2..ef31d2c 100644 --- a/libfprint/drivers/egismoc/egismoc.h +++ b/libfprint/drivers/egismoc/egismoc.h @@ -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]); diff --git a/libfprint/drivers/elanmoc/elanmoc.c b/libfprint/drivers/elanmoc/elanmoc.c index e86b79a..f5ccc11 100644 --- a/libfprint/drivers/elanmoc/elanmoc.c +++ b/libfprint/drivers/elanmoc/elanmoc.c @@ -31,7 +31,11 @@ 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 = 0x0c9d, }, + { .vid = 0x04f3, .pid = 0x0c9f, }, + { .vid = 0x04f3, .pid = 0x0ca3, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; diff --git a/libfprint/drivers/elanspi.h b/libfprint/drivers/elanspi.h index a8d7319..688f477 100644 --- a/libfprint/drivers/elanspi.h +++ b/libfprint/drivers/elanspi.h @@ -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}, diff --git a/libfprint/drivers/focaltech_moc/focaltech_moc.c b/libfprint/drivers/focaltech_moc/focaltech_moc.c index 9872c7c..17f5363 100644 --- a/libfprint/drivers/focaltech_moc/focaltech_moc.c +++ b/libfprint/drivers/focaltech_moc/focaltech_moc.c @@ -30,6 +30,9 @@ static const FpIdEntry id_table[] = { { .vid = 0x2808, .pid = 0x9e48, }, { .vid = 0x2808, .pid = 0xd979, }, { .vid = 0x2808, .pid = 0xa959, }, + { .vid = 0x2808, .pid = 0xa99a, }, + { .vid = 0x2808, .pid = 0xa57a, }, + { .vid = 0x2808, .pid = 0xa78a, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; diff --git a/libfprint/drivers/fpcmoc/fpc.c b/libfprint/drivers/fpcmoc/fpc.c index dd6bf09..e2e89e3 100644 --- a/libfprint/drivers/fpcmoc/fpc.c +++ b/libfprint/drivers/fpcmoc/fpc.c @@ -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 */ @@ -68,6 +68,9 @@ static const FpIdEntry id_table[] = { { .vid = 0x10A5, .pid = 0xDA04, }, { .vid = 0x10A5, .pid = 0xD805, }, { .vid = 0x10A5, .pid = 0xD205, }, + { .vid = 0x10A5, .pid = 0x9524, }, + { .vid = 0x10A5, .pid = 0x9544, }, + { .vid = 0x10A5, .pid = 0xC844, }, /* terminating entry */ { .vid = 0, .pid = 0, .driver_data = 0 }, }; @@ -269,6 +272,7 @@ fpc_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev); CommandData *data = fpi_ssm_get_data (ssm); + self->cmd_ssm = NULL; /* Notify about the SSM failure from here instead. */ if (error) { @@ -276,8 +280,6 @@ fpc_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) if (data->callback) data->callback (self, NULL, error); } - - self->cmd_ssm = NULL; } static void @@ -388,7 +390,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 +448,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: @@ -742,15 +750,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, FP_ENROLL_COMPLETE); + return; + } break; } - self->immobile_stage++; } fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, @@ -763,7 +778,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, FP_ENROLL_COMPLETE); + return; + } break; case FPC_ENROL_STATUS_IMAGE_LOW_COVERAGE: @@ -1623,6 +1641,9 @@ fpc_dev_probe (FpDevice *device) case 0xD805: case 0xDA04: case 0xD205: + case 0x9524: + case 0x9544: + case 0xC844: self->max_enroll_stage = MAX_ENROLL_SAMPLES; break; diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index 5a3ffac..33e137f 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -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, @@ -1363,8 +1379,10 @@ gx_fp_probe (FpDevice *device) case 0x6014: case 0x6092: case 0x6094: + case 0x609A: case 0x609C: case 0x60BC: + case 0x60C2: case 0x6304: case 0x631C: case 0x633C: @@ -1374,6 +1392,8 @@ gx_fp_probe (FpDevice *device) case 0x63AC: case 0x63BC: case 0x63CC: + case 0x650A: + case 0x650C: case 0x6582: case 0x6A94: case 0x659A: @@ -1610,10 +1630,12 @@ static const FpIdEntry id_table[] = { { .vid = 0x27c6, .pid = 0x6014, }, { .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 +1646,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 +1656,8 @@ static const FpIdEntry id_table[] = { { .vid = 0x27c6, .pid = 0x659A, }, { .vid = 0x27c6, .pid = 0x659C, }, { .vid = 0x27c6, .pid = 0x6A94, }, + { .vid = 0x27c6, .pid = 0x6512, }, + { .vid = 0x27c6, .pid = 0x689A, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; diff --git a/libfprint/drivers/goodixmoc/goodix_proto.c b/libfprint/drivers/goodixmoc/goodix_proto.c index d7713f0..5125d72 100644 --- a/libfprint/drivers/goodixmoc/goodix_proto.c +++ b/libfprint/drivers/goodixmoc/goodix_proto.c @@ -18,6 +18,8 @@ */ #include +#include + #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 (!buffer || !presp) - return -1; - if (buffer_len < 1) + if (!presp) return -1; - presp->result = buffer[0]; + + if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->result)) + g_return_val_if_reached (-1); + 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; - - 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; + uint16_t tid_size; + FpiByteReader tid_reader; + + 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: diff --git a/libfprint/drivers/goodixmoc/goodix_proto.h b/libfprint/drivers/goodixmoc/goodix_proto.h index b8ccdca..6302450 100644 --- a/libfprint/drivers/goodixmoc/goodix_proto.h +++ b/libfprint/drivers/goodixmoc/goodix_proto.h @@ -22,6 +22,8 @@ #include #include +#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); diff --git a/libfprint/drivers/realtek/realtek.c b/libfprint/drivers/realtek/realtek.c index 4532290..425aadf 100644 --- a/libfprint/drivers/realtek/realtek.c +++ b/libfprint/drivers/realtek/realtek.c @@ -28,6 +28,7 @@ G_DEFINE_TYPE (FpiDeviceRealtek, fpi_device_realtek, FP_TYPE_DEVICE) static const FpIdEntry id_table[] = { { .vid = 0x0bda, .pid = 0x5813, }, + { .vid = 0x0bda, .pid = 0x5816, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; @@ -92,6 +93,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 +148,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 +292,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 +344,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 +393,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 +433,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 +462,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 +493,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 +538,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 +585,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 +688,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 +755,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 +775,100 @@ prepare_transfer (FpDevice *dev, return g_steal_pointer (&transfer); } + +static void +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 -realtek_sensor_cmd (FpiDeviceRealtek *self, - guint8 *cmd, - guint8 *trans_data, - FpRtkMsgType message_type, - gboolean bwait_data_delay, - SynCmdMsgCallback callback) +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 +967,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 +1022,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 +1032,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 +1051,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 +1096,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 +1124,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 +1152,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 +1180,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 +1207,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 +1332,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 +1344,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 diff --git a/libfprint/drivers/realtek/realtek.h b/libfprint/drivers/realtek/realtek.h index 803922f..5658e05 100644 --- a/libfprint/drivers/realtek/realtek.h +++ b/libfprint/drivers/realtek/realtek.h @@ -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 rtk_cmd_bulk +{ + 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]; }; -struct realtek_fp_cmd +struct rtk_cmd_ctrl { - 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]; + int direction; + uint8_t request; + uint16_t value; + uint16_t index; + uint16_t len; }; -static struct realtek_fp_cmd co_start_capture = { +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}, }; \ No newline at end of file diff --git a/libfprint/drivers/synaptics/bmkt_message.c b/libfprint/drivers/synaptics/bmkt_message.c index bace95c..d297156 100644 --- a/libfprint/drivers/synaptics/bmkt_message.c +++ b/libfprint/drivers/synaptics/bmkt_message.c @@ -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; diff --git a/libfprint/drivers/synaptics/synaptics.c b/libfprint/drivers/synaptics/synaptics.c index 138e734..c0228fb 100644 --- a/libfprint/drivers/synaptics/synaptics.c +++ b/libfprint/drivers/synaptics/synaptics.c @@ -32,22 +32,29 @@ 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 = 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 = 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 = 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 = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 3d82cb3..828306b 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -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; } diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 047e64c..f8d7b6e 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -20,8 +20,8 @@ #define FP_COMPONENT "uru4000" -#include -#include +#include +#include #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)) + { + 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)) { - 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; } - 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,20 +1376,6 @@ 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); @@ -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); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 6963c59..7020726 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -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 diff --git a/libfprint/drivers/vfs301_proto.c b/libfprint/drivers/vfs301_proto.c index 6bbb3c7..122a889 100644 --- a/libfprint/drivers/vfs301_proto.c +++ b/libfprint/drivers/vfs301_proto.c @@ -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, diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 65c98c9..b9e0587 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -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 { diff --git a/libfprint/drivers/vfs7552.c b/libfprint/drivers/vfs7552.c index 852e35b..53b4d3f 100644 --- a/libfprint/drivers/vfs7552.c +++ b/libfprint/drivers/vfs7552.c @@ -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 { diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index 17a7ad0..aed4424 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -772,6 +772,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 +788,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); } diff --git a/libfprint/drivers/virtual-image.c b/libfprint/drivers/virtual-image.c index 18657c4..97eebc9 100644 --- a/libfprint/drivers/virtual-image.c +++ b/libfprint/drivers/virtual-image.c @@ -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); + } } diff --git a/libfprint/fp-device.c b/libfprint/fp-device.c index c143644..ab06e7f 100644 --- a/libfprint/fp-device.c +++ b/libfprint/fp-device.c @@ -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; @@ -1103,8 +1103,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 +1248,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 +1374,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 +1943,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 +1983,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 diff --git a/libfprint/fp-device.h b/libfprint/fp-device.h index 9dda747..e82cb53 100644 --- a/libfprint/fp-device.h +++ b/libfprint/fp-device.h @@ -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; /** diff --git a/libfprint/fp-print.h b/libfprint/fp-print.h index 7a2abee..ac6820d 100644 --- a/libfprint/fp-print.h +++ b/libfprint/fp-print.h @@ -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" diff --git a/libfprint/fpi-byte-reader.h b/libfprint/fpi-byte-reader.h index 7a89a28..c4e64d2 100644 --- a/libfprint/fpi-byte-reader.h +++ b/libfprint/fpi-byte-reader.h @@ -675,4 +675,6 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes) #endif /* FPI_BYTE_READER_DISABLE_INLINES */ +G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteReader, fpi_byte_reader_free); + G_END_DECLS diff --git a/libfprint/fpi-byte-writer.c b/libfprint/fpi-byte-writer.c index 73e42cb..cb3514a 100644 --- a/libfprint/fpi-byte-writer.c +++ b/libfprint/fpi-byte-writer.c @@ -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,10 +211,9 @@ 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; diff --git a/libfprint/fpi-byte-writer.h b/libfprint/fpi-byte-writer.h index ccdaf0b..9b21b5f 100644 --- a/libfprint/fpi-byte-writer.h +++ b/libfprint/fpi-byte-writer.h @@ -111,6 +111,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) { @@ -407,4 +418,7 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint 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 diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index 1b9fa8f..a1be30c 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -117,6 +117,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 +1046,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 +1112,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 +1158,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 +1185,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 +1237,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 +1366,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 +1432,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 +1479,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 +1508,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 +1786,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 @@ -1826,7 +1837,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 +1865,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 +1896,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(). diff --git a/libfprint/fpi-image-device.c b/libfprint/fpi-image-device.c index 64ea340..8184d3a 100644 --- a/libfprint/fpi-image-device.c +++ b/libfprint/fpi-image-device.c @@ -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. */ diff --git a/libfprint/fpi-log.h b/libfprint/fpi-log.h index 3231cf5..cd8f1bd 100644 --- a/libfprint/fpi-log.h +++ b/libfprint/fpi-log.h @@ -79,13 +79,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: diff --git a/libfprint/fpi-ssm.h b/libfprint/fpi-ssm.h index ab80a26..d2601c8 100644 --- a/libfprint/fpi-ssm.h +++ b/libfprint/fpi-ssm.h @@ -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, diff --git a/libfprint/fprint-list-metainfo.c b/libfprint/fprint-list-metainfo.c new file mode 100644 index 0000000..4faf7bd --- /dev/null +++ b/libfprint/fprint-list-metainfo.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2025 Marco Trevisan + * + * 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 \ + "\n" \ + "\n" \ + " org.freedesktop.libfprint\n" \ + " libfprint\n" \ + " CC0-1.0\n" \ + " LGPL-2.1-or-later\n" \ + " https://fprint.freedesktop.org\n" \ + " https://gitlab.freedesktop.org/libfprint/libfprint\n" \ + " https://fprint.freedesktop.org/libfprint-dev\n" \ + " https://gitlab.freedesktop.org/libfprint/libfprint/-/issues\n" \ + " Async fingerprint readers library\n" \ + " \n" \ + "

\n" \ + " The fprint project aims to support for consumer fingerprint reader devices.\n" \ + "

\n" \ + "
\n" \ + " \n" \ + "%s\n" \ + " \n" \ + "
\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_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, "usb:%s*", + device_id); + + if (i < devices_list->len - 1) + g_string_append_c (provided_modules, '\n'); + } + + g_print (METAINFO_BASE, provided_modules->str); +} diff --git a/libfprint/fprint-list-udev-hwdb.c b/libfprint/fprint-list-udev-hwdb.c index bace9f9..5cb8d68 100644 --- a/libfprint/fprint-list-udev-hwdb.c +++ b/libfprint/fprint-list-udev-hwdb.c @@ -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,16 +40,25 @@ 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 }, @@ -57,7 +69,6 @@ static const FpIdEntry allowlist_id_table[] = { { .vid = 0x06cb, .pid = 0x00b7 }, { .vid = 0x06cb, .pid = 0x00bb }, { .vid = 0x06cb, .pid = 0x00be }, - { .vid = 0x06cb, .pid = 0x00c4 }, { .vid = 0x06cb, .pid = 0x00cb }, { .vid = 0x06cb, .pid = 0x00c9 }, { .vid = 0x06cb, .pid = 0x00d8 }, @@ -67,6 +78,7 @@ static const FpIdEntry allowlist_id_table[] = { { .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 +88,18 @@ 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 = 0x9800 }, + { .vid = 0x10a5, .pid = 0xa120 }, + { .vid = 0x10a5, .pid = 0xa900 }, { .vid = 0x10a5, .pid = 0xe340 }, { .vid = 0x1188, .pid = 0x9545 }, { .vid = 0x138a, .pid = 0x0007 }, @@ -100,7 +120,11 @@ static const FpIdEntry allowlist_id_table[] = { { .vid = 0x1c7a, .pid = 0x0300 }, { .vid = 0x1c7a, .pid = 0x0575 }, { .vid = 0x1c7a, .pid = 0x0576 }, + { .vid = 0x1c7a, .pid = 0x0584 }, { .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 +153,17 @@ 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 = 0x6382 }, { .vid = 0x2808, .pid = 0x9338 }, + { .vid = 0x2808, .pid = 0x9348 }, { .vid = 0x2808, .pid = 0x93a9 }, + { .vid = 0x2808, .pid = 0xa658 }, + { .vid = 0x2808, .pid = 0xc652 }, { .vid = 0x298d, .pid = 0x2020 }, { .vid = 0x298d, .pid = 0x2033 }, + { .vid = 0x2df0, .pid = 0x0003 }, + { .vid = 0x3274, .pid = 0x8012 }, { .vid = 0x3538, .pid = 0x0930 }, { .vid = 0 }, }; diff --git a/libfprint/meson.build b/libfprint/meson.build index 8eed4dd..0ca1767 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -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', @@ -16,8 +24,7 @@ libfprint_private_sources = [ 'fpi-print.c', 'fpi-ssm.c', 'fpi-usb-transfer.c', - 'fpi-spi-transfer.c', -] +] + spi_sources libfprint_public_headers = [ 'fp-context.h', @@ -41,9 +48,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', @@ -156,7 +162,7 @@ helper_sources = { [ 'drivers/aesx660.c' ], 'aes3k' : [ 'drivers/aes3k.c' ], - 'nss' : + 'openssl' : [ ], 'udev' : [ ], @@ -268,8 +274,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: [ @@ -321,6 +332,21 @@ 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) + +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', diff --git a/meson.build b/meson.build index 435827c..baafa19 100644 --- a/meson.build +++ b/meson.build @@ -1,13 +1,14 @@ project('libfprint', [ 'c', 'cpp' ], - version: '1.94.7', + version: '1.94.9', 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', @@ -91,11 +97,15 @@ 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 = [ @@ -134,11 +144,16 @@ default_drivers = [ 'fpcmoc', 'realtek', 'focaltech_moc', +] - # SPI - 'elanspi', +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 + [ @@ -175,6 +190,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 +209,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 +266,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 diff --git a/scripts/uncrustify.cfg b/scripts/uncrustify.cfg index 34b9a35..705a097 100644 --- a/scripts/uncrustify.cfg +++ b/scripts/uncrustify.cfg @@ -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 diff --git a/tests/egismoc-0586/custom.pcapng b/tests/egismoc-0586/custom.pcapng new file mode 100644 index 0000000..f43dc6f Binary files /dev/null and b/tests/egismoc-0586/custom.pcapng differ diff --git a/tests/egismoc-0586/custom.py b/tests/egismoc-0586/custom.py new file mode 100755 index 0000000..3a66238 --- /dev/null +++ b/tests/egismoc-0586/custom.py @@ -0,0 +1,156 @@ +#!/usr/bin/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 diff --git a/tests/egismoc-0586/device b/tests/egismoc-0586/device new file mode 100644 index 0000000..fb41aee --- /dev/null +++ b/tests/egismoc-0586/device @@ -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 diff --git a/tests/egismoc-0587/custom.pcapng b/tests/egismoc-0587/custom.pcapng new file mode 100644 index 0000000..c721929 Binary files /dev/null and b/tests/egismoc-0587/custom.pcapng differ diff --git a/tests/egismoc-0587/custom.py b/tests/egismoc-0587/custom.py new file mode 100755 index 0000000..3a66238 --- /dev/null +++ b/tests/egismoc-0587/custom.py @@ -0,0 +1,156 @@ +#!/usr/bin/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 diff --git a/tests/egismoc-0587/device b/tests/egismoc-0587/device new file mode 100644 index 0000000..91744df --- /dev/null +++ b/tests/egismoc-0587/device @@ -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 + diff --git a/tests/goodixmoc/custom.py b/tests/goodixmoc/custom.py index aee4391..91922f1 100755 --- a/tests/goodixmoc/custom.py +++ b/tests/goodixmoc/custom.py @@ -53,17 +53,20 @@ def identify_done(dev, res): 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 diff --git a/tests/libfprint.supp b/tests/libfprint.supp index f2acc71..274d740 100644 --- a/tests/libfprint.supp +++ b/tests/libfprint.supp @@ -24,3 +24,12 @@ ... fun:g_thread_new } + +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:libusb_init_context +} diff --git a/tests/meson.build b/tests/meson.build index f68ed40..07c924b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -53,8 +53,11 @@ drivers_tests = [ 'egis0570', 'egismoc', 'egismoc-05a1', + 'egismoc-0586', + 'egismoc-0587', 'fpcmoc', - 'realtek', + 'realtek', + 'realtek-5816', 'focaltech_moc', ] @@ -100,11 +103,17 @@ if get_option('introspection') base_args = files(vdtest + '.py') suite = ['virtual-driver'] - r = run_command(unittest_inspector, files(vdtest + '.py'), check: true) + r = run_command(unittest_inspector, files(vdtest + '.py'), check: false) unit_tests = r.stdout().strip().split('\n') if r.returncode() == 0 and unit_tests.length() > 0 suite += vdtest + elif r.returncode() == 77 + test(vdtest, + sh, + args: ['-c', 'exit 77'] + ) + continue else unit_tests = [vdtest] endif @@ -136,8 +145,7 @@ if get_option('introspection') output: vdtest + '.test', install_dir: installed_tests_testdir, configuration: { - # FIXME: use fs.name() on meson 0.58 - 'exec': installed_tests_execdir / '@0@'.format(base_args[0]).split('/')[-1], + 'exec': installed_tests_execdir / fs.name(base_args[0]), 'env': ' '.join([ envs_str, 'LD_LIBRARY_PATH=' + installed_tests_libdir, @@ -151,7 +159,7 @@ if get_option('introspection') endif else test(vdtest, - find_program('sh'), + sh, args: ['-c', 'exit 77'] ) endif @@ -205,7 +213,7 @@ if get_option('introspection') endif else test(driver_test, - find_program('sh'), + sh, args: ['-c', 'exit 77'] ) endif @@ -224,13 +232,13 @@ if get_option('introspection') else warning('Skipping all driver tests as introspection bindings are missing') test('virtual-image', - find_program('sh'), + sh, args: ['-c', 'exit 77'] ) foreach driver_test: drivers_tests test(driver_test, - find_program('sh'), + sh, args: ['-c', 'exit 77'] ) endforeach @@ -273,7 +281,7 @@ foreach test_name: unit_tests # Create a dummy test that always skips instead warning('Test @0@ cannot be compiled due to missing dependencies'.format(test_name)) test(test_name, - find_program('sh'), + sh, suite: ['unit-tests'], args: ['-c', 'exit 77'], ) @@ -316,13 +324,25 @@ endforeach # Run udev rule generator with fatal warnings envs.set('UDEV_HWDB', udev_hwdb.full_path()) envs.set('UDEV_HWDB_CHECK_CONTENTS', default_drivers_are_enabled ? '1' : '0') +envs.set('G_MESSAGES_DEBUG', '') test('udev-hwdb', find_program('test-generated-hwdb.sh'), depends: udev_hwdb, + suite: ['data', 'no-valgrind'], env: envs) +appstreamcli = find_program('appstreamcli', required: false) +if appstreamcli.found() + test('metainfo-validate', + appstreamcli, + args: ['validate', metainfo_generator], + depends: metainfo_generator, + suite: ['data', 'no-valgrind'], + ) +endif + gdb = find_program('gdb', required: false) -if gdb.found() +if gdb.found() and libfprint_sanitizers.length() == 0 libfprint_wrapper = [ gdb.full_path(), '-batch', @@ -337,14 +357,32 @@ if gdb.found() ]) endif +if ('address' in libfprint_sanitizers or + 'undefined' in libfprint_sanitizers or + 'leak' in libfprint_sanitizers) + add_test_setup('sanitizers', + is_default: true, + timeout_multiplier: 3, + env: [ + 'ASAN_OPTIONS=verify_asan_link_order=0', + ]) +endif + valgrind = find_program('valgrind', required: false) -if valgrind.found() +if valgrind.found() and libfprint_sanitizers.length() == 0 glib_share = glib_dep.get_variable(pkgconfig: 'prefix') / 'share' / glib_dep.name() glib_suppressions = glib_share + '/valgrind/glib.supp' - libfprint_suppressions = '@0@/@1@'.format(meson.project_source_root(), - files('libfprint.supp')[0]) - python_suppressions = '@0@/@1@'.format(meson.project_source_root(), - files('valgrind-python.supp')[0]) + libfprint_suppressions = files('libfprint.supp')[0] + python_suppressions = files('valgrind-python.supp')[0] + + if meson.version().version_compare('>=1.4') + libfprint_suppressions = libfprint_suppressions.full_path() + python_suppressions = python_suppressions.full_path() + else + libfprint_suppressions = meson.project_source_root() / '@0@'.format(libfprint_suppressions) + python_suppressions = meson.project_source_root() / '@0@'.format(python_suppressions) + endif + libfprint_wrapper = [ valgrind.full_path(), '--tool=memcheck', @@ -361,11 +399,14 @@ if valgrind.found() '--suppressions=' + python_suppressions, ] add_test_setup('valgrind', - timeout_multiplier: 15, + timeout_multiplier: 20, exe_wrapper: libfprint_wrapper, + exclude_suites: ['no-valgrind'], env: [ 'G_SLICE=always-malloc', 'UNDER_VALGRIND=1', + 'FP_VIRTUAL_IMAGE_HOT_SECONDS=-1', + 'FP_VIRTUAL_DEVICE_HOT_SECONDS=-1', 'LIBFPRINT_TEST_WRAPPER=' + ' '.join(libfprint_wrapper), ]) endif diff --git a/tests/realtek-5816/custom.pcapng b/tests/realtek-5816/custom.pcapng new file mode 100644 index 0000000..579bac6 Binary files /dev/null and b/tests/realtek-5816/custom.pcapng differ diff --git a/tests/realtek-5816/custom.py b/tests/realtek-5816/custom.py new file mode 100755 index 0000000..15a71e2 --- /dev/null +++ b/tests/realtek-5816/custom.py @@ -0,0 +1,110 @@ +#!/usr/bin/python3 + +import traceback +import sys +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 + +assert d.get_driver() == "realtek" +assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) +assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) +assert d.has_feature(FPrint.DeviceFeature.VERIFY) +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 d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) + +d.open_sync() + +# 1. verify clear storage command, 2. make sure later asserts are good +d.clear_storage_sync() + +template = FPrint.Print.new(d) + +def enroll_progress(*args): + # assert d.get_finger_status() & FPrint.FingerStatusFlags.NEEDED + print('enroll progress: ' + str(args)) + +def identify_done(dev, res): + global identified + identified = True + try: + identify_match, identify_print = dev.identify_finish(res) + except gi.repository.GLib.GError as e: + print("Please try again") + else: + print('indentification_done: ', identify_match, identify_print) + assert identify_match.equal(identify_print) + +def start_identify_async(prints): + global identified + print('async identifying') + d.identify(prints, callback=identify_done) + del prints + + while not identified: + ctx.iteration(True) + + identified = False + +# List, enroll, list, verify, identify, delete +print("enrolling") +assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE +p = d.enroll_sync(template, None, enroll_progress, None) +assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE +print("enroll done") + +print("listing") +stored = d.list_prints_sync() +print("listing done") +assert len(stored) == 1 +assert stored[0].equal(p) +print("verifying") +try: + assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE + verify_res, verify_print = d.verify_sync(p) + assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE +except gi.repository.GLib.GError as e: + print("Please try again") +else: + print("verify done") + del p + 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("deleting") +d.delete_print_sync(p) +print("delete done") + +d.close_sync() + +del d +del c diff --git a/tests/realtek-5816/device b/tests/realtek-5816/device new file mode 100644 index 0000000..55f6f98 --- /dev/null +++ b/tests/realtek-5816/device @@ -0,0 +1,250 @@ +P: /devices/pci0000:00/0000:00:14.0/usb1/1-6 +N: bus/usb/001/006=12010102EF020140DA0B165800000301020109022E00010104A0FA0904000004FF02000507050102000200070583034000080705840340000807058202000200 +E: DEVNAME=/dev/bus/usb/001/006 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=bda/5816/0 +E: TYPE=239/2/1 +E: BUSNUM=001 +E: DEVNUM=006 +E: MAJOR=189 +E: MINOR=5 +E: SUBSYSTEM=usb +E: ID_VENDOR=Generic +E: ID_VENDOR_ENC=Generic +E: ID_VENDOR_ID=0bda +E: ID_MODEL=Realtek_USB2.0_Finger_Print_Bridge +E: ID_MODEL_ENC=Realtek\x20USB2.0\x20Finger\x20Print\x20Bridge +E: ID_MODEL_ID=5816 +E: ID_REVISION=0000 +E: ID_SERIAL=Generic_Realtek_USB2.0_Finger_Print_Bridge_201801010001 +E: ID_SERIAL_SHORT=201801010001 +E: ID_BUS=usb +E: ID_USB_INTERFACES=:ff0200: +E: ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp. +E: ID_PATH=pci-0000:00:14.0-usb-0:6 +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_6 +A: authorized=1\n +A: avoid_reset_quirk=0\n +A: bConfigurationValue=1\n +A: bDeviceClass=ef\n +A: bDeviceProtocol=01\n +A: bDeviceSubClass=02\n +A: bMaxPacketSize0=64\n +A: bMaxPower=500mA\n +A: bNumConfigurations=1\n +A: bNumInterfaces= 1\n +A: bcdDevice=0000\n +A: bmAttributes=a0\n +A: busnum=1\n +A: configuration=Realtek USB2.0 Finger Print Bridge\n +H: descriptors=12010102EF020140DA0B165800000301020109022E00010104A0FA0904000004FF02000507050102000200070583034000080705840340000807058202000200 +A: dev=189:5\n +A: devnum=6\n +A: devpath=6\n +L: driver=../../../../../bus/usb/drivers/usb +L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4b/device:4c/device:52 +A: idProduct=5816\n +A: idVendor=0bda\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=../1-0:1.0/usb1-port6 +A: power/active_duration=37699\n +A: power/async=enabled\n +A: power/autosuspend=2\n +A: power/autosuspend_delay_ms=2000\n +A: power/connected_duration=37699\n +A: power/control=on\n +A: power/level=on\n +A: power/persist=1\n +A: power/runtime_active_kids=0\n +A: power/runtime_active_time=37457\n +A: power/runtime_enabled=forbidden\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=0\n +A: power/runtime_usage=1\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=Realtek USB2.0 Finger Print Bridge\n +A: quirks=0x0\n +A: removable=removable\n +A: rx_lanes=1\n +A: serial=201801010001\n +A: speed=480\n +A: tx_lanes=1\n +A: urbnum=22\n +A: version= 2.01\n + +P: /devices/pci0000:00/0000:00:14.0/usb1 +N: bus/usb/001/001=12010002090001406B1D020008060302010109021900010100E0000904000001090000000705810304000C +E: DEVNAME=/dev/bus/usb/001/001 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=1d6b/2/608 +E: TYPE=9/0/1 +E: BUSNUM=001 +E: DEVNUM=001 +E: MAJOR=189 +E: MINOR=0 +E: SUBSYSTEM=usb +E: ID_VENDOR=Linux_6.8.0-40-generic_xhci-hcd +E: ID_VENDOR_ENC=Linux\x206.8.0-40-generic\x20xhci-hcd +E: ID_VENDOR_ID=1d6b +E: ID_MODEL=xHCI_Host_Controller +E: ID_MODEL_ENC=xHCI\x20Host\x20Controller +E: ID_MODEL_ID=0002 +E: ID_REVISION=0608 +E: ID_SERIAL=Linux_6.8.0-40-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_SERIAL_SHORT=0000:00:14.0 +E: ID_BUS=usb +E: ID_USB_INTERFACES=:090000: +E: ID_VENDOR_FROM_DATABASE=Linux Foundation +E: ID_AUTOSUSPEND=1 +E: ID_MODEL_FROM_DATABASE=2.0 root hub +E: ID_PATH=pci-0000:00:14.0 +E: ID_PATH_TAG=pci-0000_00_14_0 +E: ID_FOR_SEAT=usb-pci-0000_00_14_0 +E: TAGS=:seat: +E: CURRENT_TAGS=:seat: +A: authorized=1\n +A: authorized_default=1\n +A: avoid_reset_quirk=0\n +A: bConfigurationValue=1\n +A: bDeviceClass=09\n +A: bDeviceProtocol=01\n +A: bDeviceSubClass=00\n +A: bMaxPacketSize0=64\n +A: bMaxPower=0mA\n +A: bNumConfigurations=1\n +A: bNumInterfaces= 1\n +A: bcdDevice=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:4b/device:4c +A: idProduct=0002\n +A: idVendor=1d6b\n +A: interface_authorized_default=1\n +A: ltm_capable=no\n +A: manufacturer=Linux 6.8.0-40-generic xhci-hcd\n +A: maxchild=16\n +A: power/active_duration=1096259\n +A: power/async=enabled\n +A: power/autosuspend=0\n +A: power/autosuspend_delay_ms=0\n +A: power/connected_duration=1096259\n +A: power/control=auto\n +A: power/level=auto\n +A: power/runtime_active_kids=3\n +A: power/runtime_active_time=1096256\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=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=229\n +A: version= 2.00\n + +P: /devices/pci0000:00/0000:00:14.0 +E: DRIVER=xhci_hcd +E: PCI_CLASS=C0330 +E: PCI_ID=8086:A36D +E: PCI_SUBSYS_ID=1028:085C +E: PCI_SLOT_NAME=0000:00:14.0 +E: MODALIAS=pci:v00008086d0000A36Dsv00001028sd0000085Cbc0Csc03i30 +E: SUBSYSTEM=pci +E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller +E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller +E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI +E: ID_VENDOR_FROM_DATABASE=Intel Corporation +E: ID_MODEL_FROM_DATABASE=Cannon Lake PCH USB 3.1 xHCI Host Controller +A: ari_enabled=0\n +A: broken_parity_status=0\n +A: class=0x0c0330\n +H: config=86806DA3060590021030030C00008000040030D200000000000000000000000000000000000000000000000028105C08000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000005B17C10300000000316000000000000000000000000000000180C2C10800000000000000000000000590B7001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000030000000C00000000000000C000000000000000000100003000000000000000030000000C0000000000000000000000000000000000000000000000000000000000000000000000B50F120112000000 +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=0xa36d\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:4b +A: index=4\n +L: iommu=../../virtual/iommu/dmar1 +L: iommu_group=../../../kernel/iommu_groups/4 +A: irq=125\n +A: label=Onboard - Other\n +A: local_cpulist=0-3\n +A: local_cpus=f\n +A: modalias=pci:v00008086d0000A36Dsv00001028sd0000085Cbc0Csc03i30\n +A: msi_bus=1\n +A: msi_irqs/125=msi\n +A: msi_irqs/126=msi\n +A: msi_irqs/127=msi\n +A: msi_irqs/128=msi\n +A: msi_irqs/129=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 6 7 2112 7\nxHCI ring segments 25 25 4096 25\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 12 32 128 1\nbuffer-32 0 0 32 0\n +A: power/async=enabled\n +A: power/control=on\n +A: power/runtime_active_kids=1\n +A: power/runtime_active_time=1096935\n +A: power/runtime_enabled=forbidden\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=0\n +A: power/runtime_usage=1\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=0x00000000d2300000 0x00000000d230ffff 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=0x10\n +A: subsystem_device=0x085c\n +A: subsystem_vendor=0x1028\n +A: vendor=0x8086\n + diff --git a/tests/realtek/custom.pcapng b/tests/realtek/custom.pcapng index 0fe6dc7..84b1599 100644 Binary files a/tests/realtek/custom.pcapng and b/tests/realtek/custom.pcapng differ diff --git a/tests/realtek/device b/tests/realtek/device index c4f1c85..500f62d 100644 --- a/tests/realtek/device +++ b/tests/realtek/device @@ -1,14 +1,14 @@ -P: /devices/pci0000:00/0000:00:14.0/usb1/1-4 -N: bus/usb/001/005=12010102EF020140DA0B135801210301020109022E00010104A0FA0904000004FF02000507050102000200070583031000080705840310000807058202000200 -E: DEVNAME=/dev/bus/usb/001/005 +P: /devices/pci0000:00/0000:00:14.0/usb1/1-8 +N: bus/usb/001/025=12010102EF020140DA0B135801210301020109022E00010104A0FA0904000004FF02000507050102000200070583031000080705840310000807058202000200 +E: DEVNAME=/dev/bus/usb/001/025 E: DEVTYPE=usb_device E: DRIVER=usb E: PRODUCT=bda/5813/2101 E: TYPE=239/2/1 E: BUSNUM=001 -E: DEVNUM=005 +E: DEVNUM=025 E: MAJOR=189 -E: MINOR=4 +E: MINOR=24 E: SUBSYSTEM=usb E: ID_VENDOR=Generic E: ID_VENDOR_ENC=Generic @@ -22,8 +22,8 @@ E: ID_SERIAL_SHORT=201801010001 E: ID_BUS=usb E: ID_USB_INTERFACES=:ff0200: E: ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp. -E: ID_PATH=pci-0000:00:14.0-usb-0:4 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_4 +E: ID_PATH=pci-0000:00:14.0-usb-0:8 +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8 A: authorized=1\n A: avoid_reset_quirk=0\n A: bConfigurationValue=1\n @@ -39,11 +39,11 @@ A: bmAttributes=a0\n A: busnum=1\n A: configuration=Realtek USB2.0 Finger Print Bridge\n H: descriptors=12010102EF020140DA0B135801210301020109022E00010104A0FA0904000004FF02000507050102000200070583031000080705840310000807058202000200 -A: dev=189:4\n -A: devnum=5\n -A: devpath=4\n +A: dev=189:24\n +A: devnum=25\n +A: devpath=8\n L: driver=../../../../../bus/usb/drivers/usb -L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4b/device:4c/device:50 +L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4b/device:4c/device:54 A: idProduct=5813\n A: idVendor=0bda\n A: ltm_capable=no\n @@ -54,21 +54,21 @@ 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=../1-0:1.0/usb1-port4 -A: power/active_duration=91232868\n +L: port=../1-0:1.0/usb1-port8 +A: power/active_duration=271844\n A: power/async=enabled\n A: power/autosuspend=2\n A: power/autosuspend_delay_ms=2000\n -A: power/connected_duration=91232868\n +A: power/connected_duration=271844\n A: power/control=on\n A: power/level=on\n A: power/persist=1\n A: power/runtime_active_kids=0\n -A: power/runtime_active_time=91232594\n +A: power/runtime_active_time=271564\n A: power/runtime_enabled=forbidden\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n -A: power/runtime_usage=7\n +A: power/runtime_usage=1\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -85,29 +85,29 @@ A: rx_lanes=1\n A: serial=201801010001\n A: speed=480\n A: tx_lanes=1\n -A: urbnum=15076313\n +A: urbnum=297176\n A: version= 2.01\n P: /devices/pci0000:00/0000:00:14.0/usb1 -N: bus/usb/001/001=12010002090001406B1D020002060302010109021900010100E0000904000001090000000705810304000C +N: bus/usb/001/001=12010002090001406B1D020005060302010109021900010100E0000904000001090000000705810304000C E: DEVNAME=/dev/bus/usb/001/001 E: DEVTYPE=usb_device E: DRIVER=usb -E: PRODUCT=1d6b/2/602 +E: PRODUCT=1d6b/2/605 E: TYPE=9/0/1 E: BUSNUM=001 E: DEVNUM=001 E: MAJOR=189 E: MINOR=0 E: SUBSYSTEM=usb -E: ID_VENDOR=Linux_6.2.0-35-generic_xhci-hcd -E: ID_VENDOR_ENC=Linux\x206.2.0-35-generic\x20xhci-hcd +E: ID_VENDOR=Linux_6.5.0-18-generic_xhci-hcd +E: ID_VENDOR_ENC=Linux\x206.5.0-18-generic\x20xhci-hcd E: ID_VENDOR_ID=1d6b E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ID=0002 -E: ID_REVISION=0602 -E: ID_SERIAL=Linux_6.2.0-35-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_REVISION=0605 +E: ID_SERIAL=Linux_6.5.0-18-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_BUS=usb E: ID_USB_INTERFACES=:090000: @@ -130,11 +130,11 @@ A: bMaxPacketSize0=64\n A: bMaxPower=0mA\n A: bNumConfigurations=1\n A: bNumInterfaces= 1\n -A: bcdDevice=0602\n +A: bcdDevice=0605\n A: bmAttributes=e0\n A: busnum=1\n A: configuration= -H: descriptors=12010002090001406B1D020002060302010109021900010100E0000904000001090000000705810304000C +H: descriptors=12010002090001406B1D020005060302010109021900010100E0000904000001090000000705810304000C A: dev=189:0\n A: devnum=1\n A: devpath=0\n @@ -144,17 +144,17 @@ A: idProduct=0002\n A: idVendor=1d6b\n A: interface_authorized_default=1\n A: ltm_capable=no\n -A: manufacturer=Linux 6.2.0-35-generic xhci-hcd\n +A: manufacturer=Linux 6.5.0-18-generic xhci-hcd\n A: maxchild=16\n -A: power/active_duration=264747968\n +A: power/active_duration=351477916\n A: power/async=enabled\n A: power/autosuspend=0\n A: power/autosuspend_delay_ms=0\n -A: power/connected_duration=264747968\n +A: power/connected_duration=351477916\n A: power/control=auto\n A: power/level=auto\n A: power/runtime_active_kids=3\n -A: power/runtime_active_time=264747968\n +A: power/runtime_active_time=351477912\n A: power/runtime_enabled=enabled\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n @@ -175,7 +175,7 @@ A: rx_lanes=1\n A: serial=0000:00:14.0\n A: speed=480\n A: tx_lanes=1\n -A: urbnum=3177\n +A: urbnum=2135\n A: version= 2.00\n P: /devices/pci0000:00/0000:00:14.0 @@ -194,10 +194,14 @@ E: ID_MODEL_FROM_DATABASE=Cannon Lake PCH USB 3.1 xHCI Host Controller A: ari_enabled=0\n A: broken_parity_status=0\n A: class=0x0c0330\n -H: config=86806DA3060590021030030C00008000040030D200000000000000000000000000000000000000000000000028105C08000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000005919041B00000000316000000000000000000000000000000180C2C108000000000000000000000005908700D802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000030000000C00000000000000C000000000000000000100003000000000000000030000000C0000000000000000000000000000000000000000000000000000000000000000000000B50F120112000000 +H: config=86806DA3060590021030030C00008000040030D200000000000000000000000000000000000000000000000028105C08000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000004505531F00000000316000000000000000000000000000000180C2C108000000000000000000000005908700D802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000030000000C00000000000000C000000000000000000100003000000000000000030000000C0000000000000000000000000000000000000000000000000000000000000000000000B50F120112000000 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=0xa36d\n A: dma_mask_bits=64\n L: driver=../../../bus/pci/drivers/xhci_hcd @@ -205,19 +209,19 @@ A: driver_override=(null)\n A: enable=1\n L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4b A: index=4\n -A: irq=125\n +A: irq=126\n A: label=Onboard - Other\n A: local_cpulist=0-3\n A: local_cpus=f\n A: modalias=pci:v00008086d0000A36Dsv00001028sd0000085Cbc0Csc03i30\n A: msi_bus=1\n -A: msi_irqs/125=msi\n +A: msi_irqs/126=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 6 7 2112 7\nxHCI ring segments 24 24 4096 24\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 12 32 128 1\nbuffer-32 0 0 32 0\n A: power/async=enabled\n A: power/control=on\n A: power/runtime_active_kids=1\n -A: power/runtime_active_time=264748677\n +A: power/runtime_active_time=351478612\n A: power/runtime_enabled=forbidden\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n diff --git a/tests/valgrind-python.supp b/tests/valgrind-python.supp index 59e2185..ff7d779 100644 --- a/tests/valgrind-python.supp +++ b/tests/valgrind-python.supp @@ -67,3 +67,31 @@ ... fun:_Py* } + +{ + ignore__libpython_leaks + Memcheck:Leak + fun:malloc + obj:/usr/lib*/libpython3*.so.* +} + +{ + ignore__libpython_leaks + Memcheck:Leak + fun:malloc + obj:/usr/lib/*/libpython3*.so.* +} + +{ + ignore__libpython_leaks + Memcheck:Leak + fun:realloc + obj:/usr/lib*/libpython3*.so.* +} + +{ + ignore__libpython_leaks + Memcheck:Leak + fun:realloc + obj:/usr/lib/*/libpython3*.so.* +} diff --git a/tests/virtual-image.py b/tests/virtual-image.py index b3dc746..b30d519 100755 --- a/tests/virtual-image.py +++ b/tests/virtual-image.py @@ -140,6 +140,24 @@ def send_image(self, image, iterate=True): while iterate and ctx.pending(): ctx.iteration(False) + def wait_for_finger_status(self, finger_status, timeout=5000): + done = False + def on_timeout_reached(): + nonlocal done + done = True + + if 'UNDER_VALGRIND' in os.environ: + timeout = timeout * 3 + + source = GLib.timeout_add(timeout, on_timeout_reached) + while not done: + if self.dev.get_finger_status() & finger_status: + GLib.source_remove(source) + return + ctx.iteration(True) + + self.assertFalse(done) + def test_features(self): self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.CAPTURE)) self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.IDENTIFY)) @@ -204,6 +222,7 @@ def done_cb(dev, res): self.dev.enroll(template, None, progress_cb, tuple(), done_cb) # Note: Assumes 5 enroll steps for this device! + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image(image) while self._step < 1: ctx.iteration(True) @@ -262,6 +281,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('whorl') while self._verify_match is None: ctx.iteration(True) @@ -271,6 +291,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('tented_arch') while self._verify_match is None: ctx.iteration(True) @@ -284,6 +305,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl_tended_arch, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('whorl') while self._verify_match is None: ctx.iteration(True) @@ -293,6 +315,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl_tended_arch, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('tented_arch') while self._verify_match is None: ctx.iteration(True) @@ -302,6 +325,7 @@ def verify_cb(dev, res): self._verify_fp = None self._verify_error = None self.dev.verify(fp_whorl, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_retry() while self._verify_fp is None and self._verify_error is None: ctx.iteration(True) @@ -311,6 +335,7 @@ def verify_cb(dev, res): self._verify_fp = None self._verify_error = None self.dev.verify(fp_whorl, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_error() while self._verify_fp is None and self._verify_error is None: ctx.iteration(True) @@ -334,6 +359,7 @@ def identify_cb(dev, res): self._identify_fp = None self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('tented_arch') while self._identify_fp is None: ctx.iteration(True) @@ -341,6 +367,7 @@ def identify_cb(dev, res): self._identify_fp = None self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('whorl') while self._identify_fp is None: ctx.iteration(True) @@ -350,6 +377,7 @@ def identify_cb(dev, res): self._identify_fp = None self._identify_error = None self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_retry() while self._identify_fp is None and self._identify_error is None: ctx.iteration(True) @@ -393,6 +421,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl_new, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('whorl') while self._verify_match is None: ctx.iteration(True) @@ -401,6 +430,7 @@ def verify_cb(dev, res): self._verify_match = None self._verify_fp = None self.dev.verify(fp_whorl_new, callback=verify_cb) + self.wait_for_finger_status(FPrint.FingerStatusFlags.NEEDED) self.send_image('tented_arch') while self._verify_match is None: ctx.iteration(True)