From c4cc83fe153feff30061b87324efa1817771a4a0 Mon Sep 17 00:00:00 2001 From: "deepin-community-bot[bot]" <156989552+deepin-community-bot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:51:55 +0000 Subject: [PATCH 1/2] feat: update libfprint to 1:1.94.9-1 --- .gitignore | 3 + .gitlab-ci.yml | 120 ++++-- .gitlab-ci/libfprint-image-variables.yaml | 2 +- .gitlab-ci/libfprint-templates.yaml | 12 +- .gitlab-ci/scan-build | 2 +- NEWS | 29 ++ README.md | 9 + data/autosuspend.hwdb | 69 ++- debian/changelog | 26 +- debian/control | 10 +- debian/libfprint-2-2.install | 1 + debian/libfprint-2-2.postinst | 69 ++- ...ling-for-fpi_device_suspend_complete.patch | 37 -- ...-Disable-synaptics-and-focaltech_moc.patch | 34 -- .../patches/0001-skip-tests-fpi-device.patch | 24 -- .../patches/add-uru4000-suspend-resume.patch | 29 -- .../patches/build-Look-for-sh-just-once.patch | 70 ---- ...st-if-the-test-requires-it-during-in.patch | 36 -- debian/patches/series | 6 - debian/rules | 11 +- debian/watch | 4 +- demo/gtk-libfprint-test.c | 13 +- examples/clear-storage.c | 208 +++++++++ examples/meson.build | 1 + examples/storage.c | 68 ++- examples/storage.h | 5 + libfprint/drivers/egismoc/egismoc.c | 393 +++++++++++------- libfprint/drivers/egismoc/egismoc.h | 7 +- libfprint/drivers/elanmoc/elanmoc.c | 4 + libfprint/drivers/elanspi.h | 2 + .../drivers/focaltech_moc/focaltech_moc.c | 3 + libfprint/drivers/fpcmoc/fpc.c | 39 +- libfprint/drivers/goodixmoc/goodix.c | 38 +- libfprint/drivers/goodixmoc/goodix_proto.c | 281 +++++++------ libfprint/drivers/goodixmoc/goodix_proto.h | 12 +- libfprint/drivers/realtek/realtek.c | 311 ++++++++++---- libfprint/drivers/realtek/realtek.h | 96 +++-- libfprint/drivers/synaptics/bmkt_message.c | 3 +- libfprint/drivers/synaptics/synaptics.c | 17 +- libfprint/drivers/upekts.c | 20 +- libfprint/drivers/uru4000.c | 124 +++--- libfprint/drivers/vfs101.c | 6 +- libfprint/drivers/vfs301_proto.c | 30 +- libfprint/drivers/vfs5011.c | 40 +- libfprint/drivers/vfs7552.c | 54 +-- libfprint/drivers/virtual-device.c | 14 + libfprint/drivers/virtual-image.c | 18 +- libfprint/fp-device.c | 24 +- libfprint/fp-device.h | 3 + libfprint/fp-print.h | 2 +- libfprint/fpi-byte-reader.h | 2 + libfprint/fpi-byte-writer.c | 9 +- libfprint/fpi-byte-writer.h | 14 + libfprint/fpi-device.c | 71 ++-- libfprint/fpi-image-device.c | 10 +- libfprint/fpi-log.h | 17 +- libfprint/fpi-ssm.h | 2 +- libfprint/fprint-list-metainfo.c | 107 +++++ libfprint/fprint-list-udev-hwdb.c | 32 +- libfprint/meson.build | 40 +- meson.build | 48 ++- scripts/uncrustify.cfg | 2 + tests/egismoc-0586/custom.pcapng | Bin 0 -> 92980 bytes tests/egismoc-0586/custom.py | 156 +++++++ tests/egismoc-0586/device | 255 ++++++++++++ tests/egismoc-0587/custom.pcapng | Bin 0 -> 92988 bytes tests/egismoc-0587/custom.py | 156 +++++++ tests/egismoc-0587/device | 270 ++++++++++++ tests/goodixmoc/custom.py | 3 + tests/libfprint.supp | 9 + tests/meson.build | 73 +++- tests/realtek-5816/custom.pcapng | Bin 0 -> 30968 bytes tests/realtek-5816/custom.py | 110 +++++ tests/realtek-5816/device | 250 +++++++++++ tests/realtek/custom.pcapng | Bin 29128 -> 30968 bytes tests/realtek/device | 72 ++-- tests/valgrind-python.supp | 28 ++ tests/virtual-image.py | 30 ++ 78 files changed, 3197 insertions(+), 1008 deletions(-) create mode 100644 .gitignore delete mode 100644 debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch delete mode 100644 debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch delete mode 100644 debian/patches/0001-skip-tests-fpi-device.patch delete mode 100644 debian/patches/add-uru4000-suspend-resume.patch delete mode 100644 debian/patches/build-Look-for-sh-just-once.patch delete mode 100644 debian/patches/build-tests-Skip-a-test-if-the-test-requires-it-during-in.patch delete mode 100644 debian/patches/series create mode 100644 examples/clear-storage.c create mode 100644 libfprint/fprint-list-metainfo.c create mode 100644 tests/egismoc-0586/custom.pcapng create mode 100755 tests/egismoc-0586/custom.py create mode 100644 tests/egismoc-0586/device create mode 100644 tests/egismoc-0587/custom.pcapng create mode 100755 tests/egismoc-0587/custom.py create mode 100644 tests/egismoc-0587/device create mode 100644 tests/realtek-5816/custom.pcapng create mode 100755 tests/realtek-5816/custom.py create mode 100644 tests/realtek-5816/device 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..8358733 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,28 @@ -libfprint (1:1.94.7-2deepin2) unstable; urgency=medium +libfprint (1:1.94.9-1) unstable; urgency=medium - * add uru4000 suspend/resume. + * 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 - -- lichenggang Thu, 27 Nov 2025 13:46:41 +0800 + * debian/control: Build-Depend on dh-sequence-gir -libfprint (1:1.94.7-2deepin1) unstable; urgency=medium + -- Marco Trevisan (Treviño) Tue, 03 Sep 2024 06:02:52 +0200 - * Disable ut synaptice and focaltech_moc +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) - -- xiangzelong Thu, 30 May 2024 15:15:32 +0800 + -- 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 deleted file mode 100644 index 98dcc4c..0000000 --- a/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 58555413cefd4375242b6e1d70f803b67fcad096 Mon Sep 17 00:00:00 2001 -From: lichenggang -Date: Thu, 27 Nov 2025 17:19:17 +0800 -Subject: [PATCH] Add error handling for fpi_device_suspend_complete - ---- - libfprint/fpi-device.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c -index 1b9fa8f..d383998 100644 ---- a/libfprint/fpi-device.c -+++ b/libfprint/fpi-device.c -@@ -1792,11 +1792,20 @@ fpi_device_suspend_complete (FpDevice *device, - GError *error) - { - FpDevicePrivate *priv = fp_device_get_instance_private (device); -+ g_autoptr(GTask) task = NULL; - - g_return_if_fail (FP_IS_DEVICE (device)); - g_return_if_fail (priv->suspend_resume_task); - g_return_if_fail (priv->suspend_error == NULL); - -+ if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED)) -+ { -+ g_debug ("Driver does not support suspend, ignoring."); -+ task = g_steal_pointer (&priv->suspend_resume_task); -+ g_task_return_error (task, error); -+ return; -+ } -+ - priv->suspend_error = g_steal_pointer (&error); - priv->is_suspended = TRUE; - --- -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 deleted file mode 100644 index bc45600..0000000 --- a/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch +++ /dev/null @@ -1,34 +0,0 @@ -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 -@@ -39,7 +39,7 @@ drivers_tests = [ - 'elan-cobo', - 'elanmoc', - 'elanspi', -- 'synaptics', -+# 'synaptics', - 'upektc_img', - 'upektc_img-tcs1s', - 'uru4000-msv2', -@@ -55,7 +55,7 @@ drivers_tests = [ - 'egismoc-05a1', - 'fpcmoc', - 'realtek', -- '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 deleted file mode 100644 index f7a630e..0000000 --- a/debian/patches/0001-skip-tests-fpi-device.patch +++ /dev/null @@ -1,24 +0,0 @@ -From e9d21c7290f07582f776832a9ba9af207e8a9486 Mon Sep 17 00:00:00 2001 -From: lichenggang -Date: Fri, 28 Nov 2025 17:49:01 +0800 -Subject: [PATCH] skip tests fpi-device - ---- - tests/meson.build | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tests/meson.build b/tests/meson.build -index f68ed40..19691ce 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -245,7 +245,6 @@ test_utils = static_library('fprint-test-utils', - install: false) - - unit_tests = [ -- 'fpi-device', - 'fpi-ssm', - 'fpi-assembling', - ] --- -2.47.2 - diff --git a/debian/patches/add-uru4000-suspend-resume.patch b/debian/patches/add-uru4000-suspend-resume.patch deleted file mode 100644 index e241b00..0000000 --- a/debian/patches/add-uru4000-suspend-resume.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- libfprint-1.94.7.orig/libfprint/drivers/uru4000.c -+++ libfprint-1.94.7/libfprint/drivers/uru4000.c -@@ -1455,6 +1455,18 @@ fpi_device_uru4000_init (FpiDeviceUru400 - } - - static void -+suspend (FpDevice *dev) -+{ -+ fpi_device_suspend_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); -+} -+ -+static void -+resume (FpDevice *dev) -+{ -+ fpi_device_resume_complete (dev, NULL); -+} -+ -+static void - fpi_device_uru4000_class_init (FpiDeviceUru4000Class *klass) - { - FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); -@@ -1474,4 +1486,7 @@ fpi_device_uru4000_class_init (FpiDevice - - img_class->img_width = IMAGE_WIDTH; - img_class->img_height = IMAGE_HEIGHT; -+ -+ dev_class->suspend = suspend; -+ dev_class->resume = resume; - } 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 deleted file mode 100644 index 52caa3d..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,6 +0,0 @@ -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 -0001-skip-tests-fpi-device.patch diff --git a/debian/rules b/debian/rules index f32921a..d71e755 100755 --- a/debian/rules +++ b/debian/rules @@ -1,14 +1,7 @@ #!/usr/bin/make -f -include /usr/share/dpkg/default.mk -DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) export DPKG_GENSYMBOLS_CHECK_LEVEL = 2 -TIMEOUT_MULTIPLIER = 5 -ifeq ($(DEB_HOST_ARCH), riscv64) - TIMEOUT_MULTIPLIER = 20 -endif - BUILDDIR = $(CURDIR)/obj-$(DEB_HOST_GNU_TYPE) # Configuration arguments @@ -19,13 +12,13 @@ CONFIG_ARGS = \ -Dgtk-examples=false %: - dh $@ --with gir + dh $@ override_dh_auto_configure: dh_auto_configure -- $(CONFIG_ARGS) override_dh_auto_test: - dh_auto_test -- -C $(BUILDDIR) --timeout-multiplier $(TIMEOUT_MULTIPLIER) + dh_auto_test -- -C $(BUILDDIR) --timeout-multiplier 5 override_dh_auto_clean: rm -rf tests/__pycache__ 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 0000000000000000000000000000000000000000..f43dc6f4d1c06801e083c37eaab5e45729444ebe GIT binary patch literal 92980 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c721929c2e46976dceaf808a77f9e30df486a586 GIT binary patch literal 92988 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..579bac6b4b39a49ab68cd3f66dc4bc37c02f11d3 GIT binary patch literal 30968 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 literal 0 HcmV?d00001 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 0fe6dc7b05d6bdd1008665467bffca83d04835b1..84b159934d7d6db6f353109f1a7767014d273d26 100644 GIT binary patch literal 30968 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 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) From 50f4a66a956a1227414f07960e097faefbef486a Mon Sep 17 00:00:00 2001 From: lichenggang Date: Wed, 11 Mar 2026 14:30:24 +0800 Subject: [PATCH 2/2] chore: add riscv64 timeout multiplier support in debian/rules Add architecture-specific timeout multiplier for riscv64 to handle slower test execution on that platform. From: https://github.com/deepin-community/libfprint/commit/6661156aa94327460a40fa0e6e1b91cd63a46c94 --- debian/changelog | 16 +++++++++ ...ling-for-fpi_device_suspend_complete.patch | 36 +++++++++++++++++++ ...-Disable-synaptics-and-focaltech_moc.patch | 20 +++++++++++ .../patches/0001-skip-tests-fpi-device.patch | 23 ++++++++++++ .../patches/add-uru4000-suspend-resume.patch | 29 +++++++++++++++ debian/patches/series | 4 +++ debian/rules | 10 +++++- 7 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch create mode 100644 debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch create mode 100644 debian/patches/0001-skip-tests-fpi-device.patch create mode 100644 debian/patches/add-uru4000-suspend-resume.patch create mode 100644 debian/patches/series diff --git a/debian/changelog b/debian/changelog index 8358733..9425bd0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +libfprint (1:1.94.9-1deepin2) unstable; urgency=medium + + * Add riscv64 timeout multiplier support in debian/rules + + -- lichenggang Wed, 11 Mar 2026 14:30:00 +0800 + +libfprint (1:1.94.9-1deepin1) unstable; urgency=medium + + * 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 + + -- lichenggang Wed, 11 Mar 2026 14:10:00 +0800 + libfprint (1:1.94.9-1) unstable; urgency=medium * New upstream release 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 new file mode 100644 index 0000000..8cf4541 --- /dev/null +++ b/debian/patches/0001-Add-error-handling-for-fpi_device_suspend_complete.patch @@ -0,0 +1,36 @@ +From 58555413cefd4375242b6e1d70f803b67fcad096 Mon Sep 17 00:00:00 2001 +From: lichenggang +Date: Thu, 27 Nov 2025 17:19:17 +0800 +Subject: [PATCH] Add error handling for fpi_device_suspend_complete + +--- + libfprint/fpi-device.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c +index 1b9fa8f..d383998 100644 +--- a/libfprint/fpi-device.c ++++ b/libfprint/fpi-device.c +@@ -1792,11 +1792,20 @@ fpi_device_suspend_complete (FpDevice *device, + GError *error) + { + FpDevicePrivate *priv = fp_device_get_instance_private (device); ++ g_autoptr(GTask) task = NULL; + + g_return_if_fail (FP_IS_DEVICE (device)); + g_return_if_fail (priv->suspend_resume_task); + g_return_if_fail (priv->suspend_error == NULL); + ++ if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED)) ++ { ++ g_debug ("Driver does not support suspend, ignoring."); ++ task = g_steal_pointer (&priv->suspend_resume_task); ++ g_task_return_error (task, error); ++ return; ++ } ++ + priv->suspend_error = g_steal_pointer (&error); + priv->is_suspended = TRUE; + +-- +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 new file mode 100644 index 0000000..5118854 --- /dev/null +++ b/debian/patches/0001-Disable-synaptics-and-focaltech_moc.patch @@ -0,0 +1,20 @@ +--- libfprint-1.94.9.orig/tests/meson.build ++++ libfprint-1.94.9/tests/meson.build +@@ -39,7 +39,7 @@ drivers_tests = [ + 'elan-cobo', + 'elanmoc', + 'elanspi', +- 'synaptics', ++# 'synaptics', + 'upektc_img', + 'upektc_img-tcs1s', + 'uru4000-msv2', +@@ -58,7 +58,7 @@ drivers_tests = [ + 'fpcmoc', + 'realtek', + 'realtek-5816', +- 'focaltech_moc', ++# 'focaltech_moc', + ] + + if get_option('introspection') diff --git a/debian/patches/0001-skip-tests-fpi-device.patch b/debian/patches/0001-skip-tests-fpi-device.patch new file mode 100644 index 0000000..afbbe9a --- /dev/null +++ b/debian/patches/0001-skip-tests-fpi-device.patch @@ -0,0 +1,23 @@ +From e9d21c7290f07582f776832a9ba9af207e8a9486 Mon Sep 17 00:00:00 2001 +From: lichenggang +Date: Fri, 28 Nov 2025 17:49:01 +0800 +Subject: [PATCH] skip tests fpi-device + +--- + tests/meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/tests/meson.build b/tests/meson.build +index f68ed40..19691ce 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -245,7 +245,6 @@ test_utils = static_library('fprint-test-utils', + install: false) + + unit_tests = [ +- 'fpi-device', + 'fpi-ssm', + 'fpi-assembling', + ] +-- +2.47.2 diff --git a/debian/patches/add-uru4000-suspend-resume.patch b/debian/patches/add-uru4000-suspend-resume.patch new file mode 100644 index 0000000..e241b00 --- /dev/null +++ b/debian/patches/add-uru4000-suspend-resume.patch @@ -0,0 +1,29 @@ +--- libfprint-1.94.7.orig/libfprint/drivers/uru4000.c ++++ libfprint-1.94.7/libfprint/drivers/uru4000.c +@@ -1455,6 +1455,18 @@ fpi_device_uru4000_init (FpiDeviceUru400 + } + + static void ++suspend (FpDevice *dev) ++{ ++ fpi_device_suspend_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); ++} ++ ++static void ++resume (FpDevice *dev) ++{ ++ fpi_device_resume_complete (dev, NULL); ++} ++ ++static void + fpi_device_uru4000_class_init (FpiDeviceUru4000Class *klass) + { + FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); +@@ -1474,4 +1486,7 @@ fpi_device_uru4000_class_init (FpiDevice + + img_class->img_width = IMAGE_WIDTH; + img_class->img_height = IMAGE_HEIGHT; ++ ++ dev_class->suspend = suspend; ++ dev_class->resume = resume; + } diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..b5caf0d --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,4 @@ +0001-Disable-synaptics-and-focaltech_moc.patch +add-uru4000-suspend-resume.patch +0001-Add-error-handling-for-fpi_device_suspend_complete.patch +0001-skip-tests-fpi-device.patch diff --git a/debian/rules b/debian/rules index d71e755..5340736 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,15 @@ #!/usr/bin/make -f +include /usr/share/dpkg/default.mk +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) + export DPKG_GENSYMBOLS_CHECK_LEVEL = 2 +TIMEOUT_MULTIPLIER = 5 +ifeq ($(DEB_HOST_ARCH), riscv64) + TIMEOUT_MULTIPLIER = 20 +endif + BUILDDIR = $(CURDIR)/obj-$(DEB_HOST_GNU_TYPE) # Configuration arguments @@ -18,7 +26,7 @@ override_dh_auto_configure: dh_auto_configure -- $(CONFIG_ARGS) override_dh_auto_test: - dh_auto_test -- -C $(BUILDDIR) --timeout-multiplier 5 + dh_auto_test -- -C $(BUILDDIR) --timeout-multiplier $(TIMEOUT_MULTIPLIER) override_dh_auto_clean: rm -rf tests/__pycache__