From 656d4a87b6e2e73e8a279b0240f394dd5d0310d6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 29 Jan 2020 09:09:17 +0000 Subject: [PATCH 01/53] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libfprint.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 5fbf50d..7ad5b27 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint Version: 1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -57,6 +57,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint/ %changelog +* Wed Jan 29 2020 Fedora Release Engineering - 1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Wed Aug 14 2019 Benjamin Berg - 1.0-1 + libfprint-1.0-1 - Update to 1.0 From d4b024a5def050733ed3b956fbc48a2cc6b91d81 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 8 Oct 2019 15:57:47 +0200 Subject: [PATCH 02/53] Update to 1.90.1 --- .gitignore | 1 + gating.yaml | 6 ++++++ libfprint.spec | 35 +++++++++++++++++++++++++---------- sources | 2 +- tests/run-umockdev.sh | 37 +++++++++++++++++++++++++++++++++++++ tests/tests.yml | 21 +++++++++++++++++++++ 6 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 gating.yaml create mode 100755 tests/run-umockdev.sh create mode 100644 tests/tests.yml diff --git a/.gitignore b/.gitignore index 30697c9..0073a4b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-0.8.1.tar.xz /libfprint-0.8.2.tar.xz /libfprint-1.0.tar.xz +/libfprint-v1.90.1.tar.gz diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..d71584a --- /dev/null +++ b/gating.yaml @@ -0,0 +1,6 @@ +--- !Policy +product_versions: + - fedora-* +decision_context: bodhi_update_push_testing +rules: + - !PassingTestCaseRule {test_case_name: dist.depcheck} diff --git a/libfprint.spec b/libfprint.spec index 7ad5b27..d182cee 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,24 +1,30 @@ Name: libfprint -Version: 1.0 -Release: 2%{?dist} + +Version: 1.90.1 +Release: 1%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint -Source0: https://gitlab.freedesktop.org/libfprint/libfprint/uploads/a6084497941324538aefbdf7b954f1e9/%{name}-%{version}.tar.xz +Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz ExcludeArch: s390 s390x BuildRequires: meson BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: git -BuildRequires: pkgconfig(glib-2.0) >= 2.28 -BuildRequires: pkgconfig(libusb-1.0) >= 0.9.1 +BuildRequires: pkgconfig(glib-2.0) >= 2.50 +BuildRequires: pkgconfig(gio-2.0) >= 2.44.0 +BuildRequires: pkgconfig(gusb) >= 0.3.0 BuildRequires: pkgconfig(nss) BuildRequires: pkgconfig(pixman-1) BuildRequires: gtk-doc # For the udev.pc to install the rules BuildRequires: systemd +BuildRequires: gobject-introspection-devel +# For internal CI tests; umockdev 0.13.2 has an important locking fix +BuildRequires: python3-cairo python3-gobject cairo-devel +BuildRequires: umockdev >= 0.13.2 %description libfprint offers support for consumer fingerprint reader devices. @@ -32,10 +38,11 @@ The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep -%autosetup -S git +%autosetup -S git -n libfprint-v%{version} %build -%meson -Dx11-examples=false +# Include the virtual image driver for integration tests +%meson -Dx11-examples=false -Ddrivers=all %meson_build %install @@ -43,20 +50,28 @@ developing applications that use %{name}. %ldconfig_scriptlets +%check +%meson_test + %files %license COPYING %doc NEWS TODO THANKS AUTHORS README %{_libdir}/*.so.* -%{_udevrulesdir}/60-fprint-autosuspend.rules +%{_libdir}/girepository-1.0/*.typelib +%{_udevrulesdir}/60-libfprint-2-autosuspend.rules %files devel %doc HACKING.md %{_includedir}/* %{_libdir}/*.so -%{_libdir}/pkgconfig/%{name}.pc -%{_datadir}/gtk-doc/html/libfprint/ +%{_libdir}/pkgconfig/%{name}-2.pc +%{_datadir}/gir-1.0/*.gir +%{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Mon Feb 10 2020 Benjamin Berg - 1.90.1-1 +- Update to libfprint 1.90.1 + * Wed Jan 29 2020 Fedora Release Engineering - 1.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/sources b/sources index 7b11a8a..0774fe7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-1.0.tar.xz) = 6a38a691d1f2d5fe19b5bbda9b77321d2e34f1a3aa8b61f38109e0095b28e156cdd7be5ade8f3db8ff26045f8556b68e938b3e1378f4b6d84a2106566e7fdb53 +SHA512 (libfprint-v1.90.1.tar.gz) = 0548d29e55aaa59e73f0fd13cac6b85dd3a048358c365423e12884c3877c3e30422ee3fc4d18a3daba2f26383fb886f1d40a74dba5d947f7bdec6b8852995b4e diff --git a/tests/run-umockdev.sh b/tests/run-umockdev.sh new file mode 100755 index 0000000..073f811 --- /dev/null +++ b/tests/run-umockdev.sh @@ -0,0 +1,37 @@ +#!/usr/bin/bash +set -u + +# Switch into the tests directory +cd source/tests || exit 1 + +# check if we need to install additional packages +# which is the case if we are on RHEL 8 +source /etc/os-release || exit 1 + +if [[ "$ID" = *"rhel"* ]] && [[ "$VERSION_ID" == *"8"* ]]; then + dnf config-manager -y --add-repo umockdev.repo + dnf install -y umockdev-devel python3-gobject-base + pip3 install python-dbusmock +fi + +# Each directory in source/tests is a umockdev based test +# discover them +declare -a TESTS=() +for f in *; do + test -d $f && TESTS+=( "$f" ) +done + +export FP_DEVICE_EMULATION=1 + +# execute all the tests, one by one +RESULT=0 +for test in ${TESTS[@]}; do + echo "$test" + ./umockdev-test.py "$test" + RES=$? + echo "$test finished with return code $RES" + echo "" + ((RESULT += $RES)) +done + +exit $RESULT diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..7ee3761 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,21 @@ +--- +- hosts: localhost + roles: + - role: standard-test-source + tags: + - always + - role: standard-test-basic + tags: + - atomic + - classic + required_packages: + - python3-dbusmock + - umockdev + tests: + - virtual_image: + dir: . + run: source/tests/virtual-image.py + - umockdev: + dir: . + run: run-umockdev.sh + From f5dcab8b8c9ba2d9f3b66783d248f64ce12be769 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 14 Feb 2020 10:33:27 +0100 Subject: [PATCH 03/53] + libfprint-1.90.1-2 Rebuilt for F32 --- libfprint.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index d182cee..fade539 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.90.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -69,6 +69,10 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Fri Feb 14 2020 Bastien Nocera - 1.90.1-2 ++ libfprint-1.90.1-2 +- Rebuilt for F32 + * Mon Feb 10 2020 Benjamin Berg - 1.90.1-1 - Update to libfprint 1.90.1 From 5772cdf13fdd31766835da6364042314e96415f8 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 8 Jun 2020 14:27:40 +0200 Subject: [PATCH 04/53] Update to libfprint 1.90.2 Resolves #1832229 Resolves #1841834 Resolves #1841965 --- .gitignore | 1 + libfprint.spec | 10 ++++++++-- sources | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0073a4b..7af2a20 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-0.8.2.tar.xz /libfprint-1.0.tar.xz /libfprint-v1.90.1.tar.gz +/libfprint-v1.90.2.tar.gz diff --git a/libfprint.spec b/libfprint.spec index fade539..a010934 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint -Version: 1.90.1 -Release: 2%{?dist} +Version: 1.90.2 +Release: 1%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -69,6 +69,12 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Mon Jun 08 2020 Benjamin Berg - 1.90.2-1 +- Update to libfprint 1.90.2 +- Resolves #1832229 +- Resolves #1841834 +- Resolves #1841965 + * Fri Feb 14 2020 Bastien Nocera - 1.90.1-2 + libfprint-1.90.1-2 - Rebuilt for F32 diff --git a/sources b/sources index 0774fe7..0bcb2ef 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.1.tar.gz) = 0548d29e55aaa59e73f0fd13cac6b85dd3a048358c365423e12884c3877c3e30422ee3fc4d18a3daba2f26383fb886f1d40a74dba5d947f7bdec6b8852995b4e +SHA512 (libfprint-v1.90.2.tar.gz) = 58326714ce92514e2f95da84c94ca1286cadb0f0bb7de68f15aba0120a22e4a51d8bc6d3d7dc0a4e46e3620e2bd0b3247d07782a3308daf2edd44a4ddb60d226 From 92bdba7aaab2a0d6c030355b2ab647a913f834e4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 28 Jul 2020 04:40:16 +0000 Subject: [PATCH 05/53] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libfprint.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index a010934..db80134 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.90.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -69,6 +69,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Tue Jul 28 2020 Fedora Release Engineering - 1.90.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Mon Jun 08 2020 Benjamin Berg - 1.90.2-1 - Update to libfprint 1.90.2 - Resolves #1832229 From 3800407d90ade449015a30d6e44e4e356b0468ed Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 19 Jun 2020 17:28:05 +0200 Subject: [PATCH 06/53] Add git dependency to gating --- tests/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests.yml b/tests/tests.yml index 7ee3761..8960255 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -9,6 +9,7 @@ - atomic - classic required_packages: + - git - python3-dbusmock - umockdev tests: From 929289033262b4d0be67cbff62029bfd2c923d2a Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 14 Sep 2020 15:04:52 +0200 Subject: [PATCH 07/53] Update to libfprint 1.90.3 (#1878746) --- .gitignore | 1 + libfprint.spec | 7 +++++-- sources | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7af2a20..3d38e51 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-1.0.tar.xz /libfprint-v1.90.1.tar.gz /libfprint-v1.90.2.tar.gz +/libfprint-v1.90.3.tar.gz diff --git a/libfprint.spec b/libfprint.spec index db80134..7c157fa 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint -Version: 1.90.2 -Release: 2%{?dist} +Version: 1.90.3 +Release: 1%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -69,6 +69,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Mon Sep 14 2020 Benjamin Berg - 1.90.3-1 +- Update to libfprint 1.90.3 (#1878746) + * Tue Jul 28 2020 Fedora Release Engineering - 1.90.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild diff --git a/sources b/sources index 0bcb2ef..d25e8af 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.2.tar.gz) = 58326714ce92514e2f95da84c94ca1286cadb0f0bb7de68f15aba0120a22e4a51d8bc6d3d7dc0a4e46e3620e2bd0b3247d07782a3308daf2edd44a4ddb60d226 +SHA512 (libfprint-v1.90.3.tar.gz) = 3420df99c0e388af523f74c008fe603d28599d2ca482ec12a777d8b876e959cac946405fb14ba41fa536997ebd6857d945453e1374a0e05cd8f4fb02ca739891 From 03b482819ed224712e084c62cfcac8219c1400bb Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 27 Nov 2020 14:59:00 +0100 Subject: [PATCH 08/53] tests: Fix git dependency for source stage --- tests/tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests.yml b/tests/tests.yml index 8960255..ab999c2 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -4,12 +4,13 @@ - role: standard-test-source tags: - always + required_packages: + - git - role: standard-test-basic tags: - atomic - classic required_packages: - - git - python3-dbusmock - umockdev tests: From 89ef62a352cb701f4c6b3e993b6bb91c82836415 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 27 Nov 2020 15:12:24 +0100 Subject: [PATCH 09/53] New upstream release 1.90.4 (#1902256) Resolves #1889384 --- .gitignore | 1 + libfprint.spec | 6 +++++- sources | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3d38e51..084f892 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.1.tar.gz /libfprint-v1.90.2.tar.gz /libfprint-v1.90.3.tar.gz +/libfprint-v1.90.4.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 7c157fa..609ff4c 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.90.3 +Version: 1.90.4 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -69,6 +69,10 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Fri Nov 27 2020 Benjamin Berg - 1.90.4-1 +- New upstream release 1.90.4 (#1902256) + Resolves #1889384 + * Mon Sep 14 2020 Benjamin Berg - 1.90.3-1 - Update to libfprint 1.90.3 (#1878746) diff --git a/sources b/sources index d25e8af..9b9c520 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.3.tar.gz) = 3420df99c0e388af523f74c008fe603d28599d2ca482ec12a777d8b876e959cac946405fb14ba41fa536997ebd6857d945453e1374a0e05cd8f4fb02ca739891 +SHA512 (libfprint-v1.90.4.tar.gz) = dc2c95ee1bb9821fd4442901aaafab36829ec34083708c1a568e9ddff1f1911398fdccb82db51139540483d0d660d337c61c8391277c0210f58da4ca244b64bd From 5641bb2bf961d8bb9d3f6a2d0107cccd5c503aa5 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 1 Dec 2020 15:31:41 +0100 Subject: [PATCH 10/53] New upstream release 1.90.5 (#1902256) --- .gitignore | 1 + libfprint.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 084f892..65dc5f1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.2.tar.gz /libfprint-v1.90.3.tar.gz /libfprint-v1.90.4.tar.gz +/libfprint-v1.90.5.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 609ff4c..2a18e9c 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.90.4 +Version: 1.90.5 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -69,6 +69,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Tue Dec 01 2020 Benjamin Berg - 1.90.5-1 +- New upstream release 1.90.5 (#1902256) + * Fri Nov 27 2020 Benjamin Berg - 1.90.4-1 - New upstream release 1.90.4 (#1902256) Resolves #1889384 diff --git a/sources b/sources index 9b9c520..471d0d9 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.4.tar.gz) = dc2c95ee1bb9821fd4442901aaafab36829ec34083708c1a568e9ddff1f1911398fdccb82db51139540483d0d660d337c61c8391277c0210f58da4ca244b64bd +SHA512 (libfprint-v1.90.5.tar.gz) = 441d96fcb17d20198dc786780fd07a213366f48829e1ea90dec334d4ea441bf5c2c2218fc3b29c332bca0e8a0209e3df74a5845caa4b5f2552222ea760adf80f From bd329cd830192cb179d060a7ce2922facfa6a916 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 9 Dec 2020 15:29:22 +0100 Subject: [PATCH 11/53] New upstream release 1.90.6 (#1902256) --- .gitignore | 1 + ...ay-parameter-and-array-bounds-warnin.patch | 28 +++++++++++++++++++ libfprint.spec | 7 ++++- sources | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch diff --git a/.gitignore b/.gitignore index 65dc5f1..831f818 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.3.tar.gz /libfprint-v1.90.4.tar.gz /libfprint-v1.90.5.tar.gz +/libfprint-v1.90.6.tar.gz diff --git a/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch b/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch new file mode 100644 index 0000000..5399f18 --- /dev/null +++ b/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch @@ -0,0 +1,28 @@ +From 2d10d864d8bc4b952cf412f6e18e44412dba759a Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Wed, 9 Dec 2020 15:46:23 +0100 +Subject: [PATCH] nbis: Disable array-parameter and array-bounds warnings + +NBIS just does weird things and while the array-parameter warning is +easy to fix, the other is not trivial. So disable these warnings so that +we can still build using newer GCC versions. +--- + libfprint/meson.build | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libfprint/meson.build b/libfprint/meson.build +index 96cfe9b..4d1d30c 100644 +--- a/libfprint/meson.build ++++ b/libfprint/meson.build +@@ -234,6 +234,8 @@ libnbis = static_library('nbis', + '-Wno-error=redundant-decls', + '-Wno-redundant-decls', + '-Wno-discarded-qualifiers', ++ '-Wno-array-bounds', ++ '-Wno-array-parameter', + ]), + install: false) + +-- +2.26.2 + diff --git a/libfprint.spec b/libfprint.spec index 2a18e9c..76b44b5 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.90.5 +Version: 1.90.6 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -26,6 +26,8 @@ BuildRequires: gobject-introspection-devel BuildRequires: python3-cairo python3-gobject cairo-devel BuildRequires: umockdev >= 0.13.2 +Patch000: 0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch + %description libfprint offers support for consumer fingerprint reader devices. @@ -69,6 +71,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Wed Dec 09 2020 Benjamin Berg - 1.90.6-1 +- New upstream release 1.90.6 (#1902256) + * Tue Dec 01 2020 Benjamin Berg - 1.90.5-1 - New upstream release 1.90.5 (#1902256) diff --git a/sources b/sources index 471d0d9..2b9e37d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.5.tar.gz) = 441d96fcb17d20198dc786780fd07a213366f48829e1ea90dec334d4ea441bf5c2c2218fc3b29c332bca0e8a0209e3df74a5845caa4b5f2552222ea760adf80f +SHA512 (libfprint-v1.90.6.tar.gz) = 91ce2bbc5bed17d8a343fa78cede3d0f14a83706a9c950334db98933ceea5c11c3af81f9692108bf49b3a31f91a4be34812f27a7703f164ebffdbc29eb73fac8 From ac50ff481a508ecfb6d5bf89a1755eece66053bd Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 13 Jan 2021 13:49:46 +0100 Subject: [PATCH 12/53] Update to 1.90.7 (#1902256) --- .gitignore | 1 + ...ay-parameter-and-array-bounds-warnin.patch | 28 ------------------- libfprint.spec | 6 ++-- sources | 2 +- 4 files changed, 6 insertions(+), 31 deletions(-) delete mode 100644 0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch diff --git a/.gitignore b/.gitignore index 831f818..7961d6f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.4.tar.gz /libfprint-v1.90.5.tar.gz /libfprint-v1.90.6.tar.gz +/libfprint-v1.90.7.tar.gz diff --git a/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch b/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch deleted file mode 100644 index 5399f18..0000000 --- a/0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2d10d864d8bc4b952cf412f6e18e44412dba759a Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Wed, 9 Dec 2020 15:46:23 +0100 -Subject: [PATCH] nbis: Disable array-parameter and array-bounds warnings - -NBIS just does weird things and while the array-parameter warning is -easy to fix, the other is not trivial. So disable these warnings so that -we can still build using newer GCC versions. ---- - libfprint/meson.build | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libfprint/meson.build b/libfprint/meson.build -index 96cfe9b..4d1d30c 100644 ---- a/libfprint/meson.build -+++ b/libfprint/meson.build -@@ -234,6 +234,8 @@ libnbis = static_library('nbis', - '-Wno-error=redundant-decls', - '-Wno-redundant-decls', - '-Wno-discarded-qualifiers', -+ '-Wno-array-bounds', -+ '-Wno-array-parameter', - ]), - install: false) - --- -2.26.2 - diff --git a/libfprint.spec b/libfprint.spec index 76b44b5..ddaca7c 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.90.6 +Version: 1.90.7 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -26,7 +26,6 @@ BuildRequires: gobject-introspection-devel BuildRequires: python3-cairo python3-gobject cairo-devel BuildRequires: umockdev >= 0.13.2 -Patch000: 0001-nbis-Disable-array-parameter-and-array-bounds-warnin.patch %description libfprint offers support for consumer fingerprint reader devices. @@ -71,6 +70,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Wed Jan 13 13:33:12 CET 2021 Benjamin Berg - 1.90.7-1 +- Update to 1.90.7 (#1902256) + * Wed Dec 09 2020 Benjamin Berg - 1.90.6-1 - New upstream release 1.90.6 (#1902256) diff --git a/sources b/sources index 2b9e37d..9e5f821 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.6.tar.gz) = 91ce2bbc5bed17d8a343fa78cede3d0f14a83706a9c950334db98933ceea5c11c3af81f9692108bf49b3a31f91a4be34812f27a7703f164ebffdbc29eb73fac8 +SHA512 (libfprint-v1.90.7.tar.gz) = 07803315c89000db4caae5ae64e19042d83638a866fb3d8bcc5e1efcc44424d321974021a9a43db362baa85f0c52fd40dc97ec186eee0954671ddb04f5dfaf2d From ac936eabf5425cc548bd9c116fbad95ac8c62acc Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 26 Jan 2021 17:05:26 +0000 Subject: [PATCH 13/53] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libfprint.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index ddaca7c..9f7cda6 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.90.7 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -70,6 +70,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Tue Jan 26 2021 Fedora Release Engineering - 1.90.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Wed Jan 13 13:33:12 CET 2021 Benjamin Berg - 1.90.7-1 - Update to 1.90.7 (#1902256) From f570d66da9eabd667ffe0385606c310a4de39fe5 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 1 Jul 2021 17:11:22 +0200 Subject: [PATCH 14/53] Update to 1.92.0 (#1977842) --- .gitignore | 1 + 306.patch | 300 +++++++++++++++++++++++++++++++++++++++++++++++++ libfprint.spec | 12 +- sources | 2 +- 4 files changed, 311 insertions(+), 4 deletions(-) create mode 100644 306.patch diff --git a/.gitignore b/.gitignore index 7961d6f..86703ff 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.5.tar.gz /libfprint-v1.90.6.tar.gz /libfprint-v1.90.7.tar.gz +/libfprint-v1.92.0.tar.gz diff --git a/306.patch b/306.patch new file mode 100644 index 0000000..40ca308 --- /dev/null +++ b/306.patch @@ -0,0 +1,300 @@ +From 96afb4577986451eb41df39e4eea2b9d8f96cd7c Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Thu, 1 Jul 2021 17:37:53 +0200 +Subject: [PATCH 1/8] spi: Fix pointer cast on 32bit architectures + +--- + libfprint/fpi-spi-transfer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libfprint/fpi-spi-transfer.c b/libfprint/fpi-spi-transfer.c +index f820c53d..f5d2617d 100644 +--- a/libfprint/fpi-spi-transfer.c ++++ b/libfprint/fpi-spi-transfer.c +@@ -323,7 +323,7 @@ transfer_chunk (FpiSpiTransfer *transfer, gsize full_length, gsize *transferred) + { + if (skip < transfer->length_wr && len < block_size) + { +- xfer[transfers].tx_buf = (guint64) transfer->buffer_wr + skip; ++ xfer[transfers].tx_buf = (gsize) transfer->buffer_wr + skip; + xfer[transfers].len = MIN (block_size, transfer->length_wr - skip); + + len += xfer[transfers].len; +@@ -340,7 +340,7 @@ transfer_chunk (FpiSpiTransfer *transfer, gsize full_length, gsize *transferred) + { + if (skip < transfer->length_rd && len < block_size) + { +- xfer[transfers].rx_buf = (guint64) transfer->buffer_rd + skip; ++ xfer[transfers].rx_buf = (gsize) transfer->buffer_rd + skip; + xfer[transfers].len = MIN (block_size, transfer->length_rd - skip); + + len += xfer[transfers].len; +-- +GitLab + + +From 9e5cf81ef8355b1c267a883b496e580080cbf1c6 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Thu, 1 Jul 2021 17:51:07 +0200 +Subject: [PATCH 2/8] upektc_img: Fix warnings in debug format strings + +--- + libfprint/drivers/upektc_img.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c +index 34e3b9de..19bc4158 100644 +--- a/libfprint/drivers/upektc_img.c ++++ b/libfprint/drivers/upektc_img.c +@@ -221,7 +221,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, + if (response_size > transfer->actual_length) + { + fp_dbg ("response_size is %lu, actual_length is %d", +- response_size, (gint) transfer->actual_length); ++ (gulong) response_size, (gint) transfer->actual_length); + fp_dbg ("Waiting for rest of transfer"); + BUG_ON (self->response_rest); + self->response_rest = response_size - transfer->actual_length; +@@ -309,7 +309,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, + data); + BUG_ON (self->image_size != IMAGE_SIZE); + fp_dbg ("Image size is %lu", +- self->image_size); ++ (gulong) self->image_size); + img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT); + img->flags |= FPI_IMAGE_PARTIAL; + memcpy (img->data, self->image_bits, +-- +GitLab + + +From 8edfd4203c72924e9dd3377a2f3e19174339e6fc Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Thu, 1 Jul 2021 18:27:13 +0200 +Subject: [PATCH 3/8] upektc: Fix format string on architectures where 64bit is + not long + +--- + libfprint/drivers/upektc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c +index c8113f6c..115e6b60 100644 +--- a/libfprint/drivers/upektc.c ++++ b/libfprint/drivers/upektc.c +@@ -411,7 +411,7 @@ dev_init (FpImageDevice *dev) + break; + + default: +- fp_err ("Device variant %lu is not known", driver_data); ++ fp_err ("Device variant %" G_GUINT64_FORMAT " is not known", driver_data); + g_assert_not_reached (); + fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); + return; +-- +GitLab + + +From 78b1b679d79e0af0c17f8450b034b267ba837783 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Tue, 6 Jul 2021 20:48:12 +0200 +Subject: [PATCH 4/8] upeksonly: Fix format string warning by using unsigned + +There is no need to use size_t for num_rows as it is capped to NUM_ROWS +which is defined to 2048. +--- + libfprint/drivers/upeksonly.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c +index 5b2ffdf5..9d93cc76 100644 +--- a/libfprint/drivers/upeksonly.c ++++ b/libfprint/drivers/upeksonly.c +@@ -79,7 +79,7 @@ struct _FpiDeviceUpeksonly + int num_flying; + + GSList *rows; +- size_t num_rows; ++ unsigned num_rows; + unsigned char *rowbuf; + int rowbuf_offset; + +@@ -215,7 +215,7 @@ handoff_img (FpImageDevice *dev) + + self->rows = g_slist_reverse (self->rows); + +- fp_dbg ("%lu rows", self->num_rows); ++ fp_dbg ("%u rows", self->num_rows); + img = fpi_assemble_lines (&self->assembling_ctx, self->rows, self->num_rows); + + g_slist_free_full (self->rows, g_free); +@@ -295,7 +295,7 @@ row_complete (FpImageDevice *dev) + if (self->num_blank > FINGER_REMOVED_THRESHOLD) + { + self->finger_state = FINGER_REMOVED; +- fp_dbg ("detected finger removal. Blank rows: %d, Full rows: %lu", ++ fp_dbg ("detected finger removal. Blank rows: %d, Full rows: %u", + self->num_blank, self->num_rows); + handoff_img (dev); + return; +-- +GitLab + + +From 90b466f122aa74b58807e56720cd49f3b317a709 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Tue, 6 Jul 2021 20:55:00 +0200 +Subject: [PATCH 5/8] upekts: Fix format strings + +--- + libfprint/drivers/upekts.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c +index 1f1b1810..3d82cb33 100644 +--- a/libfprint/drivers/upekts.c ++++ b/libfprint/drivers/upekts.c +@@ -366,7 +366,7 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device, + fp_err ("async msg read too short (%d)", + (gint) transfer->actual_length); + error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, +- "Packet from device was too short (%lu)", ++ "Packet from device was too short (%" G_GSSIZE_FORMAT ")", + transfer->actual_length); + goto err; + } +@@ -993,7 +993,7 @@ e_handle_resp00 (FpDevice *dev, unsigned char *data, + + if (data_len != 14) + { +- fp_err ("received 3001 poll response of %lu bytes?", data_len); ++ fp_err ("received 3001 poll response of %" G_GSIZE_FORMAT " bytes?", data_len); + do_enroll_stop (dev, NULL, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "received 3001 response with wrong length")); +@@ -1090,7 +1090,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data, + + if (data_len < sizeof (scan_comp)) + { +- fp_err ("fingerprint data too short (%lu bytes)", data_len); ++ fp_err ("fingerprint data too short (%" G_GSIZE_FORMAT "u bytes)", data_len); + error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "fingerprint data too short"); + } + else if (memcmp (data, scan_comp, sizeof (scan_comp)) != 0) +@@ -1318,7 +1318,7 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data, + + if (data_len != 14) + { +- fp_warn ("received 3001 poll response of %lu bytes?", data_len); ++ fp_warn ("received 3001 poll response of %" G_GSIZE_FORMAT "u bytes?", data_len); + error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); + goto out; + } +-- +GitLab + + +From b872367aff0c0580318c9159c105a06ea849e613 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Tue, 6 Jul 2021 20:55:23 +0200 +Subject: [PATCH 6/8] virtual-device: Fix format strings + +--- + libfprint/drivers/virtual-device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c +index effcd593..1743692b 100644 +--- a/libfprint/drivers/virtual-device.c ++++ b/libfprint/drivers/virtual-device.c +@@ -192,7 +192,7 @@ process_cmds (FpDeviceVirtualDevice * self, + { + guint64 sleep_ms = g_ascii_strtoull (cmd + strlen (SLEEP_CMD_PREFIX), NULL, 10); + +- g_debug ("Sleeping %lums", sleep_ms); ++ g_debug ("Sleeping %" G_GUINT64_FORMAT "ms", sleep_ms); + self->sleep_timeout_id = g_timeout_add (sleep_ms, sleep_timeout_cb, self); + + return FALSE; +@@ -275,7 +275,7 @@ recv_instruction_cb (GObject *source_object, + gsize bytes; + + bytes = fpi_device_virtual_listener_read_finish (listener, res, &error); +- fp_dbg ("Got instructions of length %ld", bytes); ++ fp_dbg ("Got instructions of length %" G_GSIZE_FORMAT, bytes); + + if (error) + { +-- +GitLab + + +From 7bdb96f3df16e80432c7d0488762d0551cddc252 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Tue, 6 Jul 2021 22:49:15 +0200 +Subject: [PATCH 7/8] aesx660: Fix format strings + +--- + libfprint/drivers/aesx660.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c +index fb786600..dc0bc0de 100644 +--- a/libfprint/drivers/aesx660.c ++++ b/libfprint/drivers/aesx660.c +@@ -365,7 +365,7 @@ capture_read_stripe_data_cb (FpiUsbTransfer *transfer, + return; + } + +- fp_dbg ("Got %lu bytes of data", actual_length); ++ fp_dbg ("Got %" G_GSIZE_FORMAT " bytes of data", actual_length); + while (actual_length) + { + gssize payload_length; +@@ -386,7 +386,7 @@ capture_read_stripe_data_cb (FpiUsbTransfer *transfer, + (priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8); + fp_dbg ("Got frame, type %.2x payload of size %.4lx", + priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET], +- payload_length); ++ (long) payload_length); + + still_needed_len = MAX (0, AESX660_HEADER_SIZE + payload_length - (gssize) priv->stripe_packet->len); + copy_len = MIN (actual_length, still_needed_len); +@@ -441,7 +441,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev) + break; + + case CAPTURE_SET_IDLE: +- fp_dbg ("Got %lu frames", priv->strips_len); ++ fp_dbg ("Got %" G_GSIZE_FORMAT " frames", priv->strips_len); + aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd), + capture_set_idle_cmd_cb); + break; +-- +GitLab + + +From 94dbcc3d0da5e121a59f8fe634bae3d56a070464 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Tue, 6 Jul 2021 22:49:23 +0200 +Subject: [PATCH 8/8] elanspi: Fix format string + +--- + libfprint/drivers/elanspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libfprint/drivers/elanspi.c b/libfprint/drivers/elanspi.c +index fab958b6..daea67c3 100644 +--- a/libfprint/drivers/elanspi.c ++++ b/libfprint/drivers/elanspi.c +@@ -1219,7 +1219,7 @@ elanspi_guess_image (FpiDeviceElanSpi *self, guint16 *raw_image) + + sq_stddev /= (frame_width * frame_height); + +- fp_dbg (" stddev=%ld, ip=%d, is_fp=%d, is_empty=%d", sq_stddev, invalid_percent, is_fp, is_empty); ++ fp_dbg (" stddev=%" G_GUINT64_FORMAT "d, ip=%d, is_fp=%d, is_empty=%d", sq_stddev, invalid_percent, is_fp, is_empty); + + if (invalid_percent < ELANSPI_MAX_REAL_INVALID_PERCENT) + is_fp += 1; +-- +GitLab + diff --git a/libfprint.spec b/libfprint.spec index 9f7cda6..c8597f0 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint -Version: 1.90.7 -Release: 2%{?dist} +Version: 1.92.0 +Release: 1%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -19,6 +19,7 @@ BuildRequires: pkgconfig(gusb) >= 0.3.0 BuildRequires: pkgconfig(nss) BuildRequires: pkgconfig(pixman-1) BuildRequires: gtk-doc +BuildRequires: libgudev-devel # For the udev.pc to install the rules BuildRequires: systemd BuildRequires: gobject-introspection-devel @@ -26,6 +27,7 @@ BuildRequires: gobject-introspection-devel BuildRequires: python3-cairo python3-gobject cairo-devel BuildRequires: umockdev >= 0.13.2 +Patch0000: https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/306.patch %description libfprint offers support for consumer fingerprint reader devices. @@ -59,7 +61,8 @@ developing applications that use %{name}. %doc NEWS TODO THANKS AUTHORS README %{_libdir}/*.so.* %{_libdir}/girepository-1.0/*.typelib -%{_udevrulesdir}/60-libfprint-2-autosuspend.rules +%{_udevhwdbdir}/60-autosuspend-libfprint-2.hwdb +%{_udevrulesdir}/70-libfprint-2.rules %files devel %doc HACKING.md @@ -70,6 +73,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Thu Jul 01 2021 Benjamin Berg - 1.92.0-1 +- Update to 1.92.0 (#1977842) + * Tue Jan 26 2021 Fedora Release Engineering - 1.90.7-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild diff --git a/sources b/sources index 9e5f821..5b180a7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.90.7.tar.gz) = 07803315c89000db4caae5ae64e19042d83638a866fb3d8bcc5e1efcc44424d321974021a9a43db362baa85f0c52fd40dc97ec186eee0954671ddb04f5dfaf2d +SHA512 (libfprint-v1.92.0.tar.gz) = 8993c550c38f3f7d5d50afe6d55414791bdb18e13600fa88d6ad85087e6c1ca664503a0969143c82a1f2fc3e2dbacb93e044fe9ebbb4d5835462d0d3ca03104f From 07130c0eb8de47f0ef2d6f3f0851c01c1b20170d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 22 Jul 2021 11:24:08 +0000 Subject: [PATCH 15/53] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libfprint.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index c8597f0..c1fb6ca 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.92.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -73,6 +73,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Thu Jul 22 2021 Fedora Release Engineering - 1.92.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Thu Jul 01 2021 Benjamin Berg - 1.92.0-1 - Update to 1.92.0 (#1977842) From f287a267a59ba184898245d0730345cced5fd60b Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 26 Jul 2021 20:23:48 +0200 Subject: [PATCH 16/53] Add patch disabling timeouts in virtual-device to enable fedora CI --- ...o-not-time-out-when-waiting-for-SCAN.patch | 53 +++++++++++++++++++ libfprint.spec | 7 ++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch diff --git a/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch b/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch new file mode 100644 index 0000000..fff73d7 --- /dev/null +++ b/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch @@ -0,0 +1,53 @@ +From 4cdca4da247b101e01d3c6266c4b2b3ba946c6f5 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Mon, 26 Jul 2021 19:45:02 +0200 +Subject: [PATCH] virtual-device: Do not time out when waiting for SCAN command + +The timeout is designed to continue commands automatically that are +common (e.g. opening the device). This doesn't really make sense for +scan commands, and removing the timeout enables test setups where user +interaction with the device may happen at arbitrary times. + +One exception is device removal/unplug, in which case the timeout will +be added anyway. +--- + libfprint/drivers/virtual-device.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c +index 1743692..a9efb39 100644 +--- a/libfprint/drivers/virtual-device.c ++++ b/libfprint/drivers/virtual-device.c +@@ -150,6 +150,8 @@ process_cmds (FpDeviceVirtualDevice * self, + char **scan_id, + GError **error) + { ++ gboolean removed; ++ + if (g_cancellable_is_cancelled (self->cancellable) || + (fpi_device_get_current_action (FP_DEVICE (self)) != FPI_DEVICE_ACTION_NONE && + g_cancellable_is_cancelled (fpi_device_get_cancellable (FP_DEVICE (self))))) +@@ -250,8 +252,11 @@ process_cmds (FpDeviceVirtualDevice * self, + if (self->ignore_wait) + return TRUE; + ++ g_object_get (self, "removed", &removed, NULL); ++ + g_assert (self->wait_command_id == 0); +- self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self); ++ if (!scan || removed) ++ self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self); + return FALSE; + } + +@@ -304,6 +309,7 @@ recv_instruction_cb (GObject *source_object, + else if (g_str_has_prefix (cmd, UNPLUG_CMD)) + { + fpi_device_remove (FP_DEVICE (self)); ++ maybe_continue_current_action (self); + } + else if (g_str_has_prefix (cmd, SET_ENROLL_STAGES_PREFIX)) + { +-- +2.31.1 + diff --git a/libfprint.spec b/libfprint.spec index c1fb6ca..2349116 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.92.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -29,6 +29,8 @@ BuildRequires: umockdev >= 0.13.2 Patch0000: https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/306.patch +Patch9999: 0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch + %description libfprint offers support for consumer fingerprint reader devices. @@ -73,6 +75,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Mon Jul 26 2021 Benjamin Berg - 1.92.0-3 +- Add patch disabling timeouts in virtual-device to enable fedora CI + * Thu Jul 22 2021 Fedora Release Engineering - 1.92.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From 04c7a0ca5a945b2f66bd672c0403e17c61beb94b Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 27 Jul 2021 10:18:18 +0200 Subject: [PATCH 17/53] Increase timeout of tests by factor 4 --- libfprint.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 2349116..e0f4236 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -56,7 +56,7 @@ developing applications that use %{name}. %ldconfig_scriptlets %check -%meson_test +%meson_test -t 4 %files %license COPYING @@ -77,6 +77,7 @@ developing applications that use %{name}. %changelog * Mon Jul 26 2021 Benjamin Berg - 1.92.0-3 - Add patch disabling timeouts in virtual-device to enable fedora CI +- Increase timeout of tests by factor 4 * Thu Jul 22 2021 Fedora Release Engineering - 1.92.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From 41b48ba54b3b4404c8415d4b67f029cd780d2512 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 20 Aug 2021 17:18:11 +0200 Subject: [PATCH 18/53] Update to 1.94.0 (#1977842) Related: #1894694 --- .gitignore | 1 + ...o-not-time-out-when-waiting-for-SCAN.patch | 53 ---- 306.patch | 300 ------------------ libfprint.spec | 12 +- sources | 2 +- 5 files changed, 8 insertions(+), 360 deletions(-) delete mode 100644 0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch delete mode 100644 306.patch diff --git a/.gitignore b/.gitignore index 86703ff..026bf07 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.6.tar.gz /libfprint-v1.90.7.tar.gz /libfprint-v1.92.0.tar.gz +/libfprint-v1.94.0.tar.gz diff --git a/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch b/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch deleted file mode 100644 index fff73d7..0000000 --- a/0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4cdca4da247b101e01d3c6266c4b2b3ba946c6f5 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Mon, 26 Jul 2021 19:45:02 +0200 -Subject: [PATCH] virtual-device: Do not time out when waiting for SCAN command - -The timeout is designed to continue commands automatically that are -common (e.g. opening the device). This doesn't really make sense for -scan commands, and removing the timeout enables test setups where user -interaction with the device may happen at arbitrary times. - -One exception is device removal/unplug, in which case the timeout will -be added anyway. ---- - libfprint/drivers/virtual-device.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c -index 1743692..a9efb39 100644 ---- a/libfprint/drivers/virtual-device.c -+++ b/libfprint/drivers/virtual-device.c -@@ -150,6 +150,8 @@ process_cmds (FpDeviceVirtualDevice * self, - char **scan_id, - GError **error) - { -+ gboolean removed; -+ - if (g_cancellable_is_cancelled (self->cancellable) || - (fpi_device_get_current_action (FP_DEVICE (self)) != FPI_DEVICE_ACTION_NONE && - g_cancellable_is_cancelled (fpi_device_get_cancellable (FP_DEVICE (self))))) -@@ -250,8 +252,11 @@ process_cmds (FpDeviceVirtualDevice * self, - if (self->ignore_wait) - return TRUE; - -+ g_object_get (self, "removed", &removed, NULL); -+ - g_assert (self->wait_command_id == 0); -- self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self); -+ if (!scan || removed) -+ self->wait_command_id = g_timeout_add (500, wait_for_command_timeout, self); - return FALSE; - } - -@@ -304,6 +309,7 @@ recv_instruction_cb (GObject *source_object, - else if (g_str_has_prefix (cmd, UNPLUG_CMD)) - { - fpi_device_remove (FP_DEVICE (self)); -+ maybe_continue_current_action (self); - } - else if (g_str_has_prefix (cmd, SET_ENROLL_STAGES_PREFIX)) - { --- -2.31.1 - diff --git a/306.patch b/306.patch deleted file mode 100644 index 40ca308..0000000 --- a/306.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 96afb4577986451eb41df39e4eea2b9d8f96cd7c Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Thu, 1 Jul 2021 17:37:53 +0200 -Subject: [PATCH 1/8] spi: Fix pointer cast on 32bit architectures - ---- - libfprint/fpi-spi-transfer.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libfprint/fpi-spi-transfer.c b/libfprint/fpi-spi-transfer.c -index f820c53d..f5d2617d 100644 ---- a/libfprint/fpi-spi-transfer.c -+++ b/libfprint/fpi-spi-transfer.c -@@ -323,7 +323,7 @@ transfer_chunk (FpiSpiTransfer *transfer, gsize full_length, gsize *transferred) - { - if (skip < transfer->length_wr && len < block_size) - { -- xfer[transfers].tx_buf = (guint64) transfer->buffer_wr + skip; -+ xfer[transfers].tx_buf = (gsize) transfer->buffer_wr + skip; - xfer[transfers].len = MIN (block_size, transfer->length_wr - skip); - - len += xfer[transfers].len; -@@ -340,7 +340,7 @@ transfer_chunk (FpiSpiTransfer *transfer, gsize full_length, gsize *transferred) - { - if (skip < transfer->length_rd && len < block_size) - { -- xfer[transfers].rx_buf = (guint64) transfer->buffer_rd + skip; -+ xfer[transfers].rx_buf = (gsize) transfer->buffer_rd + skip; - xfer[transfers].len = MIN (block_size, transfer->length_rd - skip); - - len += xfer[transfers].len; --- -GitLab - - -From 9e5cf81ef8355b1c267a883b496e580080cbf1c6 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Thu, 1 Jul 2021 17:51:07 +0200 -Subject: [PATCH 2/8] upektc_img: Fix warnings in debug format strings - ---- - libfprint/drivers/upektc_img.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c -index 34e3b9de..19bc4158 100644 ---- a/libfprint/drivers/upektc_img.c -+++ b/libfprint/drivers/upektc_img.c -@@ -221,7 +221,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, - if (response_size > transfer->actual_length) - { - fp_dbg ("response_size is %lu, actual_length is %d", -- response_size, (gint) transfer->actual_length); -+ (gulong) response_size, (gint) transfer->actual_length); - fp_dbg ("Waiting for rest of transfer"); - BUG_ON (self->response_rest); - self->response_rest = response_size - transfer->actual_length; -@@ -309,7 +309,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, - data); - BUG_ON (self->image_size != IMAGE_SIZE); - fp_dbg ("Image size is %lu", -- self->image_size); -+ (gulong) self->image_size); - img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT); - img->flags |= FPI_IMAGE_PARTIAL; - memcpy (img->data, self->image_bits, --- -GitLab - - -From 8edfd4203c72924e9dd3377a2f3e19174339e6fc Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Thu, 1 Jul 2021 18:27:13 +0200 -Subject: [PATCH 3/8] upektc: Fix format string on architectures where 64bit is - not long - ---- - libfprint/drivers/upektc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c -index c8113f6c..115e6b60 100644 ---- a/libfprint/drivers/upektc.c -+++ b/libfprint/drivers/upektc.c -@@ -411,7 +411,7 @@ dev_init (FpImageDevice *dev) - break; - - default: -- fp_err ("Device variant %lu is not known", driver_data); -+ fp_err ("Device variant %" G_GUINT64_FORMAT " is not known", driver_data); - g_assert_not_reached (); - fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); - return; --- -GitLab - - -From 78b1b679d79e0af0c17f8450b034b267ba837783 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Jul 2021 20:48:12 +0200 -Subject: [PATCH 4/8] upeksonly: Fix format string warning by using unsigned - -There is no need to use size_t for num_rows as it is capped to NUM_ROWS -which is defined to 2048. ---- - libfprint/drivers/upeksonly.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c -index 5b2ffdf5..9d93cc76 100644 ---- a/libfprint/drivers/upeksonly.c -+++ b/libfprint/drivers/upeksonly.c -@@ -79,7 +79,7 @@ struct _FpiDeviceUpeksonly - int num_flying; - - GSList *rows; -- size_t num_rows; -+ unsigned num_rows; - unsigned char *rowbuf; - int rowbuf_offset; - -@@ -215,7 +215,7 @@ handoff_img (FpImageDevice *dev) - - self->rows = g_slist_reverse (self->rows); - -- fp_dbg ("%lu rows", self->num_rows); -+ fp_dbg ("%u rows", self->num_rows); - img = fpi_assemble_lines (&self->assembling_ctx, self->rows, self->num_rows); - - g_slist_free_full (self->rows, g_free); -@@ -295,7 +295,7 @@ row_complete (FpImageDevice *dev) - if (self->num_blank > FINGER_REMOVED_THRESHOLD) - { - self->finger_state = FINGER_REMOVED; -- fp_dbg ("detected finger removal. Blank rows: %d, Full rows: %lu", -+ fp_dbg ("detected finger removal. Blank rows: %d, Full rows: %u", - self->num_blank, self->num_rows); - handoff_img (dev); - return; --- -GitLab - - -From 90b466f122aa74b58807e56720cd49f3b317a709 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Jul 2021 20:55:00 +0200 -Subject: [PATCH 5/8] upekts: Fix format strings - ---- - libfprint/drivers/upekts.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c -index 1f1b1810..3d82cb33 100644 ---- a/libfprint/drivers/upekts.c -+++ b/libfprint/drivers/upekts.c -@@ -366,7 +366,7 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device, - fp_err ("async msg read too short (%d)", - (gint) transfer->actual_length); - error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -- "Packet from device was too short (%lu)", -+ "Packet from device was too short (%" G_GSSIZE_FORMAT ")", - transfer->actual_length); - goto err; - } -@@ -993,7 +993,7 @@ e_handle_resp00 (FpDevice *dev, unsigned char *data, - - if (data_len != 14) - { -- fp_err ("received 3001 poll response of %lu bytes?", data_len); -+ fp_err ("received 3001 poll response of %" G_GSIZE_FORMAT " bytes?", data_len); - do_enroll_stop (dev, NULL, - fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, - "received 3001 response with wrong length")); -@@ -1090,7 +1090,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data, - - if (data_len < sizeof (scan_comp)) - { -- fp_err ("fingerprint data too short (%lu bytes)", data_len); -+ fp_err ("fingerprint data too short (%" G_GSIZE_FORMAT "u bytes)", data_len); - error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "fingerprint data too short"); - } - else if (memcmp (data, scan_comp, sizeof (scan_comp)) != 0) -@@ -1318,7 +1318,7 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data, - - if (data_len != 14) - { -- fp_warn ("received 3001 poll response of %lu bytes?", data_len); -+ fp_warn ("received 3001 poll response of %" G_GSIZE_FORMAT "u bytes?", data_len); - error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); - goto out; - } --- -GitLab - - -From b872367aff0c0580318c9159c105a06ea849e613 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Jul 2021 20:55:23 +0200 -Subject: [PATCH 6/8] virtual-device: Fix format strings - ---- - libfprint/drivers/virtual-device.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c -index effcd593..1743692b 100644 ---- a/libfprint/drivers/virtual-device.c -+++ b/libfprint/drivers/virtual-device.c -@@ -192,7 +192,7 @@ process_cmds (FpDeviceVirtualDevice * self, - { - guint64 sleep_ms = g_ascii_strtoull (cmd + strlen (SLEEP_CMD_PREFIX), NULL, 10); - -- g_debug ("Sleeping %lums", sleep_ms); -+ g_debug ("Sleeping %" G_GUINT64_FORMAT "ms", sleep_ms); - self->sleep_timeout_id = g_timeout_add (sleep_ms, sleep_timeout_cb, self); - - return FALSE; -@@ -275,7 +275,7 @@ recv_instruction_cb (GObject *source_object, - gsize bytes; - - bytes = fpi_device_virtual_listener_read_finish (listener, res, &error); -- fp_dbg ("Got instructions of length %ld", bytes); -+ fp_dbg ("Got instructions of length %" G_GSIZE_FORMAT, bytes); - - if (error) - { --- -GitLab - - -From 7bdb96f3df16e80432c7d0488762d0551cddc252 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Jul 2021 22:49:15 +0200 -Subject: [PATCH 7/8] aesx660: Fix format strings - ---- - libfprint/drivers/aesx660.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c -index fb786600..dc0bc0de 100644 ---- a/libfprint/drivers/aesx660.c -+++ b/libfprint/drivers/aesx660.c -@@ -365,7 +365,7 @@ capture_read_stripe_data_cb (FpiUsbTransfer *transfer, - return; - } - -- fp_dbg ("Got %lu bytes of data", actual_length); -+ fp_dbg ("Got %" G_GSIZE_FORMAT " bytes of data", actual_length); - while (actual_length) - { - gssize payload_length; -@@ -386,7 +386,7 @@ capture_read_stripe_data_cb (FpiUsbTransfer *transfer, - (priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8); - fp_dbg ("Got frame, type %.2x payload of size %.4lx", - priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET], -- payload_length); -+ (long) payload_length); - - still_needed_len = MAX (0, AESX660_HEADER_SIZE + payload_length - (gssize) priv->stripe_packet->len); - copy_len = MIN (actual_length, still_needed_len); -@@ -441,7 +441,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev) - break; - - case CAPTURE_SET_IDLE: -- fp_dbg ("Got %lu frames", priv->strips_len); -+ fp_dbg ("Got %" G_GSIZE_FORMAT " frames", priv->strips_len); - aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd), - capture_set_idle_cmd_cb); - break; --- -GitLab - - -From 94dbcc3d0da5e121a59f8fe634bae3d56a070464 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Jul 2021 22:49:23 +0200 -Subject: [PATCH 8/8] elanspi: Fix format string - ---- - libfprint/drivers/elanspi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libfprint/drivers/elanspi.c b/libfprint/drivers/elanspi.c -index fab958b6..daea67c3 100644 ---- a/libfprint/drivers/elanspi.c -+++ b/libfprint/drivers/elanspi.c -@@ -1219,7 +1219,7 @@ elanspi_guess_image (FpiDeviceElanSpi *self, guint16 *raw_image) - - sq_stddev /= (frame_width * frame_height); - -- fp_dbg (" stddev=%ld, ip=%d, is_fp=%d, is_empty=%d", sq_stddev, invalid_percent, is_fp, is_empty); -+ fp_dbg (" stddev=%" G_GUINT64_FORMAT "d, ip=%d, is_fp=%d, is_empty=%d", sq_stddev, invalid_percent, is_fp, is_empty); - - if (invalid_percent < ELANSPI_MAX_REAL_INVALID_PERCENT) - is_fp += 1; --- -GitLab - diff --git a/libfprint.spec b/libfprint.spec index e0f4236..664b64b 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint -Version: 1.92.0 -Release: 3%{?dist} +Version: 1.94.0 +Release: 1%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -27,10 +27,6 @@ BuildRequires: gobject-introspection-devel BuildRequires: python3-cairo python3-gobject cairo-devel BuildRequires: umockdev >= 0.13.2 -Patch0000: https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/306.patch - -Patch9999: 0001-virtual-device-Do-not-time-out-when-waiting-for-SCAN.patch - %description libfprint offers support for consumer fingerprint reader devices. @@ -75,6 +71,10 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Fri Aug 20 2021 Benjamin Berg - 1.94.0-1 +- Update to 1.94.0 (#1977842) + Related: #1894694 + * Mon Jul 26 2021 Benjamin Berg - 1.92.0-3 - Add patch disabling timeouts in virtual-device to enable fedora CI - Increase timeout of tests by factor 4 diff --git a/sources b/sources index 5b180a7..c84429d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.92.0.tar.gz) = 8993c550c38f3f7d5d50afe6d55414791bdb18e13600fa88d6ad85087e6c1ca664503a0969143c82a1f2fc3e2dbacb93e044fe9ebbb4d5835462d0d3ca03104f +SHA512 (libfprint-v1.94.0.tar.gz) = db2c6f88bacdddd44c825faf0ff70e90546261b6756f06bf6b45b8f5524734c11105eca2f3d7548f96f6974e1c1b9c644c7bb69e8ccdfbfcd3264e2d4b40869a From d4c27761b3588b987237e44a7a2f902e6a653100 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 25 Aug 2021 15:02:14 +0200 Subject: [PATCH 19/53] tests: Accept 77 error code This can happen in some cases (e.g. outdated umockdev), so accept error 77 (skipped test). --- tests/run-umockdev.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/run-umockdev.sh b/tests/run-umockdev.sh index 073f811..d8c5362 100755 --- a/tests/run-umockdev.sh +++ b/tests/run-umockdev.sh @@ -31,7 +31,10 @@ for test in ${TESTS[@]}; do RES=$? echo "$test finished with return code $RES" echo "" - ((RESULT += $RES)) + # Ignore skipped tests + if [ $RES -ne 0 -a $RES -ne 77 ]; then + RESULT=1 + fi done exit $RESULT From f8b7f550566d3da00ac80efb547dc0345858d63f Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 24 Sep 2021 17:38:59 +0200 Subject: [PATCH 20/53] Update to 1.94.1 --- .gitignore | 1 + libfprint.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 026bf07..fbe5b94 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.90.7.tar.gz /libfprint-v1.92.0.tar.gz /libfprint-v1.94.0.tar.gz +/libfprint-v1.94.1.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 664b64b..b0f317f 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.0 +Version: 1.94.1 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -71,6 +71,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Fri Sep 24 2021 Benjamin Berg - 1.94.1-1 +- Update to 1.94.1 + * Fri Aug 20 2021 Benjamin Berg - 1.94.0-1 - Update to 1.94.0 (#1977842) Related: #1894694 diff --git a/sources b/sources index c84429d..f75a2a5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.0.tar.gz) = db2c6f88bacdddd44c825faf0ff70e90546261b6756f06bf6b45b8f5524734c11105eca2f3d7548f96f6974e1c1b9c644c7bb69e8ccdfbfcd3264e2d4b40869a +SHA512 (libfprint-v1.94.1.tar.gz) = 648ea42acbba720f16a265a8577256e5650a2706012879f689f8649c8a82aacedea6f0a90964367c884bd3ba13cee76ff5298c8e8e18f61dd769f07ab67bf341 From 6113d1b156353e4fdf0fe95b0d2039f4dc9a9e7b Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 3 Nov 2021 16:42:36 +0100 Subject: [PATCH 21/53] Update to 1.94.2 (#1977842) --- .gitignore | 1 + libfprint.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index fbe5b94..ecc8d00 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.92.0.tar.gz /libfprint-v1.94.0.tar.gz /libfprint-v1.94.1.tar.gz +/libfprint-v1.94.2.tar.gz diff --git a/libfprint.spec b/libfprint.spec index b0f317f..6c73f3e 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.1 +Version: 1.94.2 Release: 1%{?dist} Summary: Toolkit for fingerprint scanner @@ -71,6 +71,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Wed Nov 03 2021 Benjamin Berg - 1.94.2-1 +- Update to 1.94.2 (#1977842) + * Fri Sep 24 2021 Benjamin Berg - 1.94.1-1 - Update to 1.94.1 diff --git a/sources b/sources index f75a2a5..996e761 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.1.tar.gz) = 648ea42acbba720f16a265a8577256e5650a2706012879f689f8649c8a82aacedea6f0a90964367c884bd3ba13cee76ff5298c8e8e18f61dd769f07ab67bf341 +SHA512 (libfprint-v1.94.2.tar.gz) = d18dd86652f18f3157eea5a3e66ed7b4e352b1cd7b8d4ec56d464bc044ee138cac8d09ace9a3259c2736cab84505e0c10bd192088295a11220fd03d5230cf499 From 302ca650b7264d02d5e442434ca4e074dbd464ab Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 16:14:36 +0000 Subject: [PATCH 22/53] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libfprint.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 6c73f3e..b3ad447 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.94.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -71,6 +71,9 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog +* Thu Jan 20 2022 Fedora Release Engineering - 1.94.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Wed Nov 03 2021 Benjamin Berg - 1.94.2-1 - Update to 1.94.2 (#1977842) From 3f62f551b41442bac4aaf9d2e36811ce45136888 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 14 Feb 2022 16:56:20 +0100 Subject: [PATCH 23/53] Switch to rpmautospec --- changelog | 259 ++++++++++++++++++++++++++++++++++++++++++++++++ libfprint.spec | 262 +------------------------------------------------ 2 files changed, 261 insertions(+), 260 deletions(-) create mode 100644 changelog diff --git a/changelog b/changelog new file mode 100644 index 0000000..6d23add --- /dev/null +++ b/changelog @@ -0,0 +1,259 @@ +* Thu Jan 20 2022 Fedora Release Engineering - 1.94.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Nov 03 2021 Benjamin Berg - 1.94.2-1 +- Update to 1.94.2 (#1977842) + +* Fri Sep 24 2021 Benjamin Berg - 1.94.1-1 +- Update to 1.94.1 + +* Fri Aug 20 2021 Benjamin Berg - 1.94.0-1 +- Update to 1.94.0 (#1977842) + Related: #1894694 + +* Mon Jul 26 2021 Benjamin Berg - 1.92.0-3 +- Add patch disabling timeouts in virtual-device to enable fedora CI +- Increase timeout of tests by factor 4 + +* Thu Jul 22 2021 Fedora Release Engineering - 1.92.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Thu Jul 01 2021 Benjamin Berg - 1.92.0-1 +- Update to 1.92.0 (#1977842) + +* Tue Jan 26 2021 Fedora Release Engineering - 1.90.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Jan 13 13:33:12 CET 2021 Benjamin Berg - 1.90.7-1 +- Update to 1.90.7 (#1902256) + +* Wed Dec 09 2020 Benjamin Berg - 1.90.6-1 +- New upstream release 1.90.6 (#1902256) + +* Tue Dec 01 2020 Benjamin Berg - 1.90.5-1 +- New upstream release 1.90.5 (#1902256) + +* Fri Nov 27 2020 Benjamin Berg - 1.90.4-1 +- New upstream release 1.90.4 (#1902256) + Resolves #1889384 + +* Mon Sep 14 2020 Benjamin Berg - 1.90.3-1 +- Update to libfprint 1.90.3 (#1878746) + +* Tue Jul 28 2020 Fedora Release Engineering - 1.90.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jun 08 2020 Benjamin Berg - 1.90.2-1 +- Update to libfprint 1.90.2 +- Resolves #1832229 +- Resolves #1841834 +- Resolves #1841965 + +* Fri Feb 14 2020 Bastien Nocera - 1.90.1-2 ++ libfprint-1.90.1-2 +- Rebuilt for F32 + +* Mon Feb 10 2020 Benjamin Berg - 1.90.1-1 +- Update to libfprint 1.90.1 + +* Wed Jan 29 2020 Fedora Release Engineering - 1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Aug 14 2019 Benjamin Berg - 1.0-1 ++ libfprint-1.0-1 +- Update to 1.0 + +* Thu Jul 25 2019 Fedora Release Engineering - 0.8.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 0.8.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Fri Jul 20 2018 Bastien Nocera - 0.8.2-2 ++ libfprint-0.8.2-2 +- Fix build with newer meson (#1604585) + +* Tue Jul 17 2018 Bastien Nocera - 0.8.2-1 ++ libfprint-0.8.2-1 +- Update to 0.8.2 +- Add required gcc and gcc-c++ BR + +* Fri Jul 13 2018 Fedora Release Engineering - 0.8.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jun 12 2018 Bastien Nocera - 0.8.1-1 ++ libfprint-0.8.1-1 +- Update to 0.8.1 to fix the build + +* Tue Jun 12 2018 Bastien Nocera - 0.8.0-1 ++ libfprint-0.8.0-1 +- Update to 0.8.0 +- Port to meson, gtk-doc + +* Wed Feb 07 2018 Fedora Release Engineering - 0.7.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Feb 03 2018 Igor Gnatenko - 0.7.0-4 +- Switch to %%ldconfig_scriptlets + +* Thu Aug 03 2017 Fedora Release Engineering - 0.7.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 0.7.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon May 15 2017 Bastien Nocera - 0.7.0-1 ++ libfprint-0.7.0-1 +- Update to 0.7.0 + +* Fri Feb 10 2017 Fedora Release Engineering - 0.6.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Feb 04 2016 Fedora Release Engineering - 0.6.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 0.6.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Feb 03 2015 Bastien Nocera 0.6.0-1 +- Update to 0.6.0 + +* Wed Dec 17 2014 Rex Dieter - 0.5.1-5 +- error opening ATTR{/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.3/1-1.3:1.0/power/control} for writing (#950205) +- %%build: --disable-silent-rules + +* Sun Aug 17 2014 Fedora Release Engineering - 0.5.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 0.5.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu Jan 16 2014 Ville Skyttä - 0.5.1-2 +- Drop INSTALL from docs. + +* Sun Aug 11 2013 Bastien Nocera 0.5.1-1 +- Update to 0.5.1 + +* Sat Aug 03 2013 Fedora Release Engineering - 0.5.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu Feb 14 2013 Fedora Release Engineering - 0.5.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Dec 03 2012 Bastien Nocera 0.5.0-1 +- Update to 0.5.0 +- Re-add not useless udev rules + +* Thu Jul 19 2012 Fedora Release Engineering - 0.4.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri May 18 2012 Matthias Clasen - 0.4.0-4 +- Drop broken and useless udev rules (#744637) + +* Fri Jan 13 2012 Fedora Release Engineering - 0.4.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Nov 21 2011 Adam Jackson 0.4.0-2 +- Rebuild without Requires: ConsoleKit, going away in F17 + +* Thu Nov 10 2011 Bastien Nocera 0.4.0-1 +- Update to 0.4.0 + +* Mon Nov 07 2011 Adam Jackson 0.3.0-3 +- Rebuild for libpng 1.5 + +* Mon Feb 07 2011 Fedora Release Engineering - 0.3.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Sep 08 2010 Bastien Nocera 0.3.0-1 +- Update to 0.3.0 + +* Thu Aug 19 2010 Bastien Nocera 0.2.0-1 +- Update to 0.2.0 + +* Wed Jun 30 2010 Matthew Garrett 0.1.0-16.pre3 +- Fix #505438 to avoid message on boot on some systems + +* Tue Jun 01 2010 Bastien Nocera 0.1.0-16.pre2 +- Add README to package + +* Wed Jan 20 2010 Bastien Nocera 0.1.0-15.pre2 +- Require hal-filesystem for the fdi file + +* Tue Dec 01 2009 Bastien Nocera 0.1.0-14.pre2 +- Update AES1610 patch + +* Mon Nov 30 2009 Bastien Nocera 0.1.0-13.pre2 +- Add aes1610 driver (#499732) + +* Thu Oct 01 2009 Bastien Nocera 0.1.0-12.pre2 +- Update udev autosuspend rules and disable SGS Thomson reader + +* Fri Aug 21 2009 Tomas Mraz - 0.1.0-11.pre2 +- rebuilt with new openssl + +* Fri Jul 24 2009 Fedora Release Engineering - 0.1.0-10.pre2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 21 2009 Bastien Nocera 0.1.0-9.pre2 +- Use gdk-pixbuf for image manipulation instead of ImageMagick (#472103) + +* Sat Jun 20 2009 Bastien Nocera 0.1.0-8.pre2 +- Update to 0.1.0-pre2 + +* Tue Jun 09 2009 Matthew Garrett 0.1.0-7.pre1 +- fprint-add-udev-rules.patch - build udev rules for autosuspend +- move hal fdi into the main package rather than -devel +- add autoreconf as a build depend while carrying the udev diff + +* Tue Apr 21 2009 Karsten Hopp 0.1.0-6.pre1.1 +- Excludearch s390 s390x, we don't have USB devices there and this package + doesn't build without USB support + +* Mon Mar 09 2009 pingou - 0.1.0-6.pre1 +- Rebuilt for rawhide + +* Wed Feb 25 2009 Fedora Release Engineering - 0.1.0-5.pre1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sat Jan 17 2009 Tomas Mraz - 0.1.0-4.pre1 +- rebuild with new openssl + +* Tue Nov 25 2008 - Bastien Nocera - 0.1.0-3.pre1 +- Fix possible crasher in libfprint when setting up the fds for polling + +* Mon Nov 24 2008 - Bastien Nocera - 0.1.0-2.pre1 +- And add some API docs + +* Tue Nov 18 2008 - Bastien Nocera - 0.1.0-1.pre1 +- Fix build + +* Tue Nov 04 2008 - Bastien Nocera - 0.1.0-0.pre1 +- Update to 0.1.0-pre1 + +* Tue May 13 2008 Pingou 0.0.5-6 +- Correction on the Build Requires + +* Tue May 13 2008 Pingou 0.0.5-5 +- Correction on the Build Requires + +* Tue May 13 2008 Pingou 0.0.5-4 +- Update the Build Requires due to the change on ImageMagick + +* Tue Feb 19 2008 Fedora Release Engineering - 0.0.5-3 +- Autorebuild for GCC 4.3 + +* Sat Jan 05 2008 Pingou 0.0.5-2 +- Change on the BuildRequires + +* Sat Jan 05 2008 Pingou 0.0.5-1 +- Update to version 0.0.5 + +* Sat Dec 01 2007 Pingou 0.0.4-3 +- Changes on the Requires + +* Sun Nov 25 2007 Pingou 0.0.4-2 +- Changes on the Requires + +* Sat Nov 24 2007 Pingou 0.0.4-1 +- First release diff --git a/libfprint.spec b/libfprint.spec index b3ad447..7ed68b2 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,7 +1,7 @@ Name: libfprint Version: 1.94.2 -Release: 2%{?dist} +Release: %autorelease Summary: Toolkit for fingerprint scanner License: LGPLv2+ @@ -71,262 +71,4 @@ developing applications that use %{name}. %{_datadir}/gtk-doc/html/libfprint-2/ %changelog -* Thu Jan 20 2022 Fedora Release Engineering - 1.94.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Wed Nov 03 2021 Benjamin Berg - 1.94.2-1 -- Update to 1.94.2 (#1977842) - -* Fri Sep 24 2021 Benjamin Berg - 1.94.1-1 -- Update to 1.94.1 - -* Fri Aug 20 2021 Benjamin Berg - 1.94.0-1 -- Update to 1.94.0 (#1977842) - Related: #1894694 - -* Mon Jul 26 2021 Benjamin Berg - 1.92.0-3 -- Add patch disabling timeouts in virtual-device to enable fedora CI -- Increase timeout of tests by factor 4 - -* Thu Jul 22 2021 Fedora Release Engineering - 1.92.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Thu Jul 01 2021 Benjamin Berg - 1.92.0-1 -- Update to 1.92.0 (#1977842) - -* Tue Jan 26 2021 Fedora Release Engineering - 1.90.7-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Wed Jan 13 13:33:12 CET 2021 Benjamin Berg - 1.90.7-1 -- Update to 1.90.7 (#1902256) - -* Wed Dec 09 2020 Benjamin Berg - 1.90.6-1 -- New upstream release 1.90.6 (#1902256) - -* Tue Dec 01 2020 Benjamin Berg - 1.90.5-1 -- New upstream release 1.90.5 (#1902256) - -* Fri Nov 27 2020 Benjamin Berg - 1.90.4-1 -- New upstream release 1.90.4 (#1902256) - Resolves #1889384 - -* Mon Sep 14 2020 Benjamin Berg - 1.90.3-1 -- Update to libfprint 1.90.3 (#1878746) - -* Tue Jul 28 2020 Fedora Release Engineering - 1.90.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Mon Jun 08 2020 Benjamin Berg - 1.90.2-1 -- Update to libfprint 1.90.2 -- Resolves #1832229 -- Resolves #1841834 -- Resolves #1841965 - -* Fri Feb 14 2020 Bastien Nocera - 1.90.1-2 -+ libfprint-1.90.1-2 -- Rebuilt for F32 - -* Mon Feb 10 2020 Benjamin Berg - 1.90.1-1 -- Update to libfprint 1.90.1 - -* Wed Jan 29 2020 Fedora Release Engineering - 1.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Wed Aug 14 2019 Benjamin Berg - 1.0-1 -+ libfprint-1.0-1 -- Update to 1.0 - -* Thu Jul 25 2019 Fedora Release Engineering - 0.8.2-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Fri Feb 01 2019 Fedora Release Engineering - 0.8.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Fri Jul 20 2018 Bastien Nocera - 0.8.2-2 -+ libfprint-0.8.2-2 -- Fix build with newer meson (#1604585) - -* Tue Jul 17 2018 Bastien Nocera - 0.8.2-1 -+ libfprint-0.8.2-1 -- Update to 0.8.2 -- Add required gcc and gcc-c++ BR - -* Fri Jul 13 2018 Fedora Release Engineering - 0.8.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Tue Jun 12 2018 Bastien Nocera - 0.8.1-1 -+ libfprint-0.8.1-1 -- Update to 0.8.1 to fix the build - -* Tue Jun 12 2018 Bastien Nocera - 0.8.0-1 -+ libfprint-0.8.0-1 -- Update to 0.8.0 -- Port to meson, gtk-doc - -* Wed Feb 07 2018 Fedora Release Engineering - 0.7.0-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Sat Feb 03 2018 Igor Gnatenko - 0.7.0-4 -- Switch to %%ldconfig_scriptlets - -* Thu Aug 03 2017 Fedora Release Engineering - 0.7.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild - -* Wed Jul 26 2017 Fedora Release Engineering - 0.7.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Mon May 15 2017 Bastien Nocera - 0.7.0-1 -+ libfprint-0.7.0-1 -- Update to 0.7.0 - -* Fri Feb 10 2017 Fedora Release Engineering - 0.6.0-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Thu Feb 04 2016 Fedora Release Engineering - 0.6.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Wed Jun 17 2015 Fedora Release Engineering - 0.6.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Tue Feb 03 2015 Bastien Nocera 0.6.0-1 -- Update to 0.6.0 - -* Wed Dec 17 2014 Rex Dieter - 0.5.1-5 -- error opening ATTR{/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.3/1-1.3:1.0/power/control} for writing (#950205) -- %%build: --disable-silent-rules - -* Sun Aug 17 2014 Fedora Release Engineering - 0.5.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Sat Jun 07 2014 Fedora Release Engineering - 0.5.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Thu Jan 16 2014 Ville Skyttä - 0.5.1-2 -- Drop INSTALL from docs. - -* Sun Aug 11 2013 Bastien Nocera 0.5.1-1 -- Update to 0.5.1 - -* Sat Aug 03 2013 Fedora Release Engineering - 0.5.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild - -* Thu Feb 14 2013 Fedora Release Engineering - 0.5.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild - -* Mon Dec 03 2012 Bastien Nocera 0.5.0-1 -- Update to 0.5.0 -- Re-add not useless udev rules - -* Thu Jul 19 2012 Fedora Release Engineering - 0.4.0-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild - -* Fri May 18 2012 Matthias Clasen - 0.4.0-4 -- Drop broken and useless udev rules (#744637) - -* Fri Jan 13 2012 Fedora Release Engineering - 0.4.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild - -* Mon Nov 21 2011 Adam Jackson 0.4.0-2 -- Rebuild without Requires: ConsoleKit, going away in F17 - -* Thu Nov 10 2011 Bastien Nocera 0.4.0-1 -- Update to 0.4.0 - -* Mon Nov 07 2011 Adam Jackson 0.3.0-3 -- Rebuild for libpng 1.5 - -* Mon Feb 07 2011 Fedora Release Engineering - 0.3.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Wed Sep 08 2010 Bastien Nocera 0.3.0-1 -- Update to 0.3.0 - -* Thu Aug 19 2010 Bastien Nocera 0.2.0-1 -- Update to 0.2.0 - -* Wed Jun 30 2010 Matthew Garrett 0.1.0-16.pre3 -- Fix #505438 to avoid message on boot on some systems - -* Tue Jun 01 2010 Bastien Nocera 0.1.0-16.pre2 -- Add README to package - -* Wed Jan 20 2010 Bastien Nocera 0.1.0-15.pre2 -- Require hal-filesystem for the fdi file - -* Tue Dec 01 2009 Bastien Nocera 0.1.0-14.pre2 -- Update AES1610 patch - -* Mon Nov 30 2009 Bastien Nocera 0.1.0-13.pre2 -- Add aes1610 driver (#499732) - -* Thu Oct 01 2009 Bastien Nocera 0.1.0-12.pre2 -- Update udev autosuspend rules and disable SGS Thomson reader - -* Fri Aug 21 2009 Tomas Mraz - 0.1.0-11.pre2 -- rebuilt with new openssl - -* Fri Jul 24 2009 Fedora Release Engineering - 0.1.0-10.pre2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild - -* Tue Jul 21 2009 Bastien Nocera 0.1.0-9.pre2 -- Use gdk-pixbuf for image manipulation instead of ImageMagick (#472103) - -* Sat Jun 20 2009 Bastien Nocera 0.1.0-8.pre2 -- Update to 0.1.0-pre2 - -* Tue Jun 09 2009 Matthew Garrett 0.1.0-7.pre1 -- fprint-add-udev-rules.patch - build udev rules for autosuspend -- move hal fdi into the main package rather than -devel -- add autoreconf as a build depend while carrying the udev diff - -* Tue Apr 21 2009 Karsten Hopp 0.1.0-6.pre1.1 -- Excludearch s390 s390x, we don't have USB devices there and this package - doesn't build without USB support - -* Mon Mar 09 2009 pingou - 0.1.0-6.pre1 -- Rebuilt for rawhide - -* Wed Feb 25 2009 Fedora Release Engineering - 0.1.0-5.pre1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild - -* Sat Jan 17 2009 Tomas Mraz - 0.1.0-4.pre1 -- rebuild with new openssl - -* Tue Nov 25 2008 - Bastien Nocera - 0.1.0-3.pre1 -- Fix possible crasher in libfprint when setting up the fds for polling - -* Mon Nov 24 2008 - Bastien Nocera - 0.1.0-2.pre1 -- And add some API docs - -* Tue Nov 18 2008 - Bastien Nocera - 0.1.0-1.pre1 -- Fix build - -* Tue Nov 04 2008 - Bastien Nocera - 0.1.0-0.pre1 -- Update to 0.1.0-pre1 - -* Tue May 13 2008 Pingou 0.0.5-6 -- Correction on the Build Requires - -* Tue May 13 2008 Pingou 0.0.5-5 -- Correction on the Build Requires - -* Tue May 13 2008 Pingou 0.0.5-4 -- Update the Build Requires due to the change on ImageMagick - -* Tue Feb 19 2008 Fedora Release Engineering - 0.0.5-3 -- Autorebuild for GCC 4.3 - -* Sat Jan 05 2008 Pingou 0.0.5-2 -- Change on the BuildRequires - -* Sat Jan 05 2008 Pingou 0.0.5-1 -- Update to version 0.0.5 - -* Sat Dec 01 2007 Pingou 0.0.4-3 -- Changes on the Requires - -* Sun Nov 25 2007 Pingou 0.0.4-2 -- Changes on the Requires - -* Sat Nov 24 2007 Pingou 0.0.4-1 -- First release +%autochangelog From b0ccaef332de78f1499b34291bca9a36713bf59f Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 14 Feb 2022 17:02:44 +0100 Subject: [PATCH 24/53] Don't set removed x11-examples option Resolves: #2045801 --- libfprint.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 7ed68b2..3cbe112 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -43,7 +43,7 @@ developing applications that use %{name}. %build # Include the virtual image driver for integration tests -%meson -Dx11-examples=false -Ddrivers=all +%meson -Ddrivers=all %meson_build %install From dc82faf4a4a8bd7321b3d5d2e49facfbcf10e9c7 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 14 Feb 2022 17:04:50 +0100 Subject: [PATCH 25/53] Update to 1.94.3 Resolves: #2053718 --- .gitignore | 1 + libfprint.spec | 4 ++-- sources | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ecc8d00..3570b7c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.0.tar.gz /libfprint-v1.94.1.tar.gz /libfprint-v1.94.2.tar.gz +/libfprint-v1.94.3.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 3cbe112..3bed9d6 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.2 +Version: 1.94.3 Release: %autorelease Summary: Toolkit for fingerprint scanner @@ -56,7 +56,7 @@ developing applications that use %{name}. %files %license COPYING -%doc NEWS TODO THANKS AUTHORS README +%doc NEWS THANKS AUTHORS README.md %{_libdir}/*.so.* %{_libdir}/girepository-1.0/*.typelib %{_udevhwdbdir}/60-autosuspend-libfprint-2.hwdb diff --git a/sources b/sources index 996e761..ba640e1 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.2.tar.gz) = d18dd86652f18f3157eea5a3e66ed7b4e352b1cd7b8d4ec56d464bc044ee138cac8d09ace9a3259c2736cab84505e0c10bd192088295a11220fd03d5230cf499 +SHA512 (libfprint-v1.94.3.tar.gz) = f8f7a5fa4647e79c0251ea807bd5b84a07d1d2001962a86682298d671c9a21c22d6574e2cd31fc3a3b81b53838ef1e0ff922c125a7faa78270e699fc201f0257 From dc9e86e1e3f6f0271caddd9ef44a14f195b2b1f2 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 11 Jul 2022 15:06:54 +0200 Subject: [PATCH 26/53] Update to 1.94.4 Resolves: #2089823 --- .gitignore | 1 + libfprint.spec | 2 +- sources | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3570b7c..6a84c14 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.1.tar.gz /libfprint-v1.94.2.tar.gz /libfprint-v1.94.3.tar.gz +/libfprint-v1.94.4.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 3bed9d6..5115125 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.3 +Version: 1.94.4 Release: %autorelease Summary: Toolkit for fingerprint scanner diff --git a/sources b/sources index ba640e1..8c0c8f0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.3.tar.gz) = f8f7a5fa4647e79c0251ea807bd5b84a07d1d2001962a86682298d671c9a21c22d6574e2cd31fc3a3b81b53838ef1e0ff922c125a7faa78270e699fc201f0257 +SHA512 (libfprint-v1.94.4.tar.gz) = d1f2e62d5f08017912f8701e1b366f48dff9819897840a1570d16872fc2aad0a8757cd1d8e9d1b98e72e6b00f24ccb3d2aefc5abd824d2699cc75bc7ef8c8e93 From 7d22b98997e6cd86a8fcf1315723c03daaaa3b21 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 17:50:00 +0000 Subject: [PATCH 27/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering From c5acc461259fd1749ae268d03a5d9f3cfd6078b2 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 Nov 2022 13:06:12 +0100 Subject: [PATCH 28/53] Update to 1.94.5 --- .gitignore | 1 + libfprint.spec | 2 +- sources | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6a84c14..5f6dad0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.2.tar.gz /libfprint-v1.94.3.tar.gz /libfprint-v1.94.4.tar.gz +/libfprint-v1.94.5.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 5115125..ddae905 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.4 +Version: 1.94.5 Release: %autorelease Summary: Toolkit for fingerprint scanner diff --git a/sources b/sources index 8c0c8f0..51fc19a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.4.tar.gz) = d1f2e62d5f08017912f8701e1b366f48dff9819897840a1570d16872fc2aad0a8757cd1d8e9d1b98e72e6b00f24ccb3d2aefc5abd824d2699cc75bc7ef8c8e93 +SHA512 (libfprint-v1.94.5.tar.gz) = 033b7239acebfcccbb9f275cbbca52d68bf4a3a62f4c39a6323c943924532f73233fa3bf2e9517f6f4de04f513ba30776fcd3a98ebb8467fd2826e72a3ae3529 From 7eb880c0d65142f82b59b60f84e0a5b81ab9ff9b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 16:21:25 +0000 Subject: [PATCH 29/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering From 098d70baba2a760f6c60614649fa371210407487 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jul 2023 10:53:00 +0000 Subject: [PATCH 30/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering From 6305b23e2581bc1ef66a654b262afb08db09de44 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sun, 21 Jan 2024 04:06:36 +0000 Subject: [PATCH 31/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From c701ce89fb6efcfa7485c9e93d73c596e80d928e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jan 2024 02:11:33 +0000 Subject: [PATCH 32/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 4f101d393ee92f5792d413895dd95e9f9e7af17d Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Wed, 31 Jan 2024 13:34:45 +0800 Subject: [PATCH 33/53] Update to 1.94.6 Resolves: #2250624 --- .gitignore | 1 + libfprint.spec | 4 ++-- sources | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 5f6dad0..b41a1b9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.3.tar.gz /libfprint-v1.94.4.tar.gz /libfprint-v1.94.5.tar.gz +/libfprint-v1.94.6.tar.gz diff --git a/libfprint.spec b/libfprint.spec index ddae905..491af24 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.5 +Version: 1.94.6 Release: %autorelease Summary: Toolkit for fingerprint scanner @@ -43,7 +43,7 @@ developing applications that use %{name}. %build # Include the virtual image driver for integration tests -%meson -Ddrivers=all +%meson -Ddrivers=all -Dinstalled-tests=false %meson_build %install diff --git a/sources b/sources index 51fc19a..129d049 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.5.tar.gz) = 033b7239acebfcccbb9f275cbbca52d68bf4a3a62f4c39a6323c943924532f73233fa3bf2e9517f6f4de04f513ba30776fcd3a98ebb8467fd2826e72a3ae3529 +SHA512 (libfprint-v1.94.6.tar.gz) = 99cfce5828d7df771bfc1fd92ad357b76c265bc96443af3398c415d2bb54a931fa3018811c59ceb62b43ef416b430db4acf324aa1dca4f374eaef1f1595a154a From 05b84333616c82b751bbb18c9977029817de77cc Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 23 Feb 2024 18:26:28 +0000 Subject: [PATCH 34/53] Add tests subpackage --- libfprint.spec | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 491af24..574619e 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -38,12 +38,20 @@ Requires: %{name}%{?_isa} = %{version}-%{release} The %{name}-devel package contains libraries and header files for developing applications that use %{name}. +%package tests +Summary: Tests for the %{name} package +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tests +The %{name}-tests package contains tests that can be used to verify +the functionality of the installed %{name} package. + %prep %autosetup -S git -n libfprint-v%{version} %build # Include the virtual image driver for integration tests -%meson -Ddrivers=all -Dinstalled-tests=false +%meson -Ddrivers=all %meson_build %install @@ -70,5 +78,9 @@ developing applications that use %{name}. %{_datadir}/gir-1.0/*.gir %{_datadir}/gtk-doc/html/libfprint-2/ +%files tests +%{_libexecdir}/installed-tests/libfprint-2/ +%{_datadir}/installed-tests/libfprint-2/ + %changelog %autochangelog From 9a72ec14741631cf7755459eca836218b1b54716 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 23 Feb 2024 18:41:57 +0000 Subject: [PATCH 35/53] Update to 1.94.7 Resolves: #2232471 --- .gitignore | 1 + libfprint.spec | 2 +- sources | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b41a1b9..55ad153 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.4.tar.gz /libfprint-v1.94.5.tar.gz /libfprint-v1.94.6.tar.gz +/libfprint-v1.94.7.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 574619e..6b90f2f 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.6 +Version: 1.94.7 Release: %autorelease Summary: Toolkit for fingerprint scanner diff --git a/sources b/sources index 129d049..4bf9301 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.6.tar.gz) = 99cfce5828d7df771bfc1fd92ad357b76c265bc96443af3398c415d2bb54a931fa3018811c59ceb62b43ef416b430db4acf324aa1dca4f374eaef1f1595a154a +SHA512 (libfprint-v1.94.7.tar.gz) = 5e7afc8424862d2caaba9d6c2dbd0a339639497ddb7b096f1073464ebdfd9acec1b84470297bd51761dae4770d4113e336096536bb5f8700da2673a2685856b6 From 9dd7c7df011e96478d6779f9a6af966f465c2a6e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 13:53:02 +0000 Subject: [PATCH 36/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From f4e2d954bcc8a652dc894c3cc0de34f380d72e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Mon, 2 Sep 2024 09:52:07 +0200 Subject: [PATCH 37/53] convert license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- libfprint.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index 6b90f2f..53b5a92 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -4,7 +4,8 @@ Version: 1.94.7 Release: %autorelease Summary: Toolkit for fingerprint scanner -License: LGPLv2+ +# Automatically converted from old format: LGPLv2+ - review is highly recommended. +License: LicenseRef-Callaway-LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz ExcludeArch: s390 s390x From 3a96323138fd2e08e341f5fdf6a41180c82a5994 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Tue, 24 Sep 2024 15:33:19 +0800 Subject: [PATCH 38/53] Update to upstream version 1.94.8 Resolves: #2232471 --- .gitignore | 1 + libfprint.spec | 2 +- sources | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 55ad153..a4a0ef4 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.5.tar.gz /libfprint-v1.94.6.tar.gz /libfprint-v1.94.7.tar.gz +/libfprint-v1.94.8.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 53b5a92..56d8554 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.7 +Version: 1.94.8 Release: %autorelease Summary: Toolkit for fingerprint scanner diff --git a/sources b/sources index 4bf9301..f377002 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.7.tar.gz) = 5e7afc8424862d2caaba9d6c2dbd0a339639497ddb7b096f1073464ebdfd9acec1b84470297bd51761dae4770d4113e336096536bb5f8700da2673a2685856b6 +SHA512 (libfprint-v1.94.8.tar.gz) = 4d72764dff7e8aeb343c51fce90fcab11cf3aab20c0796e03ae5e1d89c7223af16234fa410bc20513bf56d7de60d71bfcf29ec624373be7294e66f306f99edbd From c1b082f522cf45da3a5600d259c9da31ec726e1a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 11:15:20 +0000 Subject: [PATCH 39/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 09c6ca8d0f1de2f594cbada99ee99d46e3231283 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Thu, 20 Mar 2025 14:59:34 +0800 Subject: [PATCH 40/53] Update to the upstream version 1.94.9 - Update to version 1.94.9 - Add openssl-devel dependency - Add a file /usr/share/metainfo/org.freedesktop.libfprint.metainfo.xml Resolves: #2232471 --- .gitignore | 1 + libfprint.spec | 4 +++- sources | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a4a0ef4..6205992 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.6.tar.gz /libfprint-v1.94.7.tar.gz /libfprint-v1.94.8.tar.gz +/libfprint-v1.94.9.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 56d8554..07a5807 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.8 +Version: 1.94.9 Release: %autorelease Summary: Toolkit for fingerprint scanner @@ -14,6 +14,7 @@ BuildRequires: meson BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: git +BuildRequires: openssl-devel BuildRequires: pkgconfig(glib-2.0) >= 2.50 BuildRequires: pkgconfig(gio-2.0) >= 2.44.0 BuildRequires: pkgconfig(gusb) >= 0.3.0 @@ -70,6 +71,7 @@ the functionality of the installed %{name} package. %{_libdir}/girepository-1.0/*.typelib %{_udevhwdbdir}/60-autosuspend-libfprint-2.hwdb %{_udevrulesdir}/70-libfprint-2.rules +%{_datadir}/metainfo/org.freedesktop.libfprint.metainfo.xml %files devel %doc HACKING.md diff --git a/sources b/sources index f377002..4920c59 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.8.tar.gz) = 4d72764dff7e8aeb343c51fce90fcab11cf3aab20c0796e03ae5e1d89c7223af16234fa410bc20513bf56d7de60d71bfcf29ec624373be7294e66f306f99edbd +SHA512 (libfprint-v1.94.9.tar.gz) = f8debcc1277e6112ed450c04a40cf6113afd7b38377b3fd259bedb1f553b29db758f3519491940bf9cd4ade0f8e70b68040d5bef4c8dbf5f7c2afc1802086397 From 35bbfe0e0d8c3d36e37af4132f4651ba85e978b7 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 19:39:59 +0000 Subject: [PATCH 41/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From 5e7d505a691630caaf9081d0c88f0bbd3d65abe4 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Wed, 6 Aug 2025 15:38:48 +0800 Subject: [PATCH 42/53] Migrate to tmt test Resolves: #2382943 --- .fmf/version | 1 + plans/integration.fmf | 5 +++++ tests/integration/main.fmf | 11 +++++++++++ tests/{ => integration}/run-umockdev.sh | 6 +++--- tests/tests.yml | 23 ----------------------- 5 files changed, 20 insertions(+), 26 deletions(-) create mode 100644 .fmf/version create mode 100644 plans/integration.fmf create mode 100644 tests/integration/main.fmf rename tests/{ => integration}/run-umockdev.sh (79%) delete mode 100644 tests/tests.yml diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/plans/integration.fmf b/plans/integration.fmf new file mode 100644 index 0000000..05fe63a --- /dev/null +++ b/plans/integration.fmf @@ -0,0 +1,5 @@ +summary: Test for libfprint +discover: + how: fmf +execute: + how: tmt diff --git a/tests/integration/main.fmf b/tests/integration/main.fmf new file mode 100644 index 0000000..df893f0 --- /dev/null +++ b/tests/integration/main.fmf @@ -0,0 +1,11 @@ +summary: Test for libfprint +require: + - cairo-devel + - libfprint-devel + - libfprint-tests + - umockdev-devel + - python3-cairo + - python3-gobject-base + - python3-pip + - python3-packaging +test: bash ./run-umockdev.sh diff --git a/tests/run-umockdev.sh b/tests/integration/run-umockdev.sh similarity index 79% rename from tests/run-umockdev.sh rename to tests/integration/run-umockdev.sh index d8c5362..1beeca1 100755 --- a/tests/run-umockdev.sh +++ b/tests/integration/run-umockdev.sh @@ -2,7 +2,7 @@ set -u # Switch into the tests directory -cd source/tests || exit 1 +cd /usr/share/installed-tests/libfprint-2 || exit 1 # check if we need to install additional packages # which is the case if we are on RHEL 8 @@ -14,7 +14,7 @@ if [[ "$ID" = *"rhel"* ]] && [[ "$VERSION_ID" == *"8"* ]]; then pip3 install python-dbusmock fi -# Each directory in source/tests is a umockdev based test +# Each directory in /usr/share/installed-tests/libfprint-2 is a umockdev based test # discover them declare -a TESTS=() for f in *; do @@ -27,7 +27,7 @@ export FP_DEVICE_EMULATION=1 RESULT=0 for test in ${TESTS[@]}; do echo "$test" - ./umockdev-test.py "$test" + /usr/libexec/installed-tests/libfprint-2/umockdev-test.py "$test" RES=$? echo "$test finished with return code $RES" echo "" diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index ab999c2..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -- hosts: localhost - roles: - - role: standard-test-source - tags: - - always - required_packages: - - git - - role: standard-test-basic - tags: - - atomic - - classic - required_packages: - - python3-dbusmock - - umockdev - tests: - - virtual_image: - dir: . - run: source/tests/virtual-image.py - - umockdev: - dir: . - run: run-umockdev.sh - From 0585fee3e159ad7a5ab789ad424e3fde639591ca Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Wed, 6 Aug 2025 15:42:28 +0800 Subject: [PATCH 43/53] Skip the %check section due to recent pygobject issues libfprint is trying to resolve the test issue. It was found when the test runs with pygobject3.52 and python3.14. So, the %check was temporarily skipped to ensure the build can be run. Resolves: #2385111 --- libfprint.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint.spec b/libfprint.spec index 07a5807..cae76f9 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -61,8 +61,8 @@ the functionality of the installed %{name} package. %ldconfig_scriptlets -%check -%meson_test -t 4 +# TODO: The test can't run with the recent pygobject3.52. +# So, skip the test until the issue of pygobject is fixed. %files %license COPYING From 65fc4cc2fbb662b0e1f03005b051d8dc3e998767 Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Mon, 15 Dec 2025 12:12:38 -0500 Subject: [PATCH 44/53] Drop ExcludeArch for IBM Z to allow building there for COSMIC --- libfprint.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index cae76f9..e4479c7 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -8,7 +8,6 @@ Summary: Toolkit for fingerprint scanner License: LicenseRef-Callaway-LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz -ExcludeArch: s390 s390x BuildRequires: meson BuildRequires: gcc From 0c29d397dae29f2010fb67ea30131aa8140b009b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 16 Jan 2026 18:49:48 +0000 Subject: [PATCH 45/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild From a833f30d98812b48941b8212c0a3dc3434c7fcff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Thu, 22 Jan 2026 14:05:35 +0100 Subject: [PATCH 46/53] migrate license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- libfprint.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libfprint.spec b/libfprint.spec index e4479c7..12b13db 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -5,7 +5,9 @@ Release: %autorelease Summary: Toolkit for fingerprint scanner # Automatically converted from old format: LGPLv2+ - review is highly recommended. -License: LicenseRef-Callaway-LGPLv2+ +# Most of the code is LGPL-2.1-or-later +# libfprint/nbis is NIST-PD +License: LGPL-2.1-or-later AND NIST-PD URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz From 6f0a10ed020971780ba13864ffda20c3180ac944 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Wed, 11 Feb 2026 10:44:11 +0800 Subject: [PATCH 47/53] Update to the upstream version 1.94.10 (rhbz#2437070) Update to 1.94.10 --- .gitignore | 1 + libfprint.spec | 2 +- sources | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6205992..dc47fc4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.7.tar.gz /libfprint-v1.94.8.tar.gz /libfprint-v1.94.9.tar.gz +/libfprint-v1.94.10.tar.gz diff --git a/libfprint.spec b/libfprint.spec index 12b13db..975ee8c 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.9 +Version: 1.94.10 Release: %autorelease Summary: Toolkit for fingerprint scanner diff --git a/sources b/sources index 4920c59..f3a33ff 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.9.tar.gz) = f8debcc1277e6112ed450c04a40cf6113afd7b38377b3fd259bedb1f553b29db758f3519491940bf9cd4ade0f8e70b68040d5bef4c8dbf5f7c2afc1802086397 +SHA512 (libfprint-v1.94.10.tar.gz) = 7a346cb83623e4447d67c5a932cb2d98b6e42e38eae134eb03a1c8f61b2a1e606b78967629bbddb1db174d730b318c942c3ae9cd452f30a6d273d915fc97ec43 From 4c0bc339fca356a860439265149ee81cbf153528 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Fri, 12 Jun 2026 18:56:19 -0400 Subject: [PATCH 48/53] Rebuilt for openssl 4.0 From a144073baee08ebfb990007ee3f46607b842ef48 Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Fri, 26 Jun 2026 00:26:19 -0400 Subject: [PATCH 49/53] Backport support for new Focal fingerprint reader --- 2c7842c905147a2d127c1b168b2e9d43.patch | 42 ++++++++++++++++++++++++++ libfprint.spec | 3 ++ 2 files changed, 45 insertions(+) create mode 100644 2c7842c905147a2d127c1b168b2e9d43.patch diff --git a/2c7842c905147a2d127c1b168b2e9d43.patch b/2c7842c905147a2d127c1b168b2e9d43.patch new file mode 100644 index 0000000..0f67995 --- /dev/null +++ b/2c7842c905147a2d127c1b168b2e9d43.patch @@ -0,0 +1,42 @@ +From 2c7842c905147a2d127c1b168b2e9d432b8c91a4 Mon Sep 17 00:00:00 2001 +From: Daniel Schaefer +Date: Thu, 12 Feb 2026 16:08:31 +0800 +Subject: [PATCH] focaltech_moc: add new pid:0x077A pid:0x079A + +Tested on working hardware with examples/enroll and examples/verify + +Signed-off-by: Daniel Schaefer +--- + data/autosuspend.hwdb | 2 ++ + libfprint/drivers/focaltech_moc/focaltech_moc.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb +index f49e17d6..9d1fd351 100644 +--- a/data/autosuspend.hwdb ++++ b/data/autosuspend.hwdb +@@ -185,6 +185,8 @@ usb:v2808pA99A* + usb:v2808pA57A* + usb:v2808pA78A* + usb:v2808p1579* ++usb:v2808p077A* ++usb:v2808p079A* + ID_AUTOSUSPEND=1 + ID_PERSIST=0 + +diff --git a/libfprint/drivers/focaltech_moc/focaltech_moc.c b/libfprint/drivers/focaltech_moc/focaltech_moc.c +index 2d410f88..8bd93e4b 100644 +--- a/libfprint/drivers/focaltech_moc/focaltech_moc.c ++++ b/libfprint/drivers/focaltech_moc/focaltech_moc.c +@@ -35,6 +35,8 @@ static const FpIdEntry id_table[] = { + { .vid = 0x2808, .pid = 0xa57a, }, + { .vid = 0x2808, .pid = 0xa78a, }, + { .vid = 0x2808, .pid = 0x1579, }, ++ { .vid = 0x2808, .pid = 0x077A, }, ++ { .vid = 0x2808, .pid = 0x079A, }, + { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ + }; + +-- +GitLab + diff --git a/libfprint.spec b/libfprint.spec index 975ee8c..fbffea7 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -11,6 +11,9 @@ License: LGPL-2.1-or-later AND NIST-PD URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz +# Backport from upstream +Patch00001: https://gitlab.freedesktop.org/libfprint/libfprint/-/commit/2c7842c905147a2d127c1b168b2e9d43.patch + BuildRequires: meson BuildRequires: gcc BuildRequires: gcc-c++ From f99efa9929b2fd0a4cd0d165d8d76d75c66e8501 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Tue, 23 Jun 2026 12:10:57 +0800 Subject: [PATCH 50/53] Add EGIS readers (rhbz#2480599) Add EGIS support. The MR can be found at https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/561 Signed-off-by: Kate Hsuan --- ...ry-buffer-I-O-section-for-the-byte-r.patch | 162 + ...ter-Add-APIs-to-write-and-get-GBytes.patch | 145 + ...Add-support-to-read-and-get-peek-GBy.patch | 187 + ...Add-support-to-read-to-a-static-buff.patch | 160 + ...-Add-missing-definition-of-set_short.patch | 42 + ...-transfer-Wrap-g_error_new-arguments.patch | 26 + egis_reader.patch | 3304 +++++++++++++++++ libfprint.spec | 11 + 8 files changed, 4037 insertions(+) create mode 100644 0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch create mode 100644 0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch create mode 100644 0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch create mode 100644 0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch create mode 100644 0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch create mode 100644 0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch create mode 100644 egis_reader.patch diff --git a/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch b/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch new file mode 100644 index 0000000..0df0565 --- /dev/null +++ b/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch @@ -0,0 +1,162 @@ +From 9c140036e9c4d173a19b8e3d6187526d68fbd97c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Sat, 21 Feb 2026 05:40:56 +0100 +Subject: [PATCH 1/6] doc: Include Binary buffer I/O section for the byte + reader/writer + +--- + doc/libfprint-2-sections.txt | 120 +++++++++++++++++++++++++++++++++++ + doc/libfprint-docs.xml | 6 ++ + 2 files changed, 126 insertions(+) + +diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt +index 0fb0cfa..9f3804f 100644 +--- a/doc/libfprint-2-sections.txt ++++ b/doc/libfprint-2-sections.txt +@@ -134,6 +134,126 @@ fpi_line_asmbl_ctx + fpi_assemble_lines + + ++
++fpi-byte-reader ++FpiByteReader ++FpiByteReader ++fpi_byte_reader_new ++fpi_byte_reader_free ++fpi_byte_reader_init ++fpi_byte_reader_peek_sub_reader ++fpi_byte_reader_get_sub_reader ++fpi_byte_reader_set_pos ++fpi_byte_reader_get_pos ++fpi_byte_reader_get_remaining ++fpi_byte_reader_get_size ++fpi_byte_reader_skip ++fpi_byte_reader_get_uint8 ++fpi_byte_reader_get_int8 ++fpi_byte_reader_peek_uint8 ++fpi_byte_reader_peek_int8 ++fpi_byte_reader_get_uint16_le ++fpi_byte_reader_get_int16_le ++fpi_byte_reader_peek_uint16_le ++fpi_byte_reader_peek_int16_le ++fpi_byte_reader_get_uint16_be ++fpi_byte_reader_get_int16_be ++fpi_byte_reader_peek_uint16_be ++fpi_byte_reader_peek_int16_be ++fpi_byte_reader_get_uint24_le ++fpi_byte_reader_get_int24_le ++fpi_byte_reader_peek_uint24_le ++fpi_byte_reader_peek_int24_le ++fpi_byte_reader_get_uint24_be ++fpi_byte_reader_get_int24_be ++fpi_byte_reader_peek_uint24_be ++fpi_byte_reader_peek_int24_be ++fpi_byte_reader_get_uint32_le ++fpi_byte_reader_get_int32_le ++fpi_byte_reader_peek_uint32_le ++fpi_byte_reader_peek_int32_le ++fpi_byte_reader_get_uint32_be ++fpi_byte_reader_get_int32_be ++fpi_byte_reader_peek_uint32_be ++fpi_byte_reader_peek_int32_be ++fpi_byte_reader_get_uint64_le ++fpi_byte_reader_get_int64_le ++fpi_byte_reader_peek_uint64_le ++fpi_byte_reader_peek_int64_le ++fpi_byte_reader_get_uint64_be ++fpi_byte_reader_get_int64_be ++fpi_byte_reader_peek_uint64_be ++fpi_byte_reader_peek_int64_be ++fpi_byte_reader_get_float32_le ++fpi_byte_reader_peek_float32_le ++fpi_byte_reader_get_float32_be ++fpi_byte_reader_peek_float32_be ++fpi_byte_reader_get_float64_le ++fpi_byte_reader_peek_float64_le ++fpi_byte_reader_get_float64_be ++fpi_byte_reader_peek_float64_be ++fpi_byte_reader_get_data ++fpi_byte_reader_peek_data ++fpi_byte_reader_dup_data ++fpi_byte_reader_masked_scan_uint32 ++fpi_byte_reader_masked_scan_uint32_peek ++fpi_byte_reader_skip_string ++fpi_byte_reader_skip_string_utf8 ++fpi_byte_reader_skip_string_utf16 ++fpi_byte_reader_skip_string_utf32 ++fpi_byte_reader_peek_string ++fpi_byte_reader_peek_string_utf8 ++fpi_byte_reader_get_string_utf8 ++fpi_byte_reader_dup_string_utf8 ++fpi_byte_reader_dup_string_utf16 ++fpi_byte_reader_dup_string_utf32 ++
++ ++
++fpi-byte-writer ++FpiByteWriter ++FpiByteWriter ++fpi_byte_writer_new ++fpi_byte_writer_new_with_size ++fpi_byte_writer_new_with_data ++fpi_byte_writer_init ++fpi_byte_writer_init_with_size ++fpi_byte_writer_init_with_data ++fpi_byte_writer_reset ++fpi_byte_writer_reset_and_get_data ++fpi_byte_writer_free ++fpi_byte_writer_free_and_get_data ++fpi_byte_writer_get_remaining ++fpi_byte_writer_ensure_free_space ++fpi_byte_writer_put_uint8 ++fpi_byte_writer_put_uint16_be ++fpi_byte_writer_put_uint24_be ++fpi_byte_writer_put_uint32_be ++fpi_byte_writer_put_uint64_be ++fpi_byte_writer_put_uint16_le ++fpi_byte_writer_put_uint24_le ++fpi_byte_writer_put_uint32_le ++fpi_byte_writer_put_uint64_le ++fpi_byte_writer_put_int8 ++fpi_byte_writer_put_int16_be ++fpi_byte_writer_put_int24_be ++fpi_byte_writer_put_int32_be ++fpi_byte_writer_put_int64_be ++fpi_byte_writer_put_int16_le ++fpi_byte_writer_put_int24_le ++fpi_byte_writer_put_int32_le ++fpi_byte_writer_put_int64_le ++fpi_byte_writer_put_float32_be ++fpi_byte_writer_put_float64_be ++fpi_byte_writer_put_float32_le ++fpi_byte_writer_put_float64_le ++fpi_byte_writer_put_string_utf8 ++fpi_byte_writer_put_string_utf16 ++fpi_byte_writer_put_string_utf32 ++fpi_byte_writer_put_data ++fpi_byte_writer_fill ++
++ +
+ fpi-context + fpi_get_driver_types +diff --git a/doc/libfprint-docs.xml b/doc/libfprint-docs.xml +index 0a57efb..09bb826 100644 +--- a/doc/libfprint-docs.xml ++++ b/doc/libfprint-docs.xml +@@ -48,6 +48,12 @@ + + + ++ ++ Binary buffer I/O ++ ++ ++ ++ + + Image manipulation + +-- +2.54.0 + diff --git a/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch b/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch new file mode 100644 index 0000000..f883cc9 --- /dev/null +++ b/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch @@ -0,0 +1,145 @@ +From 14763d29cf1e5ec9628fd639034675e9b22aff1e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 14:11:09 +0200 +Subject: [PATCH 2/6] fpi-byte-writer: Add APIs to write and get GBytes + +It makes it handier to handle data elements without having to keep size +and data separated +--- + doc/libfprint-2-sections.txt | 2 ++ + libfprint/fpi-byte-writer.c | 39 ++++++++++++++++++++++++++++++++++++ + libfprint/fpi-byte-writer.h | 22 ++++++++++++++++++++ + 3 files changed, 63 insertions(+) + +diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt +index 9f3804f..995ad50 100644 +--- a/doc/libfprint-2-sections.txt ++++ b/doc/libfprint-2-sections.txt +@@ -220,11 +220,13 @@ fpi_byte_writer_init + fpi_byte_writer_init_with_size + fpi_byte_writer_init_with_data + fpi_byte_writer_reset ++fpi_byte_writer_reset_and_get_bytes + fpi_byte_writer_reset_and_get_data + fpi_byte_writer_free + fpi_byte_writer_free_and_get_data + fpi_byte_writer_get_remaining + fpi_byte_writer_ensure_free_space ++fpi_byte_writer_put_bytes + fpi_byte_writer_put_uint8 + fpi_byte_writer_put_uint16_be + fpi_byte_writer_put_uint24_be +diff --git a/libfprint/fpi-byte-writer.c b/libfprint/fpi-byte-writer.c +index cb3514a..00ff447 100644 +--- a/libfprint/fpi-byte-writer.c ++++ b/libfprint/fpi-byte-writer.c +@@ -219,6 +219,36 @@ fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer) + return data; + } + ++/** ++ * fpi_byte_writer_reset_and_get_bytes: ++ * @writer: #FpiByteWriter instance ++ * ++ * Resets @writer and returns the current data as a #GBytes. ++ * ++ * Returns: (transfer full): the current data as a #GBytes. ++ */ ++GBytes * ++fpi_byte_writer_reset_and_get_bytes (FpiByteWriter * writer) ++{ ++ GBytes *bytes; ++ ++ g_return_val_if_fail (writer != NULL, NULL); ++ ++ if (!writer->owned) ++ { ++ bytes = g_bytes_new (g_steal_pointer (&writer->parent.data), ++ writer->parent.size); ++ } ++ else ++ { ++ bytes = g_bytes_new_take ((gpointer) g_steal_pointer (&writer->parent.data), ++ writer->parent.size); ++ } ++ ++ fpi_byte_writer_reset (writer); ++ return g_steal_pointer (&bytes); ++} ++ + /** + * fpi_byte_writer_free: + * @writer: (in) (transfer full): #FpiByteWriter instance +@@ -602,6 +632,15 @@ CREATE_WRITE_STRING_FUNC (32, guint32); + * + * Returns: %TRUE if the value could be written + */ ++/** ++ * fpi_byte_writer_put_bytes: ++ * @writer: #FpiByteWriter instance ++ * @bytes: (transfer none): Data to write ++ * ++ * Writes the contents of @bytes to @writer. ++ * ++ * Returns: %TRUE if the value could be written ++ */ + /** + * fpi_byte_writer_fill: + * @writer: #FpiByteWriter instance +diff --git a/libfprint/fpi-byte-writer.h b/libfprint/fpi-byte-writer.h +index 9b21b5f..699e85e 100644 +--- a/libfprint/fpi-byte-writer.h ++++ b/libfprint/fpi-byte-writer.h +@@ -77,6 +77,9 @@ void fpi_byte_writer_reset (FpiByteWriter *writer); + + guint8 * fpi_byte_writer_reset_and_get_data (FpiByteWriter *writer); + ++ ++GBytes * fpi_byte_writer_reset_and_get_bytes (FpiByteWriter *writer); ++ + /** + * fpi_byte_writer_get_pos: + * @writer: #FpiByteWriter instance +@@ -204,6 +207,9 @@ gboolean fpi_byte_writer_put_float64_le (FpiByteWriter *writer, gdoubl + gboolean fpi_byte_writer_put_data (FpiByteWriter *writer, const guint8 *data, guint size); + + ++gboolean fpi_byte_writer_put_bytes (FpiByteWriter *writer, const GBytes *bytes); ++ ++ + gboolean fpi_byte_writer_fill (FpiByteWriter *writer, guint8 value, guint size); + + +@@ -338,6 +344,18 @@ fpi_byte_writer_put_data_inline (FpiByteWriter * writer, const guint8 * data, + return TRUE; + } + ++static inline gboolean ++fpi_byte_writer_put_bytes_inline (FpiByteWriter * writer, const GBytes * bytes) ++{ ++ g_return_val_if_fail (writer != NULL, FALSE); ++ g_return_val_if_fail (bytes != NULL, FALSE); ++ const guint8 *data; ++ gsize size; ++ ++ data = g_bytes_get_data ((GBytes *) bytes, &size); ++ return fpi_byte_writer_put_data_inline (writer, data, size); ++} ++ + static inline void + fpi_byte_writer_fill_unchecked (FpiByteWriter * writer, guint8 value, guint size) + { +@@ -413,6 +431,10 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint size) + + #define fpi_byte_writer_put_data(writer, data, size) \ + G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, size)) ++#define fpi_byte_writer_put_data_static(writer, data) \ ++ G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, sizeof (data))) ++#define fpi_byte_writer_put_bytes(writer, bytes) \ ++ G_LIKELY (fpi_byte_writer_put_bytes_inline (writer, bytes)) + #define fpi_byte_writer_fill(writer, val, size) \ + G_LIKELY (fpi_byte_writer_fill_inline (writer, val, size)) + +-- +2.54.0 + diff --git a/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch b/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch new file mode 100644 index 0000000..3527bac --- /dev/null +++ b/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch @@ -0,0 +1,187 @@ +From dc48ab8b4018d1c1cc45cafaafbdac0e3d7726fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 14:15:28 +0200 +Subject: [PATCH 3/6] fpi-byte-reader: Add support to read and get/peek GBytes + +--- + doc/libfprint-2-sections.txt | 4 +++ + libfprint/fpi-byte-reader.c | 49 ++++++++++++++++++++++++++++++++++++ + libfprint/fpi-byte-reader.h | 43 +++++++++++++++++++++++++++++++ + 3 files changed, 96 insertions(+) + +diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt +index 995ad50..52ddb42 100644 +--- a/doc/libfprint-2-sections.txt ++++ b/doc/libfprint-2-sections.txt +@@ -139,8 +139,10 @@ fpi_assemble_lines + FpiByteReader + FpiByteReader + fpi_byte_reader_new ++fpi_byte_reader_new_bytes + fpi_byte_reader_free + fpi_byte_reader_init ++fpi_byte_reader_init_bytes + fpi_byte_reader_peek_sub_reader + fpi_byte_reader_get_sub_reader + fpi_byte_reader_set_pos +@@ -148,6 +150,8 @@ fpi_byte_reader_get_pos + fpi_byte_reader_get_remaining + fpi_byte_reader_get_size + fpi_byte_reader_skip ++fpi_byte_reader_get_bytes ++fpi_byte_reader_peek_bytes + fpi_byte_reader_get_uint8 + fpi_byte_reader_get_int8 + fpi_byte_reader_peek_uint8 +diff --git a/libfprint/fpi-byte-reader.c b/libfprint/fpi-byte-reader.c +index 23bc5e7..1591825 100644 +--- a/libfprint/fpi-byte-reader.c ++++ b/libfprint/fpi-byte-reader.c +@@ -65,6 +65,31 @@ fpi_byte_reader_new (const guint8 * data, guint size) + return ret; + } + ++/** ++ * fpi_byte_reader_new_bytes: (skip) ++ * @bytes: (in) (transfer none): a #GBytes instance from which the ++ * #FpiByteReader should read ++ * ++ * Create a new #FpiByteReader instance, which will read from @bytes. ++ * ++ * Free-function: fpi_byte_reader_free ++ * ++ * Returns: (transfer full): a new #FpiByteReader instance ++ */ ++FpiByteReader * ++fpi_byte_reader_new_bytes (GBytes * bytes) ++{ ++ const guint8 *data; ++ gsize size = 0; ++ ++ g_return_val_if_fail (bytes != NULL, NULL); ++ ++ data = g_bytes_get_data (bytes, &size); ++ g_return_val_if_fail (size <= G_MAXUINT, NULL); ++ ++ return fpi_byte_reader_new (data, (guint) size); ++} ++ + /** + * fpi_byte_reader_free: + * @reader: (in) (transfer full): a #FpiByteReader instance +@@ -100,6 +125,30 @@ fpi_byte_reader_init (FpiByteReader * reader, const guint8 * data, guint size) + reader->byte = 0; + } + ++/** ++ * fpi_byte_reader_init_bytes: ++ * @reader: a #FpiByteReader instance ++ * @bytes: (in) (transfer none): a #GBytes instance from which ++ * the #FpiByteReader should read ++ * ++ * Initializes a #FpiByteReader instance to read from @bytes. This function ++ * can be called on already initialized instances. ++ */ ++FpiByteReader * ++fpi_byte_reader_init_bytes (FpiByteReader * reader, GBytes * bytes) ++{ ++ g_return_val_if_fail (reader != NULL, NULL); ++ g_return_val_if_fail (bytes != NULL, NULL); ++ ++ gsize size = 0; ++ const guint8 *data = g_bytes_get_data (bytes, &size); ++ ++ g_return_val_if_fail (size <= G_MAXUINT, NULL); ++ fpi_byte_reader_init (reader, data, (guint) size); ++ ++ return reader; ++} ++ + /** + * fpi_byte_reader_peek_sub_reader: (skip) + * @reader: an existing and initialized #FpiByteReader instance +diff --git a/libfprint/fpi-byte-reader.h b/libfprint/fpi-byte-reader.h +index c4e64d2..05a3989 100644 +--- a/libfprint/fpi-byte-reader.h ++++ b/libfprint/fpi-byte-reader.h +@@ -50,6 +50,7 @@ typedef struct { + + FpiByteReader * fpi_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC; + ++FpiByteReader * fpi_byte_reader_new_bytes (GBytes *bytes) G_GNUC_MALLOC; + + void fpi_byte_reader_free (FpiByteReader *reader); + +@@ -57,6 +58,9 @@ void fpi_byte_reader_free (FpiByteReader *reader); + void fpi_byte_reader_init (FpiByteReader *reader, const guint8 *data, guint size); + + ++FpiByteReader * fpi_byte_reader_init_bytes (FpiByteReader *reader, GBytes *bytes); ++ ++ + gboolean fpi_byte_reader_peek_sub_reader (FpiByteReader * reader, + FpiByteReader * sub_reader, + guint size); +@@ -220,6 +224,13 @@ gboolean fpi_byte_reader_get_data (FpiByteReader * reader, guint s + + gboolean fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, const guint8 ** val); + ++ ++GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size); ++ ++ ++GBytes * fpi_byte_reader_peek_bytes (const FpiByteReader *reader, guint size); ++ ++ + #define fpi_byte_reader_dup_string(reader,str) \ + fpi_byte_reader_dup_string_utf8(reader,str) + +@@ -642,6 +653,34 @@ fpi_byte_reader_peek_data_inline (const FpiByteReader * reader, guint size, cons + return TRUE; + } + ++static inline GBytes * ++fpi_byte_reader_peek_bytes_inline (const FpiByteReader *reader, guint size) ++{ ++ const guint8 *data; ++ ++ g_return_val_if_fail (reader != NULL, NULL); ++ ++ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) ++ return NULL; ++ ++ data = fpi_byte_reader_peek_data_unchecked (reader); ++ return g_bytes_new_static (data, size); ++} ++ ++static inline GBytes * ++fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size) ++{ ++ const guint8 *data; ++ ++ g_return_val_if_fail (reader != NULL, NULL); ++ ++ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) ++ return NULL; ++ ++ data = fpi_byte_reader_get_data_unchecked (reader, size); ++ return g_bytes_new_static (data, size); ++} ++ + static inline guint + fpi_byte_reader_get_pos_inline (const FpiByteReader * reader) + { +@@ -672,6 +711,10 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes) + G_LIKELY(fpi_byte_reader_peek_data_inline(reader,size,val)) + #define fpi_byte_reader_skip(reader,nbytes) \ + G_LIKELY(fpi_byte_reader_skip_inline(reader,nbytes)) ++#define fpi_byte_reader_get_bytes(reader,size) \ ++ fpi_byte_reader_get_bytes_inline(reader,size) ++#define fpi_byte_reader_peek_bytes(reader,size) \ ++ fpi_byte_reader_peek_bytes_inline(reader,size) + + #endif /* FPI_BYTE_READER_DISABLE_INLINES */ + +-- +2.54.0 + diff --git a/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch b/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch new file mode 100644 index 0000000..7fe3c22 --- /dev/null +++ b/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch @@ -0,0 +1,160 @@ +From f6a8cae5b4f1555769706f7e5b222145fd3be8ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 14:16:36 +0200 +Subject: [PATCH 4/6] fpi-byte-reader: Add support to read to a static buffer + +This works through macros when the size of a buffer is statically +defined +--- + doc/libfprint-2-sections.txt | 2 ++ + libfprint/fpi-byte-reader.c | 35 ++++++++++++++++++++++ + libfprint/fpi-byte-reader.h | 57 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 94 insertions(+) + +diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt +index 52ddb42..391f1f4 100644 +--- a/doc/libfprint-2-sections.txt ++++ b/doc/libfprint-2-sections.txt +@@ -198,6 +198,8 @@ fpi_byte_reader_get_float64_be + fpi_byte_reader_peek_float64_be + fpi_byte_reader_get_data + fpi_byte_reader_peek_data ++fpi_byte_reader_get_data_static ++fpi_byte_reader_peek_data_static + fpi_byte_reader_dup_data + fpi_byte_reader_masked_scan_uint32 + fpi_byte_reader_masked_scan_uint32_peek +diff --git a/libfprint/fpi-byte-reader.c b/libfprint/fpi-byte-reader.c +index 1591825..9709a41 100644 +--- a/libfprint/fpi-byte-reader.c ++++ b/libfprint/fpi-byte-reader.c +@@ -848,6 +848,41 @@ fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, + return fpi_byte_reader_peek_data_inline (reader, size, val); + } + ++/** ++ * fpi_byte_reader_get_data_fixed: ++ * @reader: a #FpiByteReader instance ++ * @size: Size in bytes ++ * @val: (out) (array length=size): address of a buffer to copy data into ++ * ++ * Copies @size bytes from the current data position into @val if at ++ * least @size bytes are left, and updates the current position. ++ * ++ * Returns: %TRUE if successful, %FALSE otherwise. ++ */ ++gboolean ++(fpi_byte_reader_get_data_static) (FpiByteReader * reader, guint size, ++ const guint8 * val) ++{ ++ return (fpi_byte_reader_get_data_inline_static) (reader, size, val); ++} ++ ++/** ++ * fpi_byte_reader_peek_data_fixed: ++ * @reader: a #FpiByteReader instance ++ * @size: Size in bytes ++ * @val: (out) (array length=size): address of a buffer to copy data into ++ * ++ * Like fpi_byte_reader_get_data_fixed() but does not advance the position. ++ * ++ * Returns: %TRUE if successful, %FALSE otherwise. ++ */ ++gboolean ++(fpi_byte_reader_peek_data_static) (const FpiByteReader * reader, guint size, ++ guint8 * val) ++{ ++ return (fpi_byte_reader_peek_data_inline_static) (reader, size, val); ++} ++ + /** + * fpi_byte_reader_dup_data: + * @reader: a #FpiByteReader instance +diff --git a/libfprint/fpi-byte-reader.h b/libfprint/fpi-byte-reader.h +index 05a3989..278959f 100644 +--- a/libfprint/fpi-byte-reader.h ++++ b/libfprint/fpi-byte-reader.h +@@ -222,9 +222,15 @@ gboolean fpi_byte_reader_dup_data (FpiByteReader * reader, guint s + gboolean fpi_byte_reader_get_data (FpiByteReader * reader, guint size, const guint8 ** val); + + ++gboolean fpi_byte_reader_get_data_static (FpiByteReader * reader, guint size, const guint8 * val); ++ ++ + gboolean fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, const guint8 ** val); + + ++gboolean fpi_byte_reader_peek_data_static (const FpiByteReader * reader, guint size, guint8 * val); ++ ++ + GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size); + + +@@ -681,6 +687,32 @@ fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size) + return g_bytes_new_static (data, size); + } + ++static inline gboolean ++(fpi_byte_reader_get_data_inline_static) (FpiByteReader * reader, guint size, const guint8 * val) ++{ ++ g_return_val_if_fail (reader != NULL, FALSE); ++ g_return_val_if_fail (val != NULL, FALSE); ++ ++ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) ++ return FALSE; ++ ++ memcpy ((void *) val, fpi_byte_reader_get_data_unchecked (reader, size), size); ++ return TRUE; ++} ++ ++static inline gboolean ++(fpi_byte_reader_peek_data_inline_static) (const FpiByteReader * reader, guint size, guint8 * val) ++{ ++ g_return_val_if_fail (reader != NULL, FALSE); ++ g_return_val_if_fail (val != NULL, FALSE); ++ ++ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) ++ return FALSE; ++ ++ memcpy (val, fpi_byte_reader_peek_data_unchecked (reader), size); ++ return TRUE; ++} ++ + static inline guint + fpi_byte_reader_get_pos_inline (const FpiByteReader * reader) + { +@@ -716,6 +748,31 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes) + #define fpi_byte_reader_peek_bytes(reader,size) \ + fpi_byte_reader_peek_bytes_inline(reader,size) + ++/** ++ * fpi_byte_reader_get_data_static: ++ * @reader: a #FpiByteReader ++ * @val: fixed-size array (e.g. `uint8_t buf[32]`) ++ * ++ * Reads @size bytes from @reader directly into @val, where @size is ++ * deduced via `sizeof()` - only safe with true C arrays. ++ * ++ * Returns: %TRUE on success, %FALSE otherwise. ++ */ ++#define fpi_byte_reader_get_data_static(reader,val) \ ++ (fpi_byte_reader_get_data_static) (reader,sizeof(val),val) ++ ++/** ++ * fpi_byte_reader_peek_data_static: ++ * @reader: a #FpiByteReader ++ * @val: fixed-size array (e.g. `uint8_t buf[32]`) ++ * ++ * Like fpi_byte_reader_get_data_static() but does not advance the position. ++ * ++ * Returns: %TRUE on success, %FALSE otherwise. ++ */ ++#define fpi_byte_reader_peek_data_static(reader,val) \ ++ (fpi_byte_reader_peek_data_static) (reader,sizeof(val),val) ++ + #endif /* FPI_BYTE_READER_DISABLE_INLINES */ + + G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteReader, fpi_byte_reader_free); +-- +2.54.0 + diff --git a/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch b/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch new file mode 100644 index 0000000..d967dce --- /dev/null +++ b/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch @@ -0,0 +1,42 @@ +From e7c80e748ed3b00c432f3c00f2ec7b7262527db3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:27:36 +0200 +Subject: [PATCH 5/6] fpi-usb-transfer: Add missing definition of + set_short_error() + +It was in the header but not implemented +--- + libfprint/fpi-usb-transfer.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/libfprint/fpi-usb-transfer.c b/libfprint/fpi-usb-transfer.c +index ac4f60c..067ae18 100644 +--- a/libfprint/fpi-usb-transfer.c ++++ b/libfprint/fpi-usb-transfer.c +@@ -548,3 +548,23 @@ fpi_usb_transfer_submit_sync (FpiUsbTransfer *transfer, + + return res; + } ++ ++/** ++ * fpi_usb_transfer_set_short_error: ++ * @transfer: The transfer to submit, must have been filled. ++ * @short_is_error: Whether a short transfer should be considered an error ++ * ++ * Sets whether a short transfer (a transfer in which the transferred length ++ * does not match the expected length) should be considered an error ++ * ++ * By default, short transfers are not considered an error, but ++ * drivers can enforce a further check by setting this flag. ++ */ ++void ++fpi_usb_transfer_set_short_error (FpiUsbTransfer *transfer, ++ gboolean short_is_error) ++{ ++ g_return_if_fail (transfer); ++ ++ transfer->short_is_error = short_is_error; ++} +-- +2.54.0 + diff --git a/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch b/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch new file mode 100644 index 0000000..0671682 --- /dev/null +++ b/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch @@ -0,0 +1,26 @@ +From 9d4e7fc87b76819c049fc23f92b3dccdaf365e75 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 14:36:10 +0200 +Subject: [PATCH 6/6] fpi-usb-transfer: Wrap g_error_new arguments + +--- + libfprint/fpi-usb-transfer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libfprint/fpi-usb-transfer.c b/libfprint/fpi-usb-transfer.c +index 067ae18..448c566 100644 +--- a/libfprint/fpi-usb-transfer.c ++++ b/libfprint/fpi-usb-transfer.c +@@ -344,7 +344,8 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat + { + error = g_error_new (G_USB_DEVICE_ERROR, + G_USB_DEVICE_ERROR_IO, +- "Unexpected short error of %zd size (expected %zd)", transfer->actual_length, transfer->length); ++ "Unexpected short error of %zd size (expected %zd)", ++ transfer->actual_length, transfer->length); + } + + callback = transfer->callback; +-- +2.54.0 + diff --git a/egis_reader.patch b/egis_reader.patch new file mode 100644 index 0000000..57e83e5 --- /dev/null +++ b/egis_reader.patch @@ -0,0 +1,3304 @@ +From 9bddd90f06f4d9997389740b480e71d32bbc859f Mon Sep 17 00:00:00 2001 +From: Jason Huang +Date: Wed, 28 Jan 2026 21:06:48 +0800 +Subject: [PATCH 01/13] egis_etu905: Add 1c7a:05ae and 1c7a:9201 fingerprint + readers + +--- + data/autosuspend.hwdb | 6 + + libfprint/drivers/egismoc/egis_etu905.c | 1635 +++++++++++++++++++++++ + libfprint/drivers/egismoc/egis_etu905.h | 214 +++ + libfprint/meson.build | 2 + + meson.build | 2 + + tests/egis_etu905/custom.pcapng | Bin 0 -> 33644 bytes + tests/egis_etu905/custom.py | 109 ++ + tests/egis_etu905/device | 348 +++++ + tests/meson.build | 1 + + 9 files changed, 2317 insertions(+) + create mode 100644 libfprint/drivers/egismoc/egis_etu905.c + create mode 100644 libfprint/drivers/egismoc/egis_etu905.h + create mode 100644 tests/egis_etu905/custom.pcapng + create mode 100644 tests/egis_etu905/custom.py + create mode 100644 tests/egis_etu905/device + +diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb +index 55b5cb4c..a3ff00af 100644 +--- a/data/autosuspend.hwdb ++++ b/data/autosuspend.hwdb +@@ -77,6 +77,12 @@ usb:v1C7Ap0571* + ID_AUTOSUSPEND=1 + ID_PERSIST=0 + ++# Supported by libfprint driver egis_etu905 ++usb:v1C7Ap05AE* ++usb:v1C7Ap9201* ++ ID_AUTOSUSPEND=1 ++ ID_PERSIST=0 ++ + # Supported by libfprint driver egismoc + usb:v1C7Ap0582* + usb:v1C7Ap0583* +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +new file mode 100644 +index 00000000..be0c6e05 +--- /dev/null ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -0,0 +1,1635 @@ ++/* ++ * Driver for Egis Technology (LighTuning) Match-On-Chip sensors ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#define FP_COMPONENT "egis_etu905" ++ ++#include ++#include ++#include ++ ++#include "drivers_api.h" ++#include "fpi-byte-writer.h" ++ ++#include "egis_etu905.h" ++ ++struct _FpiDeviceEgisEtu905 ++{ ++ FpDevice parent; ++ FpiSsm *task_ssm; ++ FpiSsm *cmd_ssm; ++ FpiUsbTransfer *cmd_transfer; ++ GCancellable *interrupt_cancellable; ++ GPtrArray *enrolled_ids; ++ gint max_enroll_stages; ++ guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; ++}; ++ ++G_DEFINE_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FP_TYPE_DEVICE); ++ ++static const FpIdEntry egis_etu905_id_table[] = { ++ { .vid = 0x1c7a, .pid = 0x05ae, .driver_data = EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 }, ++ { .vid = 0x1c7a, .pid = 0x9201, .driver_data = EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 }, ++ { .vid = 0, .pid = 0, .driver_data = 0 } ++}; ++ ++typedef void (*SynCmdMsgCallback) (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error); ++ ++typedef struct egis_etu905_command_data ++{ ++ SynCmdMsgCallback callback; ++ guchar *buffer_in; ++ gsize length_in; ++} CommandData; ++ ++static void ++egis_etu905_command_data_free (CommandData *data) ++{ ++ g_free (data->buffer_in); ++ g_free (data); ++} ++ ++typedef struct egis_etu905_enroll_print ++{ ++ FpPrint *print; ++ int stage; ++} EnrollPrint; ++ ++static void ++egis_etu905_finger_on_sensor_cb (FpiUsbTransfer *transfer, ++ FpDevice *device, ++ gpointer userdata, ++ GError *error) ++{ ++ fp_dbg ("Finger on sensor callback"); ++ fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT); ++ ++ fpi_ssm_usb_transfer_cb (transfer, device, userdata, error); ++} ++ ++static void ++egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ fp_dbg ("Wait for finger on sensor"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); ++ ++ fpi_usb_transfer_fill_interrupt (transfer, EGIS_ETU905_EP_CMD_INTERRUPT_IN, ++ EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH); ++ transfer->ssm = ssm; ++ /* Interrupt on this device always returns 1 byte short; this is expected */ ++ transfer->short_is_error = FALSE; ++ ++ fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED); ++ ++ fpi_usb_transfer_submit (g_steal_pointer (&transfer), ++ EGIS_ETU905_USB_INTERRUPT_TIMEOUT, ++ self->interrupt_cancellable, ++ egis_etu905_finger_on_sensor_cb, ++ NULL); ++} ++ ++static gboolean ++egis_etu905_validate_response_prefix (const guchar *buffer_in, ++ const gsize buffer_in_len, ++ const guchar *valid_prefix, ++ const gsize valid_prefix_len) ++{ ++ const gboolean result = memcmp (buffer_in + ++ (egis_etu905_read_prefix_len + ++ EGIS_ETU905_CHECK_BYTES_LENGTH), ++ valid_prefix, ++ valid_prefix_len) == 0; ++ ++ fp_dbg ("Response prefix valid: %s", result ? "yes" : "NO"); ++ return result; ++} ++ ++static gboolean ++egis_etu905_validate_response_suffix (const guchar *buffer_in, ++ const gsize buffer_in_len, ++ const guchar *valid_suffix, ++ const gsize valid_suffix_len) ++{ ++ const gboolean result = memcmp (buffer_in + (buffer_in_len - valid_suffix_len), ++ valid_suffix, ++ valid_suffix_len) == 0; ++ ++ fp_dbg ("Response suffix valid: %s", result ? "yes" : "NO"); ++ return result; ++} ++ ++static void ++egis_etu905_task_ssm_done (FpiSsm *ssm, ++ FpDevice *device, ++ GError *error) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ fp_dbg ("Task SSM done"); ++ ++ /* task_ssm is going to be freed by completion of SSM */ ++ g_assert (!self->task_ssm || self->task_ssm == ssm); ++ self->task_ssm = NULL; ++ ++ g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref); ++ ++ if (error) ++ fpi_device_action_error (device, error); ++} ++ ++static void ++egis_etu905_commit_start_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Task SSM commit start callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (error) ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ else ++ fpi_ssm_jump_to_state (self->task_ssm, ENROLL_COMMIT); ++} ++ ++/* ++ * Generic callback for commands that don't need special handling on success. ++ * Advances the task SSM to the next state on success, or marks it failed on error. ++ */ ++static void ++egis_etu905_task_ssm_next_state_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ fp_dbg ("Task SSM next state callback"); ++ ++ if (error) ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ else ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++static void ++egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, ++ FpDevice *device, ++ gpointer userdata, ++ GError *error) ++{ ++ CommandData *data = userdata; ++ ++ fp_dbg ("Command receive callback"); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (transfer->ssm, error); ++ return; ++ } ++ if (data == NULL || transfer->actual_length < egis_etu905_read_prefix_len) ++ { ++ fpi_ssm_mark_failed (transfer->ssm, ++ fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); ++ return; ++ } ++ ++ /* Store the response data and let the cmd_ssm_done callback invoke ++ * the actual callback with the stored data */ ++ data->buffer_in = g_steal_pointer (&transfer->buffer); ++ data->length_in = transfer->actual_length; ++ ++ fpi_ssm_mark_completed (transfer->ssm); ++} ++ ++static void ++egis_etu905_cmd_run_state (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ g_autoptr(FpiUsbTransfer) transfer = NULL; ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case CMD_SEND: ++ if (self->cmd_transfer) ++ { ++ self->cmd_transfer->ssm = ssm; ++ fpi_usb_transfer_submit (g_steal_pointer (&self->cmd_transfer), ++ EGIS_ETU905_USB_SEND_TIMEOUT, ++ fpi_device_get_cancellable (device), ++ fpi_ssm_usb_transfer_cb, ++ NULL); ++ break; ++ } ++ ++ fpi_ssm_next_state (ssm); ++ break; ++ ++ case CMD_GET: ++ transfer = fpi_usb_transfer_new (device); ++ transfer->ssm = ssm; ++ fpi_usb_transfer_fill_bulk (transfer, EGIS_ETU905_EP_CMD_IN, ++ EGIS_ETU905_USB_IN_RECV_LENGTH); ++ fpi_usb_transfer_submit (g_steal_pointer (&transfer), ++ EGIS_ETU905_USB_RECV_TIMEOUT, ++ fpi_device_get_cancellable (device), ++ egis_etu905_cmd_receive_cb, ++ fpi_ssm_get_data (ssm)); ++ break; ++ } ++} ++ ++/* ++ * Command SSM done callback. ++ * Always invokes the callback with stored data on success or error. ++ */ ++static void ++egis_etu905_cmd_ssm_done (FpiSsm *ssm, ++ FpDevice *device, ++ GError *error) ++{ ++ g_autoptr(GError) local_error = error; ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ CommandData *data = fpi_ssm_get_data (ssm); ++ ++ g_assert (self->cmd_ssm == ssm); ++ g_assert (!self->cmd_transfer || self->cmd_transfer->ssm == ssm); ++ ++ self->cmd_ssm = NULL; ++ self->cmd_transfer = NULL; ++ ++ if (data && data->callback) ++ { ++ data->callback (device, ++ g_steal_pointer (&data->buffer_in), ++ data->length_in, ++ g_steal_pointer (&local_error)); ++ } ++} ++ ++/* ++ * 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 guint16 ++egis_etu905_get_check_bytes (FpiByteReader *reader) ++{ ++ fp_dbg ("Get check bytes"); ++ size_t sum_values = 0; ++ guint16 val; ++ ++ fpi_byte_reader_set_pos (reader, 0); ++ ++ while (fpi_byte_reader_get_uint16_be (reader, &val)) ++ sum_values += val; ++ ++ return G_MAXUINT16 - (sum_values % G_MAXUINT16); ++} ++ ++static void ++egis_etu905_exec_cmd (FpDevice *device, ++ guchar *cmd, ++ const gsize cmd_length, ++ GDestroyNotify cmd_destroy, ++ SynCmdMsgCallback callback) ++{ ++ g_auto(FpiByteWriter) writer = {0}; ++ g_autoptr(FpiUsbTransfer) transfer = NULL; ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ g_autofree CommandData *data = NULL; ++ gsize buffer_out_length = 0; ++ gboolean written = TRUE; ++ guint16 check_value; ++ ++ fp_dbg ("Execute command and get response"); ++ ++ /* ++ * buffer_out should be a fully composed command (with prefix, check bytes, etc) ++ * which looks like this: ++ * E G I S 00 00 00 01 {cb1} {cb2} {payload} ++ * where cb1 and cb2 are some check bytes generated by the ++ * egis_etu905_get_check_bytes() method and payload is what is passed via the cmd ++ * parameter ++ */ ++ buffer_out_length = egis_etu905_write_prefix_len ++ + EGIS_ETU905_CHECK_BYTES_LENGTH ++ + cmd_length; ++ ++ fpi_byte_writer_init_with_size (&writer, buffer_out_length + ++ (buffer_out_length % 2 ? 1 : 0), TRUE); ++ ++ /* Prefix */ ++ written &= fpi_byte_writer_put_data (&writer, egis_etu905_write_prefix, ++ egis_etu905_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, EGIS_ETU905_CHECK_BYTES_LENGTH); ++ ++ /* Command Payload */ ++ 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 = egis_etu905_get_check_bytes (FPI_BYTE_READER (&writer)); ++ fpi_byte_writer_set_pos (&writer, egis_etu905_write_prefix_len); ++ written &= fpi_byte_writer_put_uint16_be (&writer, check_value); ++ ++ /* destroy cmd if requested */ ++ if (cmd_destroy) ++ g_clear_pointer (&cmd, cmd_destroy); ++ ++ g_assert (self->cmd_ssm == NULL); ++ self->cmd_ssm = fpi_ssm_new (device, ++ egis_etu905_cmd_run_state, ++ CMD_STATES); ++ ++ data = g_new0 (CommandData, 1); ++ data->callback = callback; ++ fpi_ssm_set_data (self->cmd_ssm, g_steal_pointer (&data), ++ (GDestroyNotify) egis_etu905_command_data_free); ++ ++ if (!written) ++ { ++ fpi_ssm_start (self->cmd_ssm, egis_etu905_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, ++ EGIS_ETU905_EP_CMD_OUT, ++ fpi_byte_writer_reset_and_get_data (&writer), ++ buffer_out_length, ++ g_free); ++ ++ g_assert (self->cmd_transfer == NULL); ++ self->cmd_transfer = g_steal_pointer (&transfer); ++ fpi_ssm_start (self->cmd_ssm, egis_etu905_cmd_ssm_done); ++} ++ ++static void ++egis_etu905_set_print_data (FpPrint *print, ++ const gchar *device_print_id, ++ const gchar *user_id) ++{ ++ GVariant *print_id_var = NULL; ++ GVariant *fpi_data = NULL; ++ g_autofree gchar *fill_user_id = NULL; ++ ++ if (user_id) ++ fill_user_id = g_strdup (user_id); ++ else ++ fill_user_id = g_strndup (device_print_id, EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ ++ fpi_print_fill_from_user_id (print, fill_user_id); ++ ++ fpi_print_set_type (print, FPI_PRINT_RAW); ++ fpi_print_set_device_stored (print, TRUE); ++ ++ g_object_set (print, "description", fill_user_id, NULL); ++ ++ print_id_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ++ device_print_id, ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE, ++ sizeof (guchar)); ++ fpi_data = g_variant_new ("(@ay)", print_id_var); ++ g_object_set (print, "fpi-data", fpi_data, NULL); ++} ++ ++static GPtrArray * ++egis_etu905_get_enrolled_prints (FpDevice *device) ++{ ++ g_autoptr(GPtrArray) result = g_ptr_array_new_with_free_func (g_object_unref); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (!self->enrolled_ids) ++ return g_steal_pointer (&result); ++ ++ for (guint i = 0; i < self->enrolled_ids->len; i++) ++ { ++ FpPrint *print = fp_print_new (device); ++ egis_etu905_set_print_data (print, g_ptr_array_index (self->enrolled_ids, i), NULL); ++ g_ptr_array_add (result, g_object_ref_sink (print)); ++ } ++ ++ return g_steal_pointer (&result); ++} ++ ++static void ++egis_etu905_list_fill_enrolled_ids_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ fp_dbg ("List callback"); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref); ++ self->enrolled_ids = g_ptr_array_new_with_free_func (g_free); ++ ++ FpiByteReader reader; ++ gboolean read = TRUE; ++ ++ fpi_byte_reader_init (&reader, buffer_in, length_in); ++ ++ read &= fpi_byte_reader_set_pos (&reader, EGIS_ETU905_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 ++ */ ++ while (read) ++ { ++ const guint8 *data; ++ g_autofree gchar *print_id = NULL; ++ ++ read &= fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, ++ &data); ++ if (!read) ++ break; ++ ++ print_id = g_memdup2 (data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ 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_ids->len); ++ ++ if (self->task_ssm) ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++static void ++egis_etu905_list_run_state (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ g_autoptr(GPtrArray) enrolled_prints = NULL; ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case LIST_GET_ENROLLED_IDS: ++ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, NULL, ++ egis_etu905_list_fill_enrolled_ids_cb); ++ break; ++ ++ case LIST_RETURN_ENROLLED_PRINTS: ++ enrolled_prints = egis_etu905_get_enrolled_prints (device); ++ fpi_device_list_complete (device, g_steal_pointer (&enrolled_prints), NULL); ++ fpi_ssm_next_state (ssm); ++ break; ++ } ++} ++ ++static void ++egis_etu905_list (FpDevice *device) ++{ ++ fp_dbg ("List"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, ++ egis_etu905_list_run_state, ++ LIST_STATES); ++ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); ++} ++ ++static guchar * ++egis_etu905_get_delete_cmd (FpDevice *device, ++ FpPrint *delete_print, ++ gsize *length_out) ++{ ++ fp_dbg ("Get delete command"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (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; ++ gsize print_data_id_len = 0; ++ g_autofree gchar *print_description = NULL; ++ g_autofree guchar *enrolled_print_id = NULL; ++ g_autofree guchar *result = NULL; ++ gboolean written = TRUE; ++ ++ /* ++ * The final command body should contain: ++ * 1) hard-coded 00 00 ++ * 2) 2-byte size indiciator, 20*Number deleted identifiers plus 7 in form of: ++ * num_to_delete * 0x20 + 0x07 ++ * Since max prints can be higher than 7 then this goes up to 2 bytes ++ * (e9 + 9 = 109) ++ * 3) Hard-coded prefix (cmd_delete_prefix) ++ * 4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 7 ++ * (num_to_delete * 0x20) ++ * 5) All of the currently registered prints to delete in their 32-byte device ++ * identifiers (enrolled_list) ++ */ ++ ++ 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) * EGIS_ETU905_FINGERPRINT_DATA_SIZE * ++ num_to_delete; ++ /* total_length is the 6 various bytes plus prefix and body payload */ ++ const gsize total_length = (sizeof (guchar) * 6) + cmd_delete_prefix_len + ++ body_length; ++ ++ /* pre-fill entire payload with 00s */ ++ fpi_byte_writer_init_with_size (&writer, total_length, TRUE); ++ ++ /* start with 00 00 (just move starting offset up by 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 (num_to_delete > 7) ++ { ++ 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 */ ++ written &= fpi_byte_writer_change_pos (&writer, 1); ++ written &= fpi_byte_writer_put_uint8 (&writer, (num_to_delete * 0x20) + 0x07); ++ } ++ ++ /* command prefix */ ++ 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) ++ { ++ 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 */ ++ 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 */ ++ /* if passed a delete_print then fetch its data from the FpPrint */ ++ if (delete_print) ++ { ++ g_object_get (delete_print, "description", &print_description, NULL); ++ g_object_get (delete_print, "fpi-data", &print_data, NULL); ++ ++ if (!g_variant_check_format_string (print_data, "(@ay)", FALSE)) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); ++ return NULL; ++ } ++ ++ g_variant_get (print_data, "(@ay)", &print_data_id_var); ++ print_data_id = g_variant_get_fixed_array (print_data_id_var, ++ &print_data_id_len, sizeof (guchar)); ++ ++ if (!g_str_has_prefix (print_description, "FP")) ++ fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.", ++ print_description); ++ ++ fp_info ("Delete fingerprint %s", print_description); ++ ++ written &= fpi_byte_writer_put_data (&writer, print_data_id, ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ } ++ /* Otherwise assume this is a "clear" - just loop through and append all enrolled IDs */ ++ else if (self->enrolled_ids) ++ { ++ 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), ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ } ++ } ++ ++ g_assert (written); ++ ++ if (length_out) ++ *length_out = total_length; ++ ++ return fpi_byte_writer_reset_and_get_data (&writer); ++} ++ ++static void ++egis_etu905_delete_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Delete callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload indicates "success" with the delete */ ++ if (egis_etu905_validate_response_prefix (buffer_in, ++ length_in, ++ rsp_delete_success_prefix, ++ rsp_delete_success_prefix_len)) ++ { ++ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_CLEAR_STORAGE) ++ { ++ fpi_device_clear_storage_complete (device, NULL); ++ fpi_ssm_next_state (self->task_ssm); ++ } ++ else if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE) ++ { ++ fpi_device_delete_complete (device, NULL); ++ fpi_ssm_next_state (self->task_ssm); ++ } ++ else ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Unsupported delete action.")); ++ } ++ } ++ else ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Delete print was not successful")); ++ } ++} ++ ++static void ++egis_etu905_delete_run_state (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ g_autofree guchar *payload = NULL; ++ gsize payload_length = 0; ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case DELETE_GET_ENROLLED_IDS: ++ /* get enrolled_ids from device for use building delete payload below */ ++ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, NULL, ++ egis_etu905_list_fill_enrolled_ids_cb); ++ break; ++ ++ case DELETE_DELETE: ++ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE) ++ payload = egis_etu905_get_delete_cmd (device, fpi_ssm_get_data (ssm), ++ &payload_length); ++ else ++ payload = egis_etu905_get_delete_cmd (device, NULL, &payload_length); ++ ++ egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, ++ g_free, egis_etu905_delete_cb); ++ break; ++ } ++} ++ ++static void ++egis_etu905_clear_storage (FpDevice *device) ++{ ++ fp_dbg ("Clear storage"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, ++ egis_etu905_delete_run_state, ++ DELETE_STATES); ++ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); ++} ++ ++static void ++egis_etu905_delete (FpDevice *device) ++{ ++ fp_dbg ("Delete"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ FpPrint *delete_print = NULL; ++ ++ fpi_device_get_delete_data (device, &delete_print); ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, ++ egis_etu905_delete_run_state, ++ DELETE_STATES); ++ /* the print is owned by libfprint during deletion task */ ++ fpi_ssm_set_data (self->task_ssm, delete_print, NULL); ++ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); ++} ++ ++static void ++egis_etu905_enroll_status_report (FpDevice *device, ++ EnrollPrint *enroll_print, ++ EnrollStatus status, ++ GError *error) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ switch (status) ++ { ++ case ENROLL_STATUS_DEVICE_FULL: ++ case ENROLL_STATUS_DUPLICATE: ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ break; ++ ++ case ENROLL_STATUS_RETRY: ++ fpi_device_enroll_progress (device, enroll_print->stage, NULL, error); ++ break; ++ ++ case ENROLL_STATUS_PARTIAL_OK: ++ enroll_print->stage++; ++ fp_info ("Partial capture successful. Please touch the sensor again (%d/%d)", ++ enroll_print->stage, ++ self->max_enroll_stages); ++ fpi_device_enroll_progress (device, enroll_print->stage, enroll_print->print, NULL); ++ break; ++ ++ case ENROLL_STATUS_COMPLETE: ++ fp_info ("Enrollment was successful!"); ++ fpi_device_enroll_complete (device, g_object_ref (enroll_print->print), NULL); ++ break; ++ ++ default: ++ if (error) ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ else ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, ++ "Unknown error")); ++ } ++} ++ ++static void ++egis_etu905_read_capture_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Read capture callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ EnrollPrint *enroll_print = fpi_ssm_get_data (self->task_ssm); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload indicates "success" */ ++ if (egis_etu905_validate_response_prefix (buffer_in, ++ length_in, ++ rsp_read_success_prefix, ++ rsp_read_success_prefix_len) && ++ egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_read_success_suffix, ++ rsp_read_success_suffix_len)) ++ { ++ egis_etu905_enroll_status_report (device, enroll_print, ++ ENROLL_STATUS_PARTIAL_OK, NULL); ++ } ++ else ++ { ++ /* If not success then the sensor can either report "off center" or "sensor is dirty" */ ++ ++ /* "Off center" */ ++ if (egis_etu905_validate_response_prefix (buffer_in, ++ length_in, ++ rsp_read_offcenter_prefix, ++ rsp_read_offcenter_prefix_len) && ++ egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_read_offcenter_suffix, ++ rsp_read_offcenter_suffix_len)) ++ error = fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER); ++ ++ /* "Sensor is dirty" */ ++ else if (egis_etu905_validate_response_prefix (buffer_in, ++ length_in, ++ rsp_read_dirty_prefix, ++ rsp_read_dirty_prefix_len)) ++ error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, ++ "Your device is having trouble recognizing you. " ++ "Make sure your sensor is clean."); ++ ++ else ++ error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, ++ "Unknown failure trying to read your finger. " ++ "Please try again."); ++ ++ egis_etu905_enroll_status_report (device, enroll_print, ENROLL_STATUS_RETRY, error); ++ } ++ ++ 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); ++} ++ ++static void ++egis_etu905_enroll_duplicate_check_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Task SSM enroll duplicate check callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload reports "not yet enrolled" */ ++ if (egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_check_not_yet_enrolled_suffix, ++ rsp_check_not_yet_enrolled_suffix_len)) ++ fpi_ssm_jump_to_state (self->task_ssm, ENROLL_COMMIT_START); ++ else ++ egis_etu905_enroll_status_report (device, NULL, ENROLL_STATUS_DUPLICATE, ++ fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE)); ++} ++ ++static void ++egis_etu905_enroll_begin_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Enroll begin callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ FpiByteReader reader; ++ ++ fpi_byte_reader_init (&reader, buffer_in, length_in); ++ ++ fpi_byte_reader_set_pos (&reader, EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE); ++ ++ const guint8 *data = NULL; ++ ++ fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, ++ &data); ++ ++ if (data) ++ memcpy (self->sid, data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++/* ++ * Builds the full "check" payload which includes identifiers for all ++ * fingerprints which currently should exist on the storage. This payload is ++ * used during both enrollment and verify actions. ++ */ ++static guchar * ++egis_etu905_get_check_cmd (FpDevice *device, ++ gsize *length_out) ++{ ++ fp_dbg ("Get check command"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ g_auto(FpiByteWriter) writer = {0}; ++ g_autofree guchar *result = NULL; ++ 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_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_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) ++ */ ++ ++ g_assert (self->enrolled_ids); ++ const gsize body_length = sizeof (guchar) * self->enrolled_ids->len * ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE; ++ ++ /* prefix length can depend on the type */ ++ const gsize check_prefix_length = (fpi_device_get_driver_data (device) & ++ EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2) ? ++ cmd_check_prefix_type2_len : ++ cmd_check_prefix_type1_len; ++ ++ /* total_length is the 6 various bytes plus all other prefixes/suffixes and ++ * the body payload */ ++ const gsize total_length = (sizeof (guchar) * 6) ++ + check_prefix_length ++ + EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH ++ + body_length ++ + cmd_check_suffix_len; ++ ++ /* pre-fill entire payload with 00s */ ++ fpi_byte_writer_init_with_size (&writer, total_length, TRUE); ++ ++ /* start with 00 00 (just move starting offset up by 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_ids->len > 6) ++ { ++ 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 */ ++ 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) & EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2) ++ written &= fpi_byte_writer_put_data (&writer, cmd_check_prefix_type2, ++ cmd_check_prefix_type2_len); ++ else ++ 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_ids->len > 6) ++ { ++ 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 */ ++ 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 */ ++ written &= fpi_byte_writer_change_pos (&writer, ++ EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH); ++ ++ 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), ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ } ++ ++ /* command suffix */ ++ 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 fpi_byte_writer_reset_and_get_data (&writer); ++} ++ ++static void ++egis_etu905_enroll_run_state (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ g_auto(FpiByteWriter) writer = {0}; ++ EgismocSidData sid_data = {0}; ++ EnrollPrint *enroll_print = fpi_ssm_get_data (ssm); ++ g_autofree guchar *payload = NULL; ++ gsize payload_length = 0; ++ g_autofree gchar *device_print_id = NULL; ++ g_autofree gchar *user_id = NULL; ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case ENROLL_START: ++ egis_etu905_exec_cmd (device, cmd_enroll_starting, cmd_enroll_starting_len, ++ NULL, egis_etu905_enroll_begin_cb); ++ break; ++ ++ case ENROLL_CAPTURE_SENSOR_RESET: ++ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case ENROLL_CAPTURE_SENSOR_START_CAPTURE: ++ egis_etu905_exec_cmd (device, cmd_sensor_start_capture, cmd_sensor_start_capture_len, ++ NULL, ++ egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case ENROLL_CAPTURE_WAIT_FINGER: ++ egis_etu905_wait_finger_on_sensor (ssm, device); ++ break; ++ ++ case ENROLL_CAPTURE_READ_RESPONSE: ++ egis_etu905_exec_cmd (device, cmd_read_capture, cmd_read_capture_len, ++ NULL, egis_etu905_read_capture_cb); ++ break; ++ ++ case ENROLL_DUPLICATE_CHECK: ++ egis_etu905_exec_cmd (device, cmd_duplicate_check, cmd_duplicate_check_len, ++ NULL, egis_etu905_enroll_duplicate_check_cb); ++ break; ++ ++ case ENROLL_COMMIT_START: ++ egis_etu905_exec_cmd (device, cmd_commit_starting, cmd_commit_starting_len, ++ NULL, egis_etu905_commit_start_cb); ++ break; ++ ++ case ENROLL_COMMIT: ++ user_id = fpi_print_generate_user_id (enroll_print->print); ++ fp_dbg ("New fingerprint ID: %s", user_id); ++ ++ sid_data.reserve_para_1 = EGIS_ETU905_PARA_1_VALUE; ++ sid_data.reserve_para_2 = EGIS_ETU905_PARA_2_VALUE; ++ sid_data.reserve_para_3 = EGIS_ETU905_PARA_3_VALUE; ++ memcpy (sid_data.reserve_para_4, user_id, MIN (EGIS_ETU905_FINGERPRINT_DATA_SIZE, strlen (user_id))); ++ egis_etu905_set_print_data (enroll_print->print, (const gchar *) &sid_data.reserve_para_4, user_id); ++ fpi_byte_writer_init (&writer); ++ if (!fpi_byte_writer_put_data (&writer, cmd_new_print_prefix_type2, ++ cmd_new_print_prefix_type2_len)) ++ { ++ fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); ++ break; ++ } ++ if (!fpi_byte_writer_put_data (&writer, (guint8 *) &sid_data, ++ sizeof (EgismocSidData))) ++ { ++ fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); ++ break; ++ } ++ ++ payload_length = fpi_byte_writer_get_size (&writer); ++ egis_etu905_exec_cmd (device, fpi_byte_writer_reset_and_get_data (&writer), ++ payload_length, ++ g_free, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case ENROLL_COMMIT_SENSOR_RESET: ++ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case ENROLL_COMPLETE: ++ egis_etu905_enroll_status_report (device, enroll_print, ENROLL_STATUS_COMPLETE, NULL); ++ fpi_ssm_next_state (ssm); ++ break; ++ } ++} ++ ++static void ++egis_etu905_enroll (FpDevice *device) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ EnrollPrint *enroll_print = g_new0 (EnrollPrint, 1); ++ ++ fp_dbg ("Enroll"); ++ ++ fpi_device_get_enroll_data (device, &enroll_print->print); ++ enroll_print->stage = 0; ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, egis_etu905_enroll_run_state, ENROLL_STATES); ++ fpi_ssm_set_data (self->task_ssm, g_steal_pointer (&enroll_print), g_free); ++ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); ++} ++ ++static void ++egis_etu905_identify_check_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Identify check callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ gchar device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; ++ FpPrint *print = NULL; ++ FpPrint *verify_print = NULL; ++ GPtrArray *prints; ++ gboolean found = FALSE; ++ guint index; ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload indicates "match" */ ++ if (egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_identify_match_suffix, ++ rsp_identify_match_suffix_len)) ++ { ++ /* ++ On success, there is a 32 byte array of "something"(?) in chars 14-45 ++ and then the 32 byte array ID of the matched print comes as chars 46-77 ++ */ ++ memcpy (device_print_id, ++ buffer_in + EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET, ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE); ++ ++ /* Create a new print from this device_print_id and then see if it matches ++ * the one indicated ++ */ ++ print = fp_print_new (device); ++ egis_etu905_set_print_data (print, device_print_id, NULL); ++ ++ if (!print) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, ++ "Failed to build a print from " ++ "device response.")); ++ return; ++ } ++ ++ fp_info ("Identify successful for: %s", fp_print_get_description (print)); ++ ++ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) ++ { ++ fpi_device_get_identify_data (device, &prints); ++ found = g_ptr_array_find_with_equal_func (prints, ++ print, ++ (GEqualFunc) fp_print_equal, ++ &index); ++ ++ if (found) ++ fpi_device_identify_report (device, g_ptr_array_index (prints, index), print, NULL); ++ else ++ fpi_device_identify_report (device, NULL, print, NULL); ++ } ++ else ++ { ++ fpi_device_get_verify_data (device, &verify_print); ++ fp_info ("Verifying against: %s", fp_print_get_description (verify_print)); ++ ++ if (fp_print_equal (verify_print, print)) ++ fpi_device_verify_report (device, FPI_MATCH_SUCCESS, print, NULL); ++ else ++ fpi_device_verify_report (device, FPI_MATCH_FAIL, print, NULL); ++ } ++ } ++ /* If device was successfully read but it was a "not matched" */ ++ else if (egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_identify_notmatch_suffix, ++ rsp_identify_notmatch_suffix_len)) ++ { ++ fp_info ("Print was not identified by the device"); ++ ++ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY) ++ fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL); ++ else ++ fpi_device_identify_report (device, NULL, NULL, NULL); ++ } ++ else ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Unrecognized response from device.")); ++ return; ++ } ++ ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++static void ++egis_etu905_identify_run_state (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ g_autofree guchar *payload = NULL; ++ gsize payload_length = 0; ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case IDENTIFY_GET_ENROLLED_IDS: ++ /* get enrolled_ids from device for use in check stages below */ ++ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, ++ NULL, egis_etu905_list_fill_enrolled_ids_cb); ++ break; ++ ++ case IDENTIFY_CHECK_ENROLLED_NUM: ++ 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)); ++ return; ++ } ++ fpi_ssm_next_state (ssm); ++ break; ++ ++ case IDENTIFY_SENSOR_RESET: ++ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case IDENTIFY_SENSOR_IDENTIFY: ++ egis_etu905_exec_cmd (device, cmd_sensor_identify, cmd_sensor_identify_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case IDENTIFY_WAIT_FINGER: ++ egis_etu905_wait_finger_on_sensor (ssm, device); ++ break; ++ ++ case IDENTIFY_SENSOR_CHECK: ++ egis_etu905_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ case IDENTIFY_CHECK: ++ payload = egis_etu905_get_check_cmd (device, &payload_length); ++ egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, ++ g_free, egis_etu905_identify_check_cb); ++ break; ++ ++ case IDENTIFY_COMPLETE_SENSOR_RESET: ++ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, ++ NULL, egis_etu905_task_ssm_next_state_cb); ++ break; ++ ++ /* ++ * In Windows, the driver seems at this point to then immediately take ++ * another read from the sensor; this is suspected to be an on-chip ++ * "verify". However, because the user's finger is still on the sensor from ++ * the identify, then it seems to always return positive. We will consider ++ * this extra step unnecessary and just skip it in this driver. This driver ++ * will instead handle matching of the FpPrint from the gallery in the ++ * "verify" case of the callback egis_etu905_identify_check_cb. ++ */ ++ case IDENTIFY_COMPLETE: ++ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) ++ fpi_device_identify_complete (device, NULL); ++ else ++ fpi_device_verify_complete (device, NULL); ++ ++ fpi_ssm_mark_completed (ssm); ++ break; ++ } ++} ++ ++static void ++egis_etu905_identify_verify (FpDevice *device) ++{ ++ fp_dbg ("Identify or Verify"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, egis_etu905_identify_run_state, IDENTIFY_STATES); ++ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); ++} ++ ++static void ++egis_etu905_fw_version_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("Firmware version callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ g_autofree gchar *fw_version = NULL; ++ gsize prefix_length; ++ guchar *fw_version_start; ++ gsize fw_version_length; ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload indicates "success" */ ++ if (!egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_fw_version_suffix, ++ rsp_fw_version_suffix_len)) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Device firmware response " ++ "was not valid.")); ++ return; ++ } ++ ++ /* ++ * FW Version is 12 bytes: a carriage return (0x0d) plus the version string ++ * itself. Always skip [the read prefix] + [2 * check bytes] + [3 * 0x00] that ++ * come with every payload Then we will also skip the carriage return and take ++ * all but the last 2 bytes as the FW Version ++ */ ++ prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; ++ fw_version_start = buffer_in + prefix_length; ++ fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len; ++ fw_version = g_strndup ((gchar *) fw_version_start, fw_version_length); ++ ++ fp_info ("Device firmware version is %s", fw_version); ++ ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++static void ++egis_etu905_cmd_init_cb (FpDevice *device, ++ guchar *buffer_in, ++ gsize length_in, ++ GError *error) ++{ ++ fp_dbg ("cmd init callback"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ if (error) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, error); ++ return; ++ } ++ ++ /* Check that the read payload indicates "success" */ ++ if (!egis_etu905_validate_response_suffix (buffer_in, ++ length_in, ++ rsp_fw_version_suffix, ++ rsp_fw_version_suffix_len)) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "cmd init response " ++ "was not valid.")); ++ return; ++ } ++ fpi_ssm_next_state (self->task_ssm); ++} ++ ++static void ++egis_etu905_dev_init_done (FpiSsm *ssm, ++ FpDevice *device, ++ GError *error) ++{ ++ if (error) ++ { ++ g_usb_device_release_interface ( ++ fpi_device_get_usb_device (device), 0, 0, NULL); ++ egis_etu905_task_ssm_done (ssm, device, error); ++ return; ++ } ++ ++ egis_etu905_task_ssm_done (ssm, device, NULL); ++ fpi_device_open_complete (device, NULL); ++} ++ ++static void ++egis_etu905_dev_init_handler (FpiSsm *ssm, ++ FpDevice *device) ++{ ++ g_autoptr(FpiUsbTransfer) transfer = NULL; ++ ++ switch (fpi_ssm_get_cur_state (ssm)) ++ { ++ case DEV_GET_FW_VERSION: ++ egis_etu905_exec_cmd (device, cmd_fw_version, cmd_fw_version_len, ++ NULL, egis_etu905_fw_version_cb); ++ return; ++ ++ case DEV_INIT_CONTROL: ++ egis_etu905_exec_cmd (device, cmd_init, cmd_init_len, ++ NULL, egis_etu905_cmd_init_cb); ++ return; ++ ++ default: ++ g_assert_not_reached (); ++ } ++ ++ transfer = fpi_usb_transfer_new (device); ++ transfer->ssm = ssm; ++ transfer->short_is_error = TRUE; ++ fpi_usb_transfer_submit (g_steal_pointer (&transfer), ++ EGIS_ETU905_USB_CONTROL_TIMEOUT, ++ fpi_device_get_cancellable (device), ++ fpi_ssm_usb_transfer_cb, ++ NULL); ++} ++ ++static void ++egis_etu905_probe (FpDevice *device) ++{ ++ GUsbDevice *usb_dev; ++ GError *error = NULL; ++ g_autofree gchar *serial = NULL; ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (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) & EGIS_ETU905_DRIVER_MAX_ENROLL_STAGES_20) ++ self->max_enroll_stages = 20; ++ else ++ self->max_enroll_stages = EGIS_ETU905_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 ++egis_etu905_open (FpDevice *device) ++{ ++ fp_dbg ("Opening device"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ g_autoptr(GError) error = NULL; ++ ++ if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error)) ++ { ++ fpi_device_open_complete (device, g_steal_pointer (&error)); ++ return; ++ } ++ ++ if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), ++ 0, 0, &error)) ++ { ++ fpi_device_open_complete (device, g_steal_pointer (&error)); ++ return; ++ } ++ ++ g_assert (self->task_ssm == NULL); ++ self->task_ssm = fpi_ssm_new (device, egis_etu905_dev_init_handler, DEV_INIT_STATES); ++ fpi_ssm_start (self->task_ssm, egis_etu905_dev_init_done); ++} ++ ++static void ++egis_etu905_cancel (FpDevice *device) ++{ ++ fp_dbg ("Cancel"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ ++ g_cancellable_cancel (self->interrupt_cancellable); ++ g_clear_object (&self->interrupt_cancellable); ++ self->interrupt_cancellable = g_cancellable_new (); ++} ++ ++static void ++egis_etu905_suspend (FpDevice *device) ++{ ++ fp_dbg ("Suspend"); ++ ++ egis_etu905_cancel (device); ++ g_cancellable_cancel (fpi_device_get_cancellable (device)); ++ fpi_device_suspend_complete (device, NULL); ++} ++ ++static void ++egis_etu905_close (FpDevice *device) ++{ ++ g_autoptr(GError) error = NULL; ++ fp_dbg ("Closing device"); ++ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ GError *error = NULL; ++ ++ egis_etu905_cancel (device); ++ g_clear_object (&self->interrupt_cancellable); ++ ++ g_usb_device_release_interface (fpi_device_get_usb_device (device), ++ 0, 0, &error); ++ fpi_device_close_complete (device, g_steal_pointer (&error)); ++} ++ ++static void ++fpi_device_egis_etu905_init (FpiDeviceEgisEtu905 *self) ++{ ++ G_DEBUG_HERE (); ++} ++ ++static void ++fpi_device_egis_etu905_class_init (FpiDeviceEgisEtu905Class *klass) ++{ ++ FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); ++ ++ dev_class->id = FP_COMPONENT; ++ dev_class->full_name = EGIS_ETU905_DRIVER_FULLNAME; ++ ++ dev_class->type = FP_DEVICE_TYPE_USB; ++ dev_class->scan_type = FP_SCAN_TYPE_PRESS; ++ dev_class->id_table = egis_etu905_id_table; ++ dev_class->nr_enroll_stages = EGIS_ETU905_MAX_ENROLL_STAGES_DEFAULT; ++ dev_class->temp_hot_seconds = -1; ++ ++ dev_class->probe = egis_etu905_probe; ++ dev_class->open = egis_etu905_open; ++ dev_class->cancel = egis_etu905_cancel; ++ dev_class->suspend = egis_etu905_suspend; ++ dev_class->close = egis_etu905_close; ++ dev_class->identify = egis_etu905_identify_verify; ++ dev_class->verify = egis_etu905_identify_verify; ++ dev_class->enroll = egis_etu905_enroll; ++ dev_class->delete = egis_etu905_delete; ++ dev_class->clear_storage = egis_etu905_clear_storage; ++ dev_class->list = egis_etu905_list; ++ ++ fpi_device_class_auto_initialize_features (dev_class); ++ dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK; ++} +diff --git a/libfprint/drivers/egismoc/egis_etu905.h b/libfprint/drivers/egismoc/egis_etu905.h +new file mode 100644 +index 00000000..e931deca +--- /dev/null ++++ b/libfprint/drivers/egismoc/egis_etu905.h +@@ -0,0 +1,214 @@ ++/* ++ * Driver for Egis Technology (LighTuning) Match-On-Chip sensors ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#pragma once ++ ++#include "fpi-device.h" ++#include "fpi-ssm.h" ++ ++G_DECLARE_FINAL_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FPI, DEVICE_EGIS_ETU905, FpDevice) ++ ++#define EGIS_ETU905_DRIVER_FULLNAME "Egis Technology (LighTuning) Match-on-Chip" ++ ++#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 (1 << 0) ++#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1) ++#define EGIS_ETU905_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2) ++ ++#define EGIS_ETU905_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT) ++#define EGIS_ETU905_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN) ++#define EGIS_ETU905_EP_CMD_INTERRUPT_IN 0x83 ++ ++#define EGIS_ETU905_USB_CONTROL_TIMEOUT 5000 ++#define EGIS_ETU905_USB_SEND_TIMEOUT 5000 ++#define EGIS_ETU905_USB_RECV_TIMEOUT 5000 ++#define EGIS_ETU905_USB_INTERRUPT_TIMEOUT 0 /* No timeout for waiting for finger down */ ++ ++#define EGIS_ETU905_USB_IN_RECV_LENGTH 4096 ++#define EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH 64 ++ ++#define EGIS_ETU905_MAX_ENROLL_STAGES_DEFAULT 12 ++#define EGIS_ETU905_MAX_ENROLL_NUM 12 ++#define EGIS_ETU905_FINGERPRINT_DATA_SIZE 32 ++#define EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE 14 ++#define EGIS_ETU905_LIST_RESPONSE_SUFFIX_SIZE 2 ++ ++#define EGIS_ETU905_PARA_4_SIZE 68 ++ ++#define EGIS_ETU905_PARA_1_VALUE 0 ++#define EGIS_ETU905_PARA_2_VALUE 0 ++#define EGIS_ETU905_PARA_3_VALUE 32 ++ ++#pragma pack(push, 1) ++typedef struct ++{ ++ guchar reserve_para_1; ++ gushort reserve_para_2; ++ gushort reserve_para_3; ++ guchar reserve_para_4[EGIS_ETU905_PARA_4_SIZE]; ++} EgismocSidData; ++#pragma pack(pop) ++ ++/* standard prefixes for all read/writes */ ++ ++static guchar egis_etu905_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01}; ++static gsize egis_etu905_write_prefix_len = sizeof (egis_etu905_write_prefix) / sizeof (egis_etu905_write_prefix[0]); ++ ++static guchar egis_etu905_read_prefix[] = {'S', 'I', 'G', 'E', 0x00, 0x00, 0x00, 0x01}; ++static gsize egis_etu905_read_prefix_len = sizeof (egis_etu905_read_prefix) / sizeof (egis_etu905_read_prefix[0]); ++ ++ ++/* hard-coded command payloads */ ++ ++static guchar cmd_fw_version[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x0c}; ++static gsize cmd_fw_version_len = sizeof (cmd_fw_version) / sizeof (cmd_fw_version[0]); ++static guchar rsp_fw_version_suffix[] = {0x90, 0x00}; ++static gsize rsp_fw_version_suffix_len = sizeof (rsp_fw_version_suffix) / sizeof (rsp_fw_version_suffix[0]); ++ ++static guchar cmd_init[] = {0x00, 0x00, 0x00, 0x29, 0x50, 0x81, 0x80, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12, 0x00, 0x45, 0x67, 0x69, 0x73, ++ 0x46, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x51, 0xc6, 0xbd, 0x71}; ++static gsize cmd_init_len = sizeof (cmd_init) / sizeof (cmd_init[0]); ++ ++static guchar cmd_list[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x19, 0x04, 0x00, 0x00, 0x01, 0x40}; ++static gsize cmd_list_len = sizeof (cmd_list) / sizeof (cmd_list[0]); ++ ++static guchar cmd_sensor_reset[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x1a, 0x00, 0x00}; ++static gsize cmd_sensor_reset_len = sizeof (cmd_sensor_reset) / sizeof (cmd_sensor_reset[0]); ++ ++static guchar cmd_sensor_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x02, 0x00}; ++static gsize cmd_sensor_check_len = sizeof (cmd_sensor_check) / sizeof (cmd_sensor_check[0]); ++ ++static guchar cmd_sensor_identify[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x01, 0x01}; ++static gsize cmd_sensor_identify_len = sizeof (cmd_sensor_identify) / sizeof (cmd_sensor_identify[0]); ++ ++static guchar rsp_identify_match_suffix[] = {0x90, 0x00}; ++static gsize rsp_identify_match_suffix_len = sizeof (rsp_identify_match_suffix) / sizeof (rsp_identify_match_suffix[0]); ++ ++static guchar rsp_identify_notmatch_suffix[] = {0x90, 0x04}; ++static gsize rsp_identify_notmatch_suffix_len = sizeof (rsp_identify_notmatch_suffix) / sizeof (rsp_identify_notmatch_suffix[0]); ++ ++static guchar cmd_enroll_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x01, 0x00, 0x00, 0x00, 0x20}; ++static gsize cmd_enroll_starting_len = sizeof (cmd_enroll_starting) / sizeof (cmd_enroll_starting[0]); ++ ++static guchar cmd_sensor_start_capture[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x02, 0x01}; ++static gsize cmd_sensor_start_capture_len = sizeof (cmd_sensor_start_capture) / sizeof (cmd_sensor_start_capture[0]); ++ ++static guchar cmd_read_capture[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x02, 0x02, 0x00, 0x00, 0x02}; ++static gsize cmd_read_capture_len = sizeof (cmd_read_capture) / sizeof (cmd_read_capture[0]); ++ ++static guchar cmd_duplicate_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x05, 0x00}; ++static gsize cmd_duplicate_check_len = sizeof (cmd_duplicate_check) / sizeof (cmd_duplicate_check[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[] = {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[] = {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]); ++ ++static guchar cmd_commit_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x05, 0x00, 0x00, 0x00, 0x20}; ++static gsize cmd_commit_starting_len = sizeof (cmd_commit_starting) / sizeof (cmd_commit_starting[0]); ++ ++/* prefixes/suffixes and other things for dynamically created command payloads */ ++ ++#define EGIS_ETU905_CHECK_BYTES_LENGTH 2 ++#define EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET 46 ++#define EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH 32 ++ ++static guchar cmd_new_print_prefix_type2[] = {0x00, 0x00, 0x00, 0x50, 0x50, 0x16, 0x03, 0x00, 0x00, 0x00, 0x49}; ++static gsize cmd_new_print_prefix_type2_len = sizeof (cmd_new_print_prefix_type2) / sizeof (cmd_new_print_prefix_type2[0]); ++ ++static guchar cmd_delete_prefix[] = {0x50, 0x18, 0x04, 0x00, 0x00}; ++static gsize cmd_delete_prefix_len = sizeof (cmd_delete_prefix) / sizeof (cmd_delete_prefix[0]); ++static guchar rsp_delete_success_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x90, 0x00}; ++static gsize rsp_delete_success_prefix_len = sizeof (rsp_delete_success_prefix) / sizeof (rsp_delete_success_prefix[0]); ++ ++static guchar cmd_check_prefix_type1[] = {0x50, 0x17, 0x03, 0x00, 0x00}; ++static gsize cmd_check_prefix_type1_len = sizeof (cmd_check_prefix_type1) / sizeof (cmd_check_prefix_type1[0]); ++static guchar cmd_check_prefix_type2[] = {0x50, 0x17, 0x03, 0x80, 0x00}; ++static gsize cmd_check_prefix_type2_len = sizeof (cmd_check_prefix_type2) / sizeof (cmd_check_prefix_type2[0]); ++static guchar cmd_check_suffix[] = {0x00, 0x40}; ++static gsize cmd_check_suffix_len = sizeof (cmd_check_suffix) / sizeof (cmd_check_suffix[0]); ++static guchar rsp_check_not_yet_enrolled_suffix[] = {0x90, 0x04}; ++static gsize rsp_check_not_yet_enrolled_suffix_len = sizeof (rsp_check_not_yet_enrolled_suffix) / sizeof (rsp_check_not_yet_enrolled_suffix[0]); ++ ++ ++/* SSM task states and various status enums */ ++ ++typedef enum { ++ CMD_SEND, ++ CMD_GET, ++ CMD_STATES, ++} CommandStates; ++ ++typedef enum { ++ DEV_GET_FW_VERSION, ++ DEV_INIT_CONTROL, ++ DEV_INIT_STATES, ++} DeviceInitStates; ++ ++typedef enum { ++ IDENTIFY_GET_ENROLLED_IDS, ++ IDENTIFY_CHECK_ENROLLED_NUM, ++ IDENTIFY_SENSOR_RESET, ++ IDENTIFY_SENSOR_IDENTIFY, ++ IDENTIFY_WAIT_FINGER, ++ IDENTIFY_SENSOR_CHECK, ++ IDENTIFY_CHECK, ++ IDENTIFY_COMPLETE_SENSOR_RESET, ++ IDENTIFY_COMPLETE, ++ IDENTIFY_STATES, ++} IdentifyStates; ++ ++typedef enum { ++ ENROLL_START, ++ ENROLL_CAPTURE_SENSOR_RESET, ++ ENROLL_CAPTURE_SENSOR_START_CAPTURE, ++ ENROLL_CAPTURE_WAIT_FINGER, ++ ENROLL_CAPTURE_READ_RESPONSE, ++ ENROLL_DUPLICATE_CHECK, ++ ENROLL_COMMIT_START, ++ ENROLL_COMMIT, ++ ENROLL_COMMIT_SENSOR_RESET, ++ ENROLL_COMPLETE, ++ ENROLL_STATES, ++} EnrollStates; ++ ++typedef enum { ++ ENROLL_STATUS_DEVICE_FULL, ++ ENROLL_STATUS_DUPLICATE, ++ ENROLL_STATUS_PARTIAL_OK, ++ ENROLL_STATUS_RETRY, ++ ENROLL_STATUS_COMPLETE, ++} EnrollStatus; ++ ++typedef enum { ++ LIST_GET_ENROLLED_IDS, ++ LIST_RETURN_ENROLLED_PRINTS, ++ LIST_STATES, ++} ListStates; ++ ++typedef enum { ++ DELETE_GET_ENROLLED_IDS, ++ DELETE_DELETE, ++ DELETE_STATES, ++} DeleteStates; +diff --git a/libfprint/meson.build b/libfprint/meson.build +index ae0f6e24..081b18de 100644 +--- a/libfprint/meson.build ++++ b/libfprint/meson.build +@@ -127,6 +127,8 @@ driver_sources = { + [ 'drivers/egis0570.c' ], + 'egismoc' : + [ 'drivers/egismoc/egismoc.c' ], ++ 'egis_etu905' : ++ [ 'drivers/egismoc/egis_etu905.c' ], + 'vfs0050' : + [ 'drivers/vfs0050.c' ], + 'elan' : +diff --git a/meson.build b/meson.build +index 14fb11f2..02b43e4f 100644 +--- a/meson.build ++++ b/meson.build +@@ -131,6 +131,7 @@ default_drivers = [ + 'etes603', + 'egis0570', + 'egismoc', ++ 'egis_etu905', + 'vcom5s', + 'synaptics', + 'elan', +@@ -165,6 +166,7 @@ endian_independent_drivers = virtual_drivers + [ + 'aes4000', + 'egis0570', + 'egismoc', ++ 'egis_etu905', + 'elanmoc', + 'etes603', + 'focaltech_moc', +diff --git a/tests/egis_etu905/custom.pcapng b/tests/egis_etu905/custom.pcapng +new file mode 100644 +index 0000000000000000000000000000000000000000..b21c4622a1b5b44f25065882cff3d3e2687d76d1 +GIT binary patch +literal 33644 +zcmd5_3wTu3xjmT#LVzG3f*|OqRD2~QV4zCGgNO)%jX(@qv=e!ms(?H!qOAjnpx#In +z5WNNg1^n8ATB=<2T8%_}w2H+y7WGnFt8&#(K&_9;{r|J~+WX9(d7aboYKXEJln +zthN8W_FiY7J)5CzadF!x9LE`5c~Xx&dOn~_#5u(oGWx9Om}}-uo))c$R#cRgRY!kO +zH~X^anA%B`r%#IxpIJNOvbu@0qQ`shjvYJfl+u1D$2LJm!A-&&z1Iz9zVQpcJylX_l(+! +zm)B06JSkc`OC2pKFD<`xPTdug`kz3Rq{4OP`kq6vi^6TncOp)qGiTPNS5BYS-zlP_ +zt?B*tY3f6Vz0dP`F@8a%@2J*J&qc!;UHY3Np7%lJ%Qqi5Fg6m8{ax3OR+X=0{wI +zo+9dLVZKXUhxuimpG_KPHEWyL4?F07IDJ_7epr9SINJ|3J~RV<@#x(4!_SG6vUfP* +zDRR1sIKyhUZtgg%U5cD~U--jomw!#>JQq?uI8PeCUWvEP&o3&#D|$=!p&0$ied9U` +zF5E|#$Hz5ZM1OOj9i?_%YE_;+=p2p~MdSC#FLQ=CKXwKj9)Ss_@7;_a!Uf4@K!SX&6VRb +z_Q8I=3O#M$z3~A4zIoXAjN_``afMzzbLH>d&d!|EO5zMVuFe@fKI6E0zC`8pLwe$E +zR1cS0j>8!-_iX>Q8GWNusmc>0Dag2LS3Ta0E8xp{Ix2ik6IeuT%Z@rC0?s`?*B +zr*Nby!-kI-OULrMyi1RTRoC-*?J1Z~`o+J9*QNJ4z&lj&8o&4@@p4JW$;V?9694|6 +zTl^;Ux%~N@S0(yfpL4Y?9T_D_N#o^_8^<^Pls>`%{GkfpwA+Fys{TjNIUFsD#veOk +z_%J$_cj_DTSbS<(MOkS@Y5&qw`ZZWDzf*shHM@+se?hM~+=!lI2+ckuZuSkn9&n^8 +z&}{R5I^%?@`EhzW#ydIcJvtp}Dm!dy-K?{##!j9!t8V%<=lo~?aFxULk!}72)yt*# +zz0mcNnpRF#ZIZ4|1d&wJeLnoAeB_;|=`6zMys6&Fi_mn2K8xFR?*ro-tLQZc@TI0R +zm#X?RJV%QnG=2R_IwR8H%%CSZ_MFXj?76LwPvY2%-yUr2y>liJ6;^epnQNX)evZ2+KAkka)alsAg6VW%Iwc#K{CzT= +z9(u>>@}}y^?&1GPoGzWh0ZysmNaEyzd8_v#$wQ3Zvf_=@93P8Hz0wEapu?P(^{WK=DM3W&ZeCiOrzJl>(*`Ny2W{M;XXHIqHQnS$BxZg +zm@v2cV5ri_^*&`E%pIl3XN^9E@fR+e+Q^ef4&V<}_|74E4W+qUjhQp(91awT58o*5 +zMQ4>&gDih3j|M@~LLd93QFgXY~9F_1oDm*!7?n&j9Iq5TSPA +zrb%`^*iF1H9peBm`YCvi?jQboFn@&)e+cqY{S^356Mm5Sm49pxDy%bOJFfBJCBVOS +zy&Y#s$C~ap(Dk(#HAX>Ry9Ro~*!FX-Y2)KO3ppvz2j~B62<9i5Jbw>yx>O&IxaO2P +zopis=lTJ%nVsu3M$$u7E{3aJUCF=Ax;Rn&l?NW(vU!$kCTaAD(H9BxbFpbiA{(Udo_KFv3jkM<@pZBj+8o5+;f03RXql4UD +zYbdy|r}mn%zM)%q#V#na8lF)zu+ +z^G6b|OL!dSdkwu#0^YXsRlB6)q>m?^oBYv--&BOLr@RFCHxqskFY){D!15c6=K~-8 +z6!>3_Y{k{{##z#_CcNa;7@b@YN$L47^|PGrl7{x%`MW@&RsE<|f&3(s=XdIVgV70` +z@Dt>@gE+Y)&Cxre9%A$){baKre-Uy@)M@5ul~Wi$d27WD#`9f`FLk=}K~?`;c>csY +ztVYg_$VYiT+UwYdf@zd#o_{-Wy41ED;FKDTAxYAL*bvd2qulUBcSJO>8AMN?jsJcsQZydQEt9{7E^B-HZ%y>TV;rX4l +z=bw79(&J!w{sT8Ivz|X6da6E(`juXy`e-gae=qTJdve4zFZwBXXA&=$FrGhnvBh`d +z$V>H8;6JJJ%C?{SJ^#fsRv6C*KKd!}M|HDn9!bZV@cdU|lx#tMO3&{-q$MXjADrtB +z&+XdIwZ!RCwK!~^UjG;j&Tom6OVS*@BkCbWPtx=E`|!~Zus#R;+1-QPkNM}2k##GK +z=L28rwBTA*|6F+fr^Gjg^5npHml{pGE|^A{Jip(1s}VTmSlUdST*7Fy(T5LDmKvS> +z%kUaaFTBHQq^~JbqtD(ArcpZ2uWfUO?bEm}YtKiY+x?!($MssxK4jzhe?4)v@qBX) +z)@wV5YR^BWNg*8!&)<2{YUBBs2ceIme%+tW^R9Wh^!(__t4+Iu7yT5xG2-PC#`D+t +z@y(oAc|P#}rt=Ep`M++z){JdC|Ml=4;D5AM-KX$4OFGts=kJKoi3J5IJ-@!#ayspC +z@1m~H;C$&`b?=grlPI|0o-ETm|9Rqc>3j}wN}bx=XY=IKQk57Tke=^!u=q_Tr$n7x +z!Vhvk=J))Xj%$sd03UvWHe0z~)jt=W{|NDop*%U_1<5t~g7`R}Y&FW{`5zOfOMD#Q +zlp3A5A-qO|I$3<@5ag7o(Y1shR->7-twz9?8g1siiBz)HD4pkzn`85FJLr70=c7+7 +zZ(HEy<9e+2Asf%{v*tI(^MQ|fKJcej6nmft!}Hs({f+Vbcro-$^pQ~mioN`E>G@NL +zm)nyAyt1EeAYLwEJpU~pzT+UT#D04CK$TY*&+k{a(Tr{2%YHiZ`wm|HQ;u!n`G1bl +z=>@G)dj7(n`#8;dRiakS2Ra1ulT4of7vglOS{#n%lsX;Z9KuJFU)Q`N>LEr?((_kc +zZt>lA$#r^%@WcAals|1Wo)3KJ)J4y^rW~p2m#v?qThAZ#qSdI$^gE>y_y!&21kxyz +z=Px5pmr~#WCo}@*GUDXIeKB2$(Lt%v;V-qs$2=eSheuUT*^VXub$Lk1CZmz9znVV* +ze@L7vMkQN~(s_QL(oLql&?oR6F8KP)SNXUet9{7E^WT4Xi}ifnr{Vd)f4{J;2YN6( +zzv+=J#`7_zG0#W+n%cC@x#u6TWs7Nd@XCIAM3HKjFrI(6AK#2U<@w0#Zo&`ZCH}RY +zvPF-k^nBo#z17asHCxYrIYy@!v`*>yr8inmTqmVgr90aN@{>%Se-&}MR4op0N}aAE +zPA*~mq}hj$Ig#{}W}Q6H +z^86$ASdG9bH9BIj$}x;a^*(&uM@Wt82|vhK@_YV!qaHIF0bgqL-s)f)rStse(T|xv +zje9@o`ORxoKCag@>_ax5U;V~bfH)XD;XYHxaK(iE=oa7yT5xBR*8^62|lQ`|$A{EBYz$A13@D{nYRI +zt)F|wcs}saPl5mJn|41-(yrxweVfN&Dyo15p +z`F7PVVLZS0GZw!|>@NfUI>Ha@`CT6Svl-jKM?VGr^2O>qXdY)t$C~i`mtu5cL7SAG +zf63#P6MN0!C*XW{Nw7U3ndbSMiPO`Fss>K@2{`-RWb>rcQkEDUk)D6te_MR)|Hri% +z_!|g6h)(`FhzC~RsFMFH%RCCgL~~T{lXFd76$n|xhI%LndbS+iPNRF +zh^ZXyhZ9eD|@O<#C +zKQH{gomXz%X*?hJ((}h$tk!)GhUafsy3=~T_;+>4|F}!k8gVW?Khm(%^wU&cvVeHG +zgz@~fK74qx?59WnOy!mB+{8c6AO7H9%-9A#yri4HmMfVdj7e;v-p@3K_}qf +zLil0*eOqss(-eAlFsx0cIYnCFED4tbs72eUK32COrC#ymt9sPu|FT2 +zmk}qIq;n7NhQqgf +zT$1MK9Z?T4dXj#!*oTj`PpQ*$I;U)}%`-G7kH6Et{=4yf;7gt6EmHN*)=$!Te)%_6 +zBdkqJjjp;em`0gA|7zlNDQ6CFN{zMKqje0a}mAE|s?uhr~BHl81O>r>d%dz0AK1fW_7T= +z-|0NRXN}bedr;(f>bW+UMwvW+0&%+3wjAJ;V`&0$atWi+A>&)(%dvFGz2W!gcfG-C +zWb3cicF+g9ZV#qWI?w+n@wwC%USO}7p67$_pTx(W$LIJ%=0h2 +z&j&vGDeyaduIiuCe}(5~n&+?h*m7b$41NO6>b=4Ce)k+nb)?_#;yWtNPkQoa#Oc!e +z9N>hXfb&7(?9;&}f?{lF3a$H`rP_V-hyBhsaZFZ~svN_3=jc8b +zAK!_~Yg}>PV0%;jb1|pNr;+(BTXp}9G2c}4?`h=s&g;%UV7wE1ALN*d`CG8i>Hc4<`j^q? +zI9im5dI#S#jk=3oACt+y>~F#Pb^OITtE0^~@ftXAWA1f)lXzXKHV1g6jw^|mOBfw5 +zT5s{uPvm&(u_?Tct@m3UfiFGr*>8VX9sP6MFR4CbsI54xza;9o&kO_Ijf9DdcTeI +z%!(fcTUU;rLzOS6>Xt{-hh+Bz4-ltIr+6Xu_`q+b5hs^08byw@_?X*BjkfBXvb}ek +z;nha@w2DH~Jo5HUvuXw6-)%BDg2k^1R&{MB5 +ztZ>x7t;lwbq2x#cEAN&U_BVa~KGM6X)bvr@o1l-Pe!cU8{d*I=4%Uq?Tgm!pEpfWs +z9u(k&kASn5IJt!BqxC-gxVUcxe!b2qOdqXpE;T*^eDqO+U!dyWk#gW@QMhra;F>Od +z=?_-Luw;lO>q)My*=u`kxpIUK19?uS0&-;*Cv)s63m+*Bvy{Y+C0Lg4zc +z^T+gOc<;vGXROYsx72xXE7eZv>dcUgEAeOg@UhMVFM9$5pzqg?^IhyXM=7(BGkwtgm~F1){O)BQl}H1 +zR`oBVQ#e`_p;OTNDF0YHe}0)6YfbpQIQ?6@==bMu&FxsblQ>;UiUXWd!#jzSOPI0N +zVS&YW@Vlpay%#xkXb$#Wtfv>%hsWBizm}P?27IaEtYd?Heaz{Q8@MX_RjM{m6)N(_YTP#NXNl-y=7N|BkQb;c7Gg20rHBN9p>V-)h5-D!)(Z-S=UM}U8RS@`wowOuYSeH8fc5#aB>Rn@;E)sLe^5t>RL@z1~S +zKI{TB|86qB8?1Z;e1BQ0^7;QX|BiOO!03#6OPym4s-42jzn}8qJ4?}bl^3C14iJ9W +z`S;u9HD>+|e5rGfjY`NW5}2b!5jy{n^Y2so*O;*!UySxh>?gA~seg--?O4t<|DH#j +zE+x$YPO0(Z#K|ShSpFmlKIV1Mxa0wqQ}TgE#9D(G{mEW2gMtgs3F-&dn6Yf@udX-1 +zf9ZD$fX6XMi=y#U-AnuD-}QrP%={aD3iEHn_lU}e=fUab!tmQ{=HGuJUYGDVz$BE2tUYJY+y1ftkZy}Ys~x`_;M^>Jt*Hhzl +zA5y(sdY=RJk~$xMx@xC%b)t_a)%nzBi*M%(iJp56;Rn%q29r_YcAYnTf*Fs%mpVWG +zbg=bTd2RKN$1l&BV8^4GD>?>q~qk{ +vF$&oa_WAL}JRLsM{~486a#JHvJzjwC*Qv*7s}t@6q)rz-7fdJr{{{Mgzv_Nq + +literal 0 +HcmV?d00001 + +diff --git a/tests/egis_etu905/custom.py b/tests/egis_etu905/custom.py +new file mode 100644 +index 00000000..a842f26e +--- /dev/null ++++ b/tests/egis_etu905/custom.py +@@ -0,0 +1,109 @@ ++#!/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() == "egis_etu905" ++assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) ++assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) ++assert d.has_feature(FPrint.DeviceFeature.VERIFY) ++assert d.has_feature(FPrint.DeviceFeature.STORAGE) ++assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST) ++assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE) ++assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) ++ ++d.open_sync() ++ ++def enroll_progress(*args): ++ assert d.get_finger_status() == FPrint.FingerStatusFlags.PRESENT ++ print("enroll progress stage: " + str(args[1])) ++ ++def identify_done(dev, res): ++ global identified ++ identified = True ++ identify_match, identify_print = dev.identify_finish(res) ++ print("MATCH FOUND!" if identify_match else "NO MATCH FOUND") ++ assert identify_match.equal(identify_print) ++ ++# List ++print("--- LISTING ---") ++stored = d.list_prints_sync() ++prints1 = len(stored) ++print(f"--- LIST DONE: Found {prints1} prints before enroll---") ++ ++# Enroll ++print("--- ENROLLING ---") ++template = FPrint.Print.new(d) ++ ++assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE ++p = d.enroll_sync(template, None, enroll_progress, None) ++assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE ++print("--- ENROLL DONE ---") ++del template ++ ++# List ++print("--- LISTING ---") ++stored = d.list_prints_sync() ++prints2 = len(stored) ++print(f"--- LIST DONE: Found {prints2} prints after enroll---") ++assert (prints2 - prints1) == 1 ++ ++# Verify ++print("--- VERIFYING ---") ++assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE ++verify_res, verify_print = d.verify_sync(p) ++assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE ++print(f"--- VERIFY DONE: Result {verify_res} ---") ++ ++# Identify ++print("--- ASYNC IDENTIFYING ---") ++identified = False ++deserialized_prints = [] ++for p in stored: ++ deserialized_prints.append(FPrint.Print.deserialize(p.serialize())) ++ assert deserialized_prints[-1].equal(p) ++ ++d.identify(deserialized_prints, callback=identify_done) ++del deserialized_prints ++ ++while not identified: ++ ctx.iteration(True) ++print("--- IDENTIFY DONE ---") ++ ++# Delete ++print("--- DELETING ---") ++p_to_delete = next((sp for sp in stored if sp.equal(p)), None) ++if p_to_delete: ++ d.delete_print_sync(p_to_delete) ++ print("--- DELETE DONE ---") ++del p_to_delete ++del p ++ ++# List ++print("--- LISTING ---") ++stored = d.list_prints_sync() ++prints3 = len(stored) ++print(f"--- LIST DONE: Found {prints3} prints after deleting---") ++assert (prints2 - prints3) == 1 ++del stored ++ ++d.close_sync() ++ ++del d ++del c +diff --git a/tests/egis_etu905/device b/tests/egis_etu905/device +new file mode 100644 +index 00000000..4b750a79 +--- /dev/null ++++ b/tests/egis_etu905/device +@@ -0,0 +1,348 @@ ++P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3/3-3 ++N: bus/usb/003/002=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001 ++E: BUSNUM=003 ++E: DEVNAME=/dev/bus/usb/003/002 ++E: DEVNUM=002 ++E: DEVTYPE=usb_device ++E: DRIVER=usb ++E: ID_BUS=usb ++E: ID_MODEL=ETU905Axx-E ++E: ID_MODEL_ENC=ETU905Axx-E ++E: ID_MODEL_ID=05ae ++E: ID_PATH=pci-0000:05:00.4-usb-0:3 ++E: ID_PATH_TAG=pci-0000_05_00_4-usb-0_3 ++E: ID_PATH_WITH_USB_REVISION=pci-0000:05:00.4-usbv2-0:3 ++E: ID_REVISION=5342 ++E: ID_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357 ++E: ID_SERIAL_SHORT=0A8606PNA357 ++E: ID_USB_INTERFACES=:ffffff: ++E: ID_USB_MODEL=ETU905Axx-E ++E: ID_USB_MODEL_ENC=ETU905Axx-E ++E: ID_USB_MODEL_ID=05ae ++E: ID_USB_REVISION=5342 ++E: ID_USB_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357 ++E: ID_USB_SERIAL_SHORT=0A8606PNA357 ++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=257 ++E: PRODUCT=1c7a/5ae/5342 ++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=5342\n ++A: bmAttributes=a0\n ++A: busnum=3\n ++A: configuration= ++H: descriptors=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001 ++A: dev=189:257\n ++A: devnum=2\n ++A: devpath=3\n ++L: driver=../../../../../../bus/usb/drivers/usb ++L: firmware_node=../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/device:1b/device:1c/device:1f ++A: idProduct=05ae\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-port3 ++A: power/active_duration=93136758\n ++A: power/async=enabled\n ++A: power/autosuspend=2\n ++A: power/autosuspend_delay_ms=2000\n ++A: power/connected_duration=93139621\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=93138826\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=ETU905Axx-E\n ++A: quirks=0x0\n ++A: removable=fixed\n ++A: rx_lanes=1\n ++A: serial=0A8606PNA357\n ++A: speed=12\n ++A: tx_lanes=1\n ++A: urbnum=5855\n ++A: version= 2.00\n ++ ++P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3 ++N: bus/usb/003/001=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C ++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_05_00_4 ++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:05:00.4 ++E: ID_PATH_TAG=pci-0000_05_00_4 ++E: ID_REVISION=0614 ++E: ID_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4 ++E: ID_SERIAL_SHORT=0000:05:00.4 ++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=0614 ++E: ID_USB_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4 ++E: ID_USB_SERIAL_SHORT=0000:05:00.4 ++E: ID_USB_VENDOR=Linux_6.14.0-37-generic_xhci-hcd ++E: ID_USB_VENDOR_ENC=Linux\x206.14.0-37-generic\x20xhci-hcd ++E: ID_USB_VENDOR_ID=1d6b ++E: ID_VENDOR=Linux_6.14.0-37-generic_xhci-hcd ++E: ID_VENDOR_ENC=Linux\x206.14.0-37-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/614 ++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=0614\n ++A: bmAttributes=e0\n ++A: busnum=3\n ++A: configuration= ++H: descriptors=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C ++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:0c/device:1b/device:1c ++A: idProduct=0002\n ++A: idVendor=1d6b\n ++A: interface_authorized_default=1\n ++A: ltm_capable=no\n ++A: manufacturer=Linux 6.14.0-37-generic xhci-hcd\n ++A: maxchild=4\n ++A: power/active_duration=93137993\n ++A: power/async=enabled\n ++A: power/autosuspend=0\n ++A: power/autosuspend_delay_ms=0\n ++A: power/connected_duration=93139758\n ++A: power/control=auto\n ++A: power/level=auto\n ++A: power/runtime_active_kids=1\n ++A: power/runtime_active_time=93139206\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:05:00.4\n ++A: speed=480\n ++A: tx_lanes=1\n ++A: urbnum=989\n ++A: version= 2.00\n ++ ++P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4 ++E: DRIVER=xhci_hcd ++E: ID_MODEL_FROM_DATABASE=Renoir/Cezanne USB 3.1 ++E: ID_PATH=pci-0000:05:00.4 ++E: ID_PATH_TAG=pci-0000_05_00_4 ++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=Advanced Micro Devices, Inc. [AMD] ++E: MODALIAS=pci:v00001022d00001639sv000017AAsd0000382Fbc0Csc03i30 ++E: PCI_CLASS=C0330 ++E: PCI_ID=1022:1639 ++E: PCI_SLOT_NAME=0000:05:00.4 ++E: PCI_SUBSYS_ID=17AA:382F ++E: SUBSYSTEM=pci ++A: ari_enabled=0\n ++A: broken_parity_status=0\n ++A: class=0x0c0330\n ++H: config=22103916070410000030030C10008000040040D0000000000000000000000000000000000000000000000000AA172F38000000004800000000000000FF010000000000000000000009500800AA172F38016403C80000000000000000000000003120000010A00200A18F000010290000030D400040000311000000000000000000000000000000001F007100000000001E00800100000100000000000000000005C08600000000000000000000000000000000000000000000000000000000001100078000E00F0000F00F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B00012A010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ++A: consistent_dma_mask_bits=64\n ++A: current_link_speed=8.0 GT/s PCIe\n ++A: current_link_width=16\n ++A: d3cold_allowed=1\n ++A: dbc=disabled\n ++A: dbc_bInterfaceProtocol=01\n ++A: dbc_bcdDevice=0010\n ++A: dbc_idProduct=0010\n ++A: dbc_idVendor=1d6b\n ++A: dbc_poll_interval_ms=64\n ++A: device=0x1639\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:0c/device:1b ++L: iommu=../../0000:00:00.2/iommu/ivhd0 ++L: iommu_group=../../../../kernel/iommu_groups/20 ++A: irq=44\n ++A: link/l0s_aspm=0\n ++A: link/l1_aspm=0\n ++A: local_cpulist=0-11\n ++A: local_cpus=fff\n ++A: max_link_speed=8.0 GT/s PCIe\n ++A: max_link_width=16\n ++A: modalias=pci:v00001022d00001639sv000017AAsd0000382Fbc0Csc03i30\n ++A: msi_bus=1\n ++A: msi_irqs/45=msix\n ++A: msi_irqs/46=msix\n ++A: msi_irqs/47=msix\n ++A: msi_irqs/48=msix\n ++A: msi_irqs/49=msix\n ++A: msi_irqs/50=msix\n ++A: msi_irqs/51=msix\n ++A: msi_irqs/52=msix\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 4 5 2112 5\nxHCI ring segments 23 23 4096 23\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n ++A: power/async=enabled\n ++A: power/control=on\n ++A: power/runtime_active_kids=1\n ++A: power/runtime_active_time=93139523\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: reset_method=pm\n ++A: resource=0x00000000d0400000 0x00000000d04fffff 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=0x00\n ++A: subsystem_device=0x382f\n ++A: subsystem_vendor=0x17aa\n ++A: vendor=0x1022\n ++ ++P: /devices/pci0000:00/0000:00:08.1 ++E: DRIVER=pcieport ++E: ID_MODEL_FROM_DATABASE=Renoir Internal PCIe GPP Bridge to Bus ++E: ID_PATH=pci-0000:00:08.1 ++E: ID_PATH_TAG=pci-0000_00_08_1 ++E: ID_PCI_CLASS_FROM_DATABASE=Bridge ++E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode ++E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge ++E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD] ++E: MODALIAS=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00 ++E: PCI_CLASS=60400 ++E: PCI_ID=1022:1635 ++E: PCI_SLOT_NAME=0000:00:08.1 ++E: PCI_SUBSYS_ID=1022:1635 ++E: SUBSYSTEM=pci ++A: ari_enabled=0\n ++A: broken_parity_status=0\n ++A: class=0x060400\n ++H: config=221035160704100000000406100081000000000000000000000505001111000030D060D001E011F0FC000000FC000000000000005000000000000000FF01020000000000000000000000000000000000015803C80000000010A042002280000010290000030D7000400C03310000000000004000180001000000000000003100000000001E00800143001F00000000000000000000000000000000000000000005C081000000E0FE0000000000000000000000000000000000000000000000000D00000022103516000000000000000000000000000000000000000000000000000000007CA006000000000000000000000000000000000000000000000000000B000127010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900012A00000000000000007F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F000000000D0001405F001D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250001410100008001000080000000002600014400000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2700010000000000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ++A: consistent_dma_mask_bits=32\n ++A: current_link_speed=8.0 GT/s PCIe\n ++A: current_link_width=16\n ++A: d3cold_allowed=1\n ++A: device=0x1635\n ++A: dma_mask_bits=32\n ++L: driver=../../../bus/pci/drivers/pcieport ++A: driver_override=(null)\n ++A: enable=2\n ++L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c ++L: iommu=../0000:00:00.2/iommu/ivhd0 ++L: iommu_group=../../../kernel/iommu_groups/8 ++A: irq=33\n ++A: local_cpulist=0-11\n ++A: local_cpus=fff\n ++A: max_link_speed=8.0 GT/s PCIe\n ++A: max_link_width=16\n ++A: modalias=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00\n ++A: msi_bus=1\n ++A: msi_irqs/33=msi\n ++A: numa_node=-1\n ++A: power/async=enabled\n ++A: power/autosuspend_delay_ms=100\n ++A: power/control=auto\n ++A: power/runtime_active_kids=5\n ++A: power/runtime_active_time=93139537\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: power_state=D0\n ++A: reset_method=pm\n ++A: resource=0x0000000000000000 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\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000001000 0x0000000000001fff 0x0000000000000101\n0x00000000d0300000 0x00000000d06fffff 0x0000000000000200\n0x000000fce0000000 0x000000fcf01fffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n ++A: revision=0x00\n ++A: secondary_bus_number=5\n ++A: subordinate_bus_number=5\n ++A: subsystem_device=0x1635\n ++A: subsystem_vendor=0x1022\n ++A: vendor=0x1022\n ++ +diff --git a/tests/meson.build b/tests/meson.build +index 07c924be..b6e8bf95 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -52,6 +52,7 @@ drivers_tests = [ + 'nb1010', + 'egis0570', + 'egismoc', ++ 'egis_etu905', + 'egismoc-05a1', + 'egismoc-0586', + 'egismoc-0587', +-- +GitLab + + +From c216f04dd1fd1cfe21a71d26bf6e17fc1a37983a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 9 Jun 2026 14:19:17 +0200 +Subject: [PATCH 02/13] egis_etu905: Do not leak the transfer buffer + +The buffer is now owned by the data, so we should not steal it when +passing it around or we'll leak. +--- + libfprint/drivers/egismoc/egis_etu905.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index be0c6e05..f91f0472 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -207,7 +207,8 @@ egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } +- if (data == NULL || transfer->actual_length < egis_etu905_read_prefix_len) ++ ++ if (transfer->actual_length < egis_etu905_read_prefix_len) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); +@@ -216,6 +217,7 @@ egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, + + /* Store the response data and let the cmd_ssm_done callback invoke + * the actual callback with the stored data */ ++ g_assert (data != NULL); + data->buffer_in = g_steal_pointer (&transfer->buffer); + data->length_in = transfer->actual_length; + +@@ -282,7 +284,7 @@ egis_etu905_cmd_ssm_done (FpiSsm *ssm, + if (data && data->callback) + { + data->callback (device, +- g_steal_pointer (&data->buffer_in), ++ data->buffer_in, + data->length_in, + g_steal_pointer (&local_error)); + } +-- +GitLab + + +From fdbc9ee6558a54dc393a5dfa04f626be8393116c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 9 Jun 2026 13:51:28 +0200 +Subject: [PATCH 03/13] egis_etu905: Remove unused transfer + +--- + libfprint/drivers/egismoc/egis_etu905.c | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index f91f0472..0bb9a6ba 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -1445,8 +1445,6 @@ static void + egis_etu905_dev_init_handler (FpiSsm *ssm, + FpDevice *device) + { +- g_autoptr(FpiUsbTransfer) transfer = NULL; +- + switch (fpi_ssm_get_cur_state (ssm)) + { + case DEV_GET_FW_VERSION: +@@ -1462,15 +1460,6 @@ egis_etu905_dev_init_handler (FpiSsm *ssm, + default: + g_assert_not_reached (); + } +- +- transfer = fpi_usb_transfer_new (device); +- transfer->ssm = ssm; +- transfer->short_is_error = TRUE; +- fpi_usb_transfer_submit (g_steal_pointer (&transfer), +- EGIS_ETU905_USB_CONTROL_TIMEOUT, +- fpi_device_get_cancellable (device), +- fpi_ssm_usb_transfer_cb, +- NULL); + } + + static void +-- +GitLab + + +From f5806825de803a7becd02b49a3f4a6a8e32579ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 9 Jun 2026 13:56:02 +0200 +Subject: [PATCH 04/13] egis_etu905: Remove unused variable + +--- + libfprint/drivers/egismoc/egis_etu905.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 0bb9a6ba..3d52bf89 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -943,7 +943,6 @@ egis_etu905_get_check_cmd (FpDevice *device, + fp_dbg ("Get check command"); + FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); + g_auto(FpiByteWriter) writer = {0}; +- g_autofree guchar *result = NULL; + gboolean written = TRUE; + + /* +-- +GitLab + + +From 12af25d43b890077cc13a0597b772c9401ca6273 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:28:50 +0200 +Subject: [PATCH 05/13] egis_etu905: Set short error using function + +--- + libfprint/drivers/egismoc/egis_etu905.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 3d52bf89..4e58515c 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -97,7 +97,7 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, + EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH); + transfer->ssm = ssm; + /* Interrupt on this device always returns 1 byte short; this is expected */ +- transfer->short_is_error = FALSE; ++ fpi_usb_transfer_set_short_error (transfer, FALSE); + + fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED); + +@@ -382,7 +382,7 @@ egis_etu905_exec_cmd (FpDevice *device, + } + + transfer = fpi_usb_transfer_new (device); +- transfer->short_is_error = TRUE; ++ fpi_usb_transfer_set_short_error (transfer, TRUE); + transfer->ssm = self->cmd_ssm; + + fpi_usb_transfer_fill_bulk_full (transfer, +-- +GitLab + + +From 42f0b96c103195a6a7fa6b45258b72e393c90793 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:31:58 +0200 +Subject: [PATCH 06/13] egis_etu905: Rely on default device cancellable for all + the actions + +I don't see a reason why we should rely on a different cancellable for +interrupts, but happy to learn more about this +--- + libfprint/drivers/egismoc/egis_etu905.c | 33 +------------------------ + 1 file changed, 1 insertion(+), 32 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 4e58515c..3c1dcf73 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -33,7 +33,6 @@ struct _FpiDeviceEgisEtu905 + FpiSsm *task_ssm; + FpiSsm *cmd_ssm; + FpiUsbTransfer *cmd_transfer; +- GCancellable *interrupt_cancellable; + GPtrArray *enrolled_ids; + gint max_enroll_stages; + guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; +@@ -89,8 +88,6 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, + FpDevice *device) + { + fp_dbg ("Wait for finger on sensor"); +- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); +- + g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); + + fpi_usb_transfer_fill_interrupt (transfer, EGIS_ETU905_EP_CMD_INTERRUPT_IN, +@@ -103,7 +100,7 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, + + fpi_usb_transfer_submit (g_steal_pointer (&transfer), + EGIS_ETU905_USB_INTERRUPT_TIMEOUT, +- self->interrupt_cancellable, ++ fpi_device_get_cancellable (device), + egis_etu905_finger_on_sensor_cb, + NULL); + } +@@ -1551,37 +1548,11 @@ egis_etu905_open (FpDevice *device) + fpi_ssm_start (self->task_ssm, egis_etu905_dev_init_done); + } + +-static void +-egis_etu905_cancel (FpDevice *device) +-{ +- fp_dbg ("Cancel"); +- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); +- +- g_cancellable_cancel (self->interrupt_cancellable); +- g_clear_object (&self->interrupt_cancellable); +- self->interrupt_cancellable = g_cancellable_new (); +-} +- +-static void +-egis_etu905_suspend (FpDevice *device) +-{ +- fp_dbg ("Suspend"); +- +- egis_etu905_cancel (device); +- g_cancellable_cancel (fpi_device_get_cancellable (device)); +- fpi_device_suspend_complete (device, NULL); +-} +- + static void + egis_etu905_close (FpDevice *device) + { + g_autoptr(GError) error = NULL; + fp_dbg ("Closing device"); +- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); +- GError *error = NULL; +- +- egis_etu905_cancel (device); +- g_clear_object (&self->interrupt_cancellable); + + g_usb_device_release_interface (fpi_device_get_usb_device (device), + 0, 0, &error); +@@ -1610,8 +1581,6 @@ fpi_device_egis_etu905_class_init (FpiDeviceEgisEtu905Class *klass) + + dev_class->probe = egis_etu905_probe; + dev_class->open = egis_etu905_open; +- dev_class->cancel = egis_etu905_cancel; +- dev_class->suspend = egis_etu905_suspend; + dev_class->close = egis_etu905_close; + dev_class->identify = egis_etu905_identify_verify; + dev_class->verify = egis_etu905_identify_verify; +-- +GitLab + + +From 4b8f46f1f9ce3d2b2ce96d0b87fdb464f9e67abe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:32:51 +0200 +Subject: [PATCH 07/13] egis_etu905: Use fpi-bytes-reader to get the firmware + string + +--- + libfprint/drivers/egismoc/egis_etu905.c | 37 +++++++++++++++++++------ + 1 file changed, 29 insertions(+), 8 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 3c1dcf73..c4d4093d 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -1348,12 +1348,14 @@ egis_etu905_fw_version_cb (FpDevice *device, + gsize length_in, + GError *error) + { +- fp_dbg ("Firmware version callback"); + FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); +- g_autofree gchar *fw_version = NULL; +- gsize prefix_length; +- guchar *fw_version_start; ++ FpiByteReader reader; ++ const guint8 *fw_version_data = NULL; ++ const guint prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; + gsize fw_version_length; ++ g_autofree gchar *fw_version = NULL; ++ ++ fp_dbg ("Firmware version callback"); + + if (error) + { +@@ -1380,10 +1382,29 @@ egis_etu905_fw_version_cb (FpDevice *device, + * come with every payload Then we will also skip the carriage return and take + * all but the last 2 bytes as the FW Version + */ +- prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; +- fw_version_start = buffer_in + prefix_length; +- fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len; +- fw_version = g_strndup ((gchar *) fw_version_start, fw_version_length); ++ fpi_byte_reader_init (&reader, buffer_in, length_in); ++ ++ if (!fpi_byte_reader_set_pos (&reader, prefix_length)) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Device firmware response " ++ "too short for prefix.")); ++ return; ++ } ++ ++ fw_version_length = fpi_byte_reader_get_remaining (&reader) - rsp_fw_version_suffix_len; ++ ++ if (!fpi_byte_reader_get_data (&reader, fw_version_length, &fw_version_data)) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Device firmware response " ++ "too short for version string.")); ++ return; ++ } ++ ++ fw_version = g_strndup ((gchar *) fw_version_data, fw_version_length); + + fp_info ("Device firmware version is %s", fw_version); + +-- +GitLab + + +From c6f9f094afec2a1bf53e6a6132dbde130650b9ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:39:34 +0200 +Subject: [PATCH 08/13] egis_etu905: drop unused sid field + +We read it but we never use it +--- + libfprint/drivers/egismoc/egis_etu905.c | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index c4d4093d..418b43a3 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -35,7 +35,6 @@ struct _FpiDeviceEgisEtu905 + FpiUsbTransfer *cmd_transfer; + GPtrArray *enrolled_ids; + gint max_enroll_stages; +- guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; + }; + + G_DEFINE_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FP_TYPE_DEVICE); +@@ -911,20 +910,6 @@ egis_etu905_enroll_begin_cb (FpDevice *device, + return; + } + +- FpiByteReader reader; +- +- fpi_byte_reader_init (&reader, buffer_in, length_in); +- +- fpi_byte_reader_set_pos (&reader, EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE); +- +- const guint8 *data = NULL; +- +- fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, +- &data); +- +- if (data) +- memcpy (self->sid, data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); +- + fpi_ssm_next_state (self->task_ssm); + } + +-- +GitLab + + +From 65c3dcb1eb35ec0bd14b17bedf33de6c621f9ef3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:44:13 +0200 +Subject: [PATCH 09/13] egis_etu905: Avoid potential wrong memory accesses + +--- + libfprint/drivers/egismoc/egis_etu905.c | 53 ++++++++++++++++++------- + 1 file changed, 38 insertions(+), 15 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 418b43a3..c9b9ab3a 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -110,11 +110,21 @@ egis_etu905_validate_response_prefix (const guchar *buffer_in, + const guchar *valid_prefix, + const gsize valid_prefix_len) + { +- const gboolean result = memcmp (buffer_in + +- (egis_etu905_read_prefix_len + +- EGIS_ETU905_CHECK_BYTES_LENGTH), +- valid_prefix, +- valid_prefix_len) == 0; ++ FpiByteReader reader; ++ const guint8 *data = NULL; ++ gboolean result; ++ ++ fpi_byte_reader_init (&reader, buffer_in, buffer_in_len); ++ ++ if (!fpi_byte_reader_set_pos (&reader, egis_etu905_read_prefix_len + ++ EGIS_ETU905_CHECK_BYTES_LENGTH) || ++ !fpi_byte_reader_get_data (&reader, valid_prefix_len, &data)) ++ { ++ fp_dbg ("Response too short for prefix validation"); ++ return FALSE; ++ } ++ ++ result = memcmp (data, valid_prefix, valid_prefix_len) == 0; + + fp_dbg ("Response prefix valid: %s", result ? "yes" : "NO"); + return result; +@@ -126,9 +136,22 @@ egis_etu905_validate_response_suffix (const guchar *buffer_in, + const guchar *valid_suffix, + const gsize valid_suffix_len) + { +- const gboolean result = memcmp (buffer_in + (buffer_in_len - valid_suffix_len), +- valid_suffix, +- valid_suffix_len) == 0; ++ FpiByteReader reader; ++ const guint8 *data = NULL; ++ gboolean result; ++ ++ fpi_byte_reader_init (&reader, buffer_in, buffer_in_len); ++ ++ /* Guard against unsigned underflow before computing the suffix position. */ ++ if (valid_suffix_len > buffer_in_len || ++ !fpi_byte_reader_set_pos (&reader, buffer_in_len - valid_suffix_len) || ++ !fpi_byte_reader_get_data (&reader, valid_suffix_len, &data)) ++ { ++ fp_dbg ("Response too short for suffix validation"); ++ return FALSE; ++ } ++ ++ result = memcmp (data, valid_suffix, valid_suffix_len) == 0; + + fp_dbg ("Response suffix valid: %s", result ? "yes" : "NO"); + return result; +@@ -1467,10 +1490,10 @@ egis_etu905_dev_init_handler (FpiSsm *ssm, + static void + egis_etu905_probe (FpDevice *device) + { +- GUsbDevice *usb_dev; +- GError *error = NULL; ++ g_autoptr(GError) error = NULL; + g_autofree gchar *serial = NULL; + FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); ++ GUsbDevice *usb_dev; + + fp_dbg ("%s enter --> ", G_STRFUNC); + +@@ -1479,7 +1502,7 @@ egis_etu905_probe (FpDevice *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); ++ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); + return; + } + +@@ -1487,7 +1510,7 @@ egis_etu905_probe (FpDevice *device) + { + 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); ++ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); + return; + } + +@@ -1495,7 +1518,7 @@ egis_etu905_probe (FpDevice *device) + { + 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); ++ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); + return; + } + +@@ -1512,7 +1535,7 @@ egis_etu905_probe (FpDevice *device) + 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); ++ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); + return; + } + +@@ -1526,7 +1549,7 @@ egis_etu905_probe (FpDevice *device) + 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); ++ fpi_device_probe_complete (device, serial, NULL, NULL); + } + + static void +-- +GitLab + + +From 5b51f9c8ccf33424636e4e32cb6205204e816940 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:47:41 +0200 +Subject: [PATCH 10/13] egis_etu905: Sanitize print data parsing + +--- + libfprint/drivers/egismoc/egis_etu905.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index c9b9ab3a..0a5655f1 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -318,7 +318,7 @@ static guint16 + egis_etu905_get_check_bytes (FpiByteReader *reader) + { + fp_dbg ("Get check bytes"); +- size_t sum_values = 0; ++ guint64 sum_values = 0; + guint16 val; + + fpi_byte_reader_set_pos (reader, 0); +@@ -562,8 +562,6 @@ egis_etu905_get_delete_cmd (FpDevice *device, + const guchar *print_data_id = NULL; + gsize print_data_id_len = 0; + g_autofree gchar *print_description = NULL; +- g_autofree guchar *enrolled_print_id = NULL; +- g_autofree guchar *result = NULL; + gboolean written = TRUE; + + /* +@@ -639,7 +637,8 @@ egis_etu905_get_delete_cmd (FpDevice *device, + g_object_get (delete_print, "description", &print_description, NULL); + g_object_get (delete_print, "fpi-data", &print_data, NULL); + +- if (!g_variant_check_format_string (print_data, "(@ay)", FALSE)) ++ if (!print_data || ++ !g_variant_check_format_string (print_data, "(@ay)", FALSE)) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); +@@ -650,11 +649,21 @@ egis_etu905_get_delete_cmd (FpDevice *device, + print_data_id = g_variant_get_fixed_array (print_data_id_var, + &print_data_id_len, sizeof (guchar)); + +- if (!g_str_has_prefix (print_description, "FP")) ++ if (print_data_id_len != EGIS_ETU905_FINGERPRINT_DATA_SIZE) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, ++ "Stored print id has " ++ "unexpected length %zu", ++ print_data_id_len)); ++ return NULL; ++ } ++ ++ if (!print_description || !g_str_has_prefix (print_description, "FP")) + fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.", +- print_description); ++ print_description ? print_description : "(null)"); + +- fp_info ("Delete fingerprint %s", print_description); ++ fp_info ("Delete fingerprint %s", print_description ? print_description : "(null)"); + + written &= fpi_byte_writer_put_data (&writer, print_data_id, + EGIS_ETU905_FINGERPRINT_DATA_SIZE); +-- +GitLab + + +From c0a98110531e74beb5876ef084da3ed8901128c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 13:48:00 +0200 +Subject: [PATCH 11/13] egis_etu905: Do not try to continue a failed SSM + +--- + libfprint/drivers/egismoc/egis_etu905.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 0a5655f1..d45b46e2 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -755,6 +755,10 @@ egis_etu905_delete_run_state (FpiSsm *ssm, + else + payload = egis_etu905_get_delete_cmd (device, NULL, &payload_length); + ++ /* get_delete_cmd already marked task_ssm as failed */ ++ if (!payload) ++ return; ++ + egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, + g_free, egis_etu905_delete_cb); + break; +-- +GitLab + + +From 06ad44bc1da732598f82a7c11eb0bbc29850ac13 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Mon, 8 Jun 2026 15:19:54 +0200 +Subject: [PATCH 12/13] egis_etu905: Improve the identify callback data reading + +--- + libfprint/drivers/egismoc/egis_etu905.c | 41 ++++++++++++++----------- + 1 file changed, 23 insertions(+), 18 deletions(-) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index d45b46e2..7de306b4 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -496,11 +496,10 @@ egis_etu905_list_fill_enrolled_ids_cb (FpDevice *device, + */ + while (read) + { +- const guint8 *data; ++ const guint8 data[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; + g_autofree gchar *print_id = NULL; + +- read &= fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, +- &data); ++ read &= fpi_byte_reader_get_data_static (&reader, data); + if (!read) + break; + +@@ -1182,15 +1181,16 @@ egis_etu905_identify_check_cb (FpDevice *device, + gsize length_in, + GError *error) + { +- fp_dbg ("Identify check callback"); + FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); +- gchar device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; ++ guint8 device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; + FpPrint *print = NULL; + FpPrint *verify_print = NULL; + GPtrArray *prints; + gboolean found = FALSE; + guint index; + ++ fp_dbg ("Identify check callback"); ++ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); +@@ -1203,29 +1203,34 @@ egis_etu905_identify_check_cb (FpDevice *device, + rsp_identify_match_suffix, + rsp_identify_match_suffix_len)) + { ++ FpiByteReader reader; ++ + /* + On success, there is a 32 byte array of "something"(?) in chars 14-45 + and then the 32 byte array ID of the matched print comes as chars 46-77 + */ +- memcpy (device_print_id, +- buffer_in + EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET, +- EGIS_ETU905_FINGERPRINT_DATA_SIZE); +- +- /* Create a new print from this device_print_id and then see if it matches +- * the one indicated +- */ +- print = fp_print_new (device); +- egis_etu905_set_print_data (print, device_print_id, NULL); ++ fpi_byte_reader_init (&reader, buffer_in, length_in); + +- if (!print) ++ if (!fpi_byte_reader_set_pos (&reader, ++ EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET) || ++ !fpi_byte_reader_get_data_static (&reader, device_print_id)) + { + fpi_ssm_mark_failed (self->task_ssm, +- fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, +- "Failed to build a print from " +- "device response.")); ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Identify response too " ++ "short for matched print " ++ "id.")); + return; + } + ++ fp_dbg ("Device-reported matched print id: %s", device_print_id); ++ ++ /* Create a new print from this device_print_id and then see if it matches ++ * the one indicated ++ */ ++ print = fp_print_new (device); ++ egis_etu905_set_print_data (print, (const char *) device_print_id, NULL); ++ + fp_info ("Identify successful for: %s", fp_print_get_description (print)); + + if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) +-- +GitLab + + +From 6a71e039a12ead2b3120ad4789b93a44193045ec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 9 Jun 2026 13:56:24 +0200 +Subject: [PATCH 13/13] egis_etu905: Double-check that the identified ID is + part of the enrolled list + +--- + libfprint/drivers/egismoc/egis_etu905.c | 27 +++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c +index 7de306b4..dcd71ff6 100644 +--- a/libfprint/drivers/egismoc/egis_etu905.c ++++ b/libfprint/drivers/egismoc/egis_etu905.c +@@ -1203,6 +1203,7 @@ egis_etu905_identify_check_cb (FpDevice *device, + rsp_identify_match_suffix, + rsp_identify_match_suffix_len)) + { ++ gboolean id_known = FALSE; + FpiByteReader reader; + + /* +@@ -1225,6 +1226,32 @@ egis_etu905_identify_check_cb (FpDevice *device, + + fp_dbg ("Device-reported matched print id: %s", device_print_id); + ++ /* While the returned ID should indeed be part of the enrolled list, since ++ * we got it, let's double check that this is really the case. ++ */ ++ if (self->enrolled_ids) ++ { ++ for (guint i = 0; i < self->enrolled_ids->len; i++) ++ { ++ if (memcmp (g_ptr_array_index (self->enrolled_ids, i), ++ device_print_id, ++ EGIS_ETU905_FINGERPRINT_DATA_SIZE) == 0) ++ { ++ id_known = TRUE; ++ break; ++ } ++ } ++ } ++ ++ if (!id_known) ++ { ++ fpi_ssm_mark_failed (self->task_ssm, ++ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, ++ "Device reported a match " ++ "for an unknown print id.")); ++ return; ++ } ++ + /* Create a new print from this device_print_id and then see if it matches + * the one indicated + */ +-- +GitLab + diff --git a/libfprint.spec b/libfprint.spec index fbffea7..96a9cb2 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -14,6 +14,17 @@ Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{ # Backport from upstream Patch00001: https://gitlab.freedesktop.org/libfprint/libfprint/-/commit/2c7842c905147a2d127c1b168b2e9d43.patch +# the updates for the fpi +Patch10001: 0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch +Patch10002: 0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch +Patch10003: 0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch +Patch10004: 0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch +Patch10005: 0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch +Patch10006: 0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch +# Add EGIS readers +# https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/561 +Patch10007: egis_reader.patch + BuildRequires: meson BuildRequires: gcc BuildRequires: gcc-c++ From 92d8aa1d4a5a756f8090cccf1fe903c025f7225f Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 26 Jun 2026 19:38:40 +0100 Subject: [PATCH 51/53] Remove gating.yaml, it's broken It specifies only one test, which has not existed for many years (dist.depcheck). --- gating.yaml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 gating.yaml diff --git a/gating.yaml b/gating.yaml deleted file mode 100644 index d71584a..0000000 --- a/gating.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- !Policy -product_versions: - - fedora-* -decision_context: bodhi_update_push_testing -rules: - - !PassingTestCaseRule {test_case_name: dist.depcheck} From 295ed643cf9a494dca3ac230274851bedbd18b3d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jul 2026 06:00:57 +0000 Subject: [PATCH 52/53] Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild From 7b457eea05c9d5c73a6ed3bd3325eac52374c2f9 Mon Sep 17 00:00:00 2001 From: Kate Hsuan Date: Tue, 11 Aug 2026 11:43:43 +0800 Subject: [PATCH 53/53] Update to the upstream version 1.94.100 (rhbz#2506519) Update to the upstream version 1.94.100. --- .gitignore | 1 + ...ry-buffer-I-O-section-for-the-byte-r.patch | 162 - ...ter-Add-APIs-to-write-and-get-GBytes.patch | 145 - ...Add-support-to-read-and-get-peek-GBy.patch | 187 - ...Add-support-to-read-to-a-static-buff.patch | 160 - ...-Add-missing-definition-of-set_short.patch | 42 - ...-transfer-Wrap-g_error_new-arguments.patch | 26 - 2c7842c905147a2d127c1b168b2e9d43.patch | 42 - egis_reader.patch | 3304 ----------------- libfprint.spec | 16 +- sources | 2 +- 11 files changed, 3 insertions(+), 4084 deletions(-) delete mode 100644 0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch delete mode 100644 0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch delete mode 100644 0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch delete mode 100644 0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch delete mode 100644 0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch delete mode 100644 0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch delete mode 100644 2c7842c905147a2d127c1b168b2e9d43.patch delete mode 100644 egis_reader.patch diff --git a/.gitignore b/.gitignore index dc47fc4..5848b6a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ libfprint-0.3.0.tar.bz2 /libfprint-v1.94.8.tar.gz /libfprint-v1.94.9.tar.gz /libfprint-v1.94.10.tar.gz +/libfprint-v1.94.100.tar.gz diff --git a/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch b/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch deleted file mode 100644 index 0df0565..0000000 --- a/0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 9c140036e9c4d173a19b8e3d6187526d68fbd97c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Sat, 21 Feb 2026 05:40:56 +0100 -Subject: [PATCH 1/6] doc: Include Binary buffer I/O section for the byte - reader/writer - ---- - doc/libfprint-2-sections.txt | 120 +++++++++++++++++++++++++++++++++++ - doc/libfprint-docs.xml | 6 ++ - 2 files changed, 126 insertions(+) - -diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt -index 0fb0cfa..9f3804f 100644 ---- a/doc/libfprint-2-sections.txt -+++ b/doc/libfprint-2-sections.txt -@@ -134,6 +134,126 @@ fpi_line_asmbl_ctx - fpi_assemble_lines -
- -+
-+fpi-byte-reader -+FpiByteReader -+FpiByteReader -+fpi_byte_reader_new -+fpi_byte_reader_free -+fpi_byte_reader_init -+fpi_byte_reader_peek_sub_reader -+fpi_byte_reader_get_sub_reader -+fpi_byte_reader_set_pos -+fpi_byte_reader_get_pos -+fpi_byte_reader_get_remaining -+fpi_byte_reader_get_size -+fpi_byte_reader_skip -+fpi_byte_reader_get_uint8 -+fpi_byte_reader_get_int8 -+fpi_byte_reader_peek_uint8 -+fpi_byte_reader_peek_int8 -+fpi_byte_reader_get_uint16_le -+fpi_byte_reader_get_int16_le -+fpi_byte_reader_peek_uint16_le -+fpi_byte_reader_peek_int16_le -+fpi_byte_reader_get_uint16_be -+fpi_byte_reader_get_int16_be -+fpi_byte_reader_peek_uint16_be -+fpi_byte_reader_peek_int16_be -+fpi_byte_reader_get_uint24_le -+fpi_byte_reader_get_int24_le -+fpi_byte_reader_peek_uint24_le -+fpi_byte_reader_peek_int24_le -+fpi_byte_reader_get_uint24_be -+fpi_byte_reader_get_int24_be -+fpi_byte_reader_peek_uint24_be -+fpi_byte_reader_peek_int24_be -+fpi_byte_reader_get_uint32_le -+fpi_byte_reader_get_int32_le -+fpi_byte_reader_peek_uint32_le -+fpi_byte_reader_peek_int32_le -+fpi_byte_reader_get_uint32_be -+fpi_byte_reader_get_int32_be -+fpi_byte_reader_peek_uint32_be -+fpi_byte_reader_peek_int32_be -+fpi_byte_reader_get_uint64_le -+fpi_byte_reader_get_int64_le -+fpi_byte_reader_peek_uint64_le -+fpi_byte_reader_peek_int64_le -+fpi_byte_reader_get_uint64_be -+fpi_byte_reader_get_int64_be -+fpi_byte_reader_peek_uint64_be -+fpi_byte_reader_peek_int64_be -+fpi_byte_reader_get_float32_le -+fpi_byte_reader_peek_float32_le -+fpi_byte_reader_get_float32_be -+fpi_byte_reader_peek_float32_be -+fpi_byte_reader_get_float64_le -+fpi_byte_reader_peek_float64_le -+fpi_byte_reader_get_float64_be -+fpi_byte_reader_peek_float64_be -+fpi_byte_reader_get_data -+fpi_byte_reader_peek_data -+fpi_byte_reader_dup_data -+fpi_byte_reader_masked_scan_uint32 -+fpi_byte_reader_masked_scan_uint32_peek -+fpi_byte_reader_skip_string -+fpi_byte_reader_skip_string_utf8 -+fpi_byte_reader_skip_string_utf16 -+fpi_byte_reader_skip_string_utf32 -+fpi_byte_reader_peek_string -+fpi_byte_reader_peek_string_utf8 -+fpi_byte_reader_get_string_utf8 -+fpi_byte_reader_dup_string_utf8 -+fpi_byte_reader_dup_string_utf16 -+fpi_byte_reader_dup_string_utf32 -+
-+ -+
-+fpi-byte-writer -+FpiByteWriter -+FpiByteWriter -+fpi_byte_writer_new -+fpi_byte_writer_new_with_size -+fpi_byte_writer_new_with_data -+fpi_byte_writer_init -+fpi_byte_writer_init_with_size -+fpi_byte_writer_init_with_data -+fpi_byte_writer_reset -+fpi_byte_writer_reset_and_get_data -+fpi_byte_writer_free -+fpi_byte_writer_free_and_get_data -+fpi_byte_writer_get_remaining -+fpi_byte_writer_ensure_free_space -+fpi_byte_writer_put_uint8 -+fpi_byte_writer_put_uint16_be -+fpi_byte_writer_put_uint24_be -+fpi_byte_writer_put_uint32_be -+fpi_byte_writer_put_uint64_be -+fpi_byte_writer_put_uint16_le -+fpi_byte_writer_put_uint24_le -+fpi_byte_writer_put_uint32_le -+fpi_byte_writer_put_uint64_le -+fpi_byte_writer_put_int8 -+fpi_byte_writer_put_int16_be -+fpi_byte_writer_put_int24_be -+fpi_byte_writer_put_int32_be -+fpi_byte_writer_put_int64_be -+fpi_byte_writer_put_int16_le -+fpi_byte_writer_put_int24_le -+fpi_byte_writer_put_int32_le -+fpi_byte_writer_put_int64_le -+fpi_byte_writer_put_float32_be -+fpi_byte_writer_put_float64_be -+fpi_byte_writer_put_float32_le -+fpi_byte_writer_put_float64_le -+fpi_byte_writer_put_string_utf8 -+fpi_byte_writer_put_string_utf16 -+fpi_byte_writer_put_string_utf32 -+fpi_byte_writer_put_data -+fpi_byte_writer_fill -+
-+ -
- fpi-context - fpi_get_driver_types -diff --git a/doc/libfprint-docs.xml b/doc/libfprint-docs.xml -index 0a57efb..09bb826 100644 ---- a/doc/libfprint-docs.xml -+++ b/doc/libfprint-docs.xml -@@ -48,6 +48,12 @@ - - - -+ -+ Binary buffer I/O -+ -+ -+ -+ - - Image manipulation - --- -2.54.0 - diff --git a/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch b/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch deleted file mode 100644 index f883cc9..0000000 --- a/0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 14763d29cf1e5ec9628fd639034675e9b22aff1e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 14:11:09 +0200 -Subject: [PATCH 2/6] fpi-byte-writer: Add APIs to write and get GBytes - -It makes it handier to handle data elements without having to keep size -and data separated ---- - doc/libfprint-2-sections.txt | 2 ++ - libfprint/fpi-byte-writer.c | 39 ++++++++++++++++++++++++++++++++++++ - libfprint/fpi-byte-writer.h | 22 ++++++++++++++++++++ - 3 files changed, 63 insertions(+) - -diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt -index 9f3804f..995ad50 100644 ---- a/doc/libfprint-2-sections.txt -+++ b/doc/libfprint-2-sections.txt -@@ -220,11 +220,13 @@ fpi_byte_writer_init - fpi_byte_writer_init_with_size - fpi_byte_writer_init_with_data - fpi_byte_writer_reset -+fpi_byte_writer_reset_and_get_bytes - fpi_byte_writer_reset_and_get_data - fpi_byte_writer_free - fpi_byte_writer_free_and_get_data - fpi_byte_writer_get_remaining - fpi_byte_writer_ensure_free_space -+fpi_byte_writer_put_bytes - fpi_byte_writer_put_uint8 - fpi_byte_writer_put_uint16_be - fpi_byte_writer_put_uint24_be -diff --git a/libfprint/fpi-byte-writer.c b/libfprint/fpi-byte-writer.c -index cb3514a..00ff447 100644 ---- a/libfprint/fpi-byte-writer.c -+++ b/libfprint/fpi-byte-writer.c -@@ -219,6 +219,36 @@ fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer) - return data; - } - -+/** -+ * fpi_byte_writer_reset_and_get_bytes: -+ * @writer: #FpiByteWriter instance -+ * -+ * Resets @writer and returns the current data as a #GBytes. -+ * -+ * Returns: (transfer full): the current data as a #GBytes. -+ */ -+GBytes * -+fpi_byte_writer_reset_and_get_bytes (FpiByteWriter * writer) -+{ -+ GBytes *bytes; -+ -+ g_return_val_if_fail (writer != NULL, NULL); -+ -+ if (!writer->owned) -+ { -+ bytes = g_bytes_new (g_steal_pointer (&writer->parent.data), -+ writer->parent.size); -+ } -+ else -+ { -+ bytes = g_bytes_new_take ((gpointer) g_steal_pointer (&writer->parent.data), -+ writer->parent.size); -+ } -+ -+ fpi_byte_writer_reset (writer); -+ return g_steal_pointer (&bytes); -+} -+ - /** - * fpi_byte_writer_free: - * @writer: (in) (transfer full): #FpiByteWriter instance -@@ -602,6 +632,15 @@ CREATE_WRITE_STRING_FUNC (32, guint32); - * - * Returns: %TRUE if the value could be written - */ -+/** -+ * fpi_byte_writer_put_bytes: -+ * @writer: #FpiByteWriter instance -+ * @bytes: (transfer none): Data to write -+ * -+ * Writes the contents of @bytes to @writer. -+ * -+ * Returns: %TRUE if the value could be written -+ */ - /** - * fpi_byte_writer_fill: - * @writer: #FpiByteWriter instance -diff --git a/libfprint/fpi-byte-writer.h b/libfprint/fpi-byte-writer.h -index 9b21b5f..699e85e 100644 ---- a/libfprint/fpi-byte-writer.h -+++ b/libfprint/fpi-byte-writer.h -@@ -77,6 +77,9 @@ void fpi_byte_writer_reset (FpiByteWriter *writer); - - guint8 * fpi_byte_writer_reset_and_get_data (FpiByteWriter *writer); - -+ -+GBytes * fpi_byte_writer_reset_and_get_bytes (FpiByteWriter *writer); -+ - /** - * fpi_byte_writer_get_pos: - * @writer: #FpiByteWriter instance -@@ -204,6 +207,9 @@ gboolean fpi_byte_writer_put_float64_le (FpiByteWriter *writer, gdoubl - gboolean fpi_byte_writer_put_data (FpiByteWriter *writer, const guint8 *data, guint size); - - -+gboolean fpi_byte_writer_put_bytes (FpiByteWriter *writer, const GBytes *bytes); -+ -+ - gboolean fpi_byte_writer_fill (FpiByteWriter *writer, guint8 value, guint size); - - -@@ -338,6 +344,18 @@ fpi_byte_writer_put_data_inline (FpiByteWriter * writer, const guint8 * data, - return TRUE; - } - -+static inline gboolean -+fpi_byte_writer_put_bytes_inline (FpiByteWriter * writer, const GBytes * bytes) -+{ -+ g_return_val_if_fail (writer != NULL, FALSE); -+ g_return_val_if_fail (bytes != NULL, FALSE); -+ const guint8 *data; -+ gsize size; -+ -+ data = g_bytes_get_data ((GBytes *) bytes, &size); -+ return fpi_byte_writer_put_data_inline (writer, data, size); -+} -+ - static inline void - fpi_byte_writer_fill_unchecked (FpiByteWriter * writer, guint8 value, guint size) - { -@@ -413,6 +431,10 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint size) - - #define fpi_byte_writer_put_data(writer, data, size) \ - G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, size)) -+#define fpi_byte_writer_put_data_static(writer, data) \ -+ G_LIKELY (fpi_byte_writer_put_data_inline (writer, data, sizeof (data))) -+#define fpi_byte_writer_put_bytes(writer, bytes) \ -+ G_LIKELY (fpi_byte_writer_put_bytes_inline (writer, bytes)) - #define fpi_byte_writer_fill(writer, val, size) \ - G_LIKELY (fpi_byte_writer_fill_inline (writer, val, size)) - --- -2.54.0 - diff --git a/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch b/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch deleted file mode 100644 index 3527bac..0000000 --- a/0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch +++ /dev/null @@ -1,187 +0,0 @@ -From dc48ab8b4018d1c1cc45cafaafbdac0e3d7726fd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 14:15:28 +0200 -Subject: [PATCH 3/6] fpi-byte-reader: Add support to read and get/peek GBytes - ---- - doc/libfprint-2-sections.txt | 4 +++ - libfprint/fpi-byte-reader.c | 49 ++++++++++++++++++++++++++++++++++++ - libfprint/fpi-byte-reader.h | 43 +++++++++++++++++++++++++++++++ - 3 files changed, 96 insertions(+) - -diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt -index 995ad50..52ddb42 100644 ---- a/doc/libfprint-2-sections.txt -+++ b/doc/libfprint-2-sections.txt -@@ -139,8 +139,10 @@ fpi_assemble_lines - FpiByteReader - FpiByteReader - fpi_byte_reader_new -+fpi_byte_reader_new_bytes - fpi_byte_reader_free - fpi_byte_reader_init -+fpi_byte_reader_init_bytes - fpi_byte_reader_peek_sub_reader - fpi_byte_reader_get_sub_reader - fpi_byte_reader_set_pos -@@ -148,6 +150,8 @@ fpi_byte_reader_get_pos - fpi_byte_reader_get_remaining - fpi_byte_reader_get_size - fpi_byte_reader_skip -+fpi_byte_reader_get_bytes -+fpi_byte_reader_peek_bytes - fpi_byte_reader_get_uint8 - fpi_byte_reader_get_int8 - fpi_byte_reader_peek_uint8 -diff --git a/libfprint/fpi-byte-reader.c b/libfprint/fpi-byte-reader.c -index 23bc5e7..1591825 100644 ---- a/libfprint/fpi-byte-reader.c -+++ b/libfprint/fpi-byte-reader.c -@@ -65,6 +65,31 @@ fpi_byte_reader_new (const guint8 * data, guint size) - return ret; - } - -+/** -+ * fpi_byte_reader_new_bytes: (skip) -+ * @bytes: (in) (transfer none): a #GBytes instance from which the -+ * #FpiByteReader should read -+ * -+ * Create a new #FpiByteReader instance, which will read from @bytes. -+ * -+ * Free-function: fpi_byte_reader_free -+ * -+ * Returns: (transfer full): a new #FpiByteReader instance -+ */ -+FpiByteReader * -+fpi_byte_reader_new_bytes (GBytes * bytes) -+{ -+ const guint8 *data; -+ gsize size = 0; -+ -+ g_return_val_if_fail (bytes != NULL, NULL); -+ -+ data = g_bytes_get_data (bytes, &size); -+ g_return_val_if_fail (size <= G_MAXUINT, NULL); -+ -+ return fpi_byte_reader_new (data, (guint) size); -+} -+ - /** - * fpi_byte_reader_free: - * @reader: (in) (transfer full): a #FpiByteReader instance -@@ -100,6 +125,30 @@ fpi_byte_reader_init (FpiByteReader * reader, const guint8 * data, guint size) - reader->byte = 0; - } - -+/** -+ * fpi_byte_reader_init_bytes: -+ * @reader: a #FpiByteReader instance -+ * @bytes: (in) (transfer none): a #GBytes instance from which -+ * the #FpiByteReader should read -+ * -+ * Initializes a #FpiByteReader instance to read from @bytes. This function -+ * can be called on already initialized instances. -+ */ -+FpiByteReader * -+fpi_byte_reader_init_bytes (FpiByteReader * reader, GBytes * bytes) -+{ -+ g_return_val_if_fail (reader != NULL, NULL); -+ g_return_val_if_fail (bytes != NULL, NULL); -+ -+ gsize size = 0; -+ const guint8 *data = g_bytes_get_data (bytes, &size); -+ -+ g_return_val_if_fail (size <= G_MAXUINT, NULL); -+ fpi_byte_reader_init (reader, data, (guint) size); -+ -+ return reader; -+} -+ - /** - * fpi_byte_reader_peek_sub_reader: (skip) - * @reader: an existing and initialized #FpiByteReader instance -diff --git a/libfprint/fpi-byte-reader.h b/libfprint/fpi-byte-reader.h -index c4e64d2..05a3989 100644 ---- a/libfprint/fpi-byte-reader.h -+++ b/libfprint/fpi-byte-reader.h -@@ -50,6 +50,7 @@ typedef struct { - - FpiByteReader * fpi_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC; - -+FpiByteReader * fpi_byte_reader_new_bytes (GBytes *bytes) G_GNUC_MALLOC; - - void fpi_byte_reader_free (FpiByteReader *reader); - -@@ -57,6 +58,9 @@ void fpi_byte_reader_free (FpiByteReader *reader); - void fpi_byte_reader_init (FpiByteReader *reader, const guint8 *data, guint size); - - -+FpiByteReader * fpi_byte_reader_init_bytes (FpiByteReader *reader, GBytes *bytes); -+ -+ - gboolean fpi_byte_reader_peek_sub_reader (FpiByteReader * reader, - FpiByteReader * sub_reader, - guint size); -@@ -220,6 +224,13 @@ gboolean fpi_byte_reader_get_data (FpiByteReader * reader, guint s - - gboolean fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, const guint8 ** val); - -+ -+GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size); -+ -+ -+GBytes * fpi_byte_reader_peek_bytes (const FpiByteReader *reader, guint size); -+ -+ - #define fpi_byte_reader_dup_string(reader,str) \ - fpi_byte_reader_dup_string_utf8(reader,str) - -@@ -642,6 +653,34 @@ fpi_byte_reader_peek_data_inline (const FpiByteReader * reader, guint size, cons - return TRUE; - } - -+static inline GBytes * -+fpi_byte_reader_peek_bytes_inline (const FpiByteReader *reader, guint size) -+{ -+ const guint8 *data; -+ -+ g_return_val_if_fail (reader != NULL, NULL); -+ -+ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) -+ return NULL; -+ -+ data = fpi_byte_reader_peek_data_unchecked (reader); -+ return g_bytes_new_static (data, size); -+} -+ -+static inline GBytes * -+fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size) -+{ -+ const guint8 *data; -+ -+ g_return_val_if_fail (reader != NULL, NULL); -+ -+ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) -+ return NULL; -+ -+ data = fpi_byte_reader_get_data_unchecked (reader, size); -+ return g_bytes_new_static (data, size); -+} -+ - static inline guint - fpi_byte_reader_get_pos_inline (const FpiByteReader * reader) - { -@@ -672,6 +711,10 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes) - G_LIKELY(fpi_byte_reader_peek_data_inline(reader,size,val)) - #define fpi_byte_reader_skip(reader,nbytes) \ - G_LIKELY(fpi_byte_reader_skip_inline(reader,nbytes)) -+#define fpi_byte_reader_get_bytes(reader,size) \ -+ fpi_byte_reader_get_bytes_inline(reader,size) -+#define fpi_byte_reader_peek_bytes(reader,size) \ -+ fpi_byte_reader_peek_bytes_inline(reader,size) - - #endif /* FPI_BYTE_READER_DISABLE_INLINES */ - --- -2.54.0 - diff --git a/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch b/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch deleted file mode 100644 index 7fe3c22..0000000 --- a/0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch +++ /dev/null @@ -1,160 +0,0 @@ -From f6a8cae5b4f1555769706f7e5b222145fd3be8ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 14:16:36 +0200 -Subject: [PATCH 4/6] fpi-byte-reader: Add support to read to a static buffer - -This works through macros when the size of a buffer is statically -defined ---- - doc/libfprint-2-sections.txt | 2 ++ - libfprint/fpi-byte-reader.c | 35 ++++++++++++++++++++++ - libfprint/fpi-byte-reader.h | 57 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 94 insertions(+) - -diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt -index 52ddb42..391f1f4 100644 ---- a/doc/libfprint-2-sections.txt -+++ b/doc/libfprint-2-sections.txt -@@ -198,6 +198,8 @@ fpi_byte_reader_get_float64_be - fpi_byte_reader_peek_float64_be - fpi_byte_reader_get_data - fpi_byte_reader_peek_data -+fpi_byte_reader_get_data_static -+fpi_byte_reader_peek_data_static - fpi_byte_reader_dup_data - fpi_byte_reader_masked_scan_uint32 - fpi_byte_reader_masked_scan_uint32_peek -diff --git a/libfprint/fpi-byte-reader.c b/libfprint/fpi-byte-reader.c -index 1591825..9709a41 100644 ---- a/libfprint/fpi-byte-reader.c -+++ b/libfprint/fpi-byte-reader.c -@@ -848,6 +848,41 @@ fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, - return fpi_byte_reader_peek_data_inline (reader, size, val); - } - -+/** -+ * fpi_byte_reader_get_data_fixed: -+ * @reader: a #FpiByteReader instance -+ * @size: Size in bytes -+ * @val: (out) (array length=size): address of a buffer to copy data into -+ * -+ * Copies @size bytes from the current data position into @val if at -+ * least @size bytes are left, and updates the current position. -+ * -+ * Returns: %TRUE if successful, %FALSE otherwise. -+ */ -+gboolean -+(fpi_byte_reader_get_data_static) (FpiByteReader * reader, guint size, -+ const guint8 * val) -+{ -+ return (fpi_byte_reader_get_data_inline_static) (reader, size, val); -+} -+ -+/** -+ * fpi_byte_reader_peek_data_fixed: -+ * @reader: a #FpiByteReader instance -+ * @size: Size in bytes -+ * @val: (out) (array length=size): address of a buffer to copy data into -+ * -+ * Like fpi_byte_reader_get_data_fixed() but does not advance the position. -+ * -+ * Returns: %TRUE if successful, %FALSE otherwise. -+ */ -+gboolean -+(fpi_byte_reader_peek_data_static) (const FpiByteReader * reader, guint size, -+ guint8 * val) -+{ -+ return (fpi_byte_reader_peek_data_inline_static) (reader, size, val); -+} -+ - /** - * fpi_byte_reader_dup_data: - * @reader: a #FpiByteReader instance -diff --git a/libfprint/fpi-byte-reader.h b/libfprint/fpi-byte-reader.h -index 05a3989..278959f 100644 ---- a/libfprint/fpi-byte-reader.h -+++ b/libfprint/fpi-byte-reader.h -@@ -222,9 +222,15 @@ gboolean fpi_byte_reader_dup_data (FpiByteReader * reader, guint s - gboolean fpi_byte_reader_get_data (FpiByteReader * reader, guint size, const guint8 ** val); - - -+gboolean fpi_byte_reader_get_data_static (FpiByteReader * reader, guint size, const guint8 * val); -+ -+ - gboolean fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, const guint8 ** val); - - -+gboolean fpi_byte_reader_peek_data_static (const FpiByteReader * reader, guint size, guint8 * val); -+ -+ - GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size); - - -@@ -681,6 +687,32 @@ fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size) - return g_bytes_new_static (data, size); - } - -+static inline gboolean -+(fpi_byte_reader_get_data_inline_static) (FpiByteReader * reader, guint size, const guint8 * val) -+{ -+ g_return_val_if_fail (reader != NULL, FALSE); -+ g_return_val_if_fail (val != NULL, FALSE); -+ -+ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) -+ return FALSE; -+ -+ memcpy ((void *) val, fpi_byte_reader_get_data_unchecked (reader, size), size); -+ return TRUE; -+} -+ -+static inline gboolean -+(fpi_byte_reader_peek_data_inline_static) (const FpiByteReader * reader, guint size, guint8 * val) -+{ -+ g_return_val_if_fail (reader != NULL, FALSE); -+ g_return_val_if_fail (val != NULL, FALSE); -+ -+ if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size)) -+ return FALSE; -+ -+ memcpy (val, fpi_byte_reader_peek_data_unchecked (reader), size); -+ return TRUE; -+} -+ - static inline guint - fpi_byte_reader_get_pos_inline (const FpiByteReader * reader) - { -@@ -716,6 +748,31 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes) - #define fpi_byte_reader_peek_bytes(reader,size) \ - fpi_byte_reader_peek_bytes_inline(reader,size) - -+/** -+ * fpi_byte_reader_get_data_static: -+ * @reader: a #FpiByteReader -+ * @val: fixed-size array (e.g. `uint8_t buf[32]`) -+ * -+ * Reads @size bytes from @reader directly into @val, where @size is -+ * deduced via `sizeof()` - only safe with true C arrays. -+ * -+ * Returns: %TRUE on success, %FALSE otherwise. -+ */ -+#define fpi_byte_reader_get_data_static(reader,val) \ -+ (fpi_byte_reader_get_data_static) (reader,sizeof(val),val) -+ -+/** -+ * fpi_byte_reader_peek_data_static: -+ * @reader: a #FpiByteReader -+ * @val: fixed-size array (e.g. `uint8_t buf[32]`) -+ * -+ * Like fpi_byte_reader_get_data_static() but does not advance the position. -+ * -+ * Returns: %TRUE on success, %FALSE otherwise. -+ */ -+#define fpi_byte_reader_peek_data_static(reader,val) \ -+ (fpi_byte_reader_peek_data_static) (reader,sizeof(val),val) -+ - #endif /* FPI_BYTE_READER_DISABLE_INLINES */ - - G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteReader, fpi_byte_reader_free); --- -2.54.0 - diff --git a/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch b/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch deleted file mode 100644 index d967dce..0000000 --- a/0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e7c80e748ed3b00c432f3c00f2ec7b7262527db3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:27:36 +0200 -Subject: [PATCH 5/6] fpi-usb-transfer: Add missing definition of - set_short_error() - -It was in the header but not implemented ---- - libfprint/fpi-usb-transfer.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/libfprint/fpi-usb-transfer.c b/libfprint/fpi-usb-transfer.c -index ac4f60c..067ae18 100644 ---- a/libfprint/fpi-usb-transfer.c -+++ b/libfprint/fpi-usb-transfer.c -@@ -548,3 +548,23 @@ fpi_usb_transfer_submit_sync (FpiUsbTransfer *transfer, - - return res; - } -+ -+/** -+ * fpi_usb_transfer_set_short_error: -+ * @transfer: The transfer to submit, must have been filled. -+ * @short_is_error: Whether a short transfer should be considered an error -+ * -+ * Sets whether a short transfer (a transfer in which the transferred length -+ * does not match the expected length) should be considered an error -+ * -+ * By default, short transfers are not considered an error, but -+ * drivers can enforce a further check by setting this flag. -+ */ -+void -+fpi_usb_transfer_set_short_error (FpiUsbTransfer *transfer, -+ gboolean short_is_error) -+{ -+ g_return_if_fail (transfer); -+ -+ transfer->short_is_error = short_is_error; -+} --- -2.54.0 - diff --git a/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch b/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch deleted file mode 100644 index 0671682..0000000 --- a/0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9d4e7fc87b76819c049fc23f92b3dccdaf365e75 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 14:36:10 +0200 -Subject: [PATCH 6/6] fpi-usb-transfer: Wrap g_error_new arguments - ---- - libfprint/fpi-usb-transfer.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libfprint/fpi-usb-transfer.c b/libfprint/fpi-usb-transfer.c -index 067ae18..448c566 100644 ---- a/libfprint/fpi-usb-transfer.c -+++ b/libfprint/fpi-usb-transfer.c -@@ -344,7 +344,8 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat - { - error = g_error_new (G_USB_DEVICE_ERROR, - G_USB_DEVICE_ERROR_IO, -- "Unexpected short error of %zd size (expected %zd)", transfer->actual_length, transfer->length); -+ "Unexpected short error of %zd size (expected %zd)", -+ transfer->actual_length, transfer->length); - } - - callback = transfer->callback; --- -2.54.0 - diff --git a/2c7842c905147a2d127c1b168b2e9d43.patch b/2c7842c905147a2d127c1b168b2e9d43.patch deleted file mode 100644 index 0f67995..0000000 --- a/2c7842c905147a2d127c1b168b2e9d43.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2c7842c905147a2d127c1b168b2e9d432b8c91a4 Mon Sep 17 00:00:00 2001 -From: Daniel Schaefer -Date: Thu, 12 Feb 2026 16:08:31 +0800 -Subject: [PATCH] focaltech_moc: add new pid:0x077A pid:0x079A - -Tested on working hardware with examples/enroll and examples/verify - -Signed-off-by: Daniel Schaefer ---- - data/autosuspend.hwdb | 2 ++ - libfprint/drivers/focaltech_moc/focaltech_moc.c | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb -index f49e17d6..9d1fd351 100644 ---- a/data/autosuspend.hwdb -+++ b/data/autosuspend.hwdb -@@ -185,6 +185,8 @@ usb:v2808pA99A* - usb:v2808pA57A* - usb:v2808pA78A* - usb:v2808p1579* -+usb:v2808p077A* -+usb:v2808p079A* - ID_AUTOSUSPEND=1 - ID_PERSIST=0 - -diff --git a/libfprint/drivers/focaltech_moc/focaltech_moc.c b/libfprint/drivers/focaltech_moc/focaltech_moc.c -index 2d410f88..8bd93e4b 100644 ---- a/libfprint/drivers/focaltech_moc/focaltech_moc.c -+++ b/libfprint/drivers/focaltech_moc/focaltech_moc.c -@@ -35,6 +35,8 @@ static const FpIdEntry id_table[] = { - { .vid = 0x2808, .pid = 0xa57a, }, - { .vid = 0x2808, .pid = 0xa78a, }, - { .vid = 0x2808, .pid = 0x1579, }, -+ { .vid = 0x2808, .pid = 0x077A, }, -+ { .vid = 0x2808, .pid = 0x079A, }, - { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ - }; - --- -GitLab - diff --git a/egis_reader.patch b/egis_reader.patch deleted file mode 100644 index 57e83e5..0000000 --- a/egis_reader.patch +++ /dev/null @@ -1,3304 +0,0 @@ -From 9bddd90f06f4d9997389740b480e71d32bbc859f Mon Sep 17 00:00:00 2001 -From: Jason Huang -Date: Wed, 28 Jan 2026 21:06:48 +0800 -Subject: [PATCH 01/13] egis_etu905: Add 1c7a:05ae and 1c7a:9201 fingerprint - readers - ---- - data/autosuspend.hwdb | 6 + - libfprint/drivers/egismoc/egis_etu905.c | 1635 +++++++++++++++++++++++ - libfprint/drivers/egismoc/egis_etu905.h | 214 +++ - libfprint/meson.build | 2 + - meson.build | 2 + - tests/egis_etu905/custom.pcapng | Bin 0 -> 33644 bytes - tests/egis_etu905/custom.py | 109 ++ - tests/egis_etu905/device | 348 +++++ - tests/meson.build | 1 + - 9 files changed, 2317 insertions(+) - create mode 100644 libfprint/drivers/egismoc/egis_etu905.c - create mode 100644 libfprint/drivers/egismoc/egis_etu905.h - create mode 100644 tests/egis_etu905/custom.pcapng - create mode 100644 tests/egis_etu905/custom.py - create mode 100644 tests/egis_etu905/device - -diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb -index 55b5cb4c..a3ff00af 100644 ---- a/data/autosuspend.hwdb -+++ b/data/autosuspend.hwdb -@@ -77,6 +77,12 @@ usb:v1C7Ap0571* - ID_AUTOSUSPEND=1 - ID_PERSIST=0 - -+# Supported by libfprint driver egis_etu905 -+usb:v1C7Ap05AE* -+usb:v1C7Ap9201* -+ ID_AUTOSUSPEND=1 -+ ID_PERSIST=0 -+ - # Supported by libfprint driver egismoc - usb:v1C7Ap0582* - usb:v1C7Ap0583* -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -new file mode 100644 -index 00000000..be0c6e05 ---- /dev/null -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -0,0 +1,1635 @@ -+/* -+ * Driver for Egis Technology (LighTuning) Match-On-Chip sensors -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#define FP_COMPONENT "egis_etu905" -+ -+#include -+#include -+#include -+ -+#include "drivers_api.h" -+#include "fpi-byte-writer.h" -+ -+#include "egis_etu905.h" -+ -+struct _FpiDeviceEgisEtu905 -+{ -+ FpDevice parent; -+ FpiSsm *task_ssm; -+ FpiSsm *cmd_ssm; -+ FpiUsbTransfer *cmd_transfer; -+ GCancellable *interrupt_cancellable; -+ GPtrArray *enrolled_ids; -+ gint max_enroll_stages; -+ guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; -+}; -+ -+G_DEFINE_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FP_TYPE_DEVICE); -+ -+static const FpIdEntry egis_etu905_id_table[] = { -+ { .vid = 0x1c7a, .pid = 0x05ae, .driver_data = EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 }, -+ { .vid = 0x1c7a, .pid = 0x9201, .driver_data = EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 }, -+ { .vid = 0, .pid = 0, .driver_data = 0 } -+}; -+ -+typedef void (*SynCmdMsgCallback) (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error); -+ -+typedef struct egis_etu905_command_data -+{ -+ SynCmdMsgCallback callback; -+ guchar *buffer_in; -+ gsize length_in; -+} CommandData; -+ -+static void -+egis_etu905_command_data_free (CommandData *data) -+{ -+ g_free (data->buffer_in); -+ g_free (data); -+} -+ -+typedef struct egis_etu905_enroll_print -+{ -+ FpPrint *print; -+ int stage; -+} EnrollPrint; -+ -+static void -+egis_etu905_finger_on_sensor_cb (FpiUsbTransfer *transfer, -+ FpDevice *device, -+ gpointer userdata, -+ GError *error) -+{ -+ fp_dbg ("Finger on sensor callback"); -+ fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT); -+ -+ fpi_ssm_usb_transfer_cb (transfer, device, userdata, error); -+} -+ -+static void -+egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ fp_dbg ("Wait for finger on sensor"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); -+ -+ fpi_usb_transfer_fill_interrupt (transfer, EGIS_ETU905_EP_CMD_INTERRUPT_IN, -+ EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH); -+ transfer->ssm = ssm; -+ /* Interrupt on this device always returns 1 byte short; this is expected */ -+ transfer->short_is_error = FALSE; -+ -+ fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED); -+ -+ fpi_usb_transfer_submit (g_steal_pointer (&transfer), -+ EGIS_ETU905_USB_INTERRUPT_TIMEOUT, -+ self->interrupt_cancellable, -+ egis_etu905_finger_on_sensor_cb, -+ NULL); -+} -+ -+static gboolean -+egis_etu905_validate_response_prefix (const guchar *buffer_in, -+ const gsize buffer_in_len, -+ const guchar *valid_prefix, -+ const gsize valid_prefix_len) -+{ -+ const gboolean result = memcmp (buffer_in + -+ (egis_etu905_read_prefix_len + -+ EGIS_ETU905_CHECK_BYTES_LENGTH), -+ valid_prefix, -+ valid_prefix_len) == 0; -+ -+ fp_dbg ("Response prefix valid: %s", result ? "yes" : "NO"); -+ return result; -+} -+ -+static gboolean -+egis_etu905_validate_response_suffix (const guchar *buffer_in, -+ const gsize buffer_in_len, -+ const guchar *valid_suffix, -+ const gsize valid_suffix_len) -+{ -+ const gboolean result = memcmp (buffer_in + (buffer_in_len - valid_suffix_len), -+ valid_suffix, -+ valid_suffix_len) == 0; -+ -+ fp_dbg ("Response suffix valid: %s", result ? "yes" : "NO"); -+ return result; -+} -+ -+static void -+egis_etu905_task_ssm_done (FpiSsm *ssm, -+ FpDevice *device, -+ GError *error) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ fp_dbg ("Task SSM done"); -+ -+ /* task_ssm is going to be freed by completion of SSM */ -+ g_assert (!self->task_ssm || self->task_ssm == ssm); -+ self->task_ssm = NULL; -+ -+ g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref); -+ -+ if (error) -+ fpi_device_action_error (device, error); -+} -+ -+static void -+egis_etu905_commit_start_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Task SSM commit start callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (error) -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ else -+ fpi_ssm_jump_to_state (self->task_ssm, ENROLL_COMMIT); -+} -+ -+/* -+ * Generic callback for commands that don't need special handling on success. -+ * Advances the task SSM to the next state on success, or marks it failed on error. -+ */ -+static void -+egis_etu905_task_ssm_next_state_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ fp_dbg ("Task SSM next state callback"); -+ -+ if (error) -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ else -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+static void -+egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, -+ FpDevice *device, -+ gpointer userdata, -+ GError *error) -+{ -+ CommandData *data = userdata; -+ -+ fp_dbg ("Command receive callback"); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (transfer->ssm, error); -+ return; -+ } -+ if (data == NULL || transfer->actual_length < egis_etu905_read_prefix_len) -+ { -+ fpi_ssm_mark_failed (transfer->ssm, -+ fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); -+ return; -+ } -+ -+ /* Store the response data and let the cmd_ssm_done callback invoke -+ * the actual callback with the stored data */ -+ data->buffer_in = g_steal_pointer (&transfer->buffer); -+ data->length_in = transfer->actual_length; -+ -+ fpi_ssm_mark_completed (transfer->ssm); -+} -+ -+static void -+egis_etu905_cmd_run_state (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ g_autoptr(FpiUsbTransfer) transfer = NULL; -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case CMD_SEND: -+ if (self->cmd_transfer) -+ { -+ self->cmd_transfer->ssm = ssm; -+ fpi_usb_transfer_submit (g_steal_pointer (&self->cmd_transfer), -+ EGIS_ETU905_USB_SEND_TIMEOUT, -+ fpi_device_get_cancellable (device), -+ fpi_ssm_usb_transfer_cb, -+ NULL); -+ break; -+ } -+ -+ fpi_ssm_next_state (ssm); -+ break; -+ -+ case CMD_GET: -+ transfer = fpi_usb_transfer_new (device); -+ transfer->ssm = ssm; -+ fpi_usb_transfer_fill_bulk (transfer, EGIS_ETU905_EP_CMD_IN, -+ EGIS_ETU905_USB_IN_RECV_LENGTH); -+ fpi_usb_transfer_submit (g_steal_pointer (&transfer), -+ EGIS_ETU905_USB_RECV_TIMEOUT, -+ fpi_device_get_cancellable (device), -+ egis_etu905_cmd_receive_cb, -+ fpi_ssm_get_data (ssm)); -+ break; -+ } -+} -+ -+/* -+ * Command SSM done callback. -+ * Always invokes the callback with stored data on success or error. -+ */ -+static void -+egis_etu905_cmd_ssm_done (FpiSsm *ssm, -+ FpDevice *device, -+ GError *error) -+{ -+ g_autoptr(GError) local_error = error; -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ CommandData *data = fpi_ssm_get_data (ssm); -+ -+ g_assert (self->cmd_ssm == ssm); -+ g_assert (!self->cmd_transfer || self->cmd_transfer->ssm == ssm); -+ -+ self->cmd_ssm = NULL; -+ self->cmd_transfer = NULL; -+ -+ if (data && data->callback) -+ { -+ data->callback (device, -+ g_steal_pointer (&data->buffer_in), -+ data->length_in, -+ g_steal_pointer (&local_error)); -+ } -+} -+ -+/* -+ * 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 guint16 -+egis_etu905_get_check_bytes (FpiByteReader *reader) -+{ -+ fp_dbg ("Get check bytes"); -+ size_t sum_values = 0; -+ guint16 val; -+ -+ fpi_byte_reader_set_pos (reader, 0); -+ -+ while (fpi_byte_reader_get_uint16_be (reader, &val)) -+ sum_values += val; -+ -+ return G_MAXUINT16 - (sum_values % G_MAXUINT16); -+} -+ -+static void -+egis_etu905_exec_cmd (FpDevice *device, -+ guchar *cmd, -+ const gsize cmd_length, -+ GDestroyNotify cmd_destroy, -+ SynCmdMsgCallback callback) -+{ -+ g_auto(FpiByteWriter) writer = {0}; -+ g_autoptr(FpiUsbTransfer) transfer = NULL; -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ g_autofree CommandData *data = NULL; -+ gsize buffer_out_length = 0; -+ gboolean written = TRUE; -+ guint16 check_value; -+ -+ fp_dbg ("Execute command and get response"); -+ -+ /* -+ * buffer_out should be a fully composed command (with prefix, check bytes, etc) -+ * which looks like this: -+ * E G I S 00 00 00 01 {cb1} {cb2} {payload} -+ * where cb1 and cb2 are some check bytes generated by the -+ * egis_etu905_get_check_bytes() method and payload is what is passed via the cmd -+ * parameter -+ */ -+ buffer_out_length = egis_etu905_write_prefix_len -+ + EGIS_ETU905_CHECK_BYTES_LENGTH -+ + cmd_length; -+ -+ fpi_byte_writer_init_with_size (&writer, buffer_out_length + -+ (buffer_out_length % 2 ? 1 : 0), TRUE); -+ -+ /* Prefix */ -+ written &= fpi_byte_writer_put_data (&writer, egis_etu905_write_prefix, -+ egis_etu905_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, EGIS_ETU905_CHECK_BYTES_LENGTH); -+ -+ /* Command Payload */ -+ 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 = egis_etu905_get_check_bytes (FPI_BYTE_READER (&writer)); -+ fpi_byte_writer_set_pos (&writer, egis_etu905_write_prefix_len); -+ written &= fpi_byte_writer_put_uint16_be (&writer, check_value); -+ -+ /* destroy cmd if requested */ -+ if (cmd_destroy) -+ g_clear_pointer (&cmd, cmd_destroy); -+ -+ g_assert (self->cmd_ssm == NULL); -+ self->cmd_ssm = fpi_ssm_new (device, -+ egis_etu905_cmd_run_state, -+ CMD_STATES); -+ -+ data = g_new0 (CommandData, 1); -+ data->callback = callback; -+ fpi_ssm_set_data (self->cmd_ssm, g_steal_pointer (&data), -+ (GDestroyNotify) egis_etu905_command_data_free); -+ -+ if (!written) -+ { -+ fpi_ssm_start (self->cmd_ssm, egis_etu905_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, -+ EGIS_ETU905_EP_CMD_OUT, -+ fpi_byte_writer_reset_and_get_data (&writer), -+ buffer_out_length, -+ g_free); -+ -+ g_assert (self->cmd_transfer == NULL); -+ self->cmd_transfer = g_steal_pointer (&transfer); -+ fpi_ssm_start (self->cmd_ssm, egis_etu905_cmd_ssm_done); -+} -+ -+static void -+egis_etu905_set_print_data (FpPrint *print, -+ const gchar *device_print_id, -+ const gchar *user_id) -+{ -+ GVariant *print_id_var = NULL; -+ GVariant *fpi_data = NULL; -+ g_autofree gchar *fill_user_id = NULL; -+ -+ if (user_id) -+ fill_user_id = g_strdup (user_id); -+ else -+ fill_user_id = g_strndup (device_print_id, EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ -+ fpi_print_fill_from_user_id (print, fill_user_id); -+ -+ fpi_print_set_type (print, FPI_PRINT_RAW); -+ fpi_print_set_device_stored (print, TRUE); -+ -+ g_object_set (print, "description", fill_user_id, NULL); -+ -+ print_id_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, -+ device_print_id, -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE, -+ sizeof (guchar)); -+ fpi_data = g_variant_new ("(@ay)", print_id_var); -+ g_object_set (print, "fpi-data", fpi_data, NULL); -+} -+ -+static GPtrArray * -+egis_etu905_get_enrolled_prints (FpDevice *device) -+{ -+ g_autoptr(GPtrArray) result = g_ptr_array_new_with_free_func (g_object_unref); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (!self->enrolled_ids) -+ return g_steal_pointer (&result); -+ -+ for (guint i = 0; i < self->enrolled_ids->len; i++) -+ { -+ FpPrint *print = fp_print_new (device); -+ egis_etu905_set_print_data (print, g_ptr_array_index (self->enrolled_ids, i), NULL); -+ g_ptr_array_add (result, g_object_ref_sink (print)); -+ } -+ -+ return g_steal_pointer (&result); -+} -+ -+static void -+egis_etu905_list_fill_enrolled_ids_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ fp_dbg ("List callback"); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref); -+ self->enrolled_ids = g_ptr_array_new_with_free_func (g_free); -+ -+ FpiByteReader reader; -+ gboolean read = TRUE; -+ -+ fpi_byte_reader_init (&reader, buffer_in, length_in); -+ -+ read &= fpi_byte_reader_set_pos (&reader, EGIS_ETU905_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 -+ */ -+ while (read) -+ { -+ const guint8 *data; -+ g_autofree gchar *print_id = NULL; -+ -+ read &= fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, -+ &data); -+ if (!read) -+ break; -+ -+ print_id = g_memdup2 (data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ 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_ids->len); -+ -+ if (self->task_ssm) -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+static void -+egis_etu905_list_run_state (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ g_autoptr(GPtrArray) enrolled_prints = NULL; -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case LIST_GET_ENROLLED_IDS: -+ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, NULL, -+ egis_etu905_list_fill_enrolled_ids_cb); -+ break; -+ -+ case LIST_RETURN_ENROLLED_PRINTS: -+ enrolled_prints = egis_etu905_get_enrolled_prints (device); -+ fpi_device_list_complete (device, g_steal_pointer (&enrolled_prints), NULL); -+ fpi_ssm_next_state (ssm); -+ break; -+ } -+} -+ -+static void -+egis_etu905_list (FpDevice *device) -+{ -+ fp_dbg ("List"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, -+ egis_etu905_list_run_state, -+ LIST_STATES); -+ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); -+} -+ -+static guchar * -+egis_etu905_get_delete_cmd (FpDevice *device, -+ FpPrint *delete_print, -+ gsize *length_out) -+{ -+ fp_dbg ("Get delete command"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (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; -+ gsize print_data_id_len = 0; -+ g_autofree gchar *print_description = NULL; -+ g_autofree guchar *enrolled_print_id = NULL; -+ g_autofree guchar *result = NULL; -+ gboolean written = TRUE; -+ -+ /* -+ * The final command body should contain: -+ * 1) hard-coded 00 00 -+ * 2) 2-byte size indiciator, 20*Number deleted identifiers plus 7 in form of: -+ * num_to_delete * 0x20 + 0x07 -+ * Since max prints can be higher than 7 then this goes up to 2 bytes -+ * (e9 + 9 = 109) -+ * 3) Hard-coded prefix (cmd_delete_prefix) -+ * 4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 7 -+ * (num_to_delete * 0x20) -+ * 5) All of the currently registered prints to delete in their 32-byte device -+ * identifiers (enrolled_list) -+ */ -+ -+ 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) * EGIS_ETU905_FINGERPRINT_DATA_SIZE * -+ num_to_delete; -+ /* total_length is the 6 various bytes plus prefix and body payload */ -+ const gsize total_length = (sizeof (guchar) * 6) + cmd_delete_prefix_len + -+ body_length; -+ -+ /* pre-fill entire payload with 00s */ -+ fpi_byte_writer_init_with_size (&writer, total_length, TRUE); -+ -+ /* start with 00 00 (just move starting offset up by 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 (num_to_delete > 7) -+ { -+ 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 */ -+ written &= fpi_byte_writer_change_pos (&writer, 1); -+ written &= fpi_byte_writer_put_uint8 (&writer, (num_to_delete * 0x20) + 0x07); -+ } -+ -+ /* command prefix */ -+ 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) -+ { -+ 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 */ -+ 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 */ -+ /* if passed a delete_print then fetch its data from the FpPrint */ -+ if (delete_print) -+ { -+ g_object_get (delete_print, "description", &print_description, NULL); -+ g_object_get (delete_print, "fpi-data", &print_data, NULL); -+ -+ if (!g_variant_check_format_string (print_data, "(@ay)", FALSE)) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); -+ return NULL; -+ } -+ -+ g_variant_get (print_data, "(@ay)", &print_data_id_var); -+ print_data_id = g_variant_get_fixed_array (print_data_id_var, -+ &print_data_id_len, sizeof (guchar)); -+ -+ if (!g_str_has_prefix (print_description, "FP")) -+ fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.", -+ print_description); -+ -+ fp_info ("Delete fingerprint %s", print_description); -+ -+ written &= fpi_byte_writer_put_data (&writer, print_data_id, -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ } -+ /* Otherwise assume this is a "clear" - just loop through and append all enrolled IDs */ -+ else if (self->enrolled_ids) -+ { -+ 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), -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ } -+ } -+ -+ g_assert (written); -+ -+ if (length_out) -+ *length_out = total_length; -+ -+ return fpi_byte_writer_reset_and_get_data (&writer); -+} -+ -+static void -+egis_etu905_delete_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Delete callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload indicates "success" with the delete */ -+ if (egis_etu905_validate_response_prefix (buffer_in, -+ length_in, -+ rsp_delete_success_prefix, -+ rsp_delete_success_prefix_len)) -+ { -+ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_CLEAR_STORAGE) -+ { -+ fpi_device_clear_storage_complete (device, NULL); -+ fpi_ssm_next_state (self->task_ssm); -+ } -+ else if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE) -+ { -+ fpi_device_delete_complete (device, NULL); -+ fpi_ssm_next_state (self->task_ssm); -+ } -+ else -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Unsupported delete action.")); -+ } -+ } -+ else -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Delete print was not successful")); -+ } -+} -+ -+static void -+egis_etu905_delete_run_state (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ g_autofree guchar *payload = NULL; -+ gsize payload_length = 0; -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case DELETE_GET_ENROLLED_IDS: -+ /* get enrolled_ids from device for use building delete payload below */ -+ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, NULL, -+ egis_etu905_list_fill_enrolled_ids_cb); -+ break; -+ -+ case DELETE_DELETE: -+ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE) -+ payload = egis_etu905_get_delete_cmd (device, fpi_ssm_get_data (ssm), -+ &payload_length); -+ else -+ payload = egis_etu905_get_delete_cmd (device, NULL, &payload_length); -+ -+ egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, -+ g_free, egis_etu905_delete_cb); -+ break; -+ } -+} -+ -+static void -+egis_etu905_clear_storage (FpDevice *device) -+{ -+ fp_dbg ("Clear storage"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, -+ egis_etu905_delete_run_state, -+ DELETE_STATES); -+ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); -+} -+ -+static void -+egis_etu905_delete (FpDevice *device) -+{ -+ fp_dbg ("Delete"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ FpPrint *delete_print = NULL; -+ -+ fpi_device_get_delete_data (device, &delete_print); -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, -+ egis_etu905_delete_run_state, -+ DELETE_STATES); -+ /* the print is owned by libfprint during deletion task */ -+ fpi_ssm_set_data (self->task_ssm, delete_print, NULL); -+ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); -+} -+ -+static void -+egis_etu905_enroll_status_report (FpDevice *device, -+ EnrollPrint *enroll_print, -+ EnrollStatus status, -+ GError *error) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ switch (status) -+ { -+ case ENROLL_STATUS_DEVICE_FULL: -+ case ENROLL_STATUS_DUPLICATE: -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ break; -+ -+ case ENROLL_STATUS_RETRY: -+ fpi_device_enroll_progress (device, enroll_print->stage, NULL, error); -+ break; -+ -+ case ENROLL_STATUS_PARTIAL_OK: -+ enroll_print->stage++; -+ fp_info ("Partial capture successful. Please touch the sensor again (%d/%d)", -+ enroll_print->stage, -+ self->max_enroll_stages); -+ fpi_device_enroll_progress (device, enroll_print->stage, enroll_print->print, NULL); -+ break; -+ -+ case ENROLL_STATUS_COMPLETE: -+ fp_info ("Enrollment was successful!"); -+ fpi_device_enroll_complete (device, g_object_ref (enroll_print->print), NULL); -+ break; -+ -+ default: -+ if (error) -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ else -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, -+ "Unknown error")); -+ } -+} -+ -+static void -+egis_etu905_read_capture_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Read capture callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ EnrollPrint *enroll_print = fpi_ssm_get_data (self->task_ssm); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload indicates "success" */ -+ if (egis_etu905_validate_response_prefix (buffer_in, -+ length_in, -+ rsp_read_success_prefix, -+ rsp_read_success_prefix_len) && -+ egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_read_success_suffix, -+ rsp_read_success_suffix_len)) -+ { -+ egis_etu905_enroll_status_report (device, enroll_print, -+ ENROLL_STATUS_PARTIAL_OK, NULL); -+ } -+ else -+ { -+ /* If not success then the sensor can either report "off center" or "sensor is dirty" */ -+ -+ /* "Off center" */ -+ if (egis_etu905_validate_response_prefix (buffer_in, -+ length_in, -+ rsp_read_offcenter_prefix, -+ rsp_read_offcenter_prefix_len) && -+ egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_read_offcenter_suffix, -+ rsp_read_offcenter_suffix_len)) -+ error = fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER); -+ -+ /* "Sensor is dirty" */ -+ else if (egis_etu905_validate_response_prefix (buffer_in, -+ length_in, -+ rsp_read_dirty_prefix, -+ rsp_read_dirty_prefix_len)) -+ error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, -+ "Your device is having trouble recognizing you. " -+ "Make sure your sensor is clean."); -+ -+ else -+ error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, -+ "Unknown failure trying to read your finger. " -+ "Please try again."); -+ -+ egis_etu905_enroll_status_report (device, enroll_print, ENROLL_STATUS_RETRY, error); -+ } -+ -+ 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); -+} -+ -+static void -+egis_etu905_enroll_duplicate_check_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Task SSM enroll duplicate check callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload reports "not yet enrolled" */ -+ if (egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_check_not_yet_enrolled_suffix, -+ rsp_check_not_yet_enrolled_suffix_len)) -+ fpi_ssm_jump_to_state (self->task_ssm, ENROLL_COMMIT_START); -+ else -+ egis_etu905_enroll_status_report (device, NULL, ENROLL_STATUS_DUPLICATE, -+ fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE)); -+} -+ -+static void -+egis_etu905_enroll_begin_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Enroll begin callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ FpiByteReader reader; -+ -+ fpi_byte_reader_init (&reader, buffer_in, length_in); -+ -+ fpi_byte_reader_set_pos (&reader, EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE); -+ -+ const guint8 *data = NULL; -+ -+ fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, -+ &data); -+ -+ if (data) -+ memcpy (self->sid, data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+/* -+ * Builds the full "check" payload which includes identifiers for all -+ * fingerprints which currently should exist on the storage. This payload is -+ * used during both enrollment and verify actions. -+ */ -+static guchar * -+egis_etu905_get_check_cmd (FpDevice *device, -+ gsize *length_out) -+{ -+ fp_dbg ("Get check command"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ g_auto(FpiByteWriter) writer = {0}; -+ g_autofree guchar *result = NULL; -+ 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_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_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) -+ */ -+ -+ g_assert (self->enrolled_ids); -+ const gsize body_length = sizeof (guchar) * self->enrolled_ids->len * -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE; -+ -+ /* prefix length can depend on the type */ -+ const gsize check_prefix_length = (fpi_device_get_driver_data (device) & -+ EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2) ? -+ cmd_check_prefix_type2_len : -+ cmd_check_prefix_type1_len; -+ -+ /* total_length is the 6 various bytes plus all other prefixes/suffixes and -+ * the body payload */ -+ const gsize total_length = (sizeof (guchar) * 6) -+ + check_prefix_length -+ + EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH -+ + body_length -+ + cmd_check_suffix_len; -+ -+ /* pre-fill entire payload with 00s */ -+ fpi_byte_writer_init_with_size (&writer, total_length, TRUE); -+ -+ /* start with 00 00 (just move starting offset up by 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_ids->len > 6) -+ { -+ 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 */ -+ 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) & EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2) -+ written &= fpi_byte_writer_put_data (&writer, cmd_check_prefix_type2, -+ cmd_check_prefix_type2_len); -+ else -+ 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_ids->len > 6) -+ { -+ 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 */ -+ 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 */ -+ written &= fpi_byte_writer_change_pos (&writer, -+ EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH); -+ -+ 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), -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ } -+ -+ /* command suffix */ -+ 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 fpi_byte_writer_reset_and_get_data (&writer); -+} -+ -+static void -+egis_etu905_enroll_run_state (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ g_auto(FpiByteWriter) writer = {0}; -+ EgismocSidData sid_data = {0}; -+ EnrollPrint *enroll_print = fpi_ssm_get_data (ssm); -+ g_autofree guchar *payload = NULL; -+ gsize payload_length = 0; -+ g_autofree gchar *device_print_id = NULL; -+ g_autofree gchar *user_id = NULL; -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case ENROLL_START: -+ egis_etu905_exec_cmd (device, cmd_enroll_starting, cmd_enroll_starting_len, -+ NULL, egis_etu905_enroll_begin_cb); -+ break; -+ -+ case ENROLL_CAPTURE_SENSOR_RESET: -+ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case ENROLL_CAPTURE_SENSOR_START_CAPTURE: -+ egis_etu905_exec_cmd (device, cmd_sensor_start_capture, cmd_sensor_start_capture_len, -+ NULL, -+ egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case ENROLL_CAPTURE_WAIT_FINGER: -+ egis_etu905_wait_finger_on_sensor (ssm, device); -+ break; -+ -+ case ENROLL_CAPTURE_READ_RESPONSE: -+ egis_etu905_exec_cmd (device, cmd_read_capture, cmd_read_capture_len, -+ NULL, egis_etu905_read_capture_cb); -+ break; -+ -+ case ENROLL_DUPLICATE_CHECK: -+ egis_etu905_exec_cmd (device, cmd_duplicate_check, cmd_duplicate_check_len, -+ NULL, egis_etu905_enroll_duplicate_check_cb); -+ break; -+ -+ case ENROLL_COMMIT_START: -+ egis_etu905_exec_cmd (device, cmd_commit_starting, cmd_commit_starting_len, -+ NULL, egis_etu905_commit_start_cb); -+ break; -+ -+ case ENROLL_COMMIT: -+ user_id = fpi_print_generate_user_id (enroll_print->print); -+ fp_dbg ("New fingerprint ID: %s", user_id); -+ -+ sid_data.reserve_para_1 = EGIS_ETU905_PARA_1_VALUE; -+ sid_data.reserve_para_2 = EGIS_ETU905_PARA_2_VALUE; -+ sid_data.reserve_para_3 = EGIS_ETU905_PARA_3_VALUE; -+ memcpy (sid_data.reserve_para_4, user_id, MIN (EGIS_ETU905_FINGERPRINT_DATA_SIZE, strlen (user_id))); -+ egis_etu905_set_print_data (enroll_print->print, (const gchar *) &sid_data.reserve_para_4, user_id); -+ fpi_byte_writer_init (&writer); -+ if (!fpi_byte_writer_put_data (&writer, cmd_new_print_prefix_type2, -+ cmd_new_print_prefix_type2_len)) -+ { -+ fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); -+ break; -+ } -+ if (!fpi_byte_writer_put_data (&writer, (guint8 *) &sid_data, -+ sizeof (EgismocSidData))) -+ { -+ fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); -+ break; -+ } -+ -+ payload_length = fpi_byte_writer_get_size (&writer); -+ egis_etu905_exec_cmd (device, fpi_byte_writer_reset_and_get_data (&writer), -+ payload_length, -+ g_free, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case ENROLL_COMMIT_SENSOR_RESET: -+ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case ENROLL_COMPLETE: -+ egis_etu905_enroll_status_report (device, enroll_print, ENROLL_STATUS_COMPLETE, NULL); -+ fpi_ssm_next_state (ssm); -+ break; -+ } -+} -+ -+static void -+egis_etu905_enroll (FpDevice *device) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ EnrollPrint *enroll_print = g_new0 (EnrollPrint, 1); -+ -+ fp_dbg ("Enroll"); -+ -+ fpi_device_get_enroll_data (device, &enroll_print->print); -+ enroll_print->stage = 0; -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, egis_etu905_enroll_run_state, ENROLL_STATES); -+ fpi_ssm_set_data (self->task_ssm, g_steal_pointer (&enroll_print), g_free); -+ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); -+} -+ -+static void -+egis_etu905_identify_check_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Identify check callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ gchar device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; -+ FpPrint *print = NULL; -+ FpPrint *verify_print = NULL; -+ GPtrArray *prints; -+ gboolean found = FALSE; -+ guint index; -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload indicates "match" */ -+ if (egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_identify_match_suffix, -+ rsp_identify_match_suffix_len)) -+ { -+ /* -+ On success, there is a 32 byte array of "something"(?) in chars 14-45 -+ and then the 32 byte array ID of the matched print comes as chars 46-77 -+ */ -+ memcpy (device_print_id, -+ buffer_in + EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET, -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE); -+ -+ /* Create a new print from this device_print_id and then see if it matches -+ * the one indicated -+ */ -+ print = fp_print_new (device); -+ egis_etu905_set_print_data (print, device_print_id, NULL); -+ -+ if (!print) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, -+ "Failed to build a print from " -+ "device response.")); -+ return; -+ } -+ -+ fp_info ("Identify successful for: %s", fp_print_get_description (print)); -+ -+ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) -+ { -+ fpi_device_get_identify_data (device, &prints); -+ found = g_ptr_array_find_with_equal_func (prints, -+ print, -+ (GEqualFunc) fp_print_equal, -+ &index); -+ -+ if (found) -+ fpi_device_identify_report (device, g_ptr_array_index (prints, index), print, NULL); -+ else -+ fpi_device_identify_report (device, NULL, print, NULL); -+ } -+ else -+ { -+ fpi_device_get_verify_data (device, &verify_print); -+ fp_info ("Verifying against: %s", fp_print_get_description (verify_print)); -+ -+ if (fp_print_equal (verify_print, print)) -+ fpi_device_verify_report (device, FPI_MATCH_SUCCESS, print, NULL); -+ else -+ fpi_device_verify_report (device, FPI_MATCH_FAIL, print, NULL); -+ } -+ } -+ /* If device was successfully read but it was a "not matched" */ -+ else if (egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_identify_notmatch_suffix, -+ rsp_identify_notmatch_suffix_len)) -+ { -+ fp_info ("Print was not identified by the device"); -+ -+ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY) -+ fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL); -+ else -+ fpi_device_identify_report (device, NULL, NULL, NULL); -+ } -+ else -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Unrecognized response from device.")); -+ return; -+ } -+ -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+static void -+egis_etu905_identify_run_state (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ g_autofree guchar *payload = NULL; -+ gsize payload_length = 0; -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case IDENTIFY_GET_ENROLLED_IDS: -+ /* get enrolled_ids from device for use in check stages below */ -+ egis_etu905_exec_cmd (device, cmd_list, cmd_list_len, -+ NULL, egis_etu905_list_fill_enrolled_ids_cb); -+ break; -+ -+ case IDENTIFY_CHECK_ENROLLED_NUM: -+ 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)); -+ return; -+ } -+ fpi_ssm_next_state (ssm); -+ break; -+ -+ case IDENTIFY_SENSOR_RESET: -+ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case IDENTIFY_SENSOR_IDENTIFY: -+ egis_etu905_exec_cmd (device, cmd_sensor_identify, cmd_sensor_identify_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case IDENTIFY_WAIT_FINGER: -+ egis_etu905_wait_finger_on_sensor (ssm, device); -+ break; -+ -+ case IDENTIFY_SENSOR_CHECK: -+ egis_etu905_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ case IDENTIFY_CHECK: -+ payload = egis_etu905_get_check_cmd (device, &payload_length); -+ egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, -+ g_free, egis_etu905_identify_check_cb); -+ break; -+ -+ case IDENTIFY_COMPLETE_SENSOR_RESET: -+ egis_etu905_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, -+ NULL, egis_etu905_task_ssm_next_state_cb); -+ break; -+ -+ /* -+ * In Windows, the driver seems at this point to then immediately take -+ * another read from the sensor; this is suspected to be an on-chip -+ * "verify". However, because the user's finger is still on the sensor from -+ * the identify, then it seems to always return positive. We will consider -+ * this extra step unnecessary and just skip it in this driver. This driver -+ * will instead handle matching of the FpPrint from the gallery in the -+ * "verify" case of the callback egis_etu905_identify_check_cb. -+ */ -+ case IDENTIFY_COMPLETE: -+ if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) -+ fpi_device_identify_complete (device, NULL); -+ else -+ fpi_device_verify_complete (device, NULL); -+ -+ fpi_ssm_mark_completed (ssm); -+ break; -+ } -+} -+ -+static void -+egis_etu905_identify_verify (FpDevice *device) -+{ -+ fp_dbg ("Identify or Verify"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, egis_etu905_identify_run_state, IDENTIFY_STATES); -+ fpi_ssm_start (self->task_ssm, egis_etu905_task_ssm_done); -+} -+ -+static void -+egis_etu905_fw_version_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("Firmware version callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ g_autofree gchar *fw_version = NULL; -+ gsize prefix_length; -+ guchar *fw_version_start; -+ gsize fw_version_length; -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload indicates "success" */ -+ if (!egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_fw_version_suffix, -+ rsp_fw_version_suffix_len)) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Device firmware response " -+ "was not valid.")); -+ return; -+ } -+ -+ /* -+ * FW Version is 12 bytes: a carriage return (0x0d) plus the version string -+ * itself. Always skip [the read prefix] + [2 * check bytes] + [3 * 0x00] that -+ * come with every payload Then we will also skip the carriage return and take -+ * all but the last 2 bytes as the FW Version -+ */ -+ prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; -+ fw_version_start = buffer_in + prefix_length; -+ fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len; -+ fw_version = g_strndup ((gchar *) fw_version_start, fw_version_length); -+ -+ fp_info ("Device firmware version is %s", fw_version); -+ -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+static void -+egis_etu905_cmd_init_cb (FpDevice *device, -+ guchar *buffer_in, -+ gsize length_in, -+ GError *error) -+{ -+ fp_dbg ("cmd init callback"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ if (error) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, error); -+ return; -+ } -+ -+ /* Check that the read payload indicates "success" */ -+ if (!egis_etu905_validate_response_suffix (buffer_in, -+ length_in, -+ rsp_fw_version_suffix, -+ rsp_fw_version_suffix_len)) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "cmd init response " -+ "was not valid.")); -+ return; -+ } -+ fpi_ssm_next_state (self->task_ssm); -+} -+ -+static void -+egis_etu905_dev_init_done (FpiSsm *ssm, -+ FpDevice *device, -+ GError *error) -+{ -+ if (error) -+ { -+ g_usb_device_release_interface ( -+ fpi_device_get_usb_device (device), 0, 0, NULL); -+ egis_etu905_task_ssm_done (ssm, device, error); -+ return; -+ } -+ -+ egis_etu905_task_ssm_done (ssm, device, NULL); -+ fpi_device_open_complete (device, NULL); -+} -+ -+static void -+egis_etu905_dev_init_handler (FpiSsm *ssm, -+ FpDevice *device) -+{ -+ g_autoptr(FpiUsbTransfer) transfer = NULL; -+ -+ switch (fpi_ssm_get_cur_state (ssm)) -+ { -+ case DEV_GET_FW_VERSION: -+ egis_etu905_exec_cmd (device, cmd_fw_version, cmd_fw_version_len, -+ NULL, egis_etu905_fw_version_cb); -+ return; -+ -+ case DEV_INIT_CONTROL: -+ egis_etu905_exec_cmd (device, cmd_init, cmd_init_len, -+ NULL, egis_etu905_cmd_init_cb); -+ return; -+ -+ default: -+ g_assert_not_reached (); -+ } -+ -+ transfer = fpi_usb_transfer_new (device); -+ transfer->ssm = ssm; -+ transfer->short_is_error = TRUE; -+ fpi_usb_transfer_submit (g_steal_pointer (&transfer), -+ EGIS_ETU905_USB_CONTROL_TIMEOUT, -+ fpi_device_get_cancellable (device), -+ fpi_ssm_usb_transfer_cb, -+ NULL); -+} -+ -+static void -+egis_etu905_probe (FpDevice *device) -+{ -+ GUsbDevice *usb_dev; -+ GError *error = NULL; -+ g_autofree gchar *serial = NULL; -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (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) & EGIS_ETU905_DRIVER_MAX_ENROLL_STAGES_20) -+ self->max_enroll_stages = 20; -+ else -+ self->max_enroll_stages = EGIS_ETU905_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 -+egis_etu905_open (FpDevice *device) -+{ -+ fp_dbg ("Opening device"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ g_autoptr(GError) error = NULL; -+ -+ if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error)) -+ { -+ fpi_device_open_complete (device, g_steal_pointer (&error)); -+ return; -+ } -+ -+ if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), -+ 0, 0, &error)) -+ { -+ fpi_device_open_complete (device, g_steal_pointer (&error)); -+ return; -+ } -+ -+ g_assert (self->task_ssm == NULL); -+ self->task_ssm = fpi_ssm_new (device, egis_etu905_dev_init_handler, DEV_INIT_STATES); -+ fpi_ssm_start (self->task_ssm, egis_etu905_dev_init_done); -+} -+ -+static void -+egis_etu905_cancel (FpDevice *device) -+{ -+ fp_dbg ("Cancel"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ -+ g_cancellable_cancel (self->interrupt_cancellable); -+ g_clear_object (&self->interrupt_cancellable); -+ self->interrupt_cancellable = g_cancellable_new (); -+} -+ -+static void -+egis_etu905_suspend (FpDevice *device) -+{ -+ fp_dbg ("Suspend"); -+ -+ egis_etu905_cancel (device); -+ g_cancellable_cancel (fpi_device_get_cancellable (device)); -+ fpi_device_suspend_complete (device, NULL); -+} -+ -+static void -+egis_etu905_close (FpDevice *device) -+{ -+ g_autoptr(GError) error = NULL; -+ fp_dbg ("Closing device"); -+ FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ GError *error = NULL; -+ -+ egis_etu905_cancel (device); -+ g_clear_object (&self->interrupt_cancellable); -+ -+ g_usb_device_release_interface (fpi_device_get_usb_device (device), -+ 0, 0, &error); -+ fpi_device_close_complete (device, g_steal_pointer (&error)); -+} -+ -+static void -+fpi_device_egis_etu905_init (FpiDeviceEgisEtu905 *self) -+{ -+ G_DEBUG_HERE (); -+} -+ -+static void -+fpi_device_egis_etu905_class_init (FpiDeviceEgisEtu905Class *klass) -+{ -+ FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); -+ -+ dev_class->id = FP_COMPONENT; -+ dev_class->full_name = EGIS_ETU905_DRIVER_FULLNAME; -+ -+ dev_class->type = FP_DEVICE_TYPE_USB; -+ dev_class->scan_type = FP_SCAN_TYPE_PRESS; -+ dev_class->id_table = egis_etu905_id_table; -+ dev_class->nr_enroll_stages = EGIS_ETU905_MAX_ENROLL_STAGES_DEFAULT; -+ dev_class->temp_hot_seconds = -1; -+ -+ dev_class->probe = egis_etu905_probe; -+ dev_class->open = egis_etu905_open; -+ dev_class->cancel = egis_etu905_cancel; -+ dev_class->suspend = egis_etu905_suspend; -+ dev_class->close = egis_etu905_close; -+ dev_class->identify = egis_etu905_identify_verify; -+ dev_class->verify = egis_etu905_identify_verify; -+ dev_class->enroll = egis_etu905_enroll; -+ dev_class->delete = egis_etu905_delete; -+ dev_class->clear_storage = egis_etu905_clear_storage; -+ dev_class->list = egis_etu905_list; -+ -+ fpi_device_class_auto_initialize_features (dev_class); -+ dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK; -+} -diff --git a/libfprint/drivers/egismoc/egis_etu905.h b/libfprint/drivers/egismoc/egis_etu905.h -new file mode 100644 -index 00000000..e931deca ---- /dev/null -+++ b/libfprint/drivers/egismoc/egis_etu905.h -@@ -0,0 +1,214 @@ -+/* -+ * Driver for Egis Technology (LighTuning) Match-On-Chip sensors -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#pragma once -+ -+#include "fpi-device.h" -+#include "fpi-ssm.h" -+ -+G_DECLARE_FINAL_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FPI, DEVICE_EGIS_ETU905, FpDevice) -+ -+#define EGIS_ETU905_DRIVER_FULLNAME "Egis Technology (LighTuning) Match-on-Chip" -+ -+#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE1 (1 << 0) -+#define EGIS_ETU905_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1) -+#define EGIS_ETU905_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2) -+ -+#define EGIS_ETU905_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT) -+#define EGIS_ETU905_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN) -+#define EGIS_ETU905_EP_CMD_INTERRUPT_IN 0x83 -+ -+#define EGIS_ETU905_USB_CONTROL_TIMEOUT 5000 -+#define EGIS_ETU905_USB_SEND_TIMEOUT 5000 -+#define EGIS_ETU905_USB_RECV_TIMEOUT 5000 -+#define EGIS_ETU905_USB_INTERRUPT_TIMEOUT 0 /* No timeout for waiting for finger down */ -+ -+#define EGIS_ETU905_USB_IN_RECV_LENGTH 4096 -+#define EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH 64 -+ -+#define EGIS_ETU905_MAX_ENROLL_STAGES_DEFAULT 12 -+#define EGIS_ETU905_MAX_ENROLL_NUM 12 -+#define EGIS_ETU905_FINGERPRINT_DATA_SIZE 32 -+#define EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE 14 -+#define EGIS_ETU905_LIST_RESPONSE_SUFFIX_SIZE 2 -+ -+#define EGIS_ETU905_PARA_4_SIZE 68 -+ -+#define EGIS_ETU905_PARA_1_VALUE 0 -+#define EGIS_ETU905_PARA_2_VALUE 0 -+#define EGIS_ETU905_PARA_3_VALUE 32 -+ -+#pragma pack(push, 1) -+typedef struct -+{ -+ guchar reserve_para_1; -+ gushort reserve_para_2; -+ gushort reserve_para_3; -+ guchar reserve_para_4[EGIS_ETU905_PARA_4_SIZE]; -+} EgismocSidData; -+#pragma pack(pop) -+ -+/* standard prefixes for all read/writes */ -+ -+static guchar egis_etu905_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01}; -+static gsize egis_etu905_write_prefix_len = sizeof (egis_etu905_write_prefix) / sizeof (egis_etu905_write_prefix[0]); -+ -+static guchar egis_etu905_read_prefix[] = {'S', 'I', 'G', 'E', 0x00, 0x00, 0x00, 0x01}; -+static gsize egis_etu905_read_prefix_len = sizeof (egis_etu905_read_prefix) / sizeof (egis_etu905_read_prefix[0]); -+ -+ -+/* hard-coded command payloads */ -+ -+static guchar cmd_fw_version[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x0c}; -+static gsize cmd_fw_version_len = sizeof (cmd_fw_version) / sizeof (cmd_fw_version[0]); -+static guchar rsp_fw_version_suffix[] = {0x90, 0x00}; -+static gsize rsp_fw_version_suffix_len = sizeof (rsp_fw_version_suffix) / sizeof (rsp_fw_version_suffix[0]); -+ -+static guchar cmd_init[] = {0x00, 0x00, 0x00, 0x29, 0x50, 0x81, 0x80, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12, 0x00, 0x45, 0x67, 0x69, 0x73, -+ 0x46, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x51, 0xc6, 0xbd, 0x71}; -+static gsize cmd_init_len = sizeof (cmd_init) / sizeof (cmd_init[0]); -+ -+static guchar cmd_list[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x19, 0x04, 0x00, 0x00, 0x01, 0x40}; -+static gsize cmd_list_len = sizeof (cmd_list) / sizeof (cmd_list[0]); -+ -+static guchar cmd_sensor_reset[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x1a, 0x00, 0x00}; -+static gsize cmd_sensor_reset_len = sizeof (cmd_sensor_reset) / sizeof (cmd_sensor_reset[0]); -+ -+static guchar cmd_sensor_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x02, 0x00}; -+static gsize cmd_sensor_check_len = sizeof (cmd_sensor_check) / sizeof (cmd_sensor_check[0]); -+ -+static guchar cmd_sensor_identify[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x01, 0x01}; -+static gsize cmd_sensor_identify_len = sizeof (cmd_sensor_identify) / sizeof (cmd_sensor_identify[0]); -+ -+static guchar rsp_identify_match_suffix[] = {0x90, 0x00}; -+static gsize rsp_identify_match_suffix_len = sizeof (rsp_identify_match_suffix) / sizeof (rsp_identify_match_suffix[0]); -+ -+static guchar rsp_identify_notmatch_suffix[] = {0x90, 0x04}; -+static gsize rsp_identify_notmatch_suffix_len = sizeof (rsp_identify_notmatch_suffix) / sizeof (rsp_identify_notmatch_suffix[0]); -+ -+static guchar cmd_enroll_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x01, 0x00, 0x00, 0x00, 0x20}; -+static gsize cmd_enroll_starting_len = sizeof (cmd_enroll_starting) / sizeof (cmd_enroll_starting[0]); -+ -+static guchar cmd_sensor_start_capture[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x02, 0x01}; -+static gsize cmd_sensor_start_capture_len = sizeof (cmd_sensor_start_capture) / sizeof (cmd_sensor_start_capture[0]); -+ -+static guchar cmd_read_capture[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x02, 0x02, 0x00, 0x00, 0x02}; -+static gsize cmd_read_capture_len = sizeof (cmd_read_capture) / sizeof (cmd_read_capture[0]); -+ -+static guchar cmd_duplicate_check[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x05, 0x00}; -+static gsize cmd_duplicate_check_len = sizeof (cmd_duplicate_check) / sizeof (cmd_duplicate_check[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[] = {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[] = {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]); -+ -+static guchar cmd_commit_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x05, 0x00, 0x00, 0x00, 0x20}; -+static gsize cmd_commit_starting_len = sizeof (cmd_commit_starting) / sizeof (cmd_commit_starting[0]); -+ -+/* prefixes/suffixes and other things for dynamically created command payloads */ -+ -+#define EGIS_ETU905_CHECK_BYTES_LENGTH 2 -+#define EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET 46 -+#define EGIS_ETU905_CMD_CHECK_SEPARATOR_LENGTH 32 -+ -+static guchar cmd_new_print_prefix_type2[] = {0x00, 0x00, 0x00, 0x50, 0x50, 0x16, 0x03, 0x00, 0x00, 0x00, 0x49}; -+static gsize cmd_new_print_prefix_type2_len = sizeof (cmd_new_print_prefix_type2) / sizeof (cmd_new_print_prefix_type2[0]); -+ -+static guchar cmd_delete_prefix[] = {0x50, 0x18, 0x04, 0x00, 0x00}; -+static gsize cmd_delete_prefix_len = sizeof (cmd_delete_prefix) / sizeof (cmd_delete_prefix[0]); -+static guchar rsp_delete_success_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x90, 0x00}; -+static gsize rsp_delete_success_prefix_len = sizeof (rsp_delete_success_prefix) / sizeof (rsp_delete_success_prefix[0]); -+ -+static guchar cmd_check_prefix_type1[] = {0x50, 0x17, 0x03, 0x00, 0x00}; -+static gsize cmd_check_prefix_type1_len = sizeof (cmd_check_prefix_type1) / sizeof (cmd_check_prefix_type1[0]); -+static guchar cmd_check_prefix_type2[] = {0x50, 0x17, 0x03, 0x80, 0x00}; -+static gsize cmd_check_prefix_type2_len = sizeof (cmd_check_prefix_type2) / sizeof (cmd_check_prefix_type2[0]); -+static guchar cmd_check_suffix[] = {0x00, 0x40}; -+static gsize cmd_check_suffix_len = sizeof (cmd_check_suffix) / sizeof (cmd_check_suffix[0]); -+static guchar rsp_check_not_yet_enrolled_suffix[] = {0x90, 0x04}; -+static gsize rsp_check_not_yet_enrolled_suffix_len = sizeof (rsp_check_not_yet_enrolled_suffix) / sizeof (rsp_check_not_yet_enrolled_suffix[0]); -+ -+ -+/* SSM task states and various status enums */ -+ -+typedef enum { -+ CMD_SEND, -+ CMD_GET, -+ CMD_STATES, -+} CommandStates; -+ -+typedef enum { -+ DEV_GET_FW_VERSION, -+ DEV_INIT_CONTROL, -+ DEV_INIT_STATES, -+} DeviceInitStates; -+ -+typedef enum { -+ IDENTIFY_GET_ENROLLED_IDS, -+ IDENTIFY_CHECK_ENROLLED_NUM, -+ IDENTIFY_SENSOR_RESET, -+ IDENTIFY_SENSOR_IDENTIFY, -+ IDENTIFY_WAIT_FINGER, -+ IDENTIFY_SENSOR_CHECK, -+ IDENTIFY_CHECK, -+ IDENTIFY_COMPLETE_SENSOR_RESET, -+ IDENTIFY_COMPLETE, -+ IDENTIFY_STATES, -+} IdentifyStates; -+ -+typedef enum { -+ ENROLL_START, -+ ENROLL_CAPTURE_SENSOR_RESET, -+ ENROLL_CAPTURE_SENSOR_START_CAPTURE, -+ ENROLL_CAPTURE_WAIT_FINGER, -+ ENROLL_CAPTURE_READ_RESPONSE, -+ ENROLL_DUPLICATE_CHECK, -+ ENROLL_COMMIT_START, -+ ENROLL_COMMIT, -+ ENROLL_COMMIT_SENSOR_RESET, -+ ENROLL_COMPLETE, -+ ENROLL_STATES, -+} EnrollStates; -+ -+typedef enum { -+ ENROLL_STATUS_DEVICE_FULL, -+ ENROLL_STATUS_DUPLICATE, -+ ENROLL_STATUS_PARTIAL_OK, -+ ENROLL_STATUS_RETRY, -+ ENROLL_STATUS_COMPLETE, -+} EnrollStatus; -+ -+typedef enum { -+ LIST_GET_ENROLLED_IDS, -+ LIST_RETURN_ENROLLED_PRINTS, -+ LIST_STATES, -+} ListStates; -+ -+typedef enum { -+ DELETE_GET_ENROLLED_IDS, -+ DELETE_DELETE, -+ DELETE_STATES, -+} DeleteStates; -diff --git a/libfprint/meson.build b/libfprint/meson.build -index ae0f6e24..081b18de 100644 ---- a/libfprint/meson.build -+++ b/libfprint/meson.build -@@ -127,6 +127,8 @@ driver_sources = { - [ 'drivers/egis0570.c' ], - 'egismoc' : - [ 'drivers/egismoc/egismoc.c' ], -+ 'egis_etu905' : -+ [ 'drivers/egismoc/egis_etu905.c' ], - 'vfs0050' : - [ 'drivers/vfs0050.c' ], - 'elan' : -diff --git a/meson.build b/meson.build -index 14fb11f2..02b43e4f 100644 ---- a/meson.build -+++ b/meson.build -@@ -131,6 +131,7 @@ default_drivers = [ - 'etes603', - 'egis0570', - 'egismoc', -+ 'egis_etu905', - 'vcom5s', - 'synaptics', - 'elan', -@@ -165,6 +166,7 @@ endian_independent_drivers = virtual_drivers + [ - 'aes4000', - 'egis0570', - 'egismoc', -+ 'egis_etu905', - 'elanmoc', - 'etes603', - 'focaltech_moc', -diff --git a/tests/egis_etu905/custom.pcapng b/tests/egis_etu905/custom.pcapng -new file mode 100644 -index 0000000000000000000000000000000000000000..b21c4622a1b5b44f25065882cff3d3e2687d76d1 -GIT binary patch -literal 33644 -zcmd5_3wTu3xjmT#LVzG3f*|OqRD2~QV4zCGgNO)%jX(@qv=e!ms(?H!qOAjnpx#In -z5WNNg1^n8ATB=<2T8%_}w2H+y7WGnFt8&#(K&_9;{r|J~+WX9(d7aboYKXEJln -zthN8W_FiY7J)5CzadF!x9LE`5c~Xx&dOn~_#5u(oGWx9Om}}-uo))c$R#cRgRY!kO -zH~X^anA%B`r%#IxpIJNOvbu@0qQ`shjvYJfl+u1D$2LJm!A-&&z1Iz9zVQpcJylX_l(+! -zm)B06JSkc`OC2pKFD<`xPTdug`kz3Rq{4OP`kq6vi^6TncOp)qGiTPNS5BYS-zlP_ -zt?B*tY3f6Vz0dP`F@8a%@2J*J&qc!;UHY3Np7%lJ%Qqi5Fg6m8{ax3OR+X=0{wI -zo+9dLVZKXUhxuimpG_KPHEWyL4?F07IDJ_7epr9SINJ|3J~RV<@#x(4!_SG6vUfP* -zDRR1sIKyhUZtgg%U5cD~U--jomw!#>JQq?uI8PeCUWvEP&o3&#D|$=!p&0$ied9U` -zF5E|#$Hz5ZM1OOj9i?_%YE_;+=p2p~MdSC#FLQ=CKXwKj9)Ss_@7;_a!Uf4@K!SX&6VRb -z_Q8I=3O#M$z3~A4zIoXAjN_``afMzzbLH>d&d!|EO5zMVuFe@fKI6E0zC`8pLwe$E -zR1cS0j>8!-_iX>Q8GWNusmc>0Dag2LS3Ta0E8xp{Ix2ik6IeuT%Z@rC0?s`?*B -zr*Nby!-kI-OULrMyi1RTRoC-*?J1Z~`o+J9*QNJ4z&lj&8o&4@@p4JW$;V?9694|6 -zTl^;Ux%~N@S0(yfpL4Y?9T_D_N#o^_8^<^Pls>`%{GkfpwA+Fys{TjNIUFsD#veOk -z_%J$_cj_DTSbS<(MOkS@Y5&qw`ZZWDzf*shHM@+se?hM~+=!lI2+ckuZuSkn9&n^8 -z&}{R5I^%?@`EhzW#ydIcJvtp}Dm!dy-K?{##!j9!t8V%<=lo~?aFxULk!}72)yt*# -zz0mcNnpRF#ZIZ4|1d&wJeLnoAeB_;|=`6zMys6&Fi_mn2K8xFR?*ro-tLQZc@TI0R -zm#X?RJV%QnG=2R_IwR8H%%CSZ_MFXj?76LwPvY2%-yUr2y>liJ6;^epnQNX)evZ2+KAkka)alsAg6VW%Iwc#K{CzT= -z9(u>>@}}y^?&1GPoGzWh0ZysmNaEyzd8_v#$wQ3Zvf_=@93P8Hz0wEapu?P(^{WK=DM3W&ZeCiOrzJl>(*`Ny2W{M;XXHIqHQnS$BxZg -zm@v2cV5ri_^*&`E%pIl3XN^9E@fR+e+Q^ef4&V<}_|74E4W+qUjhQp(91awT58o*5 -zMQ4>&gDih3j|M@~LLd93QFgXY~9F_1oDm*!7?n&j9Iq5TSPA -zrb%`^*iF1H9peBm`YCvi?jQboFn@&)e+cqY{S^356Mm5Sm49pxDy%bOJFfBJCBVOS -zy&Y#s$C~ap(Dk(#HAX>Ry9Ro~*!FX-Y2)KO3ppvz2j~B62<9i5Jbw>yx>O&IxaO2P -zopis=lTJ%nVsu3M$$u7E{3aJUCF=Ax;Rn&l?NW(vU!$kCTaAD(H9BxbFpbiA{(Udo_KFv3jkM<@pZBj+8o5+;f03RXql4UD -zYbdy|r}mn%zM)%q#V#na8lF)zu+ -z^G6b|OL!dSdkwu#0^YXsRlB6)q>m?^oBYv--&BOLr@RFCHxqskFY){D!15c6=K~-8 -z6!>3_Y{k{{##z#_CcNa;7@b@YN$L47^|PGrl7{x%`MW@&RsE<|f&3(s=XdIVgV70` -z@Dt>@gE+Y)&Cxre9%A$){baKre-Uy@)M@5ul~Wi$d27WD#`9f`FLk=}K~?`;c>csY -ztVYg_$VYiT+UwYdf@zd#o_{-Wy41ED;FKDTAxYAL*bvd2qulUBcSJO>8AMN?jsJcsQZydQEt9{7E^B-HZ%y>TV;rX4l -z=bw79(&J!w{sT8Ivz|X6da6E(`juXy`e-gae=qTJdve4zFZwBXXA&=$FrGhnvBh`d -z$V>H8;6JJJ%C?{SJ^#fsRv6C*KKd!}M|HDn9!bZV@cdU|lx#tMO3&{-q$MXjADrtB -z&+XdIwZ!RCwK!~^UjG;j&Tom6OVS*@BkCbWPtx=E`|!~Zus#R;+1-QPkNM}2k##GK -z=L28rwBTA*|6F+fr^Gjg^5npHml{pGE|^A{Jip(1s}VTmSlUdST*7Fy(T5LDmKvS> -z%kUaaFTBHQq^~JbqtD(ArcpZ2uWfUO?bEm}YtKiY+x?!($MssxK4jzhe?4)v@qBX) -z)@wV5YR^BWNg*8!&)<2{YUBBs2ceIme%+tW^R9Wh^!(__t4+Iu7yT5xG2-PC#`D+t -z@y(oAc|P#}rt=Ep`M++z){JdC|Ml=4;D5AM-KX$4OFGts=kJKoi3J5IJ-@!#ayspC -z@1m~H;C$&`b?=grlPI|0o-ETm|9Rqc>3j}wN}bx=XY=IKQk57Tke=^!u=q_Tr$n7x -z!Vhvk=J))Xj%$sd03UvWHe0z~)jt=W{|NDop*%U_1<5t~g7`R}Y&FW{`5zOfOMD#Q -zlp3A5A-qO|I$3<@5ag7o(Y1shR->7-twz9?8g1siiBz)HD4pkzn`85FJLr70=c7+7 -zZ(HEy<9e+2Asf%{v*tI(^MQ|fKJcej6nmft!}Hs({f+Vbcro-$^pQ~mioN`E>G@NL -zm)nyAyt1EeAYLwEJpU~pzT+UT#D04CK$TY*&+k{a(Tr{2%YHiZ`wm|HQ;u!n`G1bl -z=>@G)dj7(n`#8;dRiakS2Ra1ulT4of7vglOS{#n%lsX;Z9KuJFU)Q`N>LEr?((_kc -zZt>lA$#r^%@WcAals|1Wo)3KJ)J4y^rW~p2m#v?qThAZ#qSdI$^gE>y_y!&21kxyz -z=Px5pmr~#WCo}@*GUDXIeKB2$(Lt%v;V-qs$2=eSheuUT*^VXub$Lk1CZmz9znVV* -ze@L7vMkQN~(s_QL(oLql&?oR6F8KP)SNXUet9{7E^WT4Xi}ifnr{Vd)f4{J;2YN6( -zzv+=J#`7_zG0#W+n%cC@x#u6TWs7Nd@XCIAM3HKjFrI(6AK#2U<@w0#Zo&`ZCH}RY -zvPF-k^nBo#z17asHCxYrIYy@!v`*>yr8inmTqmVgr90aN@{>%Se-&}MR4op0N}aAE -zPA*~mq}hj$Ig#{}W}Q6H -z^86$ASdG9bH9BIj$}x;a^*(&uM@Wt82|vhK@_YV!qaHIF0bgqL-s)f)rStse(T|xv -zje9@o`ORxoKCag@>_ax5U;V~bfH)XD;XYHxaK(iE=oa7yT5xBR*8^62|lQ`|$A{EBYz$A13@D{nYRI -zt)F|wcs}saPl5mJn|41-(yrxweVfN&Dyo15p -z`F7PVVLZS0GZw!|>@NfUI>Ha@`CT6Svl-jKM?VGr^2O>qXdY)t$C~i`mtu5cL7SAG -zf63#P6MN0!C*XW{Nw7U3ndbSMiPO`Fss>K@2{`-RWb>rcQkEDUk)D6te_MR)|Hri% -z_!|g6h)(`FhzC~RsFMFH%RCCgL~~T{lXFd76$n|xhI%LndbS+iPNRF -zh^ZXyhZ9eD|@O<#C -zKQH{gomXz%X*?hJ((}h$tk!)GhUafsy3=~T_;+>4|F}!k8gVW?Khm(%^wU&cvVeHG -zgz@~fK74qx?59WnOy!mB+{8c6AO7H9%-9A#yri4HmMfVdj7e;v-p@3K_}qf -zLil0*eOqss(-eAlFsx0cIYnCFED4tbs72eUK32COrC#ymt9sPu|FT2 -zmk}qIq;n7NhQqgf -zT$1MK9Z?T4dXj#!*oTj`PpQ*$I;U)}%`-G7kH6Et{=4yf;7gt6EmHN*)=$!Te)%_6 -zBdkqJjjp;em`0gA|7zlNDQ6CFN{zMKqje0a}mAE|s?uhr~BHl81O>r>d%dz0AK1fW_7T= -z-|0NRXN}bedr;(f>bW+UMwvW+0&%+3wjAJ;V`&0$atWi+A>&)(%dvFGz2W!gcfG-C -zWb3cicF+g9ZV#qWI?w+n@wwC%USO}7p67$_pTx(W$LIJ%=0h2 -z&j&vGDeyaduIiuCe}(5~n&+?h*m7b$41NO6>b=4Ce)k+nb)?_#;yWtNPkQoa#Oc!e -z9N>hXfb&7(?9;&}f?{lF3a$H`rP_V-hyBhsaZFZ~svN_3=jc8b -zAK!_~Yg}>PV0%;jb1|pNr;+(BTXp}9G2c}4?`h=s&g;%UV7wE1ALN*d`CG8i>Hc4<`j^q? -zI9im5dI#S#jk=3oACt+y>~F#Pb^OITtE0^~@ftXAWA1f)lXzXKHV1g6jw^|mOBfw5 -zT5s{uPvm&(u_?Tct@m3UfiFGr*>8VX9sP6MFR4CbsI54xza;9o&kO_Ijf9DdcTeI -z%!(fcTUU;rLzOS6>Xt{-hh+Bz4-ltIr+6Xu_`q+b5hs^08byw@_?X*BjkfBXvb}ek -z;nha@w2DH~Jo5HUvuXw6-)%BDg2k^1R&{MB5 -ztZ>x7t;lwbq2x#cEAN&U_BVa~KGM6X)bvr@o1l-Pe!cU8{d*I=4%Uq?Tgm!pEpfWs -z9u(k&kASn5IJt!BqxC-gxVUcxe!b2qOdqXpE;T*^eDqO+U!dyWk#gW@QMhra;F>Od -z=?_-Luw;lO>q)My*=u`kxpIUK19?uS0&-;*Cv)s63m+*Bvy{Y+C0Lg4zc -z^T+gOc<;vGXROYsx72xXE7eZv>dcUgEAeOg@UhMVFM9$5pzqg?^IhyXM=7(BGkwtgm~F1){O)BQl}H1 -zR`oBVQ#e`_p;OTNDF0YHe}0)6YfbpQIQ?6@==bMu&FxsblQ>;UiUXWd!#jzSOPI0N -zVS&YW@Vlpay%#xkXb$#Wtfv>%hsWBizm}P?27IaEtYd?Heaz{Q8@MX_RjM{m6)N(_YTP#NXNl-y=7N|BkQb;c7Gg20rHBN9p>V-)h5-D!)(Z-S=UM}U8RS@`wowOuYSeH8fc5#aB>Rn@;E)sLe^5t>RL@z1~S -zKI{TB|86qB8?1Z;e1BQ0^7;QX|BiOO!03#6OPym4s-42jzn}8qJ4?}bl^3C14iJ9W -z`S;u9HD>+|e5rGfjY`NW5}2b!5jy{n^Y2so*O;*!UySxh>?gA~seg--?O4t<|DH#j -zE+x$YPO0(Z#K|ShSpFmlKIV1Mxa0wqQ}TgE#9D(G{mEW2gMtgs3F-&dn6Yf@udX-1 -zf9ZD$fX6XMi=y#U-AnuD-}QrP%={aD3iEHn_lU}e=fUab!tmQ{=HGuJUYGDVz$BE2tUYJY+y1ftkZy}Ys~x`_;M^>Jt*Hhzl -zA5y(sdY=RJk~$xMx@xC%b)t_a)%nzBi*M%(iJp56;Rn%q29r_YcAYnTf*Fs%mpVWG -zbg=bTd2RKN$1l&BV8^4GD>?>q~qk{ -vF$&oa_WAL}JRLsM{~486a#JHvJzjwC*Qv*7s}t@6q)rz-7fdJr{{{Mgzv_Nq - -literal 0 -HcmV?d00001 - -diff --git a/tests/egis_etu905/custom.py b/tests/egis_etu905/custom.py -new file mode 100644 -index 00000000..a842f26e ---- /dev/null -+++ b/tests/egis_etu905/custom.py -@@ -0,0 +1,109 @@ -+#!/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() == "egis_etu905" -+assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) -+assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) -+assert d.has_feature(FPrint.DeviceFeature.VERIFY) -+assert d.has_feature(FPrint.DeviceFeature.STORAGE) -+assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST) -+assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE) -+assert d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) -+ -+d.open_sync() -+ -+def enroll_progress(*args): -+ assert d.get_finger_status() == FPrint.FingerStatusFlags.PRESENT -+ print("enroll progress stage: " + str(args[1])) -+ -+def identify_done(dev, res): -+ global identified -+ identified = True -+ identify_match, identify_print = dev.identify_finish(res) -+ print("MATCH FOUND!" if identify_match else "NO MATCH FOUND") -+ assert identify_match.equal(identify_print) -+ -+# List -+print("--- LISTING ---") -+stored = d.list_prints_sync() -+prints1 = len(stored) -+print(f"--- LIST DONE: Found {prints1} prints before enroll---") -+ -+# Enroll -+print("--- ENROLLING ---") -+template = FPrint.Print.new(d) -+ -+assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE -+p = d.enroll_sync(template, None, enroll_progress, None) -+assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE -+print("--- ENROLL DONE ---") -+del template -+ -+# List -+print("--- LISTING ---") -+stored = d.list_prints_sync() -+prints2 = len(stored) -+print(f"--- LIST DONE: Found {prints2} prints after enroll---") -+assert (prints2 - prints1) == 1 -+ -+# Verify -+print("--- VERIFYING ---") -+assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE -+verify_res, verify_print = d.verify_sync(p) -+assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE -+print(f"--- VERIFY DONE: Result {verify_res} ---") -+ -+# Identify -+print("--- ASYNC IDENTIFYING ---") -+identified = False -+deserialized_prints = [] -+for p in stored: -+ deserialized_prints.append(FPrint.Print.deserialize(p.serialize())) -+ assert deserialized_prints[-1].equal(p) -+ -+d.identify(deserialized_prints, callback=identify_done) -+del deserialized_prints -+ -+while not identified: -+ ctx.iteration(True) -+print("--- IDENTIFY DONE ---") -+ -+# Delete -+print("--- DELETING ---") -+p_to_delete = next((sp for sp in stored if sp.equal(p)), None) -+if p_to_delete: -+ d.delete_print_sync(p_to_delete) -+ print("--- DELETE DONE ---") -+del p_to_delete -+del p -+ -+# List -+print("--- LISTING ---") -+stored = d.list_prints_sync() -+prints3 = len(stored) -+print(f"--- LIST DONE: Found {prints3} prints after deleting---") -+assert (prints2 - prints3) == 1 -+del stored -+ -+d.close_sync() -+ -+del d -+del c -diff --git a/tests/egis_etu905/device b/tests/egis_etu905/device -new file mode 100644 -index 00000000..4b750a79 ---- /dev/null -+++ b/tests/egis_etu905/device -@@ -0,0 +1,348 @@ -+P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3/3-3 -+N: bus/usb/003/002=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001 -+E: BUSNUM=003 -+E: DEVNAME=/dev/bus/usb/003/002 -+E: DEVNUM=002 -+E: DEVTYPE=usb_device -+E: DRIVER=usb -+E: ID_BUS=usb -+E: ID_MODEL=ETU905Axx-E -+E: ID_MODEL_ENC=ETU905Axx-E -+E: ID_MODEL_ID=05ae -+E: ID_PATH=pci-0000:05:00.4-usb-0:3 -+E: ID_PATH_TAG=pci-0000_05_00_4-usb-0_3 -+E: ID_PATH_WITH_USB_REVISION=pci-0000:05:00.4-usbv2-0:3 -+E: ID_REVISION=5342 -+E: ID_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357 -+E: ID_SERIAL_SHORT=0A8606PNA357 -+E: ID_USB_INTERFACES=:ffffff: -+E: ID_USB_MODEL=ETU905Axx-E -+E: ID_USB_MODEL_ENC=ETU905Axx-E -+E: ID_USB_MODEL_ID=05ae -+E: ID_USB_REVISION=5342 -+E: ID_USB_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357 -+E: ID_USB_SERIAL_SHORT=0A8606PNA357 -+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=257 -+E: PRODUCT=1c7a/5ae/5342 -+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=5342\n -+A: bmAttributes=a0\n -+A: busnum=3\n -+A: configuration= -+H: descriptors=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001 -+A: dev=189:257\n -+A: devnum=2\n -+A: devpath=3\n -+L: driver=../../../../../../bus/usb/drivers/usb -+L: firmware_node=../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/device:1b/device:1c/device:1f -+A: idProduct=05ae\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-port3 -+A: power/active_duration=93136758\n -+A: power/async=enabled\n -+A: power/autosuspend=2\n -+A: power/autosuspend_delay_ms=2000\n -+A: power/connected_duration=93139621\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=93138826\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=ETU905Axx-E\n -+A: quirks=0x0\n -+A: removable=fixed\n -+A: rx_lanes=1\n -+A: serial=0A8606PNA357\n -+A: speed=12\n -+A: tx_lanes=1\n -+A: urbnum=5855\n -+A: version= 2.00\n -+ -+P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3 -+N: bus/usb/003/001=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C -+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_05_00_4 -+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:05:00.4 -+E: ID_PATH_TAG=pci-0000_05_00_4 -+E: ID_REVISION=0614 -+E: ID_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4 -+E: ID_SERIAL_SHORT=0000:05:00.4 -+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=0614 -+E: ID_USB_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4 -+E: ID_USB_SERIAL_SHORT=0000:05:00.4 -+E: ID_USB_VENDOR=Linux_6.14.0-37-generic_xhci-hcd -+E: ID_USB_VENDOR_ENC=Linux\x206.14.0-37-generic\x20xhci-hcd -+E: ID_USB_VENDOR_ID=1d6b -+E: ID_VENDOR=Linux_6.14.0-37-generic_xhci-hcd -+E: ID_VENDOR_ENC=Linux\x206.14.0-37-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/614 -+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=0614\n -+A: bmAttributes=e0\n -+A: busnum=3\n -+A: configuration= -+H: descriptors=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C -+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:0c/device:1b/device:1c -+A: idProduct=0002\n -+A: idVendor=1d6b\n -+A: interface_authorized_default=1\n -+A: ltm_capable=no\n -+A: manufacturer=Linux 6.14.0-37-generic xhci-hcd\n -+A: maxchild=4\n -+A: power/active_duration=93137993\n -+A: power/async=enabled\n -+A: power/autosuspend=0\n -+A: power/autosuspend_delay_ms=0\n -+A: power/connected_duration=93139758\n -+A: power/control=auto\n -+A: power/level=auto\n -+A: power/runtime_active_kids=1\n -+A: power/runtime_active_time=93139206\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:05:00.4\n -+A: speed=480\n -+A: tx_lanes=1\n -+A: urbnum=989\n -+A: version= 2.00\n -+ -+P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4 -+E: DRIVER=xhci_hcd -+E: ID_MODEL_FROM_DATABASE=Renoir/Cezanne USB 3.1 -+E: ID_PATH=pci-0000:05:00.4 -+E: ID_PATH_TAG=pci-0000_05_00_4 -+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=Advanced Micro Devices, Inc. [AMD] -+E: MODALIAS=pci:v00001022d00001639sv000017AAsd0000382Fbc0Csc03i30 -+E: PCI_CLASS=C0330 -+E: PCI_ID=1022:1639 -+E: PCI_SLOT_NAME=0000:05:00.4 -+E: PCI_SUBSYS_ID=17AA:382F -+E: SUBSYSTEM=pci -+A: ari_enabled=0\n -+A: broken_parity_status=0\n -+A: class=0x0c0330\n -+H: config=22103916070410000030030C10008000040040D0000000000000000000000000000000000000000000000000AA172F38000000004800000000000000FF010000000000000000000009500800AA172F38016403C80000000000000000000000003120000010A00200A18F000010290000030D400040000311000000000000000000000000000000001F007100000000001E00800100000100000000000000000005C08600000000000000000000000000000000000000000000000000000000001100078000E00F0000F00F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B00012A010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -+A: consistent_dma_mask_bits=64\n -+A: current_link_speed=8.0 GT/s PCIe\n -+A: current_link_width=16\n -+A: d3cold_allowed=1\n -+A: dbc=disabled\n -+A: dbc_bInterfaceProtocol=01\n -+A: dbc_bcdDevice=0010\n -+A: dbc_idProduct=0010\n -+A: dbc_idVendor=1d6b\n -+A: dbc_poll_interval_ms=64\n -+A: device=0x1639\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:0c/device:1b -+L: iommu=../../0000:00:00.2/iommu/ivhd0 -+L: iommu_group=../../../../kernel/iommu_groups/20 -+A: irq=44\n -+A: link/l0s_aspm=0\n -+A: link/l1_aspm=0\n -+A: local_cpulist=0-11\n -+A: local_cpus=fff\n -+A: max_link_speed=8.0 GT/s PCIe\n -+A: max_link_width=16\n -+A: modalias=pci:v00001022d00001639sv000017AAsd0000382Fbc0Csc03i30\n -+A: msi_bus=1\n -+A: msi_irqs/45=msix\n -+A: msi_irqs/46=msix\n -+A: msi_irqs/47=msix\n -+A: msi_irqs/48=msix\n -+A: msi_irqs/49=msix\n -+A: msi_irqs/50=msix\n -+A: msi_irqs/51=msix\n -+A: msi_irqs/52=msix\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 4 5 2112 5\nxHCI ring segments 23 23 4096 23\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n -+A: power/async=enabled\n -+A: power/control=on\n -+A: power/runtime_active_kids=1\n -+A: power/runtime_active_time=93139523\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: reset_method=pm\n -+A: resource=0x00000000d0400000 0x00000000d04fffff 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=0x00\n -+A: subsystem_device=0x382f\n -+A: subsystem_vendor=0x17aa\n -+A: vendor=0x1022\n -+ -+P: /devices/pci0000:00/0000:00:08.1 -+E: DRIVER=pcieport -+E: ID_MODEL_FROM_DATABASE=Renoir Internal PCIe GPP Bridge to Bus -+E: ID_PATH=pci-0000:00:08.1 -+E: ID_PATH_TAG=pci-0000_00_08_1 -+E: ID_PCI_CLASS_FROM_DATABASE=Bridge -+E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode -+E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge -+E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD] -+E: MODALIAS=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00 -+E: PCI_CLASS=60400 -+E: PCI_ID=1022:1635 -+E: PCI_SLOT_NAME=0000:00:08.1 -+E: PCI_SUBSYS_ID=1022:1635 -+E: SUBSYSTEM=pci -+A: ari_enabled=0\n -+A: broken_parity_status=0\n -+A: class=0x060400\n -+H: config=221035160704100000000406100081000000000000000000000505001111000030D060D001E011F0FC000000FC000000000000005000000000000000FF01020000000000000000000000000000000000015803C80000000010A042002280000010290000030D7000400C03310000000000004000180001000000000000003100000000001E00800143001F00000000000000000000000000000000000000000005C081000000E0FE0000000000000000000000000000000000000000000000000D00000022103516000000000000000000000000000000000000000000000000000000007CA006000000000000000000000000000000000000000000000000000B000127010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900012A00000000000000007F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F000000000D0001405F001D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250001410100008001000080000000002600014400000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2700010000000000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -+A: consistent_dma_mask_bits=32\n -+A: current_link_speed=8.0 GT/s PCIe\n -+A: current_link_width=16\n -+A: d3cold_allowed=1\n -+A: device=0x1635\n -+A: dma_mask_bits=32\n -+L: driver=../../../bus/pci/drivers/pcieport -+A: driver_override=(null)\n -+A: enable=2\n -+L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c -+L: iommu=../0000:00:00.2/iommu/ivhd0 -+L: iommu_group=../../../kernel/iommu_groups/8 -+A: irq=33\n -+A: local_cpulist=0-11\n -+A: local_cpus=fff\n -+A: max_link_speed=8.0 GT/s PCIe\n -+A: max_link_width=16\n -+A: modalias=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00\n -+A: msi_bus=1\n -+A: msi_irqs/33=msi\n -+A: numa_node=-1\n -+A: power/async=enabled\n -+A: power/autosuspend_delay_ms=100\n -+A: power/control=auto\n -+A: power/runtime_active_kids=5\n -+A: power/runtime_active_time=93139537\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: power_state=D0\n -+A: reset_method=pm\n -+A: resource=0x0000000000000000 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\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000001000 0x0000000000001fff 0x0000000000000101\n0x00000000d0300000 0x00000000d06fffff 0x0000000000000200\n0x000000fce0000000 0x000000fcf01fffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n -+A: revision=0x00\n -+A: secondary_bus_number=5\n -+A: subordinate_bus_number=5\n -+A: subsystem_device=0x1635\n -+A: subsystem_vendor=0x1022\n -+A: vendor=0x1022\n -+ -diff --git a/tests/meson.build b/tests/meson.build -index 07c924be..b6e8bf95 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -52,6 +52,7 @@ drivers_tests = [ - 'nb1010', - 'egis0570', - 'egismoc', -+ 'egis_etu905', - 'egismoc-05a1', - 'egismoc-0586', - 'egismoc-0587', --- -GitLab - - -From c216f04dd1fd1cfe21a71d26bf6e17fc1a37983a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Tue, 9 Jun 2026 14:19:17 +0200 -Subject: [PATCH 02/13] egis_etu905: Do not leak the transfer buffer - -The buffer is now owned by the data, so we should not steal it when -passing it around or we'll leak. ---- - libfprint/drivers/egismoc/egis_etu905.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index be0c6e05..f91f0472 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -207,7 +207,8 @@ egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, - fpi_ssm_mark_failed (transfer->ssm, error); - return; - } -- if (data == NULL || transfer->actual_length < egis_etu905_read_prefix_len) -+ -+ if (transfer->actual_length < egis_etu905_read_prefix_len) - { - fpi_ssm_mark_failed (transfer->ssm, - fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); -@@ -216,6 +217,7 @@ egis_etu905_cmd_receive_cb (FpiUsbTransfer *transfer, - - /* Store the response data and let the cmd_ssm_done callback invoke - * the actual callback with the stored data */ -+ g_assert (data != NULL); - data->buffer_in = g_steal_pointer (&transfer->buffer); - data->length_in = transfer->actual_length; - -@@ -282,7 +284,7 @@ egis_etu905_cmd_ssm_done (FpiSsm *ssm, - if (data && data->callback) - { - data->callback (device, -- g_steal_pointer (&data->buffer_in), -+ data->buffer_in, - data->length_in, - g_steal_pointer (&local_error)); - } --- -GitLab - - -From fdbc9ee6558a54dc393a5dfa04f626be8393116c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Tue, 9 Jun 2026 13:51:28 +0200 -Subject: [PATCH 03/13] egis_etu905: Remove unused transfer - ---- - libfprint/drivers/egismoc/egis_etu905.c | 11 ----------- - 1 file changed, 11 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index f91f0472..0bb9a6ba 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -1445,8 +1445,6 @@ static void - egis_etu905_dev_init_handler (FpiSsm *ssm, - FpDevice *device) - { -- g_autoptr(FpiUsbTransfer) transfer = NULL; -- - switch (fpi_ssm_get_cur_state (ssm)) - { - case DEV_GET_FW_VERSION: -@@ -1462,15 +1460,6 @@ egis_etu905_dev_init_handler (FpiSsm *ssm, - default: - g_assert_not_reached (); - } -- -- transfer = fpi_usb_transfer_new (device); -- transfer->ssm = ssm; -- transfer->short_is_error = TRUE; -- fpi_usb_transfer_submit (g_steal_pointer (&transfer), -- EGIS_ETU905_USB_CONTROL_TIMEOUT, -- fpi_device_get_cancellable (device), -- fpi_ssm_usb_transfer_cb, -- NULL); - } - - static void --- -GitLab - - -From f5806825de803a7becd02b49a3f4a6a8e32579ff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Tue, 9 Jun 2026 13:56:02 +0200 -Subject: [PATCH 04/13] egis_etu905: Remove unused variable - ---- - libfprint/drivers/egismoc/egis_etu905.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 0bb9a6ba..3d52bf89 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -943,7 +943,6 @@ egis_etu905_get_check_cmd (FpDevice *device, - fp_dbg ("Get check command"); - FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); - g_auto(FpiByteWriter) writer = {0}; -- g_autofree guchar *result = NULL; - gboolean written = TRUE; - - /* --- -GitLab - - -From 12af25d43b890077cc13a0597b772c9401ca6273 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:28:50 +0200 -Subject: [PATCH 05/13] egis_etu905: Set short error using function - ---- - libfprint/drivers/egismoc/egis_etu905.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 3d52bf89..4e58515c 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -97,7 +97,7 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, - EGIS_ETU905_USB_INTERRUPT_IN_RECV_LENGTH); - transfer->ssm = ssm; - /* Interrupt on this device always returns 1 byte short; this is expected */ -- transfer->short_is_error = FALSE; -+ fpi_usb_transfer_set_short_error (transfer, FALSE); - - fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED); - -@@ -382,7 +382,7 @@ egis_etu905_exec_cmd (FpDevice *device, - } - - transfer = fpi_usb_transfer_new (device); -- transfer->short_is_error = TRUE; -+ fpi_usb_transfer_set_short_error (transfer, TRUE); - transfer->ssm = self->cmd_ssm; - - fpi_usb_transfer_fill_bulk_full (transfer, --- -GitLab - - -From 42f0b96c103195a6a7fa6b45258b72e393c90793 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:31:58 +0200 -Subject: [PATCH 06/13] egis_etu905: Rely on default device cancellable for all - the actions - -I don't see a reason why we should rely on a different cancellable for -interrupts, but happy to learn more about this ---- - libfprint/drivers/egismoc/egis_etu905.c | 33 +------------------------ - 1 file changed, 1 insertion(+), 32 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 4e58515c..3c1dcf73 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -33,7 +33,6 @@ struct _FpiDeviceEgisEtu905 - FpiSsm *task_ssm; - FpiSsm *cmd_ssm; - FpiUsbTransfer *cmd_transfer; -- GCancellable *interrupt_cancellable; - GPtrArray *enrolled_ids; - gint max_enroll_stages; - guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; -@@ -89,8 +88,6 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, - FpDevice *device) - { - fp_dbg ("Wait for finger on sensor"); -- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -- - g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); - - fpi_usb_transfer_fill_interrupt (transfer, EGIS_ETU905_EP_CMD_INTERRUPT_IN, -@@ -103,7 +100,7 @@ egis_etu905_wait_finger_on_sensor (FpiSsm *ssm, - - fpi_usb_transfer_submit (g_steal_pointer (&transfer), - EGIS_ETU905_USB_INTERRUPT_TIMEOUT, -- self->interrupt_cancellable, -+ fpi_device_get_cancellable (device), - egis_etu905_finger_on_sensor_cb, - NULL); - } -@@ -1551,37 +1548,11 @@ egis_etu905_open (FpDevice *device) - fpi_ssm_start (self->task_ssm, egis_etu905_dev_init_done); - } - --static void --egis_etu905_cancel (FpDevice *device) --{ -- fp_dbg ("Cancel"); -- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -- -- g_cancellable_cancel (self->interrupt_cancellable); -- g_clear_object (&self->interrupt_cancellable); -- self->interrupt_cancellable = g_cancellable_new (); --} -- --static void --egis_etu905_suspend (FpDevice *device) --{ -- fp_dbg ("Suspend"); -- -- egis_etu905_cancel (device); -- g_cancellable_cancel (fpi_device_get_cancellable (device)); -- fpi_device_suspend_complete (device, NULL); --} -- - static void - egis_etu905_close (FpDevice *device) - { - g_autoptr(GError) error = NULL; - fp_dbg ("Closing device"); -- FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -- GError *error = NULL; -- -- egis_etu905_cancel (device); -- g_clear_object (&self->interrupt_cancellable); - - g_usb_device_release_interface (fpi_device_get_usb_device (device), - 0, 0, &error); -@@ -1610,8 +1581,6 @@ fpi_device_egis_etu905_class_init (FpiDeviceEgisEtu905Class *klass) - - dev_class->probe = egis_etu905_probe; - dev_class->open = egis_etu905_open; -- dev_class->cancel = egis_etu905_cancel; -- dev_class->suspend = egis_etu905_suspend; - dev_class->close = egis_etu905_close; - dev_class->identify = egis_etu905_identify_verify; - dev_class->verify = egis_etu905_identify_verify; --- -GitLab - - -From 4b8f46f1f9ce3d2b2ce96d0b87fdb464f9e67abe Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:32:51 +0200 -Subject: [PATCH 07/13] egis_etu905: Use fpi-bytes-reader to get the firmware - string - ---- - libfprint/drivers/egismoc/egis_etu905.c | 37 +++++++++++++++++++------ - 1 file changed, 29 insertions(+), 8 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 3c1dcf73..c4d4093d 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -1348,12 +1348,14 @@ egis_etu905_fw_version_cb (FpDevice *device, - gsize length_in, - GError *error) - { -- fp_dbg ("Firmware version callback"); - FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -- g_autofree gchar *fw_version = NULL; -- gsize prefix_length; -- guchar *fw_version_start; -+ FpiByteReader reader; -+ const guint8 *fw_version_data = NULL; -+ const guint prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; - gsize fw_version_length; -+ g_autofree gchar *fw_version = NULL; -+ -+ fp_dbg ("Firmware version callback"); - - if (error) - { -@@ -1380,10 +1382,29 @@ egis_etu905_fw_version_cb (FpDevice *device, - * come with every payload Then we will also skip the carriage return and take - * all but the last 2 bytes as the FW Version - */ -- prefix_length = egis_etu905_read_prefix_len + 2 + 3 + 1; -- fw_version_start = buffer_in + prefix_length; -- fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len; -- fw_version = g_strndup ((gchar *) fw_version_start, fw_version_length); -+ fpi_byte_reader_init (&reader, buffer_in, length_in); -+ -+ if (!fpi_byte_reader_set_pos (&reader, prefix_length)) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Device firmware response " -+ "too short for prefix.")); -+ return; -+ } -+ -+ fw_version_length = fpi_byte_reader_get_remaining (&reader) - rsp_fw_version_suffix_len; -+ -+ if (!fpi_byte_reader_get_data (&reader, fw_version_length, &fw_version_data)) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Device firmware response " -+ "too short for version string.")); -+ return; -+ } -+ -+ fw_version = g_strndup ((gchar *) fw_version_data, fw_version_length); - - fp_info ("Device firmware version is %s", fw_version); - --- -GitLab - - -From c6f9f094afec2a1bf53e6a6132dbde130650b9ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:39:34 +0200 -Subject: [PATCH 08/13] egis_etu905: drop unused sid field - -We read it but we never use it ---- - libfprint/drivers/egismoc/egis_etu905.c | 15 --------------- - 1 file changed, 15 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index c4d4093d..418b43a3 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -35,7 +35,6 @@ struct _FpiDeviceEgisEtu905 - FpiUsbTransfer *cmd_transfer; - GPtrArray *enrolled_ids; - gint max_enroll_stages; -- guint8 sid[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; - }; - - G_DEFINE_TYPE (FpiDeviceEgisEtu905, fpi_device_egis_etu905, FP_TYPE_DEVICE); -@@ -911,20 +910,6 @@ egis_etu905_enroll_begin_cb (FpDevice *device, - return; - } - -- FpiByteReader reader; -- -- fpi_byte_reader_init (&reader, buffer_in, length_in); -- -- fpi_byte_reader_set_pos (&reader, EGIS_ETU905_LIST_RESPONSE_PREFIX_SIZE); -- -- const guint8 *data = NULL; -- -- fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, -- &data); -- -- if (data) -- memcpy (self->sid, data, EGIS_ETU905_FINGERPRINT_DATA_SIZE); -- - fpi_ssm_next_state (self->task_ssm); - } - --- -GitLab - - -From 65c3dcb1eb35ec0bd14b17bedf33de6c621f9ef3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:44:13 +0200 -Subject: [PATCH 09/13] egis_etu905: Avoid potential wrong memory accesses - ---- - libfprint/drivers/egismoc/egis_etu905.c | 53 ++++++++++++++++++------- - 1 file changed, 38 insertions(+), 15 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 418b43a3..c9b9ab3a 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -110,11 +110,21 @@ egis_etu905_validate_response_prefix (const guchar *buffer_in, - const guchar *valid_prefix, - const gsize valid_prefix_len) - { -- const gboolean result = memcmp (buffer_in + -- (egis_etu905_read_prefix_len + -- EGIS_ETU905_CHECK_BYTES_LENGTH), -- valid_prefix, -- valid_prefix_len) == 0; -+ FpiByteReader reader; -+ const guint8 *data = NULL; -+ gboolean result; -+ -+ fpi_byte_reader_init (&reader, buffer_in, buffer_in_len); -+ -+ if (!fpi_byte_reader_set_pos (&reader, egis_etu905_read_prefix_len + -+ EGIS_ETU905_CHECK_BYTES_LENGTH) || -+ !fpi_byte_reader_get_data (&reader, valid_prefix_len, &data)) -+ { -+ fp_dbg ("Response too short for prefix validation"); -+ return FALSE; -+ } -+ -+ result = memcmp (data, valid_prefix, valid_prefix_len) == 0; - - fp_dbg ("Response prefix valid: %s", result ? "yes" : "NO"); - return result; -@@ -126,9 +136,22 @@ egis_etu905_validate_response_suffix (const guchar *buffer_in, - const guchar *valid_suffix, - const gsize valid_suffix_len) - { -- const gboolean result = memcmp (buffer_in + (buffer_in_len - valid_suffix_len), -- valid_suffix, -- valid_suffix_len) == 0; -+ FpiByteReader reader; -+ const guint8 *data = NULL; -+ gboolean result; -+ -+ fpi_byte_reader_init (&reader, buffer_in, buffer_in_len); -+ -+ /* Guard against unsigned underflow before computing the suffix position. */ -+ if (valid_suffix_len > buffer_in_len || -+ !fpi_byte_reader_set_pos (&reader, buffer_in_len - valid_suffix_len) || -+ !fpi_byte_reader_get_data (&reader, valid_suffix_len, &data)) -+ { -+ fp_dbg ("Response too short for suffix validation"); -+ return FALSE; -+ } -+ -+ result = memcmp (data, valid_suffix, valid_suffix_len) == 0; - - fp_dbg ("Response suffix valid: %s", result ? "yes" : "NO"); - return result; -@@ -1467,10 +1490,10 @@ egis_etu905_dev_init_handler (FpiSsm *ssm, - static void - egis_etu905_probe (FpDevice *device) - { -- GUsbDevice *usb_dev; -- GError *error = NULL; -+ g_autoptr(GError) error = NULL; - g_autofree gchar *serial = NULL; - FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -+ GUsbDevice *usb_dev; - - fp_dbg ("%s enter --> ", G_STRFUNC); - -@@ -1479,7 +1502,7 @@ egis_etu905_probe (FpDevice *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); -+ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); - return; - } - -@@ -1487,7 +1510,7 @@ egis_etu905_probe (FpDevice *device) - { - 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); -+ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); - return; - } - -@@ -1495,7 +1518,7 @@ egis_etu905_probe (FpDevice *device) - { - 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); -+ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); - return; - } - -@@ -1512,7 +1535,7 @@ egis_etu905_probe (FpDevice *device) - 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); -+ fpi_device_probe_complete (device, NULL, NULL, g_steal_pointer (&error)); - return; - } - -@@ -1526,7 +1549,7 @@ egis_etu905_probe (FpDevice *device) - 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); -+ fpi_device_probe_complete (device, serial, NULL, NULL); - } - - static void --- -GitLab - - -From 5b51f9c8ccf33424636e4e32cb6205204e816940 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:47:41 +0200 -Subject: [PATCH 10/13] egis_etu905: Sanitize print data parsing - ---- - libfprint/drivers/egismoc/egis_etu905.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index c9b9ab3a..0a5655f1 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -318,7 +318,7 @@ static guint16 - egis_etu905_get_check_bytes (FpiByteReader *reader) - { - fp_dbg ("Get check bytes"); -- size_t sum_values = 0; -+ guint64 sum_values = 0; - guint16 val; - - fpi_byte_reader_set_pos (reader, 0); -@@ -562,8 +562,6 @@ egis_etu905_get_delete_cmd (FpDevice *device, - const guchar *print_data_id = NULL; - gsize print_data_id_len = 0; - g_autofree gchar *print_description = NULL; -- g_autofree guchar *enrolled_print_id = NULL; -- g_autofree guchar *result = NULL; - gboolean written = TRUE; - - /* -@@ -639,7 +637,8 @@ egis_etu905_get_delete_cmd (FpDevice *device, - g_object_get (delete_print, "description", &print_description, NULL); - g_object_get (delete_print, "fpi-data", &print_data, NULL); - -- if (!g_variant_check_format_string (print_data, "(@ay)", FALSE)) -+ if (!print_data || -+ !g_variant_check_format_string (print_data, "(@ay)", FALSE)) - { - fpi_ssm_mark_failed (self->task_ssm, - fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); -@@ -650,11 +649,21 @@ egis_etu905_get_delete_cmd (FpDevice *device, - print_data_id = g_variant_get_fixed_array (print_data_id_var, - &print_data_id_len, sizeof (guchar)); - -- if (!g_str_has_prefix (print_description, "FP")) -+ if (print_data_id_len != EGIS_ETU905_FINGERPRINT_DATA_SIZE) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, -+ "Stored print id has " -+ "unexpected length %zu", -+ print_data_id_len)); -+ return NULL; -+ } -+ -+ if (!print_description || !g_str_has_prefix (print_description, "FP")) - fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.", -- print_description); -+ print_description ? print_description : "(null)"); - -- fp_info ("Delete fingerprint %s", print_description); -+ fp_info ("Delete fingerprint %s", print_description ? print_description : "(null)"); - - written &= fpi_byte_writer_put_data (&writer, print_data_id, - EGIS_ETU905_FINGERPRINT_DATA_SIZE); --- -GitLab - - -From c0a98110531e74beb5876ef084da3ed8901128c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 13:48:00 +0200 -Subject: [PATCH 11/13] egis_etu905: Do not try to continue a failed SSM - ---- - libfprint/drivers/egismoc/egis_etu905.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 0a5655f1..d45b46e2 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -755,6 +755,10 @@ egis_etu905_delete_run_state (FpiSsm *ssm, - else - payload = egis_etu905_get_delete_cmd (device, NULL, &payload_length); - -+ /* get_delete_cmd already marked task_ssm as failed */ -+ if (!payload) -+ return; -+ - egis_etu905_exec_cmd (device, g_steal_pointer (&payload), payload_length, - g_free, egis_etu905_delete_cb); - break; --- -GitLab - - -From 06ad44bc1da732598f82a7c11eb0bbc29850ac13 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 8 Jun 2026 15:19:54 +0200 -Subject: [PATCH 12/13] egis_etu905: Improve the identify callback data reading - ---- - libfprint/drivers/egismoc/egis_etu905.c | 41 ++++++++++++++----------- - 1 file changed, 23 insertions(+), 18 deletions(-) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index d45b46e2..7de306b4 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -496,11 +496,10 @@ egis_etu905_list_fill_enrolled_ids_cb (FpDevice *device, - */ - while (read) - { -- const guint8 *data; -+ const guint8 data[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; - g_autofree gchar *print_id = NULL; - -- read &= fpi_byte_reader_get_data (&reader, EGIS_ETU905_FINGERPRINT_DATA_SIZE, -- &data); -+ read &= fpi_byte_reader_get_data_static (&reader, data); - if (!read) - break; - -@@ -1182,15 +1181,16 @@ egis_etu905_identify_check_cb (FpDevice *device, - gsize length_in, - GError *error) - { -- fp_dbg ("Identify check callback"); - FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); -- gchar device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; -+ guint8 device_print_id[EGIS_ETU905_FINGERPRINT_DATA_SIZE]; - FpPrint *print = NULL; - FpPrint *verify_print = NULL; - GPtrArray *prints; - gboolean found = FALSE; - guint index; - -+ fp_dbg ("Identify check callback"); -+ - if (error) - { - fpi_ssm_mark_failed (self->task_ssm, error); -@@ -1203,29 +1203,34 @@ egis_etu905_identify_check_cb (FpDevice *device, - rsp_identify_match_suffix, - rsp_identify_match_suffix_len)) - { -+ FpiByteReader reader; -+ - /* - On success, there is a 32 byte array of "something"(?) in chars 14-45 - and then the 32 byte array ID of the matched print comes as chars 46-77 - */ -- memcpy (device_print_id, -- buffer_in + EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET, -- EGIS_ETU905_FINGERPRINT_DATA_SIZE); -- -- /* Create a new print from this device_print_id and then see if it matches -- * the one indicated -- */ -- print = fp_print_new (device); -- egis_etu905_set_print_data (print, device_print_id, NULL); -+ fpi_byte_reader_init (&reader, buffer_in, length_in); - -- if (!print) -+ if (!fpi_byte_reader_set_pos (&reader, -+ EGIS_ETU905_IDENTIFY_RESPONSE_PRINT_ID_OFFSET) || -+ !fpi_byte_reader_get_data_static (&reader, device_print_id)) - { - fpi_ssm_mark_failed (self->task_ssm, -- fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, -- "Failed to build a print from " -- "device response.")); -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Identify response too " -+ "short for matched print " -+ "id.")); - return; - } - -+ fp_dbg ("Device-reported matched print id: %s", device_print_id); -+ -+ /* Create a new print from this device_print_id and then see if it matches -+ * the one indicated -+ */ -+ print = fp_print_new (device); -+ egis_etu905_set_print_data (print, (const char *) device_print_id, NULL); -+ - fp_info ("Identify successful for: %s", fp_print_get_description (print)); - - if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) --- -GitLab - - -From 6a71e039a12ead2b3120ad4789b93a44193045ec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Tue, 9 Jun 2026 13:56:24 +0200 -Subject: [PATCH 13/13] egis_etu905: Double-check that the identified ID is - part of the enrolled list - ---- - libfprint/drivers/egismoc/egis_etu905.c | 27 +++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c -index 7de306b4..dcd71ff6 100644 ---- a/libfprint/drivers/egismoc/egis_etu905.c -+++ b/libfprint/drivers/egismoc/egis_etu905.c -@@ -1203,6 +1203,7 @@ egis_etu905_identify_check_cb (FpDevice *device, - rsp_identify_match_suffix, - rsp_identify_match_suffix_len)) - { -+ gboolean id_known = FALSE; - FpiByteReader reader; - - /* -@@ -1225,6 +1226,32 @@ egis_etu905_identify_check_cb (FpDevice *device, - - fp_dbg ("Device-reported matched print id: %s", device_print_id); - -+ /* While the returned ID should indeed be part of the enrolled list, since -+ * we got it, let's double check that this is really the case. -+ */ -+ if (self->enrolled_ids) -+ { -+ for (guint i = 0; i < self->enrolled_ids->len; i++) -+ { -+ if (memcmp (g_ptr_array_index (self->enrolled_ids, i), -+ device_print_id, -+ EGIS_ETU905_FINGERPRINT_DATA_SIZE) == 0) -+ { -+ id_known = TRUE; -+ break; -+ } -+ } -+ } -+ -+ if (!id_known) -+ { -+ fpi_ssm_mark_failed (self->task_ssm, -+ fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, -+ "Device reported a match " -+ "for an unknown print id.")); -+ return; -+ } -+ - /* Create a new print from this device_print_id and then see if it matches - * the one indicated - */ --- -GitLab - diff --git a/libfprint.spec b/libfprint.spec index 96a9cb2..7e54abd 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,6 +1,6 @@ Name: libfprint -Version: 1.94.10 +Version: 1.94.100 Release: %autorelease Summary: Toolkit for fingerprint scanner @@ -11,20 +11,6 @@ License: LGPL-2.1-or-later AND NIST-PD URL: http://www.freedesktop.org/wiki/Software/fprint/libfprint Source0: https://gitlab.freedesktop.org/libfprint/libfprint/-/archive/v%{version}/libfprint-v%{version}.tar.gz -# Backport from upstream -Patch00001: https://gitlab.freedesktop.org/libfprint/libfprint/-/commit/2c7842c905147a2d127c1b168b2e9d43.patch - -# the updates for the fpi -Patch10001: 0001-doc-Include-Binary-buffer-I-O-section-for-the-byte-r.patch -Patch10002: 0002-fpi-byte-writer-Add-APIs-to-write-and-get-GBytes.patch -Patch10003: 0003-fpi-byte-reader-Add-support-to-read-and-get-peek-GBy.patch -Patch10004: 0004-fpi-byte-reader-Add-support-to-read-to-a-static-buff.patch -Patch10005: 0005-fpi-usb-transfer-Add-missing-definition-of-set_short.patch -Patch10006: 0006-fpi-usb-transfer-Wrap-g_error_new-arguments.patch -# Add EGIS readers -# https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/561 -Patch10007: egis_reader.patch - BuildRequires: meson BuildRequires: gcc BuildRequires: gcc-c++ diff --git a/sources b/sources index f3a33ff..6751017 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libfprint-v1.94.10.tar.gz) = 7a346cb83623e4447d67c5a932cb2d98b6e42e38eae134eb03a1c8f61b2a1e606b78967629bbddb1db174d730b318c942c3ae9cd452f30a6d273d915fc97ec43 +SHA512 (libfprint-v1.94.100.tar.gz) = c7a167b849fd3cd0ccc861d4c021568209eedab038bbbff160825af41efaf5db55d1c38da98419fa034333820b90152dc94a975825d5d646f3f1ef7f8d04e299