mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-06-15 15:48:24 +02:00
Compare commits
No commits in common. "master" and "v1.94.1" have entirely different histories.
149 changed files with 1889 additions and 18454 deletions
227
.gitlab-ci.yml
227
.gitlab-ci.yml
|
|
@ -1,75 +1,50 @@
|
||||||
include:
|
include:
|
||||||
- local: '.gitlab-ci/libfprint-image-variables.yaml'
|
|
||||||
- local: '.gitlab-ci/libfprint-templates.yaml'
|
- local: '.gitlab-ci/libfprint-templates.yaml'
|
||||||
- project: 'freedesktop/ci-templates'
|
- project: 'freedesktop/ci-templates'
|
||||||
ref: master
|
ref: master
|
||||||
file: '/templates/fedora.yml'
|
file: '/templates/fedora.yml'
|
||||||
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/71e636e012ae0ab04c5e0fe40ca73ada91ae6bde/flatpak/flatpak_ci_initiative.yml'
|
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml'
|
||||||
|
|
||||||
default:
|
|
||||||
interruptible: true
|
|
||||||
# Auto-retry jobs in case of infra failures
|
|
||||||
retry:
|
|
||||||
max: 1
|
|
||||||
when:
|
|
||||||
- 'runner_system_failure'
|
|
||||||
- 'stuck_or_timeout_failure'
|
|
||||||
- 'scheduler_failure'
|
|
||||||
- 'api_failure'
|
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
extends: .libfprint_common_variables
|
extends: .libfprint_common_variables
|
||||||
FDO_DISTRIBUTION_TAG: $LIBFPRINT_IMAGE_TAG
|
FDO_DISTRIBUTION_TAG: latest
|
||||||
FDO_DISTRIBUTION_VERSION: rawhide
|
FDO_DISTRIBUTION_VERSION: rawhide
|
||||||
FDO_UPSTREAM_REPO: "libfprint/$CI_PROJECT_NAME"
|
FDO_UPSTREAM_REPO: "libfprint/$CI_PROJECT_NAME"
|
||||||
FEDORA_IMAGE: "registry.freedesktop.org/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
||||||
|
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
||||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||||
|
|
||||||
workflow:
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
|
||||||
- if: $CI_PIPELINE_SOURCE == 'push'
|
|
||||||
- if: $CI_PIPELINE_SOURCE == 'schedule'
|
|
||||||
- if: $CI_PROJECT_NAMESPACE == 'libfprint' && $LIBFPRINT_CI_ACTION != ''
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- image-build
|
|
||||||
- check-source
|
- check-source
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- flatpak
|
- flatpak
|
||||||
- deploy
|
|
||||||
|
|
||||||
image: $FEDORA_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
|
|
||||||
.build_one_driver_template: &build_one_driver
|
.build_one_driver_template: &build_one_driver
|
||||||
script:
|
script:
|
||||||
# Build with a driver that doesn't need imaging, or openssl
|
# Build with a driver that doesn't need imaging, or nss
|
||||||
- meson setup _build --werror -Ddrivers=$driver
|
- meson --werror -Ddrivers=$driver . _build
|
||||||
- meson compile -C _build
|
- ninja -C _build
|
||||||
- rm -rf _build/
|
- rm -rf _build/
|
||||||
|
|
||||||
.build_template: &build
|
.build_template: &build
|
||||||
script:
|
script:
|
||||||
# And build with everything
|
# And build with everything
|
||||||
- meson setup _build --werror -Ddrivers=all
|
- meson --werror -Ddrivers=all . _build
|
||||||
- meson compile -C _build
|
- ninja -C _build
|
||||||
- meson install -C _build
|
- ninja -C _build install
|
||||||
|
|
||||||
.build_template: &check_abi
|
.build_template: &check_abi
|
||||||
script:
|
script:
|
||||||
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
|
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
|
||||||
|
|
||||||
.standard_job:
|
|
||||||
rules:
|
|
||||||
- when: on_success
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
when: never
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
stage: build
|
stage: build
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
variables:
|
variables:
|
||||||
driver: virtual_image
|
driver: virtual_image
|
||||||
<<: *build_one_driver
|
<<: *build_one_driver
|
||||||
|
|
@ -84,19 +59,16 @@ build:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- meson setup _build --werror -Ddrivers=all -Db_coverage=true
|
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
||||||
|
- ninja -C _build
|
||||||
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
||||||
- ninja -C _build coverage || true
|
- ninja -C _build coverage
|
||||||
- cat _build/meson-logs/coverage.txt || true
|
- cat _build/meson-logs/coverage.txt
|
||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
|
||||||
junit: "_build/meson-logs/testlog.junit.xml"
|
|
||||||
coverage_report:
|
|
||||||
coverage_format: cobertura
|
|
||||||
path: _build/meson-logs/coverage.xml
|
|
||||||
expose_as: 'Coverage Report'
|
expose_as: 'Coverage Report'
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
|
|
@ -107,15 +79,14 @@ test:
|
||||||
|
|
||||||
test_valgrind:
|
test_valgrind:
|
||||||
stage: test
|
stage: test
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- meson setup _build -Ddrivers=all
|
- meson -Ddrivers=all . _build
|
||||||
- meson compile -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
|
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
|
||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
|
||||||
junit: "_build/meson-logs/testlog-valgrind.junit.xml"
|
|
||||||
expose_as: 'Valgrind test logs'
|
expose_as: 'Valgrind test logs'
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
|
|
@ -123,123 +94,73 @@ test_valgrind:
|
||||||
- _build/meson-logs/testlog-valgrind.txt
|
- _build/meson-logs/testlog-valgrind.txt
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
|
|
||||||
test_asan:
|
|
||||||
stage: test
|
|
||||||
extends:
|
|
||||||
- .standard_job
|
|
||||||
script:
|
|
||||||
- meson setup _build -Ddrivers=all -Db_sanitize=address,undefined
|
|
||||||
- meson test -C _build --print-errorlogs --no-stdsplit
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: "_build/meson-logs/testlog.junit.xml"
|
|
||||||
expose_as: 'Sanitizers test logs'
|
|
||||||
when: always
|
|
||||||
paths:
|
|
||||||
- _build/meson-logs
|
|
||||||
- _build/meson-logs/testlog.txt
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
test_installed:
|
|
||||||
stage: test
|
|
||||||
extends:
|
|
||||||
- .standard_job
|
|
||||||
script:
|
|
||||||
- meson setup _build --prefix=/usr -Ddrivers=all
|
|
||||||
- meson install -C _build
|
|
||||||
- mv _build _build_dir
|
|
||||||
- rm -rf tests
|
|
||||||
- gnome-desktop-testing-runner --list libfprint-2
|
|
||||||
- gnome-desktop-testing-runner libfprint-2
|
|
||||||
--report-directory=_installed-tests-report/failed/
|
|
||||||
--log-directory=_installed-tests-report/logs/
|
|
||||||
--parallel=0
|
|
||||||
artifacts:
|
|
||||||
expose_as: 'GNOME Tests Runner logs'
|
|
||||||
when: always
|
|
||||||
paths:
|
|
||||||
- _build_dir/meson-logs
|
|
||||||
- _installed-tests-report
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
|
|
||||||
test_scan_build:
|
test_scan_build:
|
||||||
stage: test
|
stage: test
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- meson setup _build -Ddrivers=all
|
- meson -Ddrivers=all . _build
|
||||||
# Wrapper to add --status-bugs and disable malloc checker
|
# Wrapper to add --status-bugs and disable malloc checker
|
||||||
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build
|
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build ninja -C _build scan-build
|
||||||
ninja -C _build scan-build
|
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_failure
|
|
||||||
paths:
|
paths:
|
||||||
- _build/meson-logs
|
- _build/meson-logs
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
|
|
||||||
test_indent:
|
test_indent:
|
||||||
stage: check-source
|
stage: check-source
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- scripts/uncrustify.sh
|
- scripts/uncrustify.sh
|
||||||
- git diff
|
- git diff
|
||||||
- git diff-index --name-only --exit-code HEAD
|
- "! git status -s | grep -q ."
|
||||||
rules:
|
|
||||||
- changes:
|
|
||||||
compare_to: 'refs/heads/master'
|
|
||||||
paths:
|
|
||||||
- '**/*.c'
|
|
||||||
- '**/*.h'
|
|
||||||
|
|
||||||
test_unsupported_list:
|
test_unsupported_list:
|
||||||
stage: check-source
|
stage: check-source
|
||||||
extends:
|
except:
|
||||||
- .standard_job
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- tests/hwdb-check-unsupported.py
|
- tests/hwdb-check-unsupported.py
|
||||||
|
|
||||||
flatpak:
|
flatpak:
|
||||||
stage: flatpak
|
stage: flatpak
|
||||||
extends: .flatpak@x86_64
|
extends: .flatpak
|
||||||
|
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36
|
||||||
variables:
|
variables:
|
||||||
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
||||||
FLATPAK_MODULE: "libfprint"
|
FLATPAK_MODULE: "libfprint"
|
||||||
APP_ID: "org.freedesktop.libfprint.Demo"
|
APP_ID: "org.freedesktop.libfprint.Demo"
|
||||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
|
||||||
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
|
|
||||||
# Build with any builder
|
|
||||||
tags: []
|
|
||||||
rules:
|
rules:
|
||||||
- if: '$CI_PROJECT_PATH != "libfprint/libfprint"'
|
- if: '$CI_PROJECT_PATH != "libfprint/libfprint"'
|
||||||
when: manual
|
when: never
|
||||||
allow_failure: true
|
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
when: never
|
when: never
|
||||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||||
allow_failure: true
|
|
||||||
when: always
|
when: always
|
||||||
- if: '$CI_COMMIT_TAG'
|
- if: '$CI_COMMIT_TAG'
|
||||||
allow_failure: true
|
|
||||||
when: always
|
when: always
|
||||||
# For any other (commit), allow manual run.
|
# For any other (commit), allow manual run.
|
||||||
# This excludes MRs which would create a duplicate pipeline
|
# This excludes MRs which would create a duplicate pipeline
|
||||||
- if: '$CI_COMMIT_BRANCH'
|
- if: '$CI_COMMIT_BRANCH'
|
||||||
when: manual
|
when: manual
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
- if: '$CI_MERGE_REQUEST_ID'
|
|
||||||
when: manual
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
# CONTAINERS creation stage
|
# CONTAINERS creation stage
|
||||||
.container_fedora_build_base:
|
container_fedora_build:
|
||||||
extends: .fdo.container-build@fedora
|
extends: .fdo.container-build@fedora
|
||||||
stage: image-build
|
only:
|
||||||
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||||
|
FDO_FORCE_REBUILD: 1
|
||||||
# a list of packages to install
|
# a list of packages to install
|
||||||
FDO_DISTRIBUTION_PACKAGES:
|
FDO_DISTRIBUTION_PACKAGES:
|
||||||
$LIBFPRINT_DEPENDENCIES
|
$LIBFPRINT_DEPENDENCIES
|
||||||
|
|
@ -247,55 +168,7 @@ flatpak:
|
||||||
libpcap-devel
|
libpcap-devel
|
||||||
libudev-devel
|
libudev-devel
|
||||||
FDO_DISTRIBUTION_EXEC: |
|
FDO_DISTRIBUTION_EXEC: |
|
||||||
$LIBFPRINT_EXEC
|
git clone https://github.com/martinpitt/umockdev.git && \
|
||||||
rules:
|
cd umockdev && \
|
||||||
- when: never
|
meson _build --prefix=/usr && \
|
||||||
|
ninja -C _build && ninja -C _build install
|
||||||
.container_fedora_build_forced:
|
|
||||||
variables:
|
|
||||||
FDO_FORCE_REBUILD: 1
|
|
||||||
|
|
||||||
container_fedora_build_schedule:
|
|
||||||
extends:
|
|
||||||
- .container_fedora_build_base
|
|
||||||
- .container_fedora_build_forced
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
|
||||||
when: always
|
|
||||||
|
|
||||||
container_fedora_build_manual:
|
|
||||||
extends:
|
|
||||||
- .container_fedora_build_base
|
|
||||||
- .container_fedora_build_forced
|
|
||||||
rules:
|
|
||||||
- if: $LIBFPRINT_CI_ACTION == "build-image"
|
|
||||||
when: always
|
|
||||||
|
|
||||||
container_fedora_build_on_deps_changed:
|
|
||||||
extends: .container_fedora_build_base
|
|
||||||
rules:
|
|
||||||
- if: $CI_PROJECT_NAMESPACE == "libfprint" && $CI_PIPELINE_SOURCE != "schedule"
|
|
||||||
changes:
|
|
||||||
compare_to: 'refs/heads/master'
|
|
||||||
paths:
|
|
||||||
- '.gitlab-ci/libfprint-image-variables.yaml'
|
|
||||||
- '.gitlab-ci/libfprint-templates.yaml'
|
|
||||||
|
|
||||||
pages:
|
|
||||||
image: alpine:latest
|
|
||||||
stage: deploy
|
|
||||||
needs:
|
|
||||||
- job: test
|
|
||||||
artifacts: true
|
|
||||||
- job: build
|
|
||||||
artifacts: true
|
|
||||||
script:
|
|
||||||
- mkdir public
|
|
||||||
- mv _build/meson-logs/coveragereport public/coverage
|
|
||||||
- mv _build/doc/html public/doc
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- public
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push"
|
|
||||||
- if: $CI_COMMIT_TAG
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
variables:
|
|
||||||
LIBFPRINT_IMAGE_TAG: v6
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
# Bump image version on .gitlab-ci/libfprint-image-variables.yaml to trigger
|
|
||||||
# a rebuild on changes to this file
|
|
||||||
|
|
||||||
.libfprint_common_variables:
|
.libfprint_common_variables:
|
||||||
LIBFPRINT_DEPENDENCIES:
|
LIBFPRINT_DEPENDENCIES:
|
||||||
appstream
|
|
||||||
doxygen
|
doxygen
|
||||||
dnf-plugins-core
|
|
||||||
flatpak-builder
|
flatpak-builder
|
||||||
gcc
|
gcc
|
||||||
gcc-c++
|
gcc-c++
|
||||||
|
|
@ -14,18 +9,15 @@
|
||||||
glib2-devel
|
glib2-devel
|
||||||
glibc-devel
|
glibc-devel
|
||||||
gobject-introspection-devel
|
gobject-introspection-devel
|
||||||
gnome-desktop-testing
|
|
||||||
gtk-doc
|
gtk-doc
|
||||||
gtk3-devel
|
gtk3-devel
|
||||||
libabigail
|
libabigail
|
||||||
libasan
|
|
||||||
libgusb-devel
|
libgusb-devel
|
||||||
libgudev-devel
|
libgudev-devel
|
||||||
libubsan
|
|
||||||
libX11-devel
|
libX11-devel
|
||||||
libXv-devel
|
libXv-devel
|
||||||
meson
|
meson
|
||||||
openssl-devel
|
nss-devel
|
||||||
pixman-devel
|
pixman-devel
|
||||||
python3-cairo
|
python3-cairo
|
||||||
python3-gobject
|
python3-gobject
|
||||||
|
|
@ -35,15 +27,3 @@
|
||||||
valgrind
|
valgrind
|
||||||
clang-analyzer
|
clang-analyzer
|
||||||
diffutils
|
diffutils
|
||||||
|
|
||||||
LIBFPRINT_EXEC: |
|
|
||||||
dnf -y install dnf-utils
|
|
||||||
debuginfo-install -y \
|
|
||||||
glib2 \
|
|
||||||
glibc \
|
|
||||||
libgusb \
|
|
||||||
libusb \
|
|
||||||
openssl \
|
|
||||||
pixman \
|
|
||||||
python3-gobject \
|
|
||||||
python3-gobject-base
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
#!/bin/sh -x
|
#!/bin/sh
|
||||||
|
|
||||||
# This wrapper just disables the malloc checker
|
# This wrapper just disables the malloc checker
|
||||||
exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc \
|
exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc "$@"
|
||||||
--exclude "$PWD/_build/meson-private" \
|
|
||||||
--exclude "$PWD/meson-private" \
|
|
||||||
"$@"
|
|
||||||
119
NEWS
119
NEWS
|
|
@ -1,121 +1,6 @@
|
||||||
This file lists notable changes in each release. For the full history of all
|
This file lists notable changes in each release. For the full history of all
|
||||||
changes, see ChangeLog.
|
changes, see ChangeLog.
|
||||||
|
|
||||||
2026-02-10: v1.94.10 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* synaptics: Add USB reset in probe to recover stall condition
|
|
||||||
* synaptics: New PIDs 0x0169, 0x019F, 0x00E9, 0x01A0, 0x0109, 0x010A
|
|
||||||
* goodixmoc: New PID 0x66A9
|
|
||||||
* goodixmoc: Fix crash in exit callback handler
|
|
||||||
* fpcmoc: New PID 0xA306
|
|
||||||
* fpcmoc: Fix interrupt cancellable leak
|
|
||||||
* elanmoc: New PIDs 0x0CA7, 0x0CA8, 0x0CB0
|
|
||||||
* egismoc: New PIDs 0x0584, 0x0588
|
|
||||||
* focaltech_moc: New PIDs 0xA27A, 0x1579
|
|
||||||
* realtek: New PID 0xFA03
|
|
||||||
* fp-device: Clarify getter for open property
|
|
||||||
* libfprint: Use fatal-warnings on g-i-scanner
|
|
||||||
|
|
||||||
2025-02-20: v1.94.9 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* uru4000: Use OpenSSL to perform AES-ECB encryption, as per this libfprint
|
|
||||||
does not support on NSS, but on openssl (>= 3.0).
|
|
||||||
* goodixmoc: New PIDs 0x60C2, 0x689A
|
|
||||||
* synaptics: New PIDs 0x016C, 0x0174, 0x0107, 0x0108, 0x00C2, 0x00F0
|
|
||||||
* fpcmoc: New PID 0xC844
|
|
||||||
* focaltech_moc: New PIDs 0xA99A, 0xA57A, 0xA78A
|
|
||||||
* elanmoc: New PIDs 0x0C98, 0x0C9D, 0x0CA3
|
|
||||||
* elanspi: New PIDs 0x3128, 0x2766
|
|
||||||
* fp-device: Add FP_DEVICE_RETRY_TOO_FAST retry error
|
|
||||||
* data: AppStream meta info listing supported USB devices.
|
|
||||||
* fixed various memory issues in multiple devices
|
|
||||||
|
|
||||||
2024-09-03: v1.94.8 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* build: Support building in non-linux unix environments (tested in FreeBSD)
|
|
||||||
* egismoc: New PIDs 0x0583, 0x0586, 0x0587.
|
|
||||||
* elanmoc: New PID 0x0C9F.
|
|
||||||
* fpcmoc: New PIDs 0x9524, 0x9544.
|
|
||||||
* goodixmoc: New PIDs 0x609A, 0x650A, 0x650C, 0x6512.
|
|
||||||
* realtek: New PID 0x5816.
|
|
||||||
* synaptics: New PIDs 0x00C4, 0x019D, 0x00C6.
|
|
||||||
* fpcmoc: fix incorrect immobile handling during enrollment.
|
|
||||||
* fpcmoc: fixed jumping to wrong state at end of custom enroll.
|
|
||||||
* egismoc: various code cleanups.
|
|
||||||
|
|
||||||
2024-02-20: v1.94.7 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* synaptics: fix enroll identify problem after user reset database.
|
|
||||||
* synaptics: New PIDs 0x0173, 0x0106, 0x0124.
|
|
||||||
* goodixmoc: New PID 0x6582.
|
|
||||||
* build: Do not require bash to build, only posix sh.
|
|
||||||
* fp-image: Simplify minutiae detection tasks.
|
|
||||||
* GLib 2.68 is now required to build libfprint.
|
|
||||||
|
|
||||||
New drivers:
|
|
||||||
* realtek (PID 0x5813).
|
|
||||||
* focaltech_moc (PIDs 0x9E48, 0xD979, 0xA959).
|
|
||||||
* egismoc (PIDs 0x0582, 0x05a1).
|
|
||||||
|
|
||||||
2023-08-17: v1.94.6 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* goodixmoc: New PIDs 0x60A4, 0x60BC, 0x6092, 0x633C and 0x6304.
|
|
||||||
* goodixmoc: Fix missing "enroll create" state.
|
|
||||||
* elanmoc: New PID 0x0C99.
|
|
||||||
* upektc: Improve compatibility with sensors 147e:2016.
|
|
||||||
* aes4000: Actually support 08FF:5501 devices.
|
|
||||||
* virtual-device-listener: Fix failing tests with GLib 2.76
|
|
||||||
* tests: Add installed tests
|
|
||||||
|
|
||||||
Bugs fixed:
|
|
||||||
* #526 libfprint: fpcmoc: use after free if enrollment or identification is
|
|
||||||
cancelled (Vasily Khoruzhick)
|
|
||||||
|
|
||||||
2022-10-13: v1.94.5 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* New driver: fpcmoc, supporting various FPC MOC Fingerprint Sensors
|
|
||||||
* goodixmoc: New PIDs 0x6014, 0x6094, 0x631C, 0x634C, 0x6384, 0x659A.
|
|
||||||
* goodixmoc: Support resetting device on firmware failure due to corrupted DB.
|
|
||||||
* elanmoc: New PIDs 0x0c88, 0x0c8c, 0x0c8d.
|
|
||||||
* synaptics: New PID 0x0104.
|
|
||||||
* upektc: New PID 0x2017.
|
|
||||||
* Fixed various memory leaks
|
|
||||||
* More tests
|
|
||||||
|
|
||||||
2022-05-24: v1.94.4 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* synaptics: New PIDs 0x0168, 0x015f
|
|
||||||
* elan: New PID 0x0c4b
|
|
||||||
* elanspi: New PID 0x241f
|
|
||||||
* synaptics: Minor fix to interrupt transfer resubmission
|
|
||||||
* Avoid sysfs writes if value is already expected
|
|
||||||
* Improvements to the testing setup
|
|
||||||
* Fixes to the internal critical section API
|
|
||||||
|
|
||||||
2021-11-02: v1.94.3 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* Ensure idle mainloop before completing enumeration (fprintd#119)
|
|
||||||
* It is now possible to extend already enrolled prints
|
|
||||||
* elanspi: Fix timeout error with some hardware (#438)
|
|
||||||
* elanspi: Fix cancellation issues
|
|
||||||
* goodixmoc: Return matching device print; fixes duplicate checking (#444)
|
|
||||||
* goodixmoc: Support clearing the storage (usually unused)
|
|
||||||
|
|
||||||
2021-11-02: v1.94.2 release
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
* goodixmoc: Fix protocol error with certain username lengths
|
|
||||||
* elanmoc: New PID 0x0c7d
|
|
||||||
* goodixmoc: New PID 0x63cc
|
|
||||||
|
|
||||||
2021-09-24: v1.94.1 release
|
2021-09-24: v1.94.1 release
|
||||||
|
|
||||||
Highlights:
|
Highlights:
|
||||||
|
|
@ -417,7 +302,7 @@ tests of the drivers using umockdev.
|
||||||
- Mark fp_dscv_print functions as deprecated
|
- Mark fp_dscv_print functions as deprecated
|
||||||
|
|
||||||
* Udev rules:
|
* Udev rules:
|
||||||
- Add some unsupported devices to the allowlist
|
- Add some unsupported devices to the whitelist
|
||||||
|
|
||||||
2017-05-14: v0.7.0 release
|
2017-05-14: v0.7.0 release
|
||||||
* Drivers:
|
* Drivers:
|
||||||
|
|
@ -467,7 +352,7 @@ tests of the drivers using umockdev.
|
||||||
- Fix possible race condition, and cancellation in uru4000 driver
|
- Fix possible race condition, and cancellation in uru4000 driver
|
||||||
|
|
||||||
* Udev rules:
|
* Udev rules:
|
||||||
- Add Microsoft keyboard to the suspend denylist
|
- Add Microsoft keyboard to the suspend blacklist
|
||||||
|
|
||||||
* Plenty of build fixes
|
* Plenty of build fixes
|
||||||
|
|
||||||
|
|
|
||||||
51
README
Normal file
51
README
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
libfprint
|
||||||
|
=========
|
||||||
|
|
||||||
|
libfprint is part of the fprint project:
|
||||||
|
https://fprint.freedesktop.org/
|
||||||
|
|
||||||
|
libfprint was originally developed as part of an academic project at the
|
||||||
|
University of Manchester with the aim of hiding differences between different
|
||||||
|
consumer fingerprint scanners and providing a single uniform API to application
|
||||||
|
developers. The ultimate goal of the fprint project is to make fingerprint
|
||||||
|
scanners widely and easily usable under common Linux environments.
|
||||||
|
|
||||||
|
The academic university project runs off a codebase maintained separately
|
||||||
|
from this one, although I try to keep them as similar as possible (I'm not
|
||||||
|
hiding anything in the academic branch, it's just the open source release
|
||||||
|
contains some commits excluded from the academic project).
|
||||||
|
|
||||||
|
THE UNIVERSITY OF MANCHESTER DOES NOT ENDORSE THIS THIS SOFTWARE RELEASE AND
|
||||||
|
IS IN NO WAY RESPONSIBLE FOR THE CODE CONTAINED WITHIN, OR ANY DAMAGES CAUSED
|
||||||
|
BY USING OR DISTRIBUTING THE SOFTWARE. Development does not happen on
|
||||||
|
university computers and the project is not hosted at the university either.
|
||||||
|
|
||||||
|
For more information on libfprint, supported devices, API documentation, etc.,
|
||||||
|
see the homepage:
|
||||||
|
https://fprint.freedesktop.org/
|
||||||
|
|
||||||
|
libfprint is licensed under the GNU LGPL version 2.1. See the COPYING file
|
||||||
|
for the license text.
|
||||||
|
|
||||||
|
Section 6 of the license states that for compiled works that use this
|
||||||
|
library, such works must include libfprint copyright notices alongside the
|
||||||
|
copyright notices for the other parts of the work. We have attempted to
|
||||||
|
make this process slightly easier for you by grouping these all in one place:
|
||||||
|
the AUTHORS file.
|
||||||
|
|
||||||
|
libfprint includes code from NIST's NBIS software distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
We include bozorth3 from the US export controlled distribution. We have
|
||||||
|
determined that it is fine to ship bozorth3 in an open source project,
|
||||||
|
see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
|
||||||
|
## Historical links
|
||||||
|
|
||||||
|
Older versions of libfprint are available at:
|
||||||
|
https://sourceforge.net/projects/fprint/files/
|
||||||
|
|
||||||
|
Historical mailing-list archives:
|
||||||
|
http://www.reactivated.net/fprint_list_archives/
|
||||||
|
|
||||||
|
Historical website:
|
||||||
|
http://web.archive.org/web/*/https://www.freedesktop.org/wiki/Software/fprint/
|
||||||
95
README.md
95
README.md
|
|
@ -1,95 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
# LibFPrint
|
|
||||||
|
|
||||||
*LibFPrint is part of the **[FPrint][Website]** project.*
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
[![Button Website]][Website]
|
|
||||||
[![Button Documentation]][Documentation]
|
|
||||||
|
|
||||||
[![Button Supported]][Supported]
|
|
||||||
[![Button Unsupported]][Unsupported]
|
|
||||||
|
|
||||||
[![Button Contribute]][Contribute]
|
|
||||||
[![Button Contributors]][Contributors]
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## History
|
|
||||||
|
|
||||||
**LibFPrint** was originally developed as part of an
|
|
||||||
academic project at the **[University Of Manchester]**.
|
|
||||||
|
|
||||||
It aimed to hide the differences between consumer
|
|
||||||
fingerprint scanners and provide a single uniform
|
|
||||||
API to application developers.
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
The ultimate goal of the **FPrint** project is to make
|
|
||||||
fingerprint scanners widely and easily usable under
|
|
||||||
common Linux environments.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
`Section 6` of the license states that for compiled works that use
|
|
||||||
this library, such works must include **LibFPrint** copyright notices
|
|
||||||
alongside the copyright notices for the other parts of the work.
|
|
||||||
|
|
||||||
**LibFPrint** includes code from **NIST's** **[NBIS]** software distribution.
|
|
||||||
|
|
||||||
We include **Bozorth3** from the **[US Export Controlled]**
|
|
||||||
distribution, which we have determined to be fine
|
|
||||||
being shipped in an open source project.
|
|
||||||
|
|
||||||
## Get in *touch*
|
|
||||||
|
|
||||||
- [IRC] - `#fprint` @ `irc.oftc.net`
|
|
||||||
- [Matrix] - `#fprint:matrix.org` bridged to the IRC channel
|
|
||||||
- [MailingList] - low traffic, not much used these days
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div align="right">
|
|
||||||
|
|
||||||
[![Badge License]][License]
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!----------------------------------------------------------------------------->
|
|
||||||
|
|
||||||
[Documentation]: https://fprint.freedesktop.org/libfprint-dev/
|
|
||||||
[Contributors]: https://gitlab.freedesktop.org/libfprint/libfprint/-/graphs/master
|
|
||||||
[Unsupported]: https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices
|
|
||||||
[Supported]: https://fprint.freedesktop.org/supported-devices.html
|
|
||||||
[Website]: https://fprint.freedesktop.org/
|
|
||||||
[MailingList]: https://lists.freedesktop.org/mailman/listinfo/fprint
|
|
||||||
[IRC]: ircs://irc.oftc.net:6697/#fprint
|
|
||||||
[Matrix]: https://matrix.to/#/#fprint:matrix.org
|
|
||||||
|
|
||||||
[Contribute]: ./HACKING.md
|
|
||||||
[License]: ./COPYING
|
|
||||||
|
|
||||||
[University Of Manchester]: https://www.manchester.ac.uk/
|
|
||||||
[US Export Controlled]: https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
[NBIS]: http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
|
|
||||||
<!---------------------------------[ Badges ]---------------------------------->
|
|
||||||
|
|
||||||
[Badge License]: https://img.shields.io/badge/License-LGPL2.1-015d93.svg?style=for-the-badge&labelColor=blue
|
|
||||||
|
|
||||||
|
|
||||||
<!---------------------------------[ Buttons ]--------------------------------->
|
|
||||||
|
|
||||||
[Button Documentation]: https://img.shields.io/badge/Documentation-04ACE6?style=for-the-badge&logoColor=white&logo=BookStack
|
|
||||||
[Button Contributors]: https://img.shields.io/badge/Contributors-FF4F8B?style=for-the-badge&logoColor=white&logo=ActiGraph
|
|
||||||
[Button Unsupported]: https://img.shields.io/badge/Unsupported_Devices-EF2D5E?style=for-the-badge&logoColor=white&logo=AdBlock
|
|
||||||
[Button Contribute]: https://img.shields.io/badge/Contribute-66459B?style=for-the-badge&logoColor=white&logo=Git
|
|
||||||
[Button Supported]: https://img.shields.io/badge/Supported_Devices-428813?style=for-the-badge&logoColor=white&logo=AdGuard
|
|
||||||
[Button Website]: https://img.shields.io/badge/Homepage-3B80AE?style=for-the-badge&logoColor=white&logo=freedesktopDotOrg
|
|
||||||
30
TODO
Normal file
30
TODO
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
LIBRARY
|
||||||
|
=======
|
||||||
|
test suite against NFIQ compliance set
|
||||||
|
make library optionally asynchronous and maybe thread-safe
|
||||||
|
nbis cleanups
|
||||||
|
API function to determine if img device supports uncond. capture
|
||||||
|
race-free way of saying "save this print but don't overwrite"
|
||||||
|
|
||||||
|
NEW DRIVERS
|
||||||
|
===========
|
||||||
|
Sunplus 895 driver
|
||||||
|
AES3400/3500 driver
|
||||||
|
ID Mouse driver
|
||||||
|
Support for 2nd generation MS devices
|
||||||
|
Support for 2nd generation UPEK devices
|
||||||
|
|
||||||
|
IMAGING
|
||||||
|
=======
|
||||||
|
ignore first frame or two with aes2501
|
||||||
|
aes2501: increase threshold "sum" for end-of-image detection
|
||||||
|
aes2501 gain calibration
|
||||||
|
aes4000 gain calibration
|
||||||
|
aes4000 resampling
|
||||||
|
PPMM parameter to get_minutiae seems to have no effect
|
||||||
|
nbis minutiae should be stored in endian-independent format
|
||||||
|
|
||||||
|
PORTABILITY
|
||||||
|
===========
|
||||||
|
OpenBSD can't do -Wshadow or visibility
|
||||||
|
OpenBSD: add compat codes for ENOTSUP ENODATA and EPROTO
|
||||||
|
|
@ -67,7 +67,7 @@ usb:v08FFp5731*
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Supported by libfprint driver aes4000
|
# Supported by libfprint driver aes4000
|
||||||
usb:v08FFp5501*
|
usb:v5501p08FF*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
|
|
@ -77,23 +77,6 @@ usb:v1C7Ap0571*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Supported by libfprint driver egis_etu905
|
|
||||||
usb:v1C7Ap05AE*
|
|
||||||
usb:v1C7Ap9201*
|
|
||||||
ID_AUTOSUSPEND=1
|
|
||||||
ID_PERSIST=0
|
|
||||||
|
|
||||||
# Supported by libfprint driver egismoc
|
|
||||||
usb:v1C7Ap0582*
|
|
||||||
usb:v1C7Ap0583*
|
|
||||||
usb:v1C7Ap0584*
|
|
||||||
usb:v1C7Ap0586*
|
|
||||||
usb:v1C7Ap0587*
|
|
||||||
usb:v1C7Ap0588*
|
|
||||||
usb:v1C7Ap05A1*
|
|
||||||
ID_AUTOSUSPEND=1
|
|
||||||
ID_PERSIST=0
|
|
||||||
|
|
||||||
# Supported by libfprint driver elan
|
# Supported by libfprint driver elan
|
||||||
usb:v04F3p0903*
|
usb:v04F3p0903*
|
||||||
usb:v04F3p0907*
|
usb:v04F3p0907*
|
||||||
|
|
@ -150,7 +133,6 @@ usb:v04F3p0C32*
|
||||||
usb:v04F3p0C33*
|
usb:v04F3p0C33*
|
||||||
usb:v04F3p0C3D*
|
usb:v04F3p0C3D*
|
||||||
usb:v04F3p0C42*
|
usb:v04F3p0C42*
|
||||||
usb:v04F3p0C4B*
|
|
||||||
usb:v04F3p0C4D*
|
usb:v04F3p0C4D*
|
||||||
usb:v04F3p0C4F*
|
usb:v04F3p0C4F*
|
||||||
usb:v04F3p0C63*
|
usb:v04F3p0C63*
|
||||||
|
|
@ -160,21 +142,7 @@ usb:v04F3p0C58*
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Supported by libfprint driver elanmoc
|
# Supported by libfprint driver elanmoc
|
||||||
usb:v04F3p0C7D*
|
|
||||||
usb:v04F3p0C7E*
|
usb:v04F3p0C7E*
|
||||||
usb:v04F3p0C82*
|
|
||||||
usb:v04F3p0C88*
|
|
||||||
usb:v04F3p0C8C*
|
|
||||||
usb:v04F3p0C8D*
|
|
||||||
usb:v04F3p0C98*
|
|
||||||
usb:v04F3p0C99*
|
|
||||||
usb:v04F3p0C9D*
|
|
||||||
usb:v04F3p0C9F*
|
|
||||||
usb:v04F3p0CA3*
|
|
||||||
usb:v04F3p0CA7*
|
|
||||||
usb:v04F3p0CA8*
|
|
||||||
usb:v04F3p0CB0*
|
|
||||||
usb:v04F3p0CB2*
|
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
|
|
@ -183,73 +151,20 @@ usb:v1C7Ap0603*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Supported by libfprint driver focaltech_moc
|
|
||||||
usb:v2808p9E48*
|
|
||||||
usb:v2808pD979*
|
|
||||||
usb:v2808pA27A*
|
|
||||||
usb:v2808pA959*
|
|
||||||
usb:v2808pA99A*
|
|
||||||
usb:v2808pA57A*
|
|
||||||
usb:v2808pA78A*
|
|
||||||
usb:v2808pA97A*
|
|
||||||
usb:v2808p1579*
|
|
||||||
usb:v2808p077A*
|
|
||||||
usb:v2808p079A*
|
|
||||||
usb:v2808p5158*
|
|
||||||
ID_AUTOSUSPEND=1
|
|
||||||
ID_PERSIST=0
|
|
||||||
|
|
||||||
# Supported by libfprint driver fpcmoc
|
|
||||||
usb:v10A5pFFE0*
|
|
||||||
usb:v10A5pA305*
|
|
||||||
usb:v10A5pA306*
|
|
||||||
usb:v10A5pDA04*
|
|
||||||
usb:v10A5pD805*
|
|
||||||
usb:v10A5pD205*
|
|
||||||
usb:v10A5p9524*
|
|
||||||
usb:v10A5p9544*
|
|
||||||
usb:v10A5pC844*
|
|
||||||
usb:v10A5p9B24*
|
|
||||||
ID_AUTOSUSPEND=1
|
|
||||||
ID_PERSIST=0
|
|
||||||
|
|
||||||
# Supported by libfprint driver goodixmoc
|
# Supported by libfprint driver goodixmoc
|
||||||
usb:v27C6p5840*
|
usb:v27C6p5840*
|
||||||
usb:v27C6p6014*
|
|
||||||
usb:v27C6p6090*
|
|
||||||
usb:v27C6p6092*
|
|
||||||
usb:v27C6p6094*
|
|
||||||
usb:v27C6p609A*
|
|
||||||
usb:v27C6p609C*
|
usb:v27C6p609C*
|
||||||
usb:v27C6p60A2*
|
usb:v27C6p60A2*
|
||||||
usb:v27C6p60A4*
|
|
||||||
usb:v27C6p60BC*
|
|
||||||
usb:v27C6p60C2*
|
|
||||||
usb:v27C6p6304*
|
|
||||||
usb:v27C6p631C*
|
|
||||||
usb:v27C6p633C*
|
|
||||||
usb:v27C6p634C*
|
|
||||||
usb:v27C6p6384*
|
|
||||||
usb:v27C6p639C*
|
usb:v27C6p639C*
|
||||||
usb:v27C6p63AC*
|
usb:v27C6p63AC*
|
||||||
usb:v27C6p63BC*
|
usb:v27C6p63BC*
|
||||||
usb:v27C6p63CC*
|
|
||||||
usb:v27C6p6496*
|
usb:v27C6p6496*
|
||||||
usb:v27C6p650A*
|
|
||||||
usb:v27C6p650C*
|
|
||||||
usb:v27C6p6582*
|
|
||||||
usb:v27C6p6584*
|
usb:v27C6p6584*
|
||||||
usb:v27C6p658C*
|
usb:v27C6p658C*
|
||||||
usb:v27C6p6592*
|
usb:v27C6p6592*
|
||||||
usb:v27C6p6594*
|
usb:v27C6p6594*
|
||||||
usb:v27C6p659A*
|
|
||||||
usb:v27C6p659C*
|
usb:v27C6p659C*
|
||||||
usb:v27C6p6A94*
|
usb:v27C6p6A94*
|
||||||
usb:v27C6p6512*
|
|
||||||
usb:v27C6p6890*
|
|
||||||
usb:v27C6p689A*
|
|
||||||
usb:v27C6p66A9*
|
|
||||||
usb:v27C6p6984*
|
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
|
|
@ -258,45 +173,19 @@ usb:v298Dp1010*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Supported by libfprint driver realtek
|
|
||||||
usb:v0BDAp5813*
|
|
||||||
usb:v0BDAp5816*
|
|
||||||
usb:v2541pFA03*
|
|
||||||
ID_AUTOSUSPEND=1
|
|
||||||
ID_PERSIST=0
|
|
||||||
|
|
||||||
# Supported by libfprint driver synaptics
|
# Supported by libfprint driver synaptics
|
||||||
usb:v06CBp00BD*
|
usb:v06CBp00BD*
|
||||||
usb:v06CBp00C2*
|
|
||||||
usb:v06CBp00C4*
|
|
||||||
usb:v06CBp00C6*
|
|
||||||
usb:v06CBp00DF*
|
usb:v06CBp00DF*
|
||||||
usb:v06CBp00E9*
|
|
||||||
usb:v06CBp00F0*
|
|
||||||
usb:v06CBp00F9*
|
usb:v06CBp00F9*
|
||||||
usb:v06CBp00FC*
|
usb:v06CBp00FC*
|
||||||
|
usb:v06CBp00C2*
|
||||||
|
usb:v06CBp00C9*
|
||||||
usb:v06CBp0100*
|
usb:v06CBp0100*
|
||||||
|
usb:v06CBp00F0*
|
||||||
usb:v06CBp0103*
|
usb:v06CBp0103*
|
||||||
usb:v06CBp0104*
|
|
||||||
usb:v06CBp0106*
|
|
||||||
usb:v06CBp0107*
|
|
||||||
usb:v06CBp0108*
|
|
||||||
usb:v06CBp0109*
|
|
||||||
usb:v06CBp010A*
|
|
||||||
usb:v06CBp0123*
|
usb:v06CBp0123*
|
||||||
usb:v06CBp0124*
|
|
||||||
usb:v06CBp0126*
|
usb:v06CBp0126*
|
||||||
usb:v06CBp0129*
|
usb:v06CBp0129*
|
||||||
usb:v06CBp015F*
|
|
||||||
usb:v06CBp0168*
|
|
||||||
usb:v06CBp0169*
|
|
||||||
usb:v06CBp016C*
|
|
||||||
usb:v06CBp0173*
|
|
||||||
usb:v06CBp0174*
|
|
||||||
usb:v06CBp019D*
|
|
||||||
usb:v06CBp019F*
|
|
||||||
usb:v06CBp01A0*
|
|
||||||
usb:v06CBp01A4*
|
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
|
|
@ -309,7 +198,6 @@ usb:v147Ep1001*
|
||||||
|
|
||||||
# Supported by libfprint driver upektc
|
# Supported by libfprint driver upektc
|
||||||
usb:v0483p2015*
|
usb:v0483p2015*
|
||||||
usb:v0483p2017*
|
|
||||||
usb:v147Ep3001*
|
usb:v147Ep3001*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
@ -365,57 +253,28 @@ usb:v138Ap0091*
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
||||||
# Known unsupported devices
|
# Known unsupported devices
|
||||||
usb:v0A5Cp5802*
|
|
||||||
usb:v047Dp00F2*
|
|
||||||
usb:v047Dp8054*
|
|
||||||
usb:v047Dp8055*
|
|
||||||
usb:v04E8p730B*
|
|
||||||
usb:v04F3p036B*
|
usb:v04F3p036B*
|
||||||
usb:v04F3p0C00*
|
usb:v04F3p0C00*
|
||||||
|
usb:v04F3p0C4B*
|
||||||
usb:v04F3p0C4C*
|
usb:v04F3p0C4C*
|
||||||
usb:v04F3p0C57*
|
usb:v04F3p0C57*
|
||||||
usb:v04F3p0C5E*
|
usb:v04F3p0C5E*
|
||||||
usb:v04F3p0C5A*
|
|
||||||
usb:v04F3p0C60*
|
|
||||||
usb:v04F3p0C6C*
|
|
||||||
usb:v04F3p0C70*
|
|
||||||
usb:v04F3p0C72*
|
|
||||||
usb:v04F3p0C77*
|
|
||||||
usb:v04F3p0C7C*
|
|
||||||
usb:v04F3p0C7F*
|
|
||||||
usb:v04F3p0C80*
|
|
||||||
usb:v04F3p0C85*
|
|
||||||
usb:v04F3p0C90*
|
|
||||||
usb:v04F3p2706*
|
usb:v04F3p2706*
|
||||||
usb:v04F3p3032*
|
|
||||||
usb:v04F3p3057*
|
|
||||||
usb:v04F3p3104*
|
|
||||||
usb:v04F3p310D*
|
|
||||||
usb:v04F3p3128*
|
|
||||||
usb:v04F3p0C8A*
|
|
||||||
usb:v05BAp000E*
|
|
||||||
usb:v06CBp0051*
|
|
||||||
usb:v06CBp0081*
|
usb:v06CBp0081*
|
||||||
usb:v06CBp0088*
|
usb:v06CBp0088*
|
||||||
usb:v06CBp008A*
|
usb:v06CBp008A*
|
||||||
usb:v06CBp009A*
|
usb:v06CBp009A*
|
||||||
usb:v06CBp009B*
|
usb:v06CBp009B*
|
||||||
usb:v06CBp00A1*
|
|
||||||
usb:v06CBp00A2*
|
usb:v06CBp00A2*
|
||||||
usb:v06CBp00A8*
|
|
||||||
usb:v06CBp00B7*
|
usb:v06CBp00B7*
|
||||||
usb:v06CBp00BB*
|
usb:v06CBp00BB*
|
||||||
usb:v06CBp00BC*
|
|
||||||
usb:v06CBp00BE*
|
usb:v06CBp00BE*
|
||||||
|
usb:v06CBp00C4*
|
||||||
usb:v06CBp00CB*
|
usb:v06CBp00CB*
|
||||||
usb:v06CBp00C9*
|
|
||||||
usb:v06CBp00D8*
|
usb:v06CBp00D8*
|
||||||
usb:v06CBp00DA*
|
usb:v06CBp00DA*
|
||||||
usb:v06CBp00DC*
|
|
||||||
usb:v06CBp00E4*
|
|
||||||
usb:v06CBp00E7*
|
usb:v06CBp00E7*
|
||||||
usb:v06CBp00FD*
|
usb:v06CBp00E9*
|
||||||
usb:v06CBp00FF*
|
|
||||||
usb:v0A5Cp5801*
|
usb:v0A5Cp5801*
|
||||||
usb:v0A5Cp5805*
|
usb:v0A5Cp5805*
|
||||||
usb:v0A5Cp5834*
|
usb:v0A5Cp5834*
|
||||||
|
|
@ -425,21 +284,7 @@ usb:v0A5Cp5842*
|
||||||
usb:v0A5Cp5843*
|
usb:v0A5Cp5843*
|
||||||
usb:v0A5Cp5844*
|
usb:v0A5Cp5844*
|
||||||
usb:v0A5Cp5845*
|
usb:v0A5Cp5845*
|
||||||
usb:v0A5Cp5860*
|
|
||||||
usb:v0A5Cp5863*
|
|
||||||
usb:v0A5Cp5864*
|
|
||||||
usb:v0A5Cp5865*
|
|
||||||
usb:v0A5Cp5866*
|
|
||||||
usb:v0A5Cp5867*
|
|
||||||
usb:v0BDAp5812*
|
|
||||||
usb:v10A5p0007*
|
usb:v10A5p0007*
|
||||||
usb:v10A5p9200*
|
|
||||||
usb:v10A5p9201*
|
|
||||||
usb:v10A5p9800*
|
|
||||||
usb:v10A5pA120*
|
|
||||||
usb:v10A5pA900*
|
|
||||||
usb:v10A5pA921*
|
|
||||||
usb:v10A5pE340*
|
|
||||||
usb:v1188p9545*
|
usb:v1188p9545*
|
||||||
usb:v138Ap0007*
|
usb:v138Ap0007*
|
||||||
usb:v138Ap003A*
|
usb:v138Ap003A*
|
||||||
|
|
@ -452,58 +297,32 @@ usb:v138Ap0094*
|
||||||
usb:v138Ap0097*
|
usb:v138Ap0097*
|
||||||
usb:v138Ap009D*
|
usb:v138Ap009D*
|
||||||
usb:v138Ap00AB*
|
usb:v138Ap00AB*
|
||||||
usb:v138Ap00A6*
|
|
||||||
usb:v147Ep1002*
|
usb:v147Ep1002*
|
||||||
usb:v1491p0088*
|
usb:v1491p0088*
|
||||||
usb:v16D1p1027*
|
usb:v16D1p1027*
|
||||||
usb:v1C7Ap0300*
|
usb:v1C7Ap0300*
|
||||||
usb:v1C7Ap0575*
|
usb:v1C7Ap0575*
|
||||||
usb:v1C7Ap0576*
|
|
||||||
usb:v1C7Ap0577*
|
|
||||||
usb:v1C7Ap057E*
|
|
||||||
usb:v2541p0236*
|
|
||||||
usb:v2541p9711*
|
|
||||||
usb:v27C6p5042*
|
usb:v27C6p5042*
|
||||||
usb:v27C6p5110*
|
usb:v27C6p5110*
|
||||||
usb:v27C6p5117*
|
usb:v27C6p5117*
|
||||||
usb:v27C6p5120*
|
|
||||||
usb:v27C6p5125*
|
|
||||||
usb:v27C6p5201*
|
usb:v27C6p5201*
|
||||||
usb:v27C6p521D*
|
usb:v27C6p521D*
|
||||||
usb:v27C6p5301*
|
usb:v27C6p5301*
|
||||||
usb:v27C6p530C*
|
usb:v27C6p530C*
|
||||||
usb:v27C6p532D*
|
usb:v27C6p532D*
|
||||||
usb:v27C6p5335*
|
|
||||||
usb:v27C6p533C*
|
usb:v27C6p533C*
|
||||||
usb:v27C6p5381*
|
usb:v27C6p5381*
|
||||||
usb:v27C6p5385*
|
usb:v27C6p5385*
|
||||||
usb:v27C6p538C*
|
usb:v27C6p538C*
|
||||||
usb:v27C6p538D*
|
usb:v27C6p538D*
|
||||||
usb:v27C6p5395*
|
usb:v27C6p5395*
|
||||||
usb:v27C6p5503*
|
|
||||||
usb:v27C6p550A*
|
|
||||||
usb:v27C6p550C*
|
|
||||||
usb:v27C6p5584*
|
usb:v27C6p5584*
|
||||||
usb:v27C6p55A2*
|
usb:v27C6p55A2*
|
||||||
usb:v27C6p55A4*
|
usb:v27C6p55A4*
|
||||||
usb:v27C6p55B4*
|
usb:v27C6p55B4*
|
||||||
usb:v27C6p5740*
|
usb:v27C6p5740*
|
||||||
usb:v27C6p5E0A*
|
|
||||||
usb:v27C6p581A*
|
|
||||||
usb:v27C6p589A*
|
|
||||||
usb:v27C6p5F10*
|
|
||||||
usb:v27C6p5F91*
|
|
||||||
usb:v27C6p6382*
|
|
||||||
usb:v2808p9338*
|
usb:v2808p9338*
|
||||||
usb:v2808p9348*
|
|
||||||
usb:v2808p93A9*
|
|
||||||
usb:v2808pA658*
|
|
||||||
usb:v2808pC652*
|
|
||||||
usb:v2808pA553*
|
|
||||||
usb:v298Dp2020*
|
|
||||||
usb:v298Dp2033*
|
usb:v298Dp2033*
|
||||||
usb:v2DF0p0003*
|
|
||||||
usb:v3274p8012*
|
|
||||||
usb:v3538p0930*
|
usb:v3538p0930*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
ID_PERSIST=0
|
ID_PERSIST=0
|
||||||
|
|
|
||||||
|
|
@ -101,14 +101,11 @@ plot_minutiae (unsigned char *rgbdata,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#define write_pixel(num) \
|
#define write_pixel(num) do { \
|
||||||
do \
|
rgbdata[((num) * 3)] = 0xff; \
|
||||||
{ \
|
rgbdata[((num) * 3) + 1] = 0; \
|
||||||
rgbdata[((num) * 3)] = 0xff; \
|
rgbdata[((num) * 3) + 2] = 0; \
|
||||||
rgbdata[((num) * 3) + 1] = 0; \
|
} while(0)
|
||||||
rgbdata[((num) * 3) + 2] = 0; \
|
|
||||||
} \
|
|
||||||
while(0)
|
|
||||||
|
|
||||||
for (i = 0; i < minutiae->len; i++)
|
for (i = 0; i < minutiae->len; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"app-id": "org.freedesktop.libfprint.Demo",
|
"app-id": "org.freedesktop.libfprint.Demo",
|
||||||
"runtime": "org.gnome.Platform",
|
"runtime": "org.gnome.Platform",
|
||||||
"runtime-version": "master",
|
"runtime-version": "3.36",
|
||||||
"sdk": "org.gnome.Sdk",
|
"sdk": "org.gnome.Sdk",
|
||||||
"command": "gtk-libfprint-test",
|
"command": "gtk-libfprint-test",
|
||||||
"finish-args": [
|
"finish-args": [
|
||||||
/* X11 + XShm access */
|
/* X11 + XShm access */
|
||||||
"--share=ipc", "--socket=fallback-x11",
|
"--share=ipc", "--socket=x11",
|
||||||
/* Wayland access */
|
/* Wayland access */
|
||||||
"--socket=wayland",
|
"--socket=wayland",
|
||||||
/* OpenGL access */
|
/* OpenGL access */
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"name": "libusb",
|
"name": "libusb",
|
||||||
"config-opts": [ "--disable-static" ],
|
"config-opts": [ "--disable-static", "--disable-udev" ],
|
||||||
"cleanup": [
|
"cleanup": [
|
||||||
"/lib/*.la",
|
"/lib/*.la",
|
||||||
"/lib/pkgconfig",
|
"/lib/pkgconfig",
|
||||||
|
|
@ -26,47 +26,48 @@
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26.tar.bz2",
|
"url": "https://github.com/libusb/libusb/archive/v1.0.22.tar.gz",
|
||||||
"sha256": "12ce7a61fc9854d1d2a1ffe095f7b5fac19ddba095c259e6067a46500381b5a5"
|
"sha256": "3500f7b182750cd9ccf9be8b1df998f83df56a39ab264976bdb3307773e16f48"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"post-install": [
|
"post-install": [
|
||||||
"install -Dm644 COPYING /app/share/licenses/libusb/COPYING"
|
"install -Dm644 COPYING /app/share/licenses/libgusb/COPYING"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libgusb",
|
"name": "libgusb",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
"config-opts": [ "-Dtests=false", "-Dvapi=false", "-Ddocs=false" ],
|
"config-opts": [ "-Dtests=false", "-Dvapi=false", "-Ddocs=false", "-Dintrospection=false" ],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://github.com/hughsie/libgusb/releases/download/0.4.6/libgusb-0.4.6.tar.xz",
|
"url": "https://github.com/hughsie/libgusb/archive/0.3.0.tar.gz",
|
||||||
"sha256": "1b0422bdcd72183272ac42eec9398c5a0bc48a02f618fa3242c468cbbd003049"
|
"sha256": "b36310f8405d5fd68f6caf4a829f7ab4c627b38fd3d02a139d411fce0f3a49f1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "gudev",
|
"name": "gudev",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
"config-opts": [ "-Dtests=disabled", "-Dintrospection=disabled", "-Dvapi=disabled" ],
|
"config-opts": [ "-Dtests=disabled", "-Dintrospection=disabled" ],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://download.gnome.org/sources/libgudev/238/libgudev-238.tar.xz",
|
"url": "https://download.gnome.org/sources/libgudev/236/libgudev-236.tar.xz",
|
||||||
"sha256": "61266ab1afc9d73dbc60a8b2af73e99d2fdff47d99544d085760e4fa667b5dd1"
|
"sha256": "e50369d06d594bae615eb7aeb787de304ebaad07a26d1043cef8e9c7ab7c9524"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libfprint",
|
"name": "libfprint",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
"config-opts": [ "-Dudev_hwdb=disabled", "-Dudev_rules=disabled", "-Dgtk-examples=true", "-Ddrivers=all" ],
|
"config-opts": [ "-Dudev_hwdb=disabled", "-Dudev_rules=disabled", "-Dx11-examples=false", "-Dgtk-examples=true", "-Ddrivers=all" ],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitlab.freedesktop.org/libfprint/libfprint.git"
|
"url": "https://gitlab.freedesktop.org/libfprint/libfprint.git",
|
||||||
|
"branch": "wip/benzea/v2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ fp_device_clear_storage_sync
|
||||||
fp_device_suspend_sync
|
fp_device_suspend_sync
|
||||||
fp_device_resume_sync
|
fp_device_resume_sync
|
||||||
FpDevice
|
FpDevice
|
||||||
FpTemperature
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
|
@ -135,134 +134,6 @@ fpi_line_asmbl_ctx
|
||||||
fpi_assemble_lines
|
fpi_assemble_lines
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<FILE>fpi-byte-reader</FILE>
|
|
||||||
<TITLE>FpiByteReader</TITLE>
|
|
||||||
FpiByteReader
|
|
||||||
fpi_byte_reader_new
|
|
||||||
fpi_byte_reader_new_bytes
|
|
||||||
fpi_byte_reader_free
|
|
||||||
fpi_byte_reader_init
|
|
||||||
fpi_byte_reader_init_bytes
|
|
||||||
fpi_byte_reader_peek_sub_reader
|
|
||||||
fpi_byte_reader_get_sub_reader
|
|
||||||
fpi_byte_reader_set_pos
|
|
||||||
fpi_byte_reader_get_pos
|
|
||||||
fpi_byte_reader_get_remaining
|
|
||||||
fpi_byte_reader_get_size
|
|
||||||
fpi_byte_reader_skip
|
|
||||||
fpi_byte_reader_get_bytes
|
|
||||||
fpi_byte_reader_peek_bytes
|
|
||||||
fpi_byte_reader_get_uint8
|
|
||||||
fpi_byte_reader_get_int8
|
|
||||||
fpi_byte_reader_peek_uint8
|
|
||||||
fpi_byte_reader_peek_int8
|
|
||||||
fpi_byte_reader_get_uint16_le
|
|
||||||
fpi_byte_reader_get_int16_le
|
|
||||||
fpi_byte_reader_peek_uint16_le
|
|
||||||
fpi_byte_reader_peek_int16_le
|
|
||||||
fpi_byte_reader_get_uint16_be
|
|
||||||
fpi_byte_reader_get_int16_be
|
|
||||||
fpi_byte_reader_peek_uint16_be
|
|
||||||
fpi_byte_reader_peek_int16_be
|
|
||||||
fpi_byte_reader_get_uint24_le
|
|
||||||
fpi_byte_reader_get_int24_le
|
|
||||||
fpi_byte_reader_peek_uint24_le
|
|
||||||
fpi_byte_reader_peek_int24_le
|
|
||||||
fpi_byte_reader_get_uint24_be
|
|
||||||
fpi_byte_reader_get_int24_be
|
|
||||||
fpi_byte_reader_peek_uint24_be
|
|
||||||
fpi_byte_reader_peek_int24_be
|
|
||||||
fpi_byte_reader_get_uint32_le
|
|
||||||
fpi_byte_reader_get_int32_le
|
|
||||||
fpi_byte_reader_peek_uint32_le
|
|
||||||
fpi_byte_reader_peek_int32_le
|
|
||||||
fpi_byte_reader_get_uint32_be
|
|
||||||
fpi_byte_reader_get_int32_be
|
|
||||||
fpi_byte_reader_peek_uint32_be
|
|
||||||
fpi_byte_reader_peek_int32_be
|
|
||||||
fpi_byte_reader_get_uint64_le
|
|
||||||
fpi_byte_reader_get_int64_le
|
|
||||||
fpi_byte_reader_peek_uint64_le
|
|
||||||
fpi_byte_reader_peek_int64_le
|
|
||||||
fpi_byte_reader_get_uint64_be
|
|
||||||
fpi_byte_reader_get_int64_be
|
|
||||||
fpi_byte_reader_peek_uint64_be
|
|
||||||
fpi_byte_reader_peek_int64_be
|
|
||||||
fpi_byte_reader_get_float32_le
|
|
||||||
fpi_byte_reader_peek_float32_le
|
|
||||||
fpi_byte_reader_get_float32_be
|
|
||||||
fpi_byte_reader_peek_float32_be
|
|
||||||
fpi_byte_reader_get_float64_le
|
|
||||||
fpi_byte_reader_peek_float64_le
|
|
||||||
fpi_byte_reader_get_float64_be
|
|
||||||
fpi_byte_reader_peek_float64_be
|
|
||||||
fpi_byte_reader_get_data
|
|
||||||
fpi_byte_reader_peek_data
|
|
||||||
fpi_byte_reader_get_data_static
|
|
||||||
fpi_byte_reader_peek_data_static
|
|
||||||
fpi_byte_reader_dup_data
|
|
||||||
fpi_byte_reader_masked_scan_uint32
|
|
||||||
fpi_byte_reader_masked_scan_uint32_peek
|
|
||||||
fpi_byte_reader_skip_string
|
|
||||||
fpi_byte_reader_skip_string_utf8
|
|
||||||
fpi_byte_reader_skip_string_utf16
|
|
||||||
fpi_byte_reader_skip_string_utf32
|
|
||||||
fpi_byte_reader_peek_string
|
|
||||||
fpi_byte_reader_peek_string_utf8
|
|
||||||
fpi_byte_reader_get_string_utf8
|
|
||||||
fpi_byte_reader_dup_string_utf8
|
|
||||||
fpi_byte_reader_dup_string_utf16
|
|
||||||
fpi_byte_reader_dup_string_utf32
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<FILE>fpi-byte-writer</FILE>
|
|
||||||
<TITLE>FpiByteWriter</TITLE>
|
|
||||||
FpiByteWriter
|
|
||||||
fpi_byte_writer_new
|
|
||||||
fpi_byte_writer_new_with_size
|
|
||||||
fpi_byte_writer_new_with_data
|
|
||||||
fpi_byte_writer_init
|
|
||||||
fpi_byte_writer_init_with_size
|
|
||||||
fpi_byte_writer_init_with_data
|
|
||||||
fpi_byte_writer_reset
|
|
||||||
fpi_byte_writer_reset_and_get_bytes
|
|
||||||
fpi_byte_writer_reset_and_get_data
|
|
||||||
fpi_byte_writer_free
|
|
||||||
fpi_byte_writer_free_and_get_data
|
|
||||||
fpi_byte_writer_get_remaining
|
|
||||||
fpi_byte_writer_ensure_free_space
|
|
||||||
fpi_byte_writer_put_bytes
|
|
||||||
fpi_byte_writer_put_uint8
|
|
||||||
fpi_byte_writer_put_uint16_be
|
|
||||||
fpi_byte_writer_put_uint24_be
|
|
||||||
fpi_byte_writer_put_uint32_be
|
|
||||||
fpi_byte_writer_put_uint64_be
|
|
||||||
fpi_byte_writer_put_uint16_le
|
|
||||||
fpi_byte_writer_put_uint24_le
|
|
||||||
fpi_byte_writer_put_uint32_le
|
|
||||||
fpi_byte_writer_put_uint64_le
|
|
||||||
fpi_byte_writer_put_int8
|
|
||||||
fpi_byte_writer_put_int16_be
|
|
||||||
fpi_byte_writer_put_int24_be
|
|
||||||
fpi_byte_writer_put_int32_be
|
|
||||||
fpi_byte_writer_put_int64_be
|
|
||||||
fpi_byte_writer_put_int16_le
|
|
||||||
fpi_byte_writer_put_int24_le
|
|
||||||
fpi_byte_writer_put_int32_le
|
|
||||||
fpi_byte_writer_put_int64_le
|
|
||||||
fpi_byte_writer_put_float32_be
|
|
||||||
fpi_byte_writer_put_float64_be
|
|
||||||
fpi_byte_writer_put_float32_le
|
|
||||||
fpi_byte_writer_put_float64_le
|
|
||||||
fpi_byte_writer_put_string_utf8
|
|
||||||
fpi_byte_writer_put_string_utf16
|
|
||||||
fpi_byte_writer_put_string_utf32
|
|
||||||
fpi_byte_writer_put_data
|
|
||||||
fpi_byte_writer_fill
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>fpi-context</FILE>
|
<FILE>fpi-context</FILE>
|
||||||
fpi_get_driver_types
|
fpi_get_driver_types
|
||||||
|
|
@ -308,7 +179,6 @@ fpi_device_enroll_complete
|
||||||
fpi_device_verify_complete
|
fpi_device_verify_complete
|
||||||
fpi_device_identify_complete
|
fpi_device_identify_complete
|
||||||
fpi_device_capture_complete
|
fpi_device_capture_complete
|
||||||
fpi_device_clear_storage_complete
|
|
||||||
fpi_device_delete_complete
|
fpi_device_delete_complete
|
||||||
fpi_device_list_complete
|
fpi_device_list_complete
|
||||||
fpi_device_suspend_complete
|
fpi_device_suspend_complete
|
||||||
|
|
@ -389,11 +259,7 @@ fpi_ssm_get_device
|
||||||
fpi_ssm_get_error
|
fpi_ssm_get_error
|
||||||
fpi_ssm_dup_error
|
fpi_ssm_dup_error
|
||||||
fpi_ssm_get_cur_state
|
fpi_ssm_get_cur_state
|
||||||
fpi_ssm_silence_debug
|
|
||||||
fpi_ssm_spi_transfer_cb
|
|
||||||
fpi_ssm_spi_transfer_with_weak_pointer_cb
|
|
||||||
fpi_ssm_usb_transfer_cb
|
fpi_ssm_usb_transfer_cb
|
||||||
fpi_ssm_usb_transfer_with_weak_pointer_cb
|
|
||||||
FpiSsm
|
FpiSsm
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
|
@ -420,20 +286,3 @@ FPI_TYPE_USB_TRANSFER
|
||||||
fpi_usb_transfer_get_type
|
fpi_usb_transfer_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<FILE>fpi-spi-transfer</FILE>
|
|
||||||
FpiSpiTransferCallback
|
|
||||||
FpiSpiTransfer
|
|
||||||
fpi_spi_transfer_new
|
|
||||||
fpi_spi_transfer_ref
|
|
||||||
fpi_spi_transfer_unref
|
|
||||||
fpi_spi_transfer_write
|
|
||||||
fpi_spi_transfer_write_full
|
|
||||||
fpi_spi_transfer_read
|
|
||||||
fpi_spi_transfer_read_full
|
|
||||||
fpi_spi_transfer_submit
|
|
||||||
fpi_spi_transfer_submit_sync
|
|
||||||
<SUBSECTION Standard>
|
|
||||||
FPI_TYPE_SPI_TRANSFER
|
|
||||||
fpi_spi_transfer_get_type
|
|
||||||
</SECTION>
|
|
||||||
|
|
|
||||||
|
|
@ -41,19 +41,12 @@
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="driver-helpers">
|
<chapter id="driver-helpers">
|
||||||
<title>USB, SPI and State Machine helpers</title>
|
<title>USB and State Machine helpers</title>
|
||||||
<xi:include href="xml/fpi-spi-transfer.xml"/>
|
|
||||||
<xi:include href="xml/fpi-usb-transfer.xml"/>
|
<xi:include href="xml/fpi-usb-transfer.xml"/>
|
||||||
<xi:include href="xml/fpi-ssm.xml"/>
|
<xi:include href="xml/fpi-ssm.xml"/>
|
||||||
<xi:include href="xml/fpi-log.xml"/>
|
<xi:include href="xml/fpi-log.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="driver-data">
|
|
||||||
<title>Binary buffer I/O</title>
|
|
||||||
<xi:include href="xml/fpi-byte-reader.xml"/>
|
|
||||||
<xi:include href="xml/fpi-byte-writer.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="driver-img">
|
<chapter id="driver-img">
|
||||||
<title>Image manipulation</title>
|
<title>Image manipulation</title>
|
||||||
<xi:include href="xml/fpi-image.xml"/>
|
<xi:include href="xml/fpi-image.xml"/>
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ content_files = [
|
||||||
|
|
||||||
expand_content_files = content_files
|
expand_content_files = content_files
|
||||||
|
|
||||||
glib_prefix = dependency('glib-2.0').get_variable(pkgconfig: 'prefix')
|
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
|
||||||
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
||||||
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
|
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
|
||||||
|
|
||||||
gnome.gtkdoc(versioned_libname,
|
gnome.gtkdoc(versioned_libname,
|
||||||
main_xml: 'libfprint-docs.xml',
|
main_xml: 'libfprint-docs.xml',
|
||||||
src_dir: join_paths(meson.project_source_root(), 'libfprint'),
|
src_dir: join_paths(meson.source_root(), 'libfprint'),
|
||||||
include_directories: include_directories('../libfprint'),
|
include_directories: include_directories('../libfprint'),
|
||||||
dependencies: libfprint_dep,
|
dependencies: libfprint_dep,
|
||||||
content_files: content_files,
|
content_files: content_files,
|
||||||
|
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
/*
|
|
||||||
* Example storage clearing program, which deletes all the
|
|
||||||
* fingers which have been previously enrolled to disk.
|
|
||||||
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
|
|
||||||
* Copyright (C) 2024 Abhinav Baid <abhinavbaid@gmail.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FP_COMPONENT "example-clear-storage"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <libfprint/fprint.h>
|
|
||||||
#include <glib-unix.h>
|
|
||||||
|
|
||||||
#include "storage.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
typedef struct _ClearStorageData
|
|
||||||
{
|
|
||||||
GMainLoop *loop;
|
|
||||||
GCancellable *cancellable;
|
|
||||||
unsigned int sigint_handler;
|
|
||||||
int ret_value;
|
|
||||||
} ClearStorageData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
clear_storage_data_free (ClearStorageData *clear_storage_data)
|
|
||||||
{
|
|
||||||
g_clear_handle_id (&clear_storage_data->sigint_handler, g_source_remove);
|
|
||||||
g_clear_object (&clear_storage_data->cancellable);
|
|
||||||
g_main_loop_unref (clear_storage_data->loop);
|
|
||||||
g_free (clear_storage_data);
|
|
||||||
}
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClearStorageData, clear_storage_data_free)
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|
||||||
{
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
ClearStorageData *clear_storage_data = user_data;
|
|
||||||
|
|
||||||
fp_device_close_finish (dev, res, &error);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
g_warning ("Failed closing device %s", error->message);
|
|
||||||
|
|
||||||
g_main_loop_quit (clear_storage_data->loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clear_storage_quit (FpDevice *dev,
|
|
||||||
ClearStorageData *clear_storage_data)
|
|
||||||
{
|
|
||||||
if (!fp_device_is_open (dev))
|
|
||||||
{
|
|
||||||
g_main_loop_quit (clear_storage_data->loop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
|
||||||
clear_storage_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_clear_storage_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|
||||||
{
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
ClearStorageData *clear_storage_data = user_data;
|
|
||||||
|
|
||||||
if (fp_device_clear_storage_finish (dev, res, &error))
|
|
||||||
{
|
|
||||||
if (!clear_saved_prints (dev, &error))
|
|
||||||
{
|
|
||||||
g_warning ("Clear saved prints from local storage failed: %s",
|
|
||||||
error->message);
|
|
||||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_print ("Clear storage successful!\n");
|
|
||||||
clear_storage_data->ret_value = EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_storage_quit (dev, clear_storage_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_warning ("Failed to clear storage: %s", error->message);
|
|
||||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
|
||||||
|
|
||||||
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
|
|
||||||
{
|
|
||||||
g_autoptr(GError) clear_error = NULL;
|
|
||||||
|
|
||||||
if (clear_saved_prints (dev, &clear_error))
|
|
||||||
clear_storage_data->ret_value = EXIT_SUCCESS;
|
|
||||||
else
|
|
||||||
g_warning ("Clear saved prints from local storage failed: %s",
|
|
||||||
clear_error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_storage_quit (dev, clear_storage_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
start_clear_storage (FpDevice *dev, ClearStorageData *clear_storage_data)
|
|
||||||
{
|
|
||||||
char buffer[20];
|
|
||||||
|
|
||||||
g_print ("Clear device storage? [y/N]? ");
|
|
||||||
if (fgets (buffer, sizeof (buffer), stdin) &&
|
|
||||||
(buffer[0] == 'Y' || buffer[0] == 'y'))
|
|
||||||
{
|
|
||||||
fp_device_clear_storage (dev, clear_storage_data->cancellable,
|
|
||||||
(GAsyncReadyCallback) on_clear_storage_completed,
|
|
||||||
clear_storage_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_storage_quit (dev, clear_storage_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|
||||||
{
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
ClearStorageData *clear_storage_data = user_data;
|
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error))
|
|
||||||
{
|
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
|
||||||
clear_storage_quit (dev, clear_storage_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_print ("Opened device. ");
|
|
||||||
|
|
||||||
start_clear_storage (dev, clear_storage_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sigint_cb (void *user_data)
|
|
||||||
{
|
|
||||||
ClearStorageData *clear_storage_data = user_data;
|
|
||||||
|
|
||||||
g_cancellable_cancel (clear_storage_data->cancellable);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
g_autoptr(FpContext) ctx = NULL;
|
|
||||||
g_autoptr(ClearStorageData) clear_storage_data = NULL;
|
|
||||||
GPtrArray *devices;
|
|
||||||
FpDevice *dev;
|
|
||||||
|
|
||||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
|
||||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
|
||||||
|
|
||||||
ctx = fp_context_new ();
|
|
||||||
|
|
||||||
devices = fp_context_get_devices (ctx);
|
|
||||||
if (!devices)
|
|
||||||
{
|
|
||||||
g_warning ("Impossible to get devices");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev = discover_device (devices);
|
|
||||||
if (!dev)
|
|
||||||
{
|
|
||||||
g_warning ("No devices detected.");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_storage_data = g_new0 (ClearStorageData, 1);
|
|
||||||
clear_storage_data->ret_value = EXIT_FAILURE;
|
|
||||||
clear_storage_data->loop = g_main_loop_new (NULL, FALSE);
|
|
||||||
clear_storage_data->cancellable = g_cancellable_new ();
|
|
||||||
clear_storage_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
|
|
||||||
SIGINT,
|
|
||||||
sigint_cb,
|
|
||||||
clear_storage_data,
|
|
||||||
NULL);
|
|
||||||
fp_device_open (dev, clear_storage_data->cancellable,
|
|
||||||
(GAsyncReadyCallback) on_device_opened,
|
|
||||||
clear_storage_data);
|
|
||||||
|
|
||||||
g_main_loop_run (clear_storage_data->loop);
|
|
||||||
|
|
||||||
return clear_storage_data->ret_value;
|
|
||||||
}
|
|
||||||
|
|
@ -35,7 +35,6 @@ typedef struct _EnrollData
|
||||||
unsigned int sigint_handler;
|
unsigned int sigint_handler;
|
||||||
FpFinger finger;
|
FpFinger finger;
|
||||||
int ret_value;
|
int ret_value;
|
||||||
gboolean update_fingerprint;
|
|
||||||
} EnrollData;
|
} EnrollData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -85,8 +84,7 @@ on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
/* Even if the device has storage, it may not be able to save all the
|
/* Even if the device has storage, it may not be able to save all the
|
||||||
* metadata that the print contains, so we can always save a local copy
|
* metadata that the print contains, so we can always save a local copy
|
||||||
* containing the handle to the device print */
|
* containing the handle to the device print */
|
||||||
int r = print_data_save (print, enroll_data->finger,
|
int r = print_data_save (print, enroll_data->finger);
|
||||||
enroll_data->update_fingerprint);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
g_warning ("Data save failed, code %d", r);
|
g_warning ("Data save failed, code %d", r);
|
||||||
|
|
@ -126,40 +124,6 @@ on_enroll_progress (FpDevice *device,
|
||||||
fp_device_get_nr_enroll_stages (device));
|
fp_device_get_nr_enroll_stages (device));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
should_update_fingerprint (void)
|
|
||||||
{
|
|
||||||
int update_choice;
|
|
||||||
gboolean update_fingerprint = FALSE;
|
|
||||||
|
|
||||||
printf ("Should an existing fingerprint be updated instead of being replaced (if present)? "
|
|
||||||
"Enter Y/y or N/n to make a choice.\n");
|
|
||||||
update_choice = getchar ();
|
|
||||||
if (update_choice == EOF)
|
|
||||||
{
|
|
||||||
g_warning ("EOF encountered while reading a character");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (update_choice)
|
|
||||||
{
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
update_fingerprint = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
update_fingerprint = FALSE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_warning ("Invalid choice %c, should be Y/y or N/n.", update_choice);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
return update_fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
{
|
{
|
||||||
|
|
@ -175,26 +139,13 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Opened device.\n");
|
printf ("Opened device. It's now time to enroll your finger.\n\n");
|
||||||
|
|
||||||
if (fp_device_has_feature (dev, FP_DEVICE_FEATURE_UPDATE_PRINT))
|
|
||||||
{
|
|
||||||
printf ("The device supports fingerprint updates.\n");
|
|
||||||
enroll_data->update_fingerprint = should_update_fingerprint ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("The device doesn't support fingerprint updates. Old prints will be erased.\n");
|
|
||||||
enroll_data->update_fingerprint = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("It's now time to enroll your finger.\n\n");
|
|
||||||
printf ("You will need to successfully scan your %s finger %d times to "
|
printf ("You will need to successfully scan your %s finger %d times to "
|
||||||
"complete the process.\n\n", finger_to_string (enroll_data->finger),
|
"complete the process.\n\n", finger_to_string (enroll_data->finger),
|
||||||
fp_device_get_nr_enroll_stages (dev));
|
fp_device_get_nr_enroll_stages (dev));
|
||||||
printf ("Scan your finger now.\n");
|
printf ("Scan your finger now.\n");
|
||||||
|
|
||||||
print_template = print_create_template (dev, enroll_data->finger, enroll_data->update_fingerprint);
|
print_template = print_create_template (dev, enroll_data->finger);
|
||||||
fp_device_enroll (dev, print_template, enroll_data->cancellable,
|
fp_device_enroll (dev, print_template, enroll_data->cancellable,
|
||||||
on_enroll_progress, NULL, NULL,
|
on_enroll_progress, NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_enroll_completed,
|
(GAsyncReadyCallback) on_enroll_completed,
|
||||||
|
|
@ -220,9 +171,11 @@ main (void)
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
FpFinger finger;
|
FpFinger finger;
|
||||||
|
|
||||||
g_print ("This program will enroll the selected finger overwriting any print for the same"
|
g_print ("This program will enroll the selected finger, unconditionally "
|
||||||
" finger that was enrolled previously. Fingerprint updates without erasing old data"
|
"overwriting any print for the same finger that was enrolled "
|
||||||
" are possible on devices supporting that. Ctrl+C interrupts program execution.\n");
|
"previously. If you want to continue, press enter, otherwise hit "
|
||||||
|
"Ctrl+C\n");
|
||||||
|
getchar ();
|
||||||
|
|
||||||
g_print ("Choose the finger to enroll:\n");
|
g_print ("Choose the finger to enroll:\n");
|
||||||
finger = finger_chooser ();
|
finger = finger_chooser ();
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,6 @@ on_identify_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
g_autoptr(FpPrint) matched_print = g_object_ref (match);
|
g_autoptr(FpPrint) matched_print = g_object_ref (match);
|
||||||
const GDate *date;
|
|
||||||
char date_str[128] = {};
|
char date_str[128] = {};
|
||||||
|
|
||||||
identify_data->ret_value = EXIT_SUCCESS;
|
identify_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
@ -156,8 +155,7 @@ on_identify_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
||||||
matched_print = g_steal_pointer (&stored_print);
|
matched_print = g_steal_pointer (&stored_print);
|
||||||
}
|
}
|
||||||
|
|
||||||
date = fp_print_get_enroll_date (matched_print);
|
if (fp_print_get_enroll_date (matched_print))
|
||||||
if (date && g_date_valid (date))
|
|
||||||
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
||||||
fp_print_get_enroll_date (matched_print));
|
fp_print_get_enroll_date (matched_print));
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ on_list_completed (FpDevice *dev,
|
||||||
finger_to_string (fp_print_get_finger (print)),
|
finger_to_string (fp_print_get_finger (print)),
|
||||||
fp_print_get_username (print));
|
fp_print_get_username (print));
|
||||||
|
|
||||||
if (date && g_date_valid (date))
|
if (date)
|
||||||
{
|
{
|
||||||
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d\0", date);
|
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d\0", date);
|
||||||
g_print (", enrolled on %s", buf);
|
g_print (", enrolled on %s", buf);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ examples = [
|
||||||
'img-capture',
|
'img-capture',
|
||||||
'manage-prints',
|
'manage-prints',
|
||||||
'verify',
|
'verify',
|
||||||
'clear-storage',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach example: examples
|
foreach example: examples
|
||||||
|
|
@ -22,8 +21,3 @@ executable('cpp-test',
|
||||||
'cpp-test.cpp',
|
'cpp-test.cpp',
|
||||||
dependencies: libfprint_dep,
|
dependencies: libfprint_dep,
|
||||||
)
|
)
|
||||||
|
|
||||||
if installed_tests
|
|
||||||
install_subdir('prints',
|
|
||||||
install_dir: installed_tests_testdir)
|
|
||||||
endif
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib/gstdio.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -56,18 +55,6 @@ get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
|
||||||
finger);
|
finger);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
|
||||||
get_print_prefix_for_device (FpDevice *dev)
|
|
||||||
{
|
|
||||||
const char *driver;
|
|
||||||
const char *dev_id;
|
|
||||||
|
|
||||||
driver = fp_device_get_driver (dev);
|
|
||||||
dev_id = fp_device_get_device_id (dev);
|
|
||||||
|
|
||||||
return g_strdup_printf ("%s/%s/", driver, dev_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GVariantDict *
|
static GVariantDict *
|
||||||
load_data (void)
|
load_data (void)
|
||||||
{
|
{
|
||||||
|
|
@ -115,23 +102,8 @@ save_data (GVariant *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FpPrint *
|
|
||||||
load_print_from_data (GVariant *data)
|
|
||||||
{
|
|
||||||
const guchar *stored_data = NULL;
|
|
||||||
gsize stored_len;
|
|
||||||
FpPrint *print;
|
|
||||||
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
stored_data = (const guchar *) g_variant_get_fixed_array (data, &stored_len, 1);
|
|
||||||
print = fp_print_deserialize (stored_data, stored_len, &error);
|
|
||||||
if (error)
|
|
||||||
g_warning ("Error deserializing data: %s", error->message);
|
|
||||||
return print;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
print_data_save (FpPrint *print, FpFinger finger, gboolean update_fingerprint)
|
print_data_save (FpPrint *print, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
|
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
|
||||||
|
|
||||||
|
|
@ -165,12 +137,25 @@ print_data_load (FpDevice *dev, FpFinger finger)
|
||||||
|
|
||||||
g_autoptr(GVariant) val = NULL;
|
g_autoptr(GVariant) val = NULL;
|
||||||
g_autoptr(GVariantDict) dict = NULL;
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
|
const guchar *stored_data = NULL;
|
||||||
|
gsize stored_len;
|
||||||
|
|
||||||
dict = load_data ();
|
dict = load_data ();
|
||||||
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
return load_print_from_data (val);
|
{
|
||||||
|
FpPrint *print;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
stored_data = (const guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
|
||||||
|
print = fp_print_deserialize (stored_data, stored_len, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
g_warning ("Error deserializing data: %s", error->message);
|
||||||
|
|
||||||
|
return print;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +167,8 @@ gallery_data_load (FpDevice *dev)
|
||||||
g_autoptr(GVariant) dict_variant = NULL;
|
g_autoptr(GVariant) dict_variant = NULL;
|
||||||
g_autofree char *dev_prefix = NULL;
|
g_autofree char *dev_prefix = NULL;
|
||||||
GPtrArray *gallery;
|
GPtrArray *gallery;
|
||||||
|
const char *driver;
|
||||||
|
const char *dev_id;
|
||||||
GVariantIter iter;
|
GVariantIter iter;
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
gchar *key;
|
gchar *key;
|
||||||
|
|
@ -189,7 +176,9 @@ gallery_data_load (FpDevice *dev)
|
||||||
gallery = g_ptr_array_new_with_free_func (g_object_unref);
|
gallery = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
dict = load_data ();
|
dict = load_data ();
|
||||||
dict_variant = g_variant_dict_end (dict);
|
dict_variant = g_variant_dict_end (dict);
|
||||||
dev_prefix = get_print_prefix_for_device (dev);
|
driver = fp_device_get_driver (dev);
|
||||||
|
dev_id = fp_device_get_device_id (dev);
|
||||||
|
dev_prefix = g_strdup_printf ("%s/%s/", driver, dev_id);
|
||||||
|
|
||||||
g_variant_iter_init (&iter, dict_variant);
|
g_variant_iter_init (&iter, dict_variant);
|
||||||
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
||||||
|
|
@ -217,80 +206,17 @@ gallery_data_load (FpDevice *dev)
|
||||||
return gallery;
|
return gallery;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
clear_saved_prints (FpDevice *dev,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
g_autoptr(GVariantDict) dict = NULL;
|
|
||||||
g_autoptr(GVariantDict) updated_dict = NULL;
|
|
||||||
g_autoptr(GVariant) dict_variant = NULL;
|
|
||||||
g_autofree char *dev_prefix = NULL;
|
|
||||||
GPtrArray *print_keys;
|
|
||||||
GVariantIter iter;
|
|
||||||
GVariant *value;
|
|
||||||
gchar *key;
|
|
||||||
|
|
||||||
print_keys = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
dict = load_data ();
|
|
||||||
dict_variant = g_variant_dict_end (dict);
|
|
||||||
dev_prefix = get_print_prefix_for_device (dev);
|
|
||||||
|
|
||||||
g_variant_iter_init (&iter, dict_variant);
|
|
||||||
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
|
|
||||||
{
|
|
||||||
if (!g_str_has_prefix (key, dev_prefix))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_ptr_array_add (print_keys, g_strdup (key));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!print_keys->len)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
updated_dict = load_data ();
|
|
||||||
|
|
||||||
for (guint i = 0; i < print_keys->len; ++i)
|
|
||||||
{
|
|
||||||
key = g_ptr_array_index (print_keys, i);
|
|
||||||
if (!g_variant_dict_remove (updated_dict, key))
|
|
||||||
{
|
|
||||||
g_warning ("Print '%s' key not found!", key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_debug ("Dropping print '%s' from gallery", key);
|
|
||||||
}
|
|
||||||
|
|
||||||
save_data (g_variant_dict_end (updated_dict));
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
FpPrint *
|
FpPrint *
|
||||||
print_create_template (FpDevice *dev, FpFinger finger, gboolean load_existing)
|
print_create_template (FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autoptr(GVariantDict) dict = NULL;
|
|
||||||
g_autoptr(GDateTime) datetime = NULL;
|
g_autoptr(GDateTime) datetime = NULL;
|
||||||
g_autoptr(GDate) date = NULL;
|
g_autoptr(GDate) date = NULL;
|
||||||
g_autoptr(GVariant) existing_val = NULL;
|
|
||||||
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
|
|
||||||
FpPrint *template = NULL;
|
FpPrint *template = NULL;
|
||||||
gint year, month, day;
|
gint year, month, day;
|
||||||
|
|
||||||
if (load_existing)
|
template = fp_print_new (dev);
|
||||||
{
|
fp_print_set_finger (template, finger);
|
||||||
dict = load_data ();
|
fp_print_set_username (template, g_get_user_name ());
|
||||||
existing_val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
|
||||||
if (existing_val != NULL)
|
|
||||||
template = load_print_from_data (existing_val);
|
|
||||||
}
|
|
||||||
if (template == NULL)
|
|
||||||
{
|
|
||||||
template = fp_print_new (dev);
|
|
||||||
fp_print_set_finger (template, finger);
|
|
||||||
fp_print_set_username (template, g_get_user_name ());
|
|
||||||
}
|
|
||||||
|
|
||||||
datetime = g_date_time_new_now_local ();
|
datetime = g_date_time_new_now_local ();
|
||||||
g_date_time_get_ymd (datetime, &year, &month, &day);
|
g_date_time_get_ymd (datetime, &year, &month, &day);
|
||||||
date = g_date_new_dmy (day, month, year);
|
date = g_date_new_dmy (day, month, year);
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <libfprint/fprint.h>
|
|
||||||
|
|
||||||
int print_data_save (FpPrint *print,
|
int print_data_save (FpPrint *print,
|
||||||
FpFinger finger,
|
FpFinger finger);
|
||||||
gboolean update_fingerprint);
|
|
||||||
FpPrint * print_data_load (FpDevice *dev,
|
FpPrint * print_data_load (FpDevice *dev,
|
||||||
FpFinger finger);
|
FpFinger finger);
|
||||||
GPtrArray * gallery_data_load (FpDevice *dev);
|
GPtrArray * gallery_data_load (FpDevice *dev);
|
||||||
gboolean clear_saved_prints (FpDevice *dev,
|
FpPrint * print_create_template (FpDevice *dev,
|
||||||
GError **error);
|
FpFinger finger);
|
||||||
FpPrint * print_create_template (FpDevice *dev,
|
|
||||||
FpFinger finger,
|
|
||||||
const gboolean load_existing);
|
|
||||||
gboolean print_image_save (FpPrint *print,
|
gboolean print_image_save (FpPrint *print,
|
||||||
const char *path);
|
const char *path);
|
||||||
gboolean save_image_to_pgm (FpImage *img,
|
gboolean save_image_to_pgm (FpImage *img,
|
||||||
|
|
|
||||||
|
|
@ -130,14 +130,12 @@ on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
const GDate *date = fp_print_get_enroll_date (match);
|
char date_str[128];
|
||||||
char date_str[128] = "<unknown>";
|
|
||||||
|
|
||||||
verify_data->ret_value = EXIT_SUCCESS;
|
verify_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
||||||
if (date && g_date_valid (date))
|
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
||||||
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
fp_print_get_enroll_date (match));
|
||||||
fp_print_get_enroll_date (match));
|
|
||||||
g_debug ("Match report: device %s matched finger %s successifully "
|
g_debug ("Match report: device %s matched finger %s successifully "
|
||||||
"with print %s, enrolled on date %s by user %s",
|
"with print %s, enrolled on date %s by user %s",
|
||||||
fp_device_get_name (dev),
|
fp_device_get_name (dev),
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
gcov-ignore-parse-errors = suspicious_hits.warn
|
|
||||||
|
|
@ -124,7 +124,7 @@ G_DEFINE_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
|
||||||
|
|
||||||
|
|
||||||
static const FpIdEntry id_table[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x08ff, .pid = 0x5501 },
|
{ .pid = 0x08ff, .vid = 0x5501 },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ data_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GErro
|
||||||
{
|
{
|
||||||
if (!self->stop && (self->strips_len > 0))
|
if (!self->stop && (self->strips_len > 0))
|
||||||
{
|
{
|
||||||
g_autoptr(FpImage) img = NULL;
|
FpImage *img;
|
||||||
self->strips = g_slist_reverse (self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||||
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||||
|
|
@ -199,7 +199,7 @@ data_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GErro
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
FpImage *resizeImage = fpi_image_resize (img, EGIS0570_RESIZE, EGIS0570_RESIZE);
|
FpImage *resizeImage = fpi_image_resize (img, EGIS0570_RESIZE, EGIS0570_RESIZE);
|
||||||
fpi_image_device_image_captured (img_self, g_steal_pointer (&resizeImage));
|
fpi_image_device_image_captured (img_self, resizeImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_image_device_report_finger_status (img_self, FALSE);
|
fpi_image_device_report_finger_status (img_self, FALSE);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,214 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,223 +0,0 @@
|
||||||
/*
|
|
||||||
* Driver for Egis Technology (LighTuning) Match-On-Chip sensors
|
|
||||||
* Originally authored 2023 by Joshua Grisham <josh@joshuagrisham.com>
|
|
||||||
*
|
|
||||||
* Portions of code and logic inspired from the elanmoc libfprint driver
|
|
||||||
* which is copyright (C) 2021 Elan Microelectronics Inc (see elanmoc.c)
|
|
||||||
*
|
|
||||||
* Based on original reverse-engineering work by Joshua Grisham. The protocol has
|
|
||||||
* been reverse-engineered from captures of the official Windows driver, and by
|
|
||||||
* testing commands on the sensor with a multiplatform Python prototype driver:
|
|
||||||
* https://github.com/joshuagrisham/galaxy-book2-pro-linux/tree/main/fingerprint/
|
|
||||||
*
|
|
||||||
* 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 (FpiDeviceEgisMoc, fpi_device_egismoc, FPI, DEVICE_EGISMOC, FpDevice)
|
|
||||||
|
|
||||||
#define EGISMOC_DRIVER_FULLNAME "Egis Technology (LighTuning) Match-on-Chip"
|
|
||||||
|
|
||||||
#define EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 (1 << 0)
|
|
||||||
#define EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1)
|
|
||||||
#define EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2)
|
|
||||||
|
|
||||||
#define EGISMOC_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT)
|
|
||||||
#define EGISMOC_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN)
|
|
||||||
#define EGISMOC_EP_CMD_INTERRUPT_IN 0x83
|
|
||||||
|
|
||||||
#define EGISMOC_USB_CONTROL_TIMEOUT 5000
|
|
||||||
#define EGISMOC_USB_SEND_TIMEOUT 5000
|
|
||||||
#define EGISMOC_USB_RECV_TIMEOUT 5000
|
|
||||||
#define EGISMOC_USB_INTERRUPT_TIMEOUT 60000
|
|
||||||
|
|
||||||
#define EGISMOC_USB_IN_RECV_LENGTH 4096
|
|
||||||
#define EGISMOC_USB_INTERRUPT_IN_RECV_LENGTH 64
|
|
||||||
|
|
||||||
#define EGISMOC_MAX_ENROLL_STAGES_DEFAULT 10
|
|
||||||
#define EGISMOC_MAX_ENROLL_NUM 10
|
|
||||||
#define EGISMOC_FINGERPRINT_DATA_SIZE 32
|
|
||||||
#define EGISMOC_LIST_RESPONSE_PREFIX_SIZE 14
|
|
||||||
#define EGISMOC_LIST_RESPONSE_SUFFIX_SIZE 2
|
|
||||||
|
|
||||||
/* standard prefixes for all read/writes */
|
|
||||||
|
|
||||||
static guchar egismoc_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01};
|
|
||||||
static gsize egismoc_write_prefix_len = sizeof (egismoc_write_prefix) / sizeof (egismoc_write_prefix[0]);
|
|
||||||
|
|
||||||
static guchar egismoc_read_prefix[] = {'S', 'I', 'G', 'E', 0x00, 0x00, 0x00, 0x01};
|
|
||||||
static gsize egismoc_read_prefix_len = sizeof (egismoc_read_prefix) / sizeof (egismoc_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_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_sensor_enroll[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x17, 0x01, 0x00};
|
|
||||||
static gsize cmd_sensor_enroll_len = sizeof (cmd_sensor_enroll) / sizeof (cmd_sensor_enroll[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 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]);
|
|
||||||
|
|
||||||
|
|
||||||
/* commands which exist on the device but are currently not used */
|
|
||||||
/*
|
|
||||||
static guchar cmd_sensor_cancel[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x04, 0x00};
|
|
||||||
static gsize cmd_sensor_cancel_len = sizeof(cmd_sensor_cancel) / sizeof(cmd_sensor_cancel[0]);
|
|
||||||
|
|
||||||
static guchar cmd_sensor_verify[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x01, 0x00};
|
|
||||||
static gsize cmd_sensor_verify_len = sizeof(cmd_sensor_verify) / sizeof(cmd_sensor_verify[0]);
|
|
||||||
|
|
||||||
static guchar cmd_read_verify[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x02, 0x00};
|
|
||||||
static gsize cmd_read_verify_len = sizeof(cmd_read_verify) / sizeof(cmd_read_verify[0]);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* prefixes/suffixes and other things for dynamically created command payloads */
|
|
||||||
|
|
||||||
#define EGISMOC_CHECK_BYTES_LENGTH 2
|
|
||||||
#define EGISMOC_IDENTIFY_RESPONSE_PRINT_ID_OFFSET 46
|
|
||||||
#define EGISMOC_CMD_CHECK_SEPARATOR_LENGTH 32
|
|
||||||
|
|
||||||
static guchar cmd_new_print_prefix[] = {0x00, 0x00, 0x00, 0x27, 0x50, 0x16, 0x03, 0x00, 0x00, 0x00, 0x20};
|
|
||||||
static gsize cmd_new_print_prefix_len = sizeof (cmd_new_print_prefix) / sizeof (cmd_new_print_prefix[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_INIT_CONTROL1,
|
|
||||||
DEV_INIT_CONTROL2,
|
|
||||||
DEV_INIT_CONTROL3,
|
|
||||||
DEV_INIT_CONTROL4,
|
|
||||||
DEV_INIT_CONTROL5,
|
|
||||||
DEV_GET_FW_VERSION,
|
|
||||||
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_GET_ENROLLED_IDS,
|
|
||||||
ENROLL_CHECK_ENROLLED_NUM,
|
|
||||||
ENROLL_SENSOR_RESET,
|
|
||||||
ENROLL_SENSOR_ENROLL,
|
|
||||||
ENROLL_WAIT_FINGER,
|
|
||||||
ENROLL_SENSOR_CHECK,
|
|
||||||
ENROLL_CHECK,
|
|
||||||
ENROLL_START,
|
|
||||||
ENROLL_CAPTURE_SENSOR_RESET,
|
|
||||||
ENROLL_CAPTURE_SENSOR_START_CAPTURE,
|
|
||||||
ENROLL_CAPTURE_WAIT_FINGER,
|
|
||||||
ENROLL_CAPTURE_READ_RESPONSE,
|
|
||||||
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;
|
|
||||||
|
|
@ -357,7 +357,7 @@ elan_cmd_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
if (transfer->endpoint & FPI_USB_ENDPOINT_IN)
|
if (transfer->endpoint & FPI_USB_ENDPOINT_IN)
|
||||||
{
|
{
|
||||||
/* just finished receiving */
|
/* just finished receiving */
|
||||||
self->last_read = g_memdup2 (transfer->buffer, transfer->actual_length);
|
self->last_read = g_memdup (transfer->buffer, transfer->actual_length);
|
||||||
elan_cmd_done (ssm);
|
elan_cmd_done (ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,6 @@ static const FpIdEntry elan_id_table[] = {
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c4b, .driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV},
|
||||||
|
|
|
||||||
|
|
@ -25,21 +25,7 @@
|
||||||
G_DEFINE_TYPE (FpiDeviceElanmoc, fpi_device_elanmoc, FP_TYPE_DEVICE)
|
G_DEFINE_TYPE (FpiDeviceElanmoc, fpi_device_elanmoc, FP_TYPE_DEVICE)
|
||||||
|
|
||||||
static const FpIdEntry id_table[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x04f3, .pid = 0x0c7d, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c7e, },
|
{ .vid = 0x04f3, .pid = 0x0c7e, },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c82, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c88, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c8c, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c8d, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c98, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c99, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c9d, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c9f, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0ca3, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0ca7, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0ca8, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0cb0, },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0cb2, },
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -58,9 +44,9 @@ elanmoc_compose_cmd (
|
||||||
const struct elanmoc_cmd *cmd_info
|
const struct elanmoc_cmd *cmd_info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
g_autofree uint8_t *cmd_buf = NULL;
|
g_autofree char *cmd_buf = NULL;
|
||||||
|
|
||||||
cmd_buf = g_new0 (uint8_t, cmd_info->cmd_len);
|
cmd_buf = g_malloc0 (cmd_info->cmd_len);
|
||||||
if(cmd_info->cmd_len < ELAN_MAX_HDR_LEN)
|
if(cmd_info->cmd_len < ELAN_MAX_HDR_LEN)
|
||||||
memcpy (cmd_buf, &cmd_info->cmd_header, cmd_info->cmd_len);
|
memcpy (cmd_buf, &cmd_info->cmd_header, cmd_info->cmd_len);
|
||||||
else
|
else
|
||||||
|
|
@ -136,10 +122,10 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ELAN_MOC_CMD_SEND = 0,
|
FP_CMD_SEND = 0,
|
||||||
ELAN_MOC_CMD_GET,
|
FP_CMD_GET,
|
||||||
ELAN_MOC_CMD_NUM_STATES,
|
FP_CMD_NUM_STATES,
|
||||||
} ElanMocCmdState;
|
} FpCmdState;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_cmd_run_state (FpiSsm *ssm,
|
fp_cmd_run_state (FpiSsm *ssm,
|
||||||
|
|
@ -150,7 +136,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case ELAN_MOC_CMD_SEND:
|
case FP_CMD_SEND:
|
||||||
if (self->cmd_transfer)
|
if (self->cmd_transfer)
|
||||||
{
|
{
|
||||||
self->cmd_transfer->ssm = ssm;
|
self->cmd_transfer->ssm = ssm;
|
||||||
|
|
@ -166,7 +152,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELAN_MOC_CMD_GET:
|
case FP_CMD_GET:
|
||||||
if (self->cmd_len_in == 0)
|
if (self->cmd_len_in == 0)
|
||||||
{
|
{
|
||||||
CommandData *data = fpi_ssm_get_data (ssm);
|
CommandData *data = fpi_ssm_get_data (ssm);
|
||||||
|
|
@ -233,7 +219,7 @@ elanmoc_get_cmd (FpDevice *device, guint8 *buffer_out,
|
||||||
|
|
||||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||||
fp_cmd_run_state,
|
fp_cmd_run_state,
|
||||||
ELAN_MOC_CMD_NUM_STATES);
|
FP_CMD_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
||||||
|
|
||||||
|
|
@ -388,9 +374,9 @@ elanmoc_enroll_cb (FpiDeviceElanmoc *self,
|
||||||
enroll_status_report (self, ENROLL_RSP_RETRY, self->num_frames, NULL);
|
enroll_status_report (self, ENROLL_RSP_RETRY, self->num_frames, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->num_frames == self->max_moc_enroll_time && buffer_in[1] == ELAN_MSG_OK)
|
if (self->num_frames == ELAN_MOC_ENROLL_TIMES && buffer_in[1] == ELAN_MSG_OK)
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
else if (self->num_frames < self->max_moc_enroll_time)
|
else if (self->num_frames < ELAN_MOC_ENROLL_TIMES)
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, MOC_ENROLL_WAIT_FINGER);
|
fpi_ssm_jump_to_state (self->task_ssm, MOC_ENROLL_WAIT_FINGER);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||||
|
|
@ -453,7 +439,7 @@ elan_enroll_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||||
case MOC_ENROLL_WAIT_FINGER:
|
case MOC_ENROLL_WAIT_FINGER:
|
||||||
cmd_buf = elanmoc_compose_cmd (&elanmoc_enroll_cmd);
|
cmd_buf = elanmoc_compose_cmd (&elanmoc_enroll_cmd);
|
||||||
cmd_buf[3] = self->curr_enrolled;
|
cmd_buf[3] = self->curr_enrolled;
|
||||||
cmd_buf[4] = self->max_moc_enroll_time;
|
cmd_buf[4] = ELAN_MOC_ENROLL_TIMES;
|
||||||
cmd_buf[5] = self->num_frames;
|
cmd_buf[5] = self->num_frames;
|
||||||
elanmoc_get_cmd (dev, cmd_buf, elanmoc_enroll_cmd.cmd_len, elanmoc_enroll_cmd.resp_len, 1, elanmoc_enroll_cb);
|
elanmoc_get_cmd (dev, cmd_buf, elanmoc_enroll_cmd.cmd_len, elanmoc_enroll_cmd.resp_len, 1, elanmoc_enroll_cb);
|
||||||
break;
|
break;
|
||||||
|
|
@ -518,7 +504,7 @@ create_print_from_response (FpiDeviceElanmoc *self,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
userid = g_memdup2 (&buffer_in[5], userid_len);
|
userid = g_memdup (&buffer_in[5], userid_len);
|
||||||
userid_safe = g_strndup ((const char *) &buffer_in[5], userid_len);
|
userid_safe = g_strndup ((const char *) &buffer_in[5], userid_len);
|
||||||
print = fp_print_new (FP_DEVICE (self));
|
print = fp_print_new (FP_DEVICE (self));
|
||||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, userid, userid_len, 1);
|
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, userid, userid_len, 1);
|
||||||
|
|
@ -770,7 +756,6 @@ identify_status_report (FpiDeviceElanmoc *self, int verify_status_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum identify_states {
|
enum identify_states {
|
||||||
IDENTIFY_SET_MODE,
|
|
||||||
IDENTIFY_WAIT_FINGER,
|
IDENTIFY_WAIT_FINGER,
|
||||||
IDENTIFY_NUM_STATES,
|
IDENTIFY_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
@ -806,13 +791,6 @@ elan_identify_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||||
fp_info ("elanmoc %s ", __func__);
|
fp_info ("elanmoc %s ", __func__);
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case IDENTIFY_SET_MODE:
|
|
||||||
fp_info ("elanmoc %s IDENTIFY_SET_MODE", __func__);
|
|
||||||
cmd_buf = elanmoc_compose_cmd (&elanmoc_set_mod_cmd);
|
|
||||||
cmd_buf[3] = 0x03;
|
|
||||||
elanmoc_get_cmd (dev, cmd_buf, elanmoc_set_mod_cmd.cmd_len, elanmoc_set_mod_cmd.resp_len, 0, elanmoc_cmd_ack_cb);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IDENTIFY_WAIT_FINGER:
|
case IDENTIFY_WAIT_FINGER:
|
||||||
fp_info ("elanmoc %s VERIFY_WAIT_FINGER", __func__);
|
fp_info ("elanmoc %s VERIFY_WAIT_FINGER", __func__);
|
||||||
cmd_buf = elanmoc_compose_cmd (&elanmoc_verify_cmd);
|
cmd_buf = elanmoc_compose_cmd (&elanmoc_verify_cmd);
|
||||||
|
|
@ -1019,12 +997,6 @@ elanmoc_get_status_cb (FpiDeviceElanmoc *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_in[1] != 0x03 && self->cmd_retry_cnt != 0)
|
if (buffer_in[1] != 0x03 && self->cmd_retry_cnt != 0)
|
||||||
{
|
|
||||||
self->cmd_retry_cnt--;
|
|
||||||
cmd_buf = elanmoc_compose_cmd (&cal_status_cmd);
|
|
||||||
elanmoc_get_cmd (FP_DEVICE (self), cmd_buf, cal_status_cmd.cmd_len, cal_status_cmd.resp_len, 0, elanmoc_get_status_cb);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if(self->cmd_retry_cnt == 0)
|
if(self->cmd_retry_cnt == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1033,6 +1005,12 @@ elanmoc_get_status_cb (FpiDeviceElanmoc *self,
|
||||||
"Sensor not ready"));
|
"Sensor not ready"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self->cmd_retry_cnt--;
|
||||||
|
cmd_buf = elanmoc_compose_cmd (&cal_status_cmd);
|
||||||
|
elanmoc_get_cmd (FP_DEVICE (self), cmd_buf, cal_status_cmd.cmd_len, cal_status_cmd.resp_len, 0, elanmoc_get_status_cb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1080,7 +1058,6 @@ elanmoc_open (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceElanmoc *self = FPI_DEVICE_ELANMOC (device);
|
FpiDeviceElanmoc *self = FPI_DEVICE_ELANMOC (device);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gint productid = 0;
|
|
||||||
|
|
||||||
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
|
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1088,28 +1065,6 @@ elanmoc_open (FpDevice *device)
|
||||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
productid = g_usb_device_get_pid (fpi_device_get_usb_device (device));
|
|
||||||
switch (productid)
|
|
||||||
{
|
|
||||||
case 0x0c8c:
|
|
||||||
self->max_moc_enroll_time = 11;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0c99:
|
|
||||||
self->max_moc_enroll_time = 14;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0c8d:
|
|
||||||
self->max_moc_enroll_time = 17;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
self->max_moc_enroll_time = ELAN_MOC_ENROLL_TIMES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_device_set_nr_enroll_stages (device, self->max_moc_enroll_time);
|
|
||||||
|
|
||||||
self->task_ssm = fpi_ssm_new (FP_DEVICE (self), dev_init_handler, DEV_INIT_STATES);
|
self->task_ssm = fpi_ssm_new (FP_DEVICE (self), dev_init_handler, DEV_INIT_STATES);
|
||||||
fpi_ssm_start (self->task_ssm, task_ssm_init_done);
|
fpi_ssm_start (self->task_ssm, task_ssm_init_done);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,6 @@ struct _FpiDeviceElanmoc
|
||||||
unsigned char y_trace;
|
unsigned char y_trace;
|
||||||
int num_frames;
|
int num_frames;
|
||||||
int curr_enrolled;
|
int curr_enrolled;
|
||||||
int max_moc_enroll_time;
|
|
||||||
int cancel_result;
|
int cancel_result;
|
||||||
int cmd_retry_cnt;
|
int cmd_retry_cnt;
|
||||||
int list_index;
|
int list_index;
|
||||||
|
|
|
||||||
|
|
@ -439,12 +439,6 @@ elanspi_capture_old_line_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpoin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* check for termination */
|
|
||||||
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_NONE)
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_completed (transfer->ssm);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* check for cancellation */
|
/* check for cancellation */
|
||||||
if (fpi_device_action_is_cancelled (dev))
|
if (fpi_device_action_is_cancelled (dev))
|
||||||
{
|
{
|
||||||
|
|
@ -612,7 +606,6 @@ elanspi_calibrate_old_handler (FpiSsm *ssm, FpDevice *dev)
|
||||||
case ELANSPI_CALIBOLD_CHECKFIN_CAPTURE:
|
case ELANSPI_CALIBOLD_CHECKFIN_CAPTURE:
|
||||||
case ELANSPI_CALIBOLD_DACFINE_CAPTURE:
|
case ELANSPI_CALIBOLD_DACFINE_CAPTURE:
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
||||||
fpi_ssm_silence_debug (chld);
|
|
||||||
fpi_ssm_start_subsm (ssm, chld);
|
fpi_ssm_start_subsm (ssm, chld);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -867,7 +860,6 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
|
||||||
case ELANSPI_CALIBHV_CAPTURE:
|
case ELANSPI_CALIBHV_CAPTURE:
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
||||||
fpi_ssm_silence_debug (chld);
|
|
||||||
fpi_ssm_start_subsm (ssm, chld);
|
fpi_ssm_start_subsm (ssm, chld);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1123,7 +1115,6 @@ do_sw_reset:
|
||||||
chld = fpi_ssm_new_full (dev, elanspi_calibrate_hv_handler, ELANSPI_CALIBHV_NSTATES, ELANSPI_CALIBHV_PROTECT, "HV calibrate");
|
chld = fpi_ssm_new_full (dev, elanspi_calibrate_hv_handler, ELANSPI_CALIBHV_NSTATES, ELANSPI_CALIBHV_PROTECT, "HV calibrate");
|
||||||
else
|
else
|
||||||
chld = fpi_ssm_new_full (dev, elanspi_calibrate_old_handler, ELANSPI_CALIBOLD_NSTATES, ELANSPI_CALIBOLD_PROTECT, "old calibrate");
|
chld = fpi_ssm_new_full (dev, elanspi_calibrate_old_handler, ELANSPI_CALIBOLD_NSTATES, ELANSPI_CALIBOLD_PROTECT, "old calibrate");
|
||||||
fpi_ssm_silence_debug (chld);
|
|
||||||
fpi_ssm_start_subsm (ssm, chld);
|
fpi_ssm_start_subsm (ssm, chld);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1132,7 +1123,6 @@ do_sw_reset:
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
||||||
else
|
else
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
||||||
fpi_ssm_silence_debug (chld);
|
|
||||||
fpi_ssm_start_subsm (ssm, chld);
|
fpi_ssm_start_subsm (ssm, chld);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1229,6 +1219,8 @@ elanspi_guess_image (FpiDeviceElanSpi *self, guint16 *raw_image)
|
||||||
|
|
||||||
sq_stddev /= (frame_width * frame_height);
|
sq_stddev /= (frame_width * frame_height);
|
||||||
|
|
||||||
|
fp_dbg ("<guess> 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)
|
if (invalid_percent < ELANSPI_MAX_REAL_INVALID_PERCENT)
|
||||||
is_fp += 1;
|
is_fp += 1;
|
||||||
if (invalid_percent > ELANSPI_MIN_EMPTY_INVALID_PERCENT)
|
if (invalid_percent > ELANSPI_MIN_EMPTY_INVALID_PERCENT)
|
||||||
|
|
@ -1239,8 +1231,6 @@ elanspi_guess_image (FpiDeviceElanSpi *self, guint16 *raw_image)
|
||||||
if (sq_stddev < ELANSPI_MAX_EMPTY_STDDEV)
|
if (sq_stddev < ELANSPI_MAX_EMPTY_STDDEV)
|
||||||
is_empty += 1;
|
is_empty += 1;
|
||||||
|
|
||||||
fp_dbg ("<guess> stddev=%" G_GUINT64_FORMAT "d, ip=%d, is_fp=%d, is_empty=%d", sq_stddev, invalid_percent, is_fp, is_empty);
|
|
||||||
|
|
||||||
if (is_fp > is_empty)
|
if (is_fp > is_empty)
|
||||||
return ELANSPI_GUESS_FINGERPRINT;
|
return ELANSPI_GUESS_FINGERPRINT;
|
||||||
else if (is_empty > is_fp)
|
else if (is_empty > is_fp)
|
||||||
|
|
@ -1492,12 +1482,11 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
{
|
{
|
||||||
fp_dbg ("<capture> got deactivate; exiting");
|
fp_dbg ("<capture> got deactivate; exiting");
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
|
||||||
fpi_ssm_mark_completed (ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
|
|
||||||
/* mark deactivate done */
|
/* mark deactivate done */
|
||||||
fpi_image_device_deactivate_complete (FP_IMAGE_DEVICE (dev), NULL);
|
fpi_image_device_deactivate_complete (FP_IMAGE_DEVICE (dev), NULL);
|
||||||
|
self->deactivating = FALSE;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1506,7 +1495,6 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
|
||||||
else
|
else
|
||||||
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
|
||||||
fpi_ssm_silence_debug (chld);
|
|
||||||
fpi_ssm_start_subsm (ssm, chld);
|
fpi_ssm_start_subsm (ssm, chld);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,37 +97,7 @@ static const struct elanspi_reg_entry elanspi_calibration_table_default[] = {
|
||||||
{0xff, 0xff}
|
{0xff, 0xff}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elanspi_reg_entry elanspi_calibration_table_id6[] = {
|
static const struct elanspi_reg_entry elanspi_calibration_table_id567[] = {
|
||||||
{0x2A, 0x07},
|
|
||||||
{0x1, 0x00},
|
|
||||||
{0x2, 0x5f},
|
|
||||||
{0x3, 0x00},
|
|
||||||
{0x4, 0x5f},
|
|
||||||
{0x5, 0x60},
|
|
||||||
{0x6, 0xC0},
|
|
||||||
{0x7, 0x80},
|
|
||||||
{0x8, 0x04},
|
|
||||||
{0xA, 0x97},
|
|
||||||
{0xB, 0x72},
|
|
||||||
{0xC, 0x69},
|
|
||||||
{0xF, 0x2A},
|
|
||||||
{0x11, 0x2A},
|
|
||||||
{0x13, 0x27},
|
|
||||||
{0x15, 0x67},
|
|
||||||
{0x18, 0x04},
|
|
||||||
{0x21, 0x20},
|
|
||||||
{0x22, 0x36},
|
|
||||||
{0x29, 0x02},
|
|
||||||
{0x2A, 0x03},
|
|
||||||
{0x2A, 0x5F},
|
|
||||||
{0x2B, 0xC0},
|
|
||||||
{0x2C, 0x10},
|
|
||||||
{0x2E, 0xFF},
|
|
||||||
|
|
||||||
{0xff, 0xff}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct elanspi_reg_entry elanspi_calibration_table_id57[] = {
|
|
||||||
{0x2A, 0x07},
|
{0x2A, 0x07},
|
||||||
{0x5, 0x60},
|
{0x5, 0x60},
|
||||||
{0x6, 0xC0},
|
{0x6, 0xC0},
|
||||||
|
|
@ -173,9 +143,9 @@ static const struct elanspi_regtable elanspi_calibration_table_old = {
|
||||||
.other = elanspi_calibration_table_default,
|
.other = elanspi_calibration_table_default,
|
||||||
.entries = {
|
.entries = {
|
||||||
{ .sid = 0x0, .table = elanspi_calibration_table_id0 },
|
{ .sid = 0x0, .table = elanspi_calibration_table_id0 },
|
||||||
{ .sid = 0x5, .table = elanspi_calibration_table_id57 },
|
{ .sid = 0x5, .table = elanspi_calibration_table_id567 },
|
||||||
{ .sid = 0x6, .table = elanspi_calibration_table_id6 },
|
{ .sid = 0x6, .table = elanspi_calibration_table_id567 },
|
||||||
{ .sid = 0x7, .table = elanspi_calibration_table_id57 },
|
{ .sid = 0x7, .table = elanspi_calibration_table_id567 },
|
||||||
{ .sid = 0x0, .table = NULL }
|
{ .sid = 0x0, .table = NULL }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -340,17 +310,14 @@ static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
|
||||||
|
|
||||||
// using checkargs ACPI:HIDPID
|
// using checkargs ACPI:HIDPID
|
||||||
static const FpIdEntry elanspi_id_table[] = {
|
static const FpIdEntry elanspi_id_table[] = {
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x2766}, .driver_data = ELANSPI_NO_ROTATE},
|
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30c6}, .driver_data = ELANSPI_180_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30c6}, .driver_data = ELANSPI_180_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3128}, .driver_data = ELANSPI_90LEFT_ROTATE},
|
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3134}, .driver_data = ELANSPI_90LEFT_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3134}, .driver_data = ELANSPI_90LEFT_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3148}, .driver_data = ELANSPI_180_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3148}, .driver_data = ELANSPI_180_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN70A1", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x30b2}, .driver_data = ELANSPI_NO_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE},
|
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x309f}, .driver_data = ELANSPI_180_ROTATE},
|
||||||
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x241f}, .driver_data = ELANSPI_NO_ROTATE},
|
|
||||||
{.udev_types = 0}
|
{.udev_types = 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Focaltech Microelectronics
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
#include <libusb.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceFocaltechMoc, fpi_device_focaltech_moc, FPI, DEVICE_FOCALTECH_MOC, FpDevice)
|
|
||||||
|
|
||||||
#define FOCALTECH_MOC_DRIVER_FULLNAME "Focaltech MOC Sensors"
|
|
||||||
|
|
||||||
#define FOCALTECH_MOC_CMD_TIMEOUT 1000
|
|
||||||
#define FOCALTECH_MOC_MAX_FINGERS 10
|
|
||||||
#define FOCALTECH_MOC_UID_PREFIX_LENGTH 8
|
|
||||||
#define FOCALTECH_MOC_USER_ID_LENGTH 64
|
|
||||||
|
|
||||||
typedef void (*FocaltechCmdMsgCallback) (FpiDeviceFocaltechMoc *self,
|
|
||||||
GError *error);
|
|
||||||
|
|
||||||
struct _FpiDeviceFocaltechMoc
|
|
||||||
{
|
|
||||||
FpDevice parent;
|
|
||||||
FpiSsm *task_ssm;
|
|
||||||
FpiSsm *cmd_ssm;
|
|
||||||
FpiUsbTransfer *cmd_transfer;
|
|
||||||
gboolean cmd_cancelable;
|
|
||||||
gsize cmd_len_in;
|
|
||||||
int num_frames;
|
|
||||||
int delete_slot;
|
|
||||||
guint8 bulk_in_ep;
|
|
||||||
guint8 bulk_out_ep;
|
|
||||||
};
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,221 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 Fingerprint Cards AB <tech@fingerprints.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fpi-device.h"
|
|
||||||
#include "fpi-ssm.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define TEMPLATE_ID_SIZE (32)
|
|
||||||
#define MAX_FW_VERSION_STR_LEN (16)
|
|
||||||
#define FPC_CMD_INIT (0x01)
|
|
||||||
#define FPC_CMD_ARM (0x02)
|
|
||||||
#define FPC_CMD_ABORT (0x03)
|
|
||||||
#define FPC_CMD_INDICATE_S_STATE (0x08)
|
|
||||||
#define FPC_CMD_GET_IMG (0x09)
|
|
||||||
#define FPC_CMD_GET_KPI (0x0C)
|
|
||||||
#define FPC_CMD_LOAD_DB (0x60)
|
|
||||||
#define FPC_CMD_STORE_DB (0x61)
|
|
||||||
#define FPC_CMD_DELETE_DB (0x62)
|
|
||||||
#define FPC_CMD_DELETE_TEMPLATE (0x63)
|
|
||||||
#define FPC_CMD_BEGIN_ENROL (0x67)
|
|
||||||
#define FPC_CMD_ENROL (0x68)
|
|
||||||
#define FPC_CMD_END_ENROL (0x69)
|
|
||||||
#define FPC_CMD_BIND_IDENTITY (0x6A)
|
|
||||||
#define FPC_CMD_IDENTIFY (0x6B)
|
|
||||||
#define FPC_CMD_ENUM (0x70)
|
|
||||||
#define FPC_EVT_INIT_RESULT (0x02)
|
|
||||||
#define FPC_EVT_FINGER_DWN (0x06)
|
|
||||||
#define FPC_EVT_IMG (0x08)
|
|
||||||
#define FPC_EVT_FID_DATA (0x31)
|
|
||||||
#define FPC_DB_ID_LEN (16)
|
|
||||||
#define FPC_IDENTITY_TYPE_WILDCARD (0x1)
|
|
||||||
#define FPC_IDENTITY_TYPE_RESERVED (0x3)
|
|
||||||
#define FPC_IDENTITY_WILDCARD (0x25066282)
|
|
||||||
#define FPC_SUBTYPE_ANY (0xFF)
|
|
||||||
#define FPC_SUBTYPE_RESERVED (0xF5)
|
|
||||||
#define FPC_SUBTYPE_NOINFORMATION (0x00)
|
|
||||||
#define FPC_CAPTUREID_RESERVED (0x701100F)
|
|
||||||
#define FPC_SESSIONID_RESERVED (0x0077FF12)
|
|
||||||
#define FPC_TEMPLATES_MAX (10)
|
|
||||||
#define SECURITY_MAX_SID_SIZE (68)
|
|
||||||
#define FPC_HOST_MS_S0 (0x10)
|
|
||||||
#define FPC_HOST_MS_SX (0x11)
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceFpcMoc, fpi_device_fpcmoc, FPI,
|
|
||||||
DEVICE_FPCMOC, FpDevice);
|
|
||||||
|
|
||||||
typedef struct _FPC_FID_DATA
|
|
||||||
{
|
|
||||||
guint32 identity_type;
|
|
||||||
guint32 reserved;
|
|
||||||
guint32 identity_size;
|
|
||||||
guint32 subfactor;
|
|
||||||
guint8 data[SECURITY_MAX_SID_SIZE];
|
|
||||||
} FPC_FID_DATA, *PFPC_FID_DATA;
|
|
||||||
|
|
||||||
typedef struct _FPC_LOAD_DB
|
|
||||||
{
|
|
||||||
gint32 status;
|
|
||||||
guint32 reserved;
|
|
||||||
guint32 database_id_size;
|
|
||||||
guint8 data[FPC_DB_ID_LEN];
|
|
||||||
} FPC_LOAD_DB, *PFPC_LOAD_DB;
|
|
||||||
|
|
||||||
typedef union _FPC_DELETE_DB
|
|
||||||
{
|
|
||||||
guint32 reserved;
|
|
||||||
guint32 database_id_size;
|
|
||||||
guint8 data[FPC_DB_ID_LEN];
|
|
||||||
} FPC_DB_OP, *PFPC_DB_OP;
|
|
||||||
|
|
||||||
typedef struct _FPC_BEGIN_ENROL
|
|
||||||
{
|
|
||||||
gint32 status;
|
|
||||||
guint32 reserved1;
|
|
||||||
guint32 reserved2;
|
|
||||||
} FPC_BEGIN_ENROL, *PFPC_BEGIN_ENROL;
|
|
||||||
|
|
||||||
typedef struct _FPC_ENROL
|
|
||||||
{
|
|
||||||
gint32 status;
|
|
||||||
guint32 remaining;
|
|
||||||
} FPC_ENROL, *PFPC_ENROL;
|
|
||||||
|
|
||||||
typedef struct _FPC_END_ENROL
|
|
||||||
{
|
|
||||||
gint32 status;
|
|
||||||
guint32 fid;
|
|
||||||
} FPC_END_ENROL, *PFPC_END_ENROL;
|
|
||||||
|
|
||||||
typedef struct _FPC_IDENTIFY
|
|
||||||
{
|
|
||||||
gint32 status;
|
|
||||||
guint32 identity_type;
|
|
||||||
guint32 identity_offset;
|
|
||||||
guint32 identity_size;
|
|
||||||
guint32 subfactor;
|
|
||||||
guint8 data[SECURITY_MAX_SID_SIZE];
|
|
||||||
} FPC_IDENTIFY, *PFPC_IDENTIFY;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guint32 cmdid;
|
|
||||||
guint32 length;
|
|
||||||
guint32 status;
|
|
||||||
} evt_hdr_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
evt_hdr_t hdr;
|
|
||||||
guint16 sensor;
|
|
||||||
guint16 hw_id;
|
|
||||||
guint16 img_w;
|
|
||||||
guint16 img_h;
|
|
||||||
guint8 fw_version[MAX_FW_VERSION_STR_LEN];
|
|
||||||
guint16 fw_capabilities;
|
|
||||||
} evt_initiated_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guint8 subfactor;
|
|
||||||
guint32 identity_type;
|
|
||||||
guint32 identity_size;
|
|
||||||
guint8 identity[SECURITY_MAX_SID_SIZE];
|
|
||||||
} __attribute__((packed)) fpc_fid_data_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
evt_hdr_t hdr;
|
|
||||||
gint status;
|
|
||||||
guint32 num_ids;
|
|
||||||
fpc_fid_data_t fid_data[FPC_TEMPLATES_MAX];
|
|
||||||
} __attribute__((packed)) evt_enum_fids_t;
|
|
||||||
|
|
||||||
typedef struct _fp_cmd_response
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
evt_hdr_t evt_hdr;
|
|
||||||
evt_initiated_t evt_inited;
|
|
||||||
evt_enum_fids_t evt_enum_fids;
|
|
||||||
};
|
|
||||||
} fpc_cmd_response_t, *pfpc_cmd_response_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
FPC_ENROL_STATUS_COMPLETED = 0,
|
|
||||||
FPC_ENROL_STATUS_PROGRESS = 1,
|
|
||||||
FPC_ENROL_STATUS_FAILED_COULD_NOT_COMPLETE = 2,
|
|
||||||
FPC_ENROL_STATUS_FAILED_ALREADY_ENROLED = 3,
|
|
||||||
FPC_ENROL_STATUS_IMAGE_LOW_COVERAGE = 4,
|
|
||||||
FPC_ENROL_STATUS_IMAGE_TOO_SIMILAR = 5,
|
|
||||||
FPC_ENROL_STATUS_IMAGE_LOW_QUALITY = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_CMDTYPE_UNKNOWN = 0,
|
|
||||||
FPC_CMDTYPE_TO_DEVICE,
|
|
||||||
FPC_CMDTYPE_TO_DEVICE_EVTDATA,
|
|
||||||
FPC_CMDTYPE_FROM_DEVICE,
|
|
||||||
} FpcCmdType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_CMD_SEND = 0,
|
|
||||||
FPC_CMD_GET_DATA,
|
|
||||||
FPC_CMD_SUSPENDED,
|
|
||||||
FPC_CMD_RESUME,
|
|
||||||
FPC_CMD_NUM_STATES,
|
|
||||||
} FpcCmdState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_INIT = 0,
|
|
||||||
FPC_INIT_LOAD_DB,
|
|
||||||
FPC_INIT_NUM_STATES,
|
|
||||||
} FpcInitState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_ENROLL_ENUM = 0,
|
|
||||||
FPC_ENROLL_CREATE,
|
|
||||||
FPC_ENROLL_CAPTURE,
|
|
||||||
FPC_ENROLL_GET_IMG,
|
|
||||||
FPC_ENROLL_UPDATE,
|
|
||||||
FPC_ENROLL_COMPLETE,
|
|
||||||
FPC_ENROLL_CHECK_DUPLICATE,
|
|
||||||
FPC_ENROLL_BINDID,
|
|
||||||
FPC_ENROLL_COMMIT,
|
|
||||||
FPC_ENROLL_DICARD,
|
|
||||||
FPC_ENROLL_CLEANUP,
|
|
||||||
FPC_ENROLL_NUM_STATES,
|
|
||||||
} FpcEnrollState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_VERIFY_CAPTURE = 0,
|
|
||||||
FPC_VERIFY_GET_IMG,
|
|
||||||
FPC_VERIFY_IDENTIFY,
|
|
||||||
FPC_VERIFY_CANCEL,
|
|
||||||
FPC_VERIFY_NUM_STATES,
|
|
||||||
} FpcVerifyState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FPC_CLEAR_DELETE_DB = 0,
|
|
||||||
FPC_CLEAR_CREATE_DB,
|
|
||||||
FPC_CLEAR_NUM_STATES,
|
|
||||||
} FpClearState;
|
|
||||||
|
|
@ -128,13 +128,11 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||||
FpiByteReader reader = {0};
|
|
||||||
CommandData *data = user_data;
|
CommandData *data = user_data;
|
||||||
int ssm_state = 0;
|
int ret = -1, ssm_state = 0;
|
||||||
gxfp_cmd_response_t cmd_reponse = {0, };
|
gxfp_cmd_response_t cmd_reponse = {0, };
|
||||||
pack_header header;
|
pack_header header;
|
||||||
guint32 crc32_calc = 0;
|
guint32 crc32_calc = 0;
|
||||||
guint32 crc32 = 0;
|
|
||||||
guint16 cmd = 0;
|
guint16 cmd = 0;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
|
|
@ -156,28 +154,17 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.data = transfer->buffer;
|
ret = gx_proto_parse_header (transfer->buffer, transfer->actual_length, &header);
|
||||||
reader.size = transfer->actual_length;
|
if (ret != 0)
|
||||||
|
|
||||||
if (gx_proto_parse_header (&reader, &header) != 0)
|
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Corrupted message header received"));
|
"Corrupted message received"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fpi_byte_reader_set_pos (&reader, PACKAGE_HEADER_SIZE + header.len))
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Package crc read failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
|
gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc);
|
||||||
|
if(crc32_calc != GUINT32_FROM_LE (*(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)))
|
||||||
if (!fpi_byte_reader_get_uint32_le (&reader, &crc32) ||
|
|
||||||
crc32_calc != crc32)
|
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
|
|
@ -187,11 +174,8 @@ fp_cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||||
|
|
||||||
cmd = MAKE_CMD_EX (header.cmd0, header.cmd1);
|
cmd = MAKE_CMD_EX (header.cmd0, header.cmd1);
|
||||||
|
|
||||||
fpi_byte_reader_set_pos (&reader, 0);
|
ret = gx_proto_parse_body (cmd, &transfer->buffer[PACKAGE_HEADER_SIZE], header.len, &cmd_reponse);
|
||||||
reader.data = &transfer->buffer[PACKAGE_HEADER_SIZE];
|
if (ret != 0)
|
||||||
reader.size = header.len;
|
|
||||||
|
|
||||||
if (gx_proto_parse_body (cmd, &reader, &cmd_reponse) != 0)
|
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
|
|
@ -238,7 +222,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case GOODIX_CMD_SEND:
|
case FP_CMD_SEND:
|
||||||
if (self->cmd_transfer)
|
if (self->cmd_transfer)
|
||||||
{
|
{
|
||||||
self->cmd_transfer->ssm = ssm;
|
self->cmd_transfer->ssm = ssm;
|
||||||
|
|
@ -254,7 +238,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_CMD_GET_ACK:
|
case FP_CMD_GET_ACK:
|
||||||
transfer = fpi_usb_transfer_new (dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
||||||
|
|
@ -266,7 +250,7 @@ fp_cmd_run_state (FpiSsm *ssm,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_CMD_GET_DATA:
|
case FP_CMD_GET_DATA:
|
||||||
transfer = fpi_usb_transfer_new (dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE);
|
||||||
|
|
@ -354,7 +338,7 @@ goodix_sensor_cmd (FpiDeviceGoodixMoc *self,
|
||||||
|
|
||||||
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self),
|
||||||
fp_cmd_run_state,
|
fp_cmd_run_state,
|
||||||
GOODIX_CMD_NUM_STATES);
|
FP_CMD_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free);
|
||||||
|
|
||||||
|
|
@ -436,9 +420,12 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
||||||
gxfp_cmd_response_t *resp,
|
gxfp_cmd_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
|
g_autoptr(GPtrArray) templates = NULL;
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
FpPrint *new_scan = NULL;
|
FpPrint *match = NULL;
|
||||||
FpPrint *matching = NULL;
|
FpPrint *print = NULL;
|
||||||
|
gint cnt = 0;
|
||||||
|
gboolean find = false;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
|
@ -447,68 +434,51 @@ fp_verify_cb (FpiDeviceGoodixMoc *self,
|
||||||
}
|
}
|
||||||
if (resp->verify.match)
|
if (resp->verify.match)
|
||||||
{
|
{
|
||||||
new_scan = fp_print_from_template (self, &resp->verify.template);
|
match = fp_print_from_template (self, &resp->verify.template);
|
||||||
|
|
||||||
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
||||||
{
|
{
|
||||||
fpi_device_get_verify_data (device, &matching);
|
templates = g_ptr_array_sized_new (1);
|
||||||
if (!fp_print_equal (matching, new_scan))
|
fpi_device_get_verify_data (device, &print);
|
||||||
matching = NULL;
|
g_ptr_array_add (templates, print);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GPtrArray *templates = NULL;
|
|
||||||
fpi_device_get_identify_data (device, &templates);
|
fpi_device_get_identify_data (device, &templates);
|
||||||
|
g_ptr_array_ref (templates);
|
||||||
|
}
|
||||||
|
for (cnt = 0; cnt < templates->len; cnt++)
|
||||||
|
{
|
||||||
|
print = g_ptr_array_index (templates, cnt);
|
||||||
|
|
||||||
for (gint i = 0; i < templates->len; i++)
|
if (fp_print_equal (print, match))
|
||||||
{
|
{
|
||||||
if (fp_print_equal (g_ptr_array_index (templates, i), new_scan))
|
find = true;
|
||||||
{
|
break;
|
||||||
matching = g_ptr_array_index (templates, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (find)
|
||||||
|
{
|
||||||
|
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
||||||
|
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, match, error);
|
||||||
|
else
|
||||||
|
fpi_device_identify_report (device, print, match, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
if (!find)
|
||||||
fpi_device_verify_report (device, matching ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL, new_scan, error);
|
{
|
||||||
else
|
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY)
|
||||||
fpi_device_identify_report (device, matching, new_scan, error);
|
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
|
||||||
|
else
|
||||||
|
fpi_device_identify_report (device, NULL, NULL, error);
|
||||||
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fp_verify_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
|
||||||
gxfp_cmd_response_t *resp,
|
|
||||||
GError *error)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* if reach max timeout(5sec) finger not up, try again */
|
|
||||||
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
|
||||||
{
|
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_VERIFY_WAIT_FINGER_UP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (resp->finger_status.status != GX_SUCCESS)
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_failed (self->task_ssm,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Switch finger mode failed"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
|
||||||
FP_FINGER_STATUS_NONE,
|
|
||||||
FP_FINGER_STATUS_PRESENT);
|
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
{
|
{
|
||||||
|
|
@ -522,7 +492,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case GOODIX_VERIFY_PWR_BTN_SHIELD_ON:
|
case FP_VERIFY_PWR_BTN_SHIELD_ON:
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
@ -530,7 +500,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_pwr_btn_shield_cb);
|
fp_pwr_btn_shield_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_VERIFY_CAPTURE:
|
case FP_VERIFY_CAPTURE:
|
||||||
fpi_device_report_finger_status_changes (device,
|
fpi_device_report_finger_status_changes (device,
|
||||||
FP_FINGER_STATUS_NEEDED,
|
FP_FINGER_STATUS_NEEDED,
|
||||||
FP_FINGER_STATUS_NONE);
|
FP_FINGER_STATUS_NONE);
|
||||||
|
|
@ -541,7 +511,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_verify_capture_cb);
|
fp_verify_capture_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_VERIFY_IDENTIFY:
|
case FP_VERIFY_IDENTIFY:
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT,
|
goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT,
|
||||||
false,
|
false,
|
||||||
(const guint8 *) nonce,
|
(const guint8 *) nonce,
|
||||||
|
|
@ -549,18 +519,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_verify_cb);
|
fp_verify_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_VERIFY_WAIT_FINGER_UP:
|
case FP_VERIFY_PWR_BTN_SHIELD_OFF:
|
||||||
{
|
|
||||||
guint8 dummy = 0;
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP,
|
|
||||||
true,
|
|
||||||
&dummy,
|
|
||||||
1,
|
|
||||||
fp_verify_finger_mode_cb);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GOODIX_VERIFY_PWR_BTN_SHIELD_OFF:
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
@ -687,20 +646,20 @@ fp_enroll_enum_cb (FpiDeviceGoodixMoc *self,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_enroll_create_cb (FpiDeviceGoodixMoc *self,
|
fp_enroll_init_cb (FpiDeviceGoodixMoc *self,
|
||||||
gxfp_cmd_response_t *resp,
|
gxfp_cmd_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
fpi_ssm_mark_failed (self->task_ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy (self->template_id, resp->enroll_create.tid, TEMPLATE_ID_SIZE);
|
memcpy (self->template_id, resp->enroll_init.tid, TEMPLATE_ID_SIZE);
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -717,12 +676,12 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||||
/* */
|
/* */
|
||||||
if (resp->result >= GX_FAILED)
|
if (resp->result >= GX_FAILED)
|
||||||
{
|
{
|
||||||
fp_info ("Capture sample failed, result: 0x%x", resp->result);
|
fp_warn ("Capture sample failed, result: 0x%x", resp->result);
|
||||||
fpi_device_enroll_progress (FP_DEVICE (self),
|
fpi_device_enroll_progress (FP_DEVICE (self),
|
||||||
self->enroll_stage,
|
self->enroll_stage,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
fpi_device_report_finger_status_changes (FP_DEVICE (self),
|
||||||
|
|
@ -731,7 +690,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||||
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
|
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
|
||||||
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
|
(resp->capture_data_resp.img_coverage < self->sensorcfg->config[5]))
|
||||||
{
|
{
|
||||||
fp_info ("Capture sample poor quality(%d): %d or coverage(%d): %d",
|
fp_warn ("Capture sample poor quality(%d): %d or coverage(%d): %d",
|
||||||
self->sensorcfg->config[4],
|
self->sensorcfg->config[4],
|
||||||
resp->capture_data_resp.img_quality,
|
resp->capture_data_resp.img_quality,
|
||||||
self->sensorcfg->config[5],
|
self->sensorcfg->config[5],
|
||||||
|
|
@ -740,7 +699,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
|
||||||
self->enroll_stage,
|
self->enroll_stage,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER));
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -771,7 +730,7 @@ fp_enroll_update_cb (FpiDeviceGoodixMoc *self,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER));
|
fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER));
|
||||||
}
|
}
|
||||||
else if (resp->enroll_update.rollback || resp->result == 0x73)
|
else if (resp->enroll_update.rollback)
|
||||||
{
|
{
|
||||||
fpi_device_enroll_progress (FP_DEVICE (self),
|
fpi_device_enroll_progress (FP_DEVICE (self),
|
||||||
self->enroll_stage,
|
self->enroll_stage,
|
||||||
|
|
@ -786,7 +745,7 @@ fp_enroll_update_cb (FpiDeviceGoodixMoc *self,
|
||||||
/* if enroll complete, no need to wait finger up */
|
/* if enroll complete, no need to wait finger up */
|
||||||
if (self->enroll_stage >= self->max_enroll_stage)
|
if (self->enroll_stage >= self->max_enroll_stage)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CHECK_DUPLICATE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CHECK_DUPLICATE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -805,14 +764,9 @@ fp_enroll_check_duplicate_cb (FpiDeviceGoodixMoc *self,
|
||||||
}
|
}
|
||||||
if (resp->check_duplicate_resp.duplicate)
|
if (resp->check_duplicate_resp.duplicate)
|
||||||
{
|
{
|
||||||
g_autoptr(FpPrint) print = NULL;
|
|
||||||
|
|
||||||
print = g_object_ref_sink (fp_print_from_template (self, &resp->check_duplicate_resp.template));
|
|
||||||
|
|
||||||
fpi_ssm_mark_failed (self->task_ssm,
|
fpi_ssm_mark_failed (self->task_ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_DUPLICATE,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_DUPLICATE,
|
||||||
"Finger was already enrolled as '%s'",
|
"Finger has already enrolled"));
|
||||||
fp_print_get_description (print)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -852,7 +806,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||||
/* if reach max timeout(5sec) finger not up, switch to finger up again */
|
/* if reach max timeout(5sec) finger not up, switch to finger up again */
|
||||||
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_WAIT_FINGER_UP);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (resp->finger_status.status != GX_SUCCESS)
|
else if (resp->finger_status.status != GX_SUCCESS)
|
||||||
|
|
@ -867,7 +821,7 @@ fp_finger_mode_cb (FpiDeviceGoodixMoc *self,
|
||||||
FP_FINGER_STATUS_PRESENT);
|
FP_FINGER_STATUS_PRESENT);
|
||||||
if (self->enroll_stage < self->max_enroll_stage)
|
if (self->enroll_stage < self->max_enroll_stage)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_ENROLL_CAPTURE);
|
fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
|
|
@ -893,17 +847,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case GOODIX_ENROLL_PWR_BTN_SHIELD_ON:
|
case FP_ENROLL_ENUM:
|
||||||
{
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
|
||||||
false,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
fp_pwr_btn_shield_cb);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GOODIX_ENROLL_ENUM:
|
|
||||||
{
|
{
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT,
|
goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT,
|
||||||
false,
|
false,
|
||||||
|
|
@ -913,17 +857,27 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_CREATE:
|
case FP_ENROLL_PWR_BTN_SHIELD_ON:
|
||||||
|
{
|
||||||
|
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON,
|
||||||
|
false,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
fp_pwr_btn_shield_cb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FP_ENROLL_CREATE:
|
||||||
{
|
{
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_ENROLL_INIT, MOC_CMD1_DEFAULT,
|
goodix_sensor_cmd (self, MOC_CMD0_ENROLL_INIT, MOC_CMD1_DEFAULT,
|
||||||
false,
|
false,
|
||||||
(const guint8 *) &dummy,
|
(const guint8 *) &dummy,
|
||||||
1,
|
1,
|
||||||
fp_enroll_create_cb);
|
fp_enroll_init_cb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_CAPTURE:
|
case FP_ENROLL_CAPTURE:
|
||||||
fpi_device_report_finger_status_changes (device,
|
fpi_device_report_finger_status_changes (device,
|
||||||
FP_FINGER_STATUS_NEEDED,
|
FP_FINGER_STATUS_NEEDED,
|
||||||
FP_FINGER_STATUS_NONE);
|
FP_FINGER_STATUS_NONE);
|
||||||
|
|
@ -934,7 +888,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_enroll_capture_cb);
|
fp_enroll_capture_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_UPDATE:
|
case FP_ENROLL_UPDATE:
|
||||||
dummy[0] = 1;
|
dummy[0] = 1;
|
||||||
dummy[1] = self->sensorcfg->config[2];
|
dummy[1] = self->sensorcfg->config[2];
|
||||||
dummy[2] = self->sensorcfg->config[3];
|
dummy[2] = self->sensorcfg->config[3];
|
||||||
|
|
@ -945,7 +899,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_enroll_update_cb);
|
fp_enroll_update_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_WAIT_FINGER_UP:
|
case FP_ENROLL_WAIT_FINGER_UP:
|
||||||
dummy[0] = 0;
|
dummy[0] = 0;
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP,
|
goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP,
|
||||||
true,
|
true,
|
||||||
|
|
@ -954,7 +908,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_finger_mode_cb);
|
fp_finger_mode_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_CHECK_DUPLICATE:
|
case FP_ENROLL_CHECK_DUPLICATE:
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_CHECK4DUPLICATE, MOC_CMD1_DEFAULT,
|
goodix_sensor_cmd (self, MOC_CMD0_CHECK4DUPLICATE, MOC_CMD1_DEFAULT,
|
||||||
false,
|
false,
|
||||||
(const guint8 *) &dummy,
|
(const guint8 *) &dummy,
|
||||||
|
|
@ -962,7 +916,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_enroll_check_duplicate_cb);
|
fp_enroll_check_duplicate_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_COMMIT:
|
case FP_ENROLL_COMMIT:
|
||||||
{
|
{
|
||||||
fpi_device_get_enroll_data (device, &print);
|
fpi_device_get_enroll_data (device, &print);
|
||||||
user_id = fpi_print_generate_user_id (print);
|
user_id = fpi_print_generate_user_id (print);
|
||||||
|
|
@ -1015,7 +969,7 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_ENROLL_PWR_BTN_SHIELD_OFF:
|
case FP_ENROLL_PWR_BTN_SHIELD_OFF:
|
||||||
{
|
{
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF,
|
||||||
false,
|
false,
|
||||||
|
|
@ -1097,47 +1051,6 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
|
||||||
fpi_ssm_next_state (self->task_ssm);
|
fpi_ssm_next_state (self->task_ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fp_init_cb_reset_or_complete (FpiDeviceGoodixMoc *self,
|
|
||||||
gxfp_cmd_response_t *resp,
|
|
||||||
GError *error)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
fp_warn ("Template storage appears to have been corrupted! Error was: %s", error->message);
|
|
||||||
fp_warn ("A known reason for this to happen is a firmware bug triggered by another storage area being initialized.");
|
|
||||||
fpi_ssm_jump_to_state (self->task_ssm, GOODIX_INIT_RESET_DEVICE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_completed (self->task_ssm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fp_init_reset_device_cb (FpiDeviceGoodixMoc *self,
|
|
||||||
gxfp_cmd_response_t *resp,
|
|
||||||
GError *error)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
fp_warn ("Reset failed: %s", error->message);
|
|
||||||
fpi_ssm_mark_failed (self->task_ssm, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((resp->result >= GX_FAILED) && (resp->result != GX_ERROR_FINGER_ID_NOEXIST))
|
|
||||||
{
|
|
||||||
fp_warn ("Reset failed, device reported: 0x%x", resp->result);
|
|
||||||
fpi_ssm_mark_failed (self->task_ssm,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"Failed clear storage, result: 0x%x",
|
|
||||||
resp->result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_warn ("Reset completed");
|
|
||||||
fpi_ssm_mark_completed (self->task_ssm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
|
|
@ -1147,7 +1060,7 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case GOODIX_INIT_VERSION:
|
case FP_INIT_VERSION:
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_GET_VERSION, MOC_CMD1_DEFAULT,
|
goodix_sensor_cmd (self, MOC_CMD0_GET_VERSION, MOC_CMD1_DEFAULT,
|
||||||
false,
|
false,
|
||||||
&dummy,
|
&dummy,
|
||||||
|
|
@ -1155,37 +1068,13 @@ fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
|
||||||
fp_init_version_cb);
|
fp_init_version_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_INIT_CONFIG:
|
case FP_INIT_CONFIG:
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_UPDATE_CONFIG, MOC_CMD1_WRITE_CFG_TO_FLASH,
|
goodix_sensor_cmd (self, MOC_CMD0_UPDATE_CONFIG, MOC_CMD1_WRITE_CFG_TO_FLASH,
|
||||||
false,
|
false,
|
||||||
(guint8 *) self->sensorcfg,
|
(guint8 *) self->sensorcfg,
|
||||||
sizeof (gxfp_sensor_cfg_t),
|
sizeof (gxfp_sensor_cfg_t),
|
||||||
fp_init_config_cb);
|
fp_init_config_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GOODIX_INIT_TEMPLATE_LIST:
|
|
||||||
/* List prints to check whether the template DB was corrupted.
|
|
||||||
* As of 2022-06-13 there is a known firmware issue that can cause the
|
|
||||||
* stored templates for Linux to be corrupted when the Windows storage
|
|
||||||
* area is initialized.
|
|
||||||
* In that case, we'll get a protocol failure trying to retrieve the
|
|
||||||
* list of prints.
|
|
||||||
*/
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT,
|
|
||||||
FALSE,
|
|
||||||
(const guint8 *) &dummy,
|
|
||||||
1,
|
|
||||||
fp_init_cb_reset_or_complete);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GOODIX_INIT_RESET_DEVICE:
|
|
||||||
fp_warn ("Resetting device storage, you will need to enroll all prints again!");
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DELETE_ALL,
|
|
||||||
FALSE,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
fp_init_reset_device_cb);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1281,32 +1170,6 @@ fp_template_delete_cb (FpiDeviceGoodixMoc *self,
|
||||||
fp_info ("Successfully deleted enrolled user");
|
fp_info ("Successfully deleted enrolled user");
|
||||||
fpi_device_delete_complete (device, NULL);
|
fpi_device_delete_complete (device, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fp_template_delete_all_cb (FpiDeviceGoodixMoc *self,
|
|
||||||
gxfp_cmd_response_t *resp,
|
|
||||||
GError *error)
|
|
||||||
{
|
|
||||||
FpDevice *device = FP_DEVICE (self);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
fpi_device_clear_storage_complete (device, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((resp->result >= GX_FAILED) && (resp->result != GX_ERROR_FINGER_ID_NOEXIST))
|
|
||||||
{
|
|
||||||
fpi_device_clear_storage_complete (FP_DEVICE (self),
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"Failed clear storage, result: 0x%x",
|
|
||||||
resp->result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_info ("Successfully cleared storage");
|
|
||||||
fpi_device_clear_storage_complete (device, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* fp_template_list Function
|
* fp_template_list Function
|
||||||
|
|
@ -1415,31 +1278,11 @@ gx_fp_probe (FpDevice *device)
|
||||||
{
|
{
|
||||||
case 0x6496:
|
case 0x6496:
|
||||||
case 0x60A2:
|
case 0x60A2:
|
||||||
case 0x60A4:
|
|
||||||
case 0x6014:
|
|
||||||
case 0x6090:
|
|
||||||
case 0x6092:
|
|
||||||
case 0x6094:
|
|
||||||
case 0x609A:
|
|
||||||
case 0x609C:
|
case 0x609C:
|
||||||
case 0x60BC:
|
|
||||||
case 0x60C2:
|
|
||||||
case 0x6304:
|
|
||||||
case 0x631C:
|
|
||||||
case 0x633C:
|
|
||||||
case 0x634C:
|
|
||||||
case 0x6384:
|
|
||||||
case 0x639C:
|
case 0x639C:
|
||||||
case 0x63AC:
|
case 0x63AC:
|
||||||
case 0x63BC:
|
case 0x63BC:
|
||||||
case 0x63CC:
|
|
||||||
case 0x650A:
|
|
||||||
case 0x650C:
|
|
||||||
case 0x6582:
|
|
||||||
case 0x6A94:
|
case 0x6A94:
|
||||||
case 0x659A:
|
|
||||||
case 0x6890:
|
|
||||||
case 0x6984:
|
|
||||||
self->max_enroll_stage = 12;
|
self->max_enroll_stage = 12;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1495,7 +1338,7 @@ gx_fp_init (FpDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->task_ssm = fpi_ssm_new (device, fp_init_sm_run_state,
|
self->task_ssm = fpi_ssm_new (device, fp_init_sm_run_state,
|
||||||
GOODIX_INIT_NUM_STATES);
|
FP_INIT_NUM_STATES);
|
||||||
|
|
||||||
fpi_ssm_start (self->task_ssm, fp_init_ssm_done);
|
fpi_ssm_start (self->task_ssm, fp_init_ssm_done);
|
||||||
|
|
||||||
|
|
@ -1526,7 +1369,9 @@ gx_fp_exit_cb (FpiDeviceGoodixMoc *self,
|
||||||
gxfp_cmd_response_t *resp,
|
gxfp_cmd_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (resp && resp->result >= GX_FAILED)
|
|
||||||
|
|
||||||
|
if (resp->result >= GX_FAILED)
|
||||||
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
|
fp_dbg ("Setting power button shield failed, result: 0x%x", resp->result);
|
||||||
self->is_power_button_shield_on = false;
|
self->is_power_button_shield_on = false;
|
||||||
gx_fp_release_interface (self, error);
|
gx_fp_release_interface (self, error);
|
||||||
|
|
@ -1561,8 +1406,8 @@ gx_fp_verify_identify (FpDevice *device)
|
||||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
||||||
|
|
||||||
self->task_ssm = fpi_ssm_new_full (device, fp_verify_sm_run_state,
|
self->task_ssm = fpi_ssm_new_full (device, fp_verify_sm_run_state,
|
||||||
GOODIX_VERIFY_NUM_STATES,
|
FP_VERIFY_NUM_STATES,
|
||||||
GOODIX_VERIFY_PWR_BTN_SHIELD_OFF,
|
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||||
"verify");
|
"verify");
|
||||||
|
|
||||||
fpi_ssm_start (self->task_ssm, fp_verify_ssm_done);
|
fpi_ssm_start (self->task_ssm, fp_verify_ssm_done);
|
||||||
|
|
@ -1578,8 +1423,8 @@ gx_fp_enroll (FpDevice *device)
|
||||||
self->enroll_stage = 0;
|
self->enroll_stage = 0;
|
||||||
|
|
||||||
self->task_ssm = fpi_ssm_new_full (device, fp_enroll_sm_run_state,
|
self->task_ssm = fpi_ssm_new_full (device, fp_enroll_sm_run_state,
|
||||||
GOODIX_ENROLL_NUM_STATES,
|
FP_ENROLL_NUM_STATES,
|
||||||
GOODIX_ENROLL_PWR_BTN_SHIELD_OFF,
|
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||||
"enroll");
|
"enroll");
|
||||||
|
|
||||||
fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
|
fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done);
|
||||||
|
|
@ -1647,19 +1492,6 @@ gx_fp_template_delete (FpDevice *device)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gx_fp_template_delete_all (FpDevice *device)
|
|
||||||
{
|
|
||||||
FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device);
|
|
||||||
|
|
||||||
goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DELETE_ALL,
|
|
||||||
false,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
fp_template_delete_all_cb);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
||||||
{
|
{
|
||||||
|
|
@ -1668,41 +1500,18 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self)
|
||||||
|
|
||||||
static const FpIdEntry id_table[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x27c6, .pid = 0x5840, },
|
{ .vid = 0x27c6, .pid = 0x5840, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6014, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6090, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6092, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6094, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x609A, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x609C, },
|
{ .vid = 0x27c6, .pid = 0x609C, },
|
||||||
{ .vid = 0x27c6, .pid = 0x60A2, },
|
{ .vid = 0x27c6, .pid = 0x60A2, },
|
||||||
{ .vid = 0x27c6, .pid = 0x60A4, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x60BC, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x60C2, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6304, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x631C, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x633C, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x634C, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6384, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x639C, },
|
{ .vid = 0x27c6, .pid = 0x639C, },
|
||||||
{ .vid = 0x27c6, .pid = 0x63AC, },
|
{ .vid = 0x27c6, .pid = 0x63AC, },
|
||||||
{ .vid = 0x27c6, .pid = 0x63BC, },
|
{ .vid = 0x27c6, .pid = 0x63BC, },
|
||||||
{ .vid = 0x27c6, .pid = 0x63CC, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6496, },
|
{ .vid = 0x27c6, .pid = 0x6496, },
|
||||||
{ .vid = 0x27c6, .pid = 0x650A, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x650C, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6582, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6584, },
|
{ .vid = 0x27c6, .pid = 0x6584, },
|
||||||
{ .vid = 0x27c6, .pid = 0x658C, },
|
{ .vid = 0x27c6, .pid = 0x658C, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6592, },
|
{ .vid = 0x27c6, .pid = 0x6592, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6594, },
|
{ .vid = 0x27c6, .pid = 0x6594, },
|
||||||
{ .vid = 0x27c6, .pid = 0x659A, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x659C, },
|
{ .vid = 0x27c6, .pid = 0x659C, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6A94, },
|
{ .vid = 0x27c6, .pid = 0x6A94, },
|
||||||
{ .vid = 0x27c6, .pid = 0x6512, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6890, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x689A, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x66A9, },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6984, },
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1725,7 +1534,6 @@ fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass)
|
||||||
dev_class->probe = gx_fp_probe;
|
dev_class->probe = gx_fp_probe;
|
||||||
dev_class->enroll = gx_fp_enroll;
|
dev_class->enroll = gx_fp_enroll;
|
||||||
dev_class->delete = gx_fp_template_delete;
|
dev_class->delete = gx_fp_template_delete;
|
||||||
dev_class->clear_storage = gx_fp_template_delete_all;
|
|
||||||
dev_class->list = gx_fp_template_list;
|
dev_class->list = gx_fp_template_list;
|
||||||
dev_class->verify = gx_fp_verify_identify;
|
dev_class->verify = gx_fp_verify_identify;
|
||||||
dev_class->identify = gx_fp_verify_identify;
|
dev_class->identify = gx_fp_verify_identify;
|
||||||
|
|
|
||||||
|
|
@ -25,40 +25,38 @@
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FPI, DEVICE_GOODIXMOC, FpDevice)
|
G_DECLARE_FINAL_TYPE (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FPI, DEVICE_GOODIXMOC, FpDevice)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GOODIX_CMD_SEND = 0,
|
FP_CMD_SEND = 0,
|
||||||
GOODIX_CMD_GET_ACK,
|
FP_CMD_GET_ACK,
|
||||||
GOODIX_CMD_GET_DATA,
|
FP_CMD_GET_DATA,
|
||||||
GOODIX_CMD_NUM_STATES,
|
FP_CMD_NUM_STATES,
|
||||||
} GoodixCmdState;
|
} FpCmdState;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GOODIX_INIT_VERSION = 0,
|
FP_INIT_VERSION = 0,
|
||||||
GOODIX_INIT_CONFIG,
|
FP_INIT_CONFIG,
|
||||||
GOODIX_INIT_TEMPLATE_LIST,
|
FP_INIT_NUM_STATES,
|
||||||
GOODIX_INIT_RESET_DEVICE,
|
} FpInitState;
|
||||||
GOODIX_INIT_NUM_STATES,
|
|
||||||
} GoodixInitState;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GOODIX_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
FP_ENROLL_PWR_BTN_SHIELD_ON = 0,
|
||||||
GOODIX_ENROLL_ENUM,
|
FP_ENROLL_ENUM,
|
||||||
GOODIX_ENROLL_CREATE,
|
FP_ENROLL_IDENTIFY,
|
||||||
GOODIX_ENROLL_CAPTURE,
|
FP_ENROLL_CREATE,
|
||||||
GOODIX_ENROLL_UPDATE,
|
FP_ENROLL_CAPTURE,
|
||||||
GOODIX_ENROLL_WAIT_FINGER_UP,
|
FP_ENROLL_UPDATE,
|
||||||
GOODIX_ENROLL_CHECK_DUPLICATE,
|
FP_ENROLL_WAIT_FINGER_UP,
|
||||||
GOODIX_ENROLL_COMMIT,
|
FP_ENROLL_CHECK_DUPLICATE,
|
||||||
GOODIX_ENROLL_PWR_BTN_SHIELD_OFF,
|
FP_ENROLL_COMMIT,
|
||||||
GOODIX_ENROLL_NUM_STATES,
|
FP_ENROLL_PWR_BTN_SHIELD_OFF,
|
||||||
} GoodixEnrollState;
|
FP_ENROLL_NUM_STATES,
|
||||||
|
} FpEnrollState;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GOODIX_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
FP_VERIFY_PWR_BTN_SHIELD_ON = 0,
|
||||||
GOODIX_VERIFY_CAPTURE,
|
FP_VERIFY_CAPTURE,
|
||||||
GOODIX_VERIFY_IDENTIFY,
|
FP_VERIFY_IDENTIFY,
|
||||||
GOODIX_VERIFY_WAIT_FINGER_UP,
|
FP_VERIFY_PWR_BTN_SHIELD_OFF,
|
||||||
GOODIX_VERIFY_PWR_BTN_SHIELD_OFF,
|
FP_VERIFY_NUM_STATES,
|
||||||
GOODIX_VERIFY_NUM_STATES,
|
} FpVerifyState;
|
||||||
} GoodixVerifyState;
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "goodix_proto.h"
|
#include "goodix_proto.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -109,7 +107,7 @@ reflect (uint32_t data, uint8_t n_bits)
|
||||||
* If the LSB bit is set, set the reflection of it.
|
* If the LSB bit is set, set the reflection of it.
|
||||||
*/
|
*/
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
reflection |= (1LU << ((n_bits - 1) - bit));
|
reflection |= (1 << ((n_bits - 1) - bit));
|
||||||
|
|
||||||
data = (data >> 1);
|
data = (data >> 1);
|
||||||
}
|
}
|
||||||
|
|
@ -213,11 +211,7 @@ gx_proto_build_package (uint8_t *ppackage,
|
||||||
init_pack_header (&header, payload_size, cmd, 0);
|
init_pack_header (&header, payload_size, cmd, 0);
|
||||||
|
|
||||||
memcpy (ppackage, &header, PACKAGE_HEADER_SIZE);
|
memcpy (ppackage, &header, PACKAGE_HEADER_SIZE);
|
||||||
|
memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
|
||||||
if (payload)
|
|
||||||
memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size);
|
|
||||||
else
|
|
||||||
ppackage[PACKAGE_HEADER_SIZE] = 0;
|
|
||||||
|
|
||||||
gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size);
|
gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size);
|
||||||
|
|
||||||
|
|
@ -226,108 +220,95 @@ gx_proto_build_package (uint8_t *ppackage,
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
gx_proto_parse_header (FpiByteReader *reader,
|
gx_proto_parse_header (
|
||||||
pack_header *pheader)
|
uint8_t *buffer,
|
||||||
|
uint32_t buffer_len,
|
||||||
|
pack_header *pheader)
|
||||||
{
|
{
|
||||||
if (!pheader)
|
if (!buffer || !pheader)
|
||||||
|
return -1;
|
||||||
|
if (buffer_len < PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->cmd0))
|
memcpy (pheader, buffer, sizeof (pack_header));
|
||||||
g_return_val_if_reached (-1);
|
pheader->len = GUINT16_FROM_LE (pheader->len);
|
||||||
|
if (buffer_len < pheader->len + PACKAGE_HEADER_SIZE)
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->cmd1))
|
return -1;
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->packagenum))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->reserved))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint16_le (reader, &pheader->len))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->crc8))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &pheader->rev_crc8))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
pheader->len -= PACKAGE_CRC_SIZE;
|
pheader->len -= PACKAGE_CRC_SIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gx_proto_parse_fingerid (FpiByteReader *reader,
|
gx_proto_parse_fingerid (
|
||||||
ptemplate_format_t template)
|
uint8_t * fid_buffer,
|
||||||
|
uint16_t fid_buffer_size,
|
||||||
|
ptemplate_format_t template
|
||||||
|
)
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t * buffer = NULL;
|
||||||
const uint8_t *buffer;
|
uint16_t Offset = 0;
|
||||||
|
|
||||||
if (!template)
|
if (!template || !fid_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &byte) || byte != 67)
|
if (fid_buffer_size < G_STRUCT_OFFSET (template_format_t, payload) + sizeof (uint32_t))
|
||||||
g_return_val_if_reached (-1);
|
return -1;
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &template->type))
|
buffer = fid_buffer;
|
||||||
g_return_val_if_reached (-1);
|
Offset = 0;
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &template->finger_index))
|
if (buffer[Offset++] != 67)
|
||||||
g_return_val_if_reached (-1);
|
return -1;
|
||||||
|
fid_buffer_size--;
|
||||||
|
|
||||||
if (!fpi_byte_reader_skip (reader, 1))
|
template->type = buffer[Offset++];
|
||||||
g_return_val_if_reached (-1);
|
fid_buffer_size--;
|
||||||
|
template->finger_index = buffer[Offset++];
|
||||||
if (!fpi_byte_reader_get_data (reader, sizeof (template->accountid), &buffer))
|
fid_buffer_size--;
|
||||||
g_return_val_if_reached (-1);
|
Offset++;
|
||||||
|
memcpy (template->accountid, &buffer[Offset], sizeof (template->accountid));
|
||||||
memcpy (template->accountid, buffer, sizeof (template->accountid));
|
Offset += sizeof (template->accountid);
|
||||||
|
memcpy (template->tid, &buffer[Offset], sizeof (template->tid));
|
||||||
if (!fpi_byte_reader_get_data (reader, sizeof (template->tid), &buffer))
|
Offset += sizeof (template->tid); // Offset == 68
|
||||||
g_return_val_if_reached (-1);
|
template->payload.size = buffer[Offset++];
|
||||||
|
if (template->payload.size > sizeof (template->payload.data))
|
||||||
memcpy (template->tid, buffer, sizeof (template->tid));
|
return -1;
|
||||||
|
memset (template->payload.data, 0, template->payload.size);
|
||||||
if (!fpi_byte_reader_get_uint8 (reader, &template->payload.size))
|
memcpy (template->payload.data, &buffer[Offset], template->payload.size);
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_data (reader, template->payload.size, &buffer))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
memcpy (template->payload.data, buffer, template->payload.size);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_response_t presp)
|
gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_cmd_response_t presp)
|
||||||
{
|
{
|
||||||
if (!presp)
|
uint16_t offset = 0;
|
||||||
|
uint8_t *fingerlist = NULL;
|
||||||
|
|
||||||
|
if (!buffer || !presp)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (buffer_len < 1)
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->result))
|
return -1;
|
||||||
g_return_val_if_reached (-1);
|
presp->result = buffer[0];
|
||||||
|
|
||||||
switch (HIBYTE (cmd))
|
switch (HIBYTE (cmd))
|
||||||
{
|
{
|
||||||
case RESPONSE_PACKAGE_CMD:
|
case RESPONSE_PACKAGE_CMD:
|
||||||
{
|
{
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &presp->parse_msg.ack_cmd))
|
if (buffer_len < sizeof (gxfp_parse_msg_t) + 1)
|
||||||
g_return_val_if_reached (-1);
|
return -1;
|
||||||
|
presp->parse_msg.ack_cmd = buffer[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_UPDATE_CONFIG:
|
case MOC_CMD0_UPDATE_CONFIG:
|
||||||
{
|
{
|
||||||
presp->finger_config.status = presp->result;
|
presp->finger_config.status = buffer[0];
|
||||||
/* to compatiable old version firmware */
|
if (buffer_len >= 3)
|
||||||
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
|
presp->finger_config.max_stored_prints = buffer[2];
|
||||||
|
else
|
||||||
|
/* to compatiable old version firmware */
|
||||||
|
presp->finger_config.max_stored_prints = FP_MAX_FINGERNUM;
|
||||||
|
|
||||||
if (fpi_byte_reader_skip (byte_reader, 1))
|
|
||||||
fpi_byte_reader_get_uint8 (byte_reader,
|
|
||||||
&presp->finger_config.max_stored_prints);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -338,99 +319,81 @@ gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_respons
|
||||||
|
|
||||||
case MOC_CMD0_PWR_BTN_SHIELD:
|
case MOC_CMD0_PWR_BTN_SHIELD:
|
||||||
presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
|
presp->power_button_shield_resp.resp_cmd1 = LOBYTE (cmd);
|
||||||
uint8_t support_pwr_shield;
|
if (buffer_len >= 2)
|
||||||
|
{
|
||||||
if (fpi_byte_reader_get_uint8 (byte_reader, &support_pwr_shield) &&
|
uint8_t support_pwr_shield = buffer[1];
|
||||||
support_pwr_shield == 0xFF)
|
if (support_pwr_shield == 0xFF)
|
||||||
g_debug ("Power button shield feature not supported!\n");
|
g_debug ("Power button shield feature not supported!\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_GET_VERSION:
|
case MOC_CMD0_GET_VERSION:
|
||||||
const uint8_t *version_info;
|
if (buffer_len < sizeof (gxfp_version_info_t) + 1)
|
||||||
|
return -1;
|
||||||
if (!fpi_byte_reader_get_data (byte_reader, sizeof (gxfp_version_info_t), &version_info))
|
memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t));
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
memcpy (&presp->version_info, version_info, sizeof (gxfp_version_info_t));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_CAPTURE_DATA:
|
case MOC_CMD0_CAPTURE_DATA:
|
||||||
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
|
if (LOBYTE (cmd) == MOC_CMD1_DEFAULT)
|
||||||
{
|
{
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
if (buffer_len < sizeof (gxfp_capturedata_t) + 1)
|
||||||
&presp->capture_data_resp.img_quality))
|
return -1;
|
||||||
g_return_val_if_reached (-1);
|
presp->capture_data_resp.img_quality = buffer[1];
|
||||||
|
presp->capture_data_resp.img_coverage = buffer[2];
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
|
||||||
&presp->capture_data_resp.img_coverage))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_ENROLL_INIT:
|
case MOC_CMD0_ENROLL_INIT:
|
||||||
if (presp->result != GX_SUCCESS)
|
if (buffer_len < sizeof (gxfp_enroll_init_t) + 1)
|
||||||
break;
|
return -1;
|
||||||
const uint8_t *tid;
|
if (presp->result == GX_SUCCESS)
|
||||||
if (!fpi_byte_reader_get_data (byte_reader, TEMPLATE_ID_SIZE, &tid))
|
memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE);
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
memcpy (presp->enroll_create.tid, tid, TEMPLATE_ID_SIZE);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_ENROLL:
|
case MOC_CMD0_ENROLL:
|
||||||
presp->enroll_update.rollback = (presp->result < 0x80) ? false : true;
|
if (buffer_len < sizeof (gxfp_enroll_update_t))
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
return -1;
|
||||||
&presp->enroll_update.img_overlay))
|
presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true;
|
||||||
g_return_val_if_reached (-1);
|
presp->enroll_update.img_overlay = buffer[1];
|
||||||
|
presp->enroll_update.img_preoverlay = buffer[2];
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
|
||||||
&presp->enroll_update.img_preoverlay))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_CHECK4DUPLICATE:
|
case MOC_CMD0_CHECK4DUPLICATE:
|
||||||
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
|
presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true;
|
||||||
if (presp->check_duplicate_resp.duplicate)
|
if (presp->check_duplicate_resp.duplicate)
|
||||||
{
|
{
|
||||||
uint16_t tid_size;
|
if (buffer_len < 3)
|
||||||
FpiByteReader tid_reader;
|
return -1;
|
||||||
|
uint16_t tid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + 1));
|
||||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &tid_size))
|
if ((buffer_len < tid_size + 3) || (buffer_len > sizeof (template_format_t)) + 3)
|
||||||
g_return_val_if_reached (-1);
|
return -1;
|
||||||
|
memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size);
|
||||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &tid_reader, tid_size))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (gx_proto_parse_fingerid (&tid_reader, &presp->check_duplicate_resp.template) != 0)
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_GETFINGERLIST:
|
case MOC_CMD0_GETFINGERLIST:
|
||||||
if (presp->result != GX_SUCCESS)
|
if (presp->result != GX_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
if (buffer_len < 2)
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader,
|
return -1;
|
||||||
&presp->finger_list_resp.finger_num))
|
presp->finger_list_resp.finger_num = buffer[1];
|
||||||
g_return_val_if_reached (-1);
|
fingerlist = buffer + 2;
|
||||||
|
|
||||||
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
|
for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++)
|
||||||
{
|
{
|
||||||
uint16_t fingerid_length;
|
uint16_t fingerid_length = GUINT16_FROM_LE (*(uint16_t *) (fingerlist + offset));
|
||||||
FpiByteReader fingerid_reader;
|
offset += 2;
|
||||||
|
if (buffer_len < fingerid_length + offset + 2)
|
||||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_length))
|
return -1;
|
||||||
g_return_val_if_reached (-1);
|
if (gx_proto_parse_fingerid (fingerlist + offset,
|
||||||
|
fingerid_length,
|
||||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &fingerid_reader,
|
|
||||||
fingerid_length))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (gx_proto_parse_fingerid (&fingerid_reader,
|
|
||||||
&presp->finger_list_resp.finger_list[num]) != 0)
|
&presp->finger_list_resp.finger_list[num]) != 0)
|
||||||
{
|
{
|
||||||
g_warning ("Failed to parse finger list");
|
g_error ("parse fingerlist error");
|
||||||
g_return_val_if_reached (-1);
|
presp->finger_list_resp.finger_num = 0;
|
||||||
|
presp->result = GX_FAILED;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
offset += fingerid_length;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -439,32 +402,21 @@ gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_respons
|
||||||
uint32_t score = 0;
|
uint32_t score = 0;
|
||||||
uint8_t study = 0;
|
uint8_t study = 0;
|
||||||
uint16_t fingerid_size = 0;
|
uint16_t fingerid_size = 0;
|
||||||
|
presp->verify.match = (buffer[0] == 0) ? true : false;
|
||||||
presp->verify.match = (presp->result == 0) ? true : false;
|
|
||||||
|
|
||||||
if (presp->verify.match)
|
if (presp->verify.match)
|
||||||
{
|
{
|
||||||
FpiByteReader finger_reader;
|
if (buffer_len < sizeof (template_format_t) + 10)
|
||||||
|
return -1;
|
||||||
if (!fpi_byte_reader_get_uint16_le (byte_reader,
|
offset += 1;
|
||||||
&presp->verify.rejectdetail))
|
presp->verify.rejectdetail = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||||
g_return_val_if_reached (-1);
|
offset += 2;
|
||||||
|
score = GUINT32_FROM_LE (*(uint32_t *) (buffer + offset));
|
||||||
if (!fpi_byte_reader_get_uint32_le (byte_reader, &score))
|
offset += 4;
|
||||||
g_return_val_if_reached (-1);
|
study = buffer[offset];
|
||||||
|
offset += 1;
|
||||||
if (!fpi_byte_reader_get_uint8 (byte_reader, &study))
|
fingerid_size = GUINT16_FROM_LE (*(uint16_t *) (buffer + offset));
|
||||||
g_return_val_if_reached (-1);
|
offset += 2;
|
||||||
|
if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0)
|
||||||
if (!fpi_byte_reader_get_uint16_le (byte_reader, &fingerid_size))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_sub_reader (byte_reader, &finger_reader,
|
|
||||||
fingerid_size))
|
|
||||||
g_return_val_if_reached (-1);
|
|
||||||
|
|
||||||
if (gx_proto_parse_fingerid (&finger_reader,
|
|
||||||
&presp->verify.template) != 0)
|
|
||||||
{
|
{
|
||||||
presp->result = GX_FAILED;
|
presp->result = GX_FAILED;
|
||||||
break;
|
break;
|
||||||
|
|
@ -475,7 +427,7 @@ gx_proto_parse_body (uint16_t cmd, FpiByteReader *byte_reader, pgxfp_cmd_respons
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOC_CMD0_FINGER_MODE:
|
case MOC_CMD0_FINGER_MODE:
|
||||||
presp->finger_status.status = presp->result;
|
presp->finger_status.status = buffer[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -508,4 +460,4 @@ gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig)
|
||||||
memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE);
|
memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -22,8 +22,6 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "fpi-byte-reader.h"
|
|
||||||
|
|
||||||
#define PACKAGE_CRC_SIZE (4)
|
#define PACKAGE_CRC_SIZE (4)
|
||||||
#define PACKAGE_HEADER_SIZE (8)
|
#define PACKAGE_HEADER_SIZE (8)
|
||||||
|
|
||||||
|
|
@ -107,24 +105,22 @@ typedef struct _gxfp_parse_msg
|
||||||
} gxfp_parse_msg_t, *pgxfp_parse_msg_t;
|
} gxfp_parse_msg_t, *pgxfp_parse_msg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _gxfp_enroll_create
|
typedef struct _gxfp_enroll_init
|
||||||
{
|
{
|
||||||
uint8_t tid[TEMPLATE_ID_SIZE];
|
uint8_t tid[TEMPLATE_ID_SIZE];
|
||||||
} gxfp_enroll_create_t, *pgxfp_enroll_create_t;
|
} gxfp_enroll_init_t, *pgxfp_enroll_init_t;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct _template_format
|
typedef struct _template_format
|
||||||
{
|
{
|
||||||
uint8_t _0x43_byte;
|
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t finger_index;
|
uint8_t finger_index;
|
||||||
uint8_t pad0;
|
|
||||||
uint8_t accountid[32];
|
uint8_t accountid[32];
|
||||||
uint8_t tid[32];
|
uint8_t tid[32];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t size;
|
uint32_t size;
|
||||||
uint8_t data[56];
|
uint8_t data[56];
|
||||||
} payload;
|
} payload;
|
||||||
uint8_t reserve[2];
|
uint8_t reserve[2];
|
||||||
} template_format_t, *ptemplate_format_t;
|
} template_format_t, *ptemplate_format_t;
|
||||||
|
|
@ -135,7 +131,7 @@ typedef struct _template_format
|
||||||
typedef struct _gxfp_verify
|
typedef struct _gxfp_verify
|
||||||
{
|
{
|
||||||
bool match;
|
bool match;
|
||||||
uint16_t rejectdetail;
|
uint32_t rejectdetail;
|
||||||
template_format_t template;
|
template_format_t template;
|
||||||
} gxfp_verify_t, *pgxfp_verify_t;
|
} gxfp_verify_t, *pgxfp_verify_t;
|
||||||
|
|
||||||
|
|
@ -194,7 +190,7 @@ typedef struct _fp_cmd_response
|
||||||
{
|
{
|
||||||
gxfp_parse_msg_t parse_msg;
|
gxfp_parse_msg_t parse_msg;
|
||||||
gxfp_verify_t verify;
|
gxfp_verify_t verify;
|
||||||
gxfp_enroll_create_t enroll_create;
|
gxfp_enroll_init_t enroll_init;
|
||||||
gxfp_capturedata_t capture_data_resp;
|
gxfp_capturedata_t capture_data_resp;
|
||||||
gxfp_check_duplicate_t check_duplicate_resp;
|
gxfp_check_duplicate_t check_duplicate_resp;
|
||||||
gxfp_enroll_commit_t enroll_commit;
|
gxfp_enroll_commit_t enroll_commit;
|
||||||
|
|
@ -234,11 +230,13 @@ int gx_proto_build_package (uint8_t *ppackage,
|
||||||
const uint8_t *payload,
|
const uint8_t *payload,
|
||||||
uint32_t payload_size);
|
uint32_t payload_size);
|
||||||
|
|
||||||
int gx_proto_parse_header (FpiByteReader *reader,
|
int gx_proto_parse_header (uint8_t *buffer,
|
||||||
pack_header *pheader);
|
uint32_t buffer_len,
|
||||||
|
pack_header *pheader);
|
||||||
|
|
||||||
int gx_proto_parse_body (uint16_t cmd,
|
int gx_proto_parse_body (uint16_t cmd,
|
||||||
FpiByteReader *byte_reader,
|
uint8_t *buffer,
|
||||||
|
uint16_t buffer_len,
|
||||||
pgxfp_cmd_response_t presponse);
|
pgxfp_cmd_response_t presponse);
|
||||||
|
|
||||||
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,246 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022-2023 Realtek Corp.
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define EP_IN (2 | FPI_USB_ENDPOINT_IN)
|
|
||||||
#define EP_OUT (1 | FPI_USB_ENDPOINT_OUT)
|
|
||||||
|
|
||||||
#define EP_IN_MAX_BUF_SIZE 2048
|
|
||||||
|
|
||||||
#define FP_RTK_CMD_BULK_TOTAL_LEN 12
|
|
||||||
#define FP_RTK_CMD_BULK_LEN 2
|
|
||||||
#define FP_RTK_CMD_BULK_PARAM_LEN 4
|
|
||||||
#define FP_RTK_CMD_BULK_ADDR_LEN 4
|
|
||||||
#define FP_RTK_CMD_BULK_DATA_LEN 2
|
|
||||||
|
|
||||||
#define TEMPLATE_LEN_COMMON 35
|
|
||||||
|
|
||||||
#define SUBFACTOR_OFFSET 2
|
|
||||||
#define UID_OFFSET 3
|
|
||||||
#define UID_PAYLOAD_LEN_DEFAULT 32
|
|
||||||
|
|
||||||
/* Command transfer timeout :ms*/
|
|
||||||
#define CMD_TIMEOUT 1000
|
|
||||||
#define DATA_TIMEOUT 5000
|
|
||||||
#define STATUS_TIMEOUT 2000
|
|
||||||
|
|
||||||
#define MAX_ENROLL_SAMPLES 8
|
|
||||||
#define DEFAULT_UID_LEN 28
|
|
||||||
#define SUB_FINGER_01 0xFF
|
|
||||||
|
|
||||||
#define GET_BULK_CMD_TYPE(val) ((val & 0xC0) >> 6)
|
|
||||||
#define GET_TRANS_DATA_LEN(len_h, len_l) ((len_h << 8) | len_l)
|
|
||||||
#define GET_LEN_L(total_data_len) ((total_data_len) & 0xff)
|
|
||||||
#define GET_LEN_H(total_data_len) ((total_data_len) >> 8)
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceRealtek, fpi_device_realtek, FPI, DEVICE_REALTEK, FpDevice)
|
|
||||||
|
|
||||||
typedef void (*SynCmdMsgCallback) (FpiDeviceRealtek *self,
|
|
||||||
uint8_t *buffer_in,
|
|
||||||
GError *error);
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SynCmdMsgCallback callback;
|
|
||||||
} CommandData;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_CMD_BULK_ONLY = 0,
|
|
||||||
FP_RTK_CMD_BULK_READ,
|
|
||||||
FP_RTK_CMD_BULK_WRITE,
|
|
||||||
} FpRtkCmdType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_MSG_DEFAULT = 0,
|
|
||||||
FP_RTK_MSG_NO_STATUS,
|
|
||||||
} FpRtkMsgType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_PURPOSE_VERIFY = 0x01,
|
|
||||||
FP_RTK_PURPOSE_IDENTIFY = 0x02,
|
|
||||||
FP_RTK_PURPOSE_ENROLL = 0x04,
|
|
||||||
} FpRtkPurpose;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_SUCCESS = 0x0,
|
|
||||||
FP_RTK_TOO_HIGH,
|
|
||||||
FP_RTK_TOO_LOW,
|
|
||||||
FP_RTK_TOO_LEFT,
|
|
||||||
FP_RTK_TOO_RIGHT,
|
|
||||||
FP_RTK_TOO_FAST,
|
|
||||||
FP_RTK_TOO_SLOW,
|
|
||||||
FP_RTK_POOR_QUALITY,
|
|
||||||
FP_RTK_TOO_SKEWED,
|
|
||||||
FP_RTK_TOO_SHORT,
|
|
||||||
FP_RTK_MERGE_FAILURE,
|
|
||||||
FP_RTK_MATCH_FAIL,
|
|
||||||
FP_RTK_CMD_ERR,
|
|
||||||
} FpRtkInStatus;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_ENROLL_GET_TEMPLATE = 0,
|
|
||||||
FP_RTK_ENROLL_BEGIN_POS,
|
|
||||||
FP_RTK_ENROLL_CAPTURE,
|
|
||||||
FP_RTK_ENROLL_FINISH_CAPTURE,
|
|
||||||
FP_RTK_ENROLL_ACCEPT_SAMPLE,
|
|
||||||
FP_RTK_ENROLL_CHECK_DUPLICATE,
|
|
||||||
FP_RTK_ENROLL_COMMIT,
|
|
||||||
FP_RTK_ENROLL_CANCEL_CAPTURE,
|
|
||||||
FP_RTK_ENROLL_NUM_STATES,
|
|
||||||
} FpRtkEnrollState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_VERIFY_GET_TEMPLATE = 0,
|
|
||||||
FP_RTK_VERIFY_CAPTURE,
|
|
||||||
FP_RTK_VERIFY_FINISH_CAPTURE,
|
|
||||||
FP_RTK_VERIFY_ACCEPT_SAMPLE,
|
|
||||||
FP_RTK_VERIFY_INDENTIFY_FEATURE,
|
|
||||||
FP_RTK_VERIFY_UPDATE_TEMPLATE,
|
|
||||||
FP_RTK_VERIFY_CANCEL_CAPTURE,
|
|
||||||
FP_RTK_VERIFY_NUM_STATES,
|
|
||||||
} FpRtkVerifyState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_DELETE_GET_POS = 0,
|
|
||||||
FP_RTK_DELETE_PRINT,
|
|
||||||
FP_RTK_DELETE_NUM_STATES,
|
|
||||||
} FpRtkDeleteState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_INIT_GET_DEVICE_INFO = 0,
|
|
||||||
FP_RTK_INIT_SELECT_OS,
|
|
||||||
FP_RTK_INIT_GET_ENROLL_NUM,
|
|
||||||
FP_RTK_INIT_NUM_STATES,
|
|
||||||
} FpRtkInitState;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FP_RTK_CMD_SEND = 0,
|
|
||||||
FP_RTK_CMD_TRANS_DATA,
|
|
||||||
FP_RTK_CMD_GET_STATUS,
|
|
||||||
FP_RTK_CMD_NUM_STATES,
|
|
||||||
} FpRtkCmdState;
|
|
||||||
|
|
||||||
struct _FpiDeviceRealtek
|
|
||||||
{
|
|
||||||
FpDevice parent;
|
|
||||||
FpiSsm *task_ssm;
|
|
||||||
FpiSsm *cmd_ssm;
|
|
||||||
FpiUsbTransfer *cmd_transfer;
|
|
||||||
FpiUsbTransfer *data_transfer;
|
|
||||||
gint cmd_type;
|
|
||||||
FpRtkMsgType message_type;
|
|
||||||
gboolean cmd_cancellable;
|
|
||||||
gint enroll_stage;
|
|
||||||
gint max_enroll_stage;
|
|
||||||
guchar *read_data;
|
|
||||||
gsize trans_data_len;
|
|
||||||
FpRtkPurpose fp_purpose;
|
|
||||||
gint pos_index;
|
|
||||||
gint template_num;
|
|
||||||
gint template_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rtk_cmd_bulk
|
|
||||||
{
|
|
||||||
uint8_t cmd[FP_RTK_CMD_BULK_LEN];
|
|
||||||
uint8_t param[FP_RTK_CMD_BULK_PARAM_LEN];
|
|
||||||
uint8_t addr[FP_RTK_CMD_BULK_ADDR_LEN];
|
|
||||||
uint8_t data_len[FP_RTK_CMD_BULK_DATA_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rtk_cmd_ctrl
|
|
||||||
{
|
|
||||||
int direction;
|
|
||||||
uint8_t request;
|
|
||||||
uint16_t value;
|
|
||||||
uint16_t index;
|
|
||||||
uint16_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_ctrl get_device_info = {
|
|
||||||
.direction = G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
|
||||||
.request = 0x07,
|
|
||||||
.value = 0x000D,
|
|
||||||
.index = 0x0000,
|
|
||||||
.len = 0x0008,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_start_capture = {
|
|
||||||
.cmd = {0x05, 0x05},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_finish_capture = {
|
|
||||||
.cmd = {0x45, 0x06},
|
|
||||||
.data_len = {0x05},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_accept_sample = {
|
|
||||||
.cmd = {0x45, 0x08},
|
|
||||||
.data_len = {0x09},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk nor_identify_feature = {
|
|
||||||
.cmd = {0x45, 0x22},
|
|
||||||
.data_len = {0x2A},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_get_enroll_num = {
|
|
||||||
.cmd = {0x45, 0x0d},
|
|
||||||
.data_len = {0x02},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_get_template = {
|
|
||||||
.cmd = {0x45, 0x0E},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk nor_enroll_begin = {
|
|
||||||
.cmd = {0x05, 0x20},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_check_duplicate = {
|
|
||||||
.cmd = {0x45, 0x10},
|
|
||||||
.data_len = {0x22},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk nor_enroll_commit = {
|
|
||||||
.cmd = {0x85, 0x21},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_update_template = {
|
|
||||||
.cmd = {0x05, 0x11},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_delete_record = {
|
|
||||||
.cmd = {0x05, 0x0F},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_select_system = {
|
|
||||||
.cmd = {0x05, 0x13},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rtk_cmd_bulk co_cancel_capture = {
|
|
||||||
.cmd = {0x05, 0x07},
|
|
||||||
};
|
|
||||||
|
|
@ -256,8 +256,7 @@ bmkt_compose_message (uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_nu
|
||||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
||||||
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
||||||
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
||||||
if (payload_size > 0)
|
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
||||||
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
|
||||||
|
|
||||||
*cmd_len = message_len;
|
*cmd_len = message_len;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,36 +32,17 @@ static void compose_and_send_identify_msg (FpDevice *device);
|
||||||
|
|
||||||
static const FpIdEntry id_table[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00BD, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00BD, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C2, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C4, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C6, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00DF, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00DF, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00E9, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F0, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F9, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F9, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FC, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00FC, },
|
||||||
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C2, },
|
||||||
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00C9, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0100, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0100, },
|
||||||
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x00F0, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0103, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0103, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0104, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0106, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0107, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0108, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0109, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x010A, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0123, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0123, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0124, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0129, },
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x015F, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0168, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0169, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x016C, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0173, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0174, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x019D, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x019F, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x01A0, },
|
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x01A4, },
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -123,11 +104,7 @@ cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||||
|
|
||||||
if (self->cmd_complete_on_removal)
|
if (self->cmd_complete_on_removal)
|
||||||
{
|
{
|
||||||
if (self->delay_error)
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
|
||||||
g_steal_pointer (&self->delay_error));
|
|
||||||
else
|
|
||||||
fpi_ssm_mark_completed (transfer->ssm);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +225,6 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_critical_leave (device);
|
|
||||||
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
|
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
@ -662,21 +638,18 @@ verify (FpDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
identify_complete_after_finger_removal (FpiDeviceSynaptics *self, GError *error)
|
identify_complete_after_finger_removal (FpiDeviceSynaptics *self)
|
||||||
{
|
{
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
|
|
||||||
if (self->finger_on_sensor)
|
if (self->finger_on_sensor)
|
||||||
{
|
{
|
||||||
fp_dbg ("delaying identify report until after finger removal!");
|
fp_dbg ("delaying identify report until after finger removal!");
|
||||||
if (error)
|
|
||||||
g_propagate_error (&self->delay_error, error);
|
|
||||||
|
|
||||||
self->cmd_complete_on_removal = TRUE;
|
self->cmd_complete_on_removal = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_identify_complete (device, error);
|
fpi_device_identify_complete (device, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -726,18 +699,19 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
||||||
fp_info ("Match error occurred");
|
fp_info ("Match error occurred");
|
||||||
fpi_device_identify_report (device, NULL, NULL,
|
fpi_device_identify_report (device, NULL, NULL,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||||
identify_complete_after_finger_removal (self, NULL);
|
identify_complete_after_finger_removal (self);
|
||||||
}
|
}
|
||||||
else if (resp->result == BMKT_FP_NO_MATCH)
|
else if (resp->result == BMKT_FP_NO_MATCH)
|
||||||
{
|
{
|
||||||
fp_info ("Print didn't match");
|
fp_info ("Print didn't match");
|
||||||
fpi_device_identify_report (device, NULL, NULL, NULL);
|
fpi_device_identify_report (device, NULL, NULL, NULL);
|
||||||
identify_complete_after_finger_removal (self, NULL);
|
identify_complete_after_finger_removal (self);
|
||||||
}
|
}
|
||||||
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS || resp->result == BMKT_FP_DATABASE_EMPTY)
|
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||||
{
|
{
|
||||||
fp_info ("Print is not in database");
|
fp_info ("Print is not in database");
|
||||||
identify_complete_after_finger_removal (self, fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
fpi_device_identify_complete (device,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -773,7 +747,7 @@ identify_msg_cb (FpiDeviceSynaptics *self,
|
||||||
else
|
else
|
||||||
fpi_device_identify_report (device, NULL, print, NULL);
|
fpi_device_identify_report (device, NULL, print, NULL);
|
||||||
|
|
||||||
identify_complete_after_finger_removal (self, NULL);
|
identify_complete_after_finger_removal (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1261,12 +1235,6 @@ dev_probe (FpDevice *device)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_usb_device_reset (usb_dev, &error))
|
|
||||||
{
|
|
||||||
fp_dbg ("%s g_usb_device_reset failed %s", G_STRFUNC, error->message);
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error))
|
||||||
goto err_close;
|
goto err_close;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,5 +127,4 @@ struct _FpiDeviceSynaptics
|
||||||
|
|
||||||
struct syna_enroll_resp_data enroll_resp_data;
|
struct syna_enroll_resp_data enroll_resp_data;
|
||||||
syna_state_t state;
|
syna_state_t state;
|
||||||
GError *delay_error;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -74,26 +74,26 @@ struct _FpiDeviceUpeksonly
|
||||||
FpiSsm *loopsm;
|
FpiSsm *loopsm;
|
||||||
|
|
||||||
/* Do we really need multiple concurrent transfers? */
|
/* Do we really need multiple concurrent transfers? */
|
||||||
GCancellable *img_cancellable;
|
GCancellable *img_cancellable;
|
||||||
GPtrArray *img_transfers;
|
GPtrArray *img_transfers;
|
||||||
int num_flying;
|
int num_flying;
|
||||||
|
|
||||||
GSList *rows;
|
GSList *rows;
|
||||||
unsigned num_rows;
|
unsigned num_rows;
|
||||||
unsigned char *rowbuf;
|
unsigned char *rowbuf;
|
||||||
int rowbuf_offset;
|
int rowbuf_offset;
|
||||||
|
|
||||||
int wraparounds;
|
int wraparounds;
|
||||||
int num_blank;
|
int num_blank;
|
||||||
int num_nonblank;
|
int num_nonblank;
|
||||||
enum sonly_fs finger_state;
|
enum sonly_fs finger_state;
|
||||||
int last_seqnum;
|
int last_seqnum;
|
||||||
|
|
||||||
enum sonly_kill_transfers_action killing_transfers;
|
enum sonly_kill_transfers_action killing_transfers;
|
||||||
GError *kill_error;
|
GError *kill_error;
|
||||||
FpiSsm *kill_ssm;
|
FpiSsm *kill_ssm;
|
||||||
|
|
||||||
struct fpi_line_asmbl_ctx assembling_ctx;
|
struct fpi_line_asmbl_ctx assembling_ctx;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceUpeksonly, fpi_device_upeksonly, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUpeksonly, fpi_device_upeksonly, FPI,
|
||||||
DEVICE_UPEKSONLY, FpImageDevice);
|
DEVICE_UPEKSONLY, FpImageDevice);
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,6 @@ dev_deinit (FpImageDevice *dev)
|
||||||
|
|
||||||
static const FpIdEntry id_table[] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x0483, .pid = 0x2015, .driver_data = UPEKTC_2015 },
|
{ .vid = 0x0483, .pid = 0x2015, .driver_data = UPEKTC_2015 },
|
||||||
{ .vid = 0x0483, .pid = 0x2017, .driver_data = UPEKTC_2015 },
|
|
||||||
{ .vid = 0x147e, .pid = 0x3001, .driver_data = UPEKTC_3001 },
|
{ .vid = 0x147e, .pid = 0x3001, .driver_data = UPEKTC_3001 },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ static void start_deactivation (FpImageDevice *dev);
|
||||||
#define CTRL_TIMEOUT 4000
|
#define CTRL_TIMEOUT 4000
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
|
#define IMAGE_WIDTH 144
|
||||||
|
#define IMAGE_HEIGHT 384
|
||||||
|
#define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT)
|
||||||
|
|
||||||
#define MAX_CMD_SIZE 64
|
#define MAX_CMD_SIZE 64
|
||||||
#define MAX_RESPONSE_SIZE 2052
|
#define MAX_RESPONSE_SIZE 2052
|
||||||
#define SHORT_RESPONSE_SIZE 64
|
#define SHORT_RESPONSE_SIZE 64
|
||||||
|
|
@ -43,10 +47,8 @@ struct _FpiDeviceUpektcImg
|
||||||
unsigned char response[MAX_RESPONSE_SIZE];
|
unsigned char response[MAX_RESPONSE_SIZE];
|
||||||
unsigned char *image_bits;
|
unsigned char *image_bits;
|
||||||
unsigned char seq;
|
unsigned char seq;
|
||||||
size_t expected_image_size;
|
|
||||||
size_t image_size;
|
size_t image_size;
|
||||||
size_t response_rest;
|
size_t response_rest;
|
||||||
gboolean area_sensor;
|
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
|
||||||
|
|
@ -178,7 +180,6 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_GET_CLASS (dev);
|
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
unsigned char *data = self->response;
|
unsigned char *data = self->response;
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
@ -246,30 +247,8 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
CAPTURE_ACK_00_28);
|
CAPTURE_ACK_00_28);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x13:
|
|
||||||
/* finger is present keep your finger on reader */
|
|
||||||
fpi_device_report_finger_status_changes (device,
|
|
||||||
FP_FINGER_STATUS_NEEDED,
|
|
||||||
FP_FINGER_STATUS_NONE);
|
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
|
||||||
self->area_sensor ?
|
|
||||||
CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* finger is present! */
|
/* finger is present! */
|
||||||
fpi_device_report_finger_status_changes (device,
|
|
||||||
FP_FINGER_STATUS_PRESENT,
|
|
||||||
FP_FINGER_STATUS_NONE);
|
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
|
||||||
CAPTURE_ACK_00_28);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x01:
|
|
||||||
/* no finger! */
|
|
||||||
fpi_device_report_finger_status_changes (device,
|
|
||||||
FP_FINGER_STATUS_NONE,
|
|
||||||
FP_FINGER_STATUS_PRESENT);
|
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28);
|
CAPTURE_ACK_00_28);
|
||||||
break;
|
break;
|
||||||
|
|
@ -282,20 +261,18 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
fpi_image_device_report_finger_status (dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
self->area_sensor ?
|
CAPTURE_ACK_00_28_TERM);
|
||||||
CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
/* too much horizontal movement */
|
/* too much horisontal movement */
|
||||||
fp_err ("too much horizontal movement, aborting");
|
fp_err ("too much horisontal movement, aborting");
|
||||||
fpi_image_device_retry_scan (dev,
|
fpi_image_device_retry_scan (dev,
|
||||||
FP_DEVICE_RETRY_CENTER_FINGER);
|
FP_DEVICE_RETRY_CENTER_FINGER);
|
||||||
fpi_image_device_report_finger_status (dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
self->area_sensor ?
|
CAPTURE_ACK_00_28_TERM);
|
||||||
CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -306,8 +283,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
fpi_image_device_report_finger_status (dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state (transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
self->area_sensor ?
|
CAPTURE_ACK_00_28_TERM);
|
||||||
CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -331,13 +307,13 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
self->image_size +=
|
self->image_size +=
|
||||||
upektc_img_process_image_frame (self->image_bits + self->image_size,
|
upektc_img_process_image_frame (self->image_bits + self->image_size,
|
||||||
data);
|
data);
|
||||||
BUG_ON (self->image_size != self->expected_image_size);
|
BUG_ON (self->image_size != IMAGE_SIZE);
|
||||||
fp_dbg ("Image size is %lu",
|
fp_dbg ("Image size is %lu",
|
||||||
(gulong) self->image_size);
|
(gulong) self->image_size);
|
||||||
img = fp_image_new (img_class->img_width, img_class->img_height);
|
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||||
img->flags |= FPI_IMAGE_PARTIAL;
|
img->flags |= FPI_IMAGE_PARTIAL;
|
||||||
memcpy (img->data, self->image_bits,
|
memcpy (img->data, self->image_bits,
|
||||||
self->image_size);
|
IMAGE_SIZE);
|
||||||
fpi_image_device_image_captured (dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
fpi_image_device_report_finger_status (dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
@ -370,12 +346,8 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
switch (fpi_ssm_get_cur_state (ssm))
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
{
|
{
|
||||||
case CAPTURE_INIT_CAPTURE:
|
case CAPTURE_INIT_CAPTURE:
|
||||||
if (self->area_sensor)
|
upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture),
|
||||||
upektc_img_submit_req (ssm, dev, upek2020_init_capture_press, sizeof (upek2020_init_capture_press),
|
self->seq, capture_reqs_cb);
|
||||||
self->seq, capture_reqs_cb);
|
|
||||||
else
|
|
||||||
upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture),
|
|
||||||
self->seq, capture_reqs_cb);
|
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -541,81 +513,15 @@ init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: process response properly */
|
||||||
static void
|
static void
|
||||||
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
if (!error)
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
unsigned char *data = self->response;
|
else
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data[12] == 0x06 && data[13] == 0x14) /* if get_info */
|
|
||||||
{
|
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_GET_CLASS (dev);
|
|
||||||
uint16_t width = (data[51] << 8) | data[50];
|
|
||||||
uint16_t height = (data[53] << 8) | data[52];
|
|
||||||
|
|
||||||
self->area_sensor = !(data[49] & 0x80);
|
|
||||||
|
|
||||||
switch (width)
|
|
||||||
{
|
|
||||||
case 256:
|
|
||||||
fp_dbg ("Sensor type : TCS1x, width x height: %hu x %hu", width, height); /* 360x256 --- 270x192 must be set */
|
|
||||||
BUG_ON (height != 360);
|
|
||||||
img_class->img_width = 192;
|
|
||||||
img_class->img_height = 270;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 208:
|
|
||||||
fp_dbg ("Sensor type : TCS2, width x height: %hu x %hu", width, height); /* 288x208 --- 216x156 must be set */
|
|
||||||
BUG_ON (height != 288);
|
|
||||||
img_class->img_width = 156;
|
|
||||||
img_class->img_height = 216;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 248:
|
|
||||||
fp_dbg ("Sensor type : TCS3, width x height: %hu x %hu", width, height); /* 360x248 --- 270x186 must be set */
|
|
||||||
BUG_ON (height != 360);
|
|
||||||
img_class->img_width = 186;
|
|
||||||
img_class->img_height = 270;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 192:
|
|
||||||
fp_dbg ("Sensor type : TCS4x, width x height: %hu x %hu", width, height); /* 512x192 --- 384x144 must be set */
|
|
||||||
BUG_ON (height != 512);
|
|
||||||
img_class->img_width = 144;
|
|
||||||
img_class->img_height = 384;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 144:
|
|
||||||
fp_dbg ("Sensor type : TCS5x, width x height: %hu x %hu", width, height); /* 512x144 --- 384x108 must be set */
|
|
||||||
BUG_ON (height != 512);
|
|
||||||
img_class->img_width = 108;
|
|
||||||
img_class->img_height = 384;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fp_dbg ("Sensor type : Unknown");
|
|
||||||
|
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Unknown sensor type (reported size %dx%d)",
|
|
||||||
width, height));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->expected_image_size = img_class->img_width * img_class->img_height;
|
|
||||||
self->image_bits = g_malloc0 (self->expected_image_size * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_ssm_next_state (transfer->ssm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -710,6 +616,7 @@ dev_deactivate (FpImageDevice *dev)
|
||||||
static void
|
static void
|
||||||
dev_init (FpImageDevice *dev)
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* TODO check that device has endpoints we're using */
|
/* TODO check that device has endpoints we're using */
|
||||||
|
|
@ -720,6 +627,7 @@ dev_init (FpImageDevice *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->image_bits = g_malloc0 (IMAGE_SIZE * 2);
|
||||||
fpi_image_device_open_complete (dev, NULL);
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -779,6 +687,6 @@ fpi_device_upektc_img_class_init (FpiDeviceUpektcImgClass *klass)
|
||||||
|
|
||||||
img_class->bz3_threshold = 20;
|
img_class->bz3_threshold = 20;
|
||||||
|
|
||||||
img_class->img_width = -1;
|
img_class->img_width = IMAGE_WIDTH;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = IMAGE_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,22 +75,6 @@ static const unsigned char upek2020_init_capture[] = {
|
||||||
0x02,
|
0x02,
|
||||||
0x00, /* Wait for acceptable finger */
|
0x00, /* Wait for acceptable finger */
|
||||||
0x02,
|
0x02,
|
||||||
0x25, 0xa9 /* CRC */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char upek2020_init_capture_press[] = {
|
|
||||||
'C', 'i', 'a', 'o',
|
|
||||||
0x00,
|
|
||||||
0x00, 0x0e, /* Seq = 7, len = 0x00e */
|
|
||||||
0x28, /* CMD = 0x28 */
|
|
||||||
0x0b, 0x00, /* Inner len = 0x000b */
|
|
||||||
0x00, 0x00,
|
|
||||||
0x0e, /* SUBCMD = 0x0e */
|
|
||||||
0x02,
|
|
||||||
0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */
|
|
||||||
0x02,
|
|
||||||
0x01, /* Wait for finger */
|
|
||||||
0x02,
|
|
||||||
0x14, 0x9a /* CRC */
|
0x14, 0x9a /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,9 +196,8 @@ struct read_msg_data
|
||||||
static void __read_msg_async (FpDevice *dev,
|
static void __read_msg_async (FpDevice *dev,
|
||||||
struct read_msg_data *udata);
|
struct read_msg_data *udata);
|
||||||
|
|
||||||
#define READ_MSG_DATA_CB_ERR(dev, udata, error) \
|
#define READ_MSG_DATA_CB_ERR(dev, udata, error) (udata)->callback (dev, \
|
||||||
(udata)->callback (dev, \
|
READ_MSG_CMD, 0, 0, NULL, 0, (udata)->user_data, error)
|
||||||
READ_MSG_CMD, 0, 0, NULL, 0, (udata)->user_data, error)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
busy_ack_sent_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
busy_ack_sent_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
|
@ -1244,7 +1243,7 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
|
||||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||||
|
|
||||||
/* Report the error immediately if possible, otherwise delay it. */
|
/* Report the error immediately if possible, otherwise delay it. */
|
||||||
if (!error || error->domain == FP_DEVICE_RETRY)
|
if (error && error->domain == FP_DEVICE_RETRY)
|
||||||
fpi_device_verify_report (dev, res, NULL, error);
|
fpi_device_verify_report (dev, res, NULL, error);
|
||||||
else
|
else
|
||||||
data->error = error;
|
data->error = error;
|
||||||
|
|
@ -1296,7 +1295,7 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||||
memcpy (msg, verify_hdr, sizeof (verify_hdr));
|
memcpy (msg, verify_hdr, sizeof (verify_hdr));
|
||||||
memcpy (msg + sizeof (verify_hdr), data, data_len);
|
memcpy (msg + sizeof (verify_hdr), data, data_len);
|
||||||
|
|
||||||
transfer = alloc_send_cmd28_transfer (dev, 0x03, msg, msg_len);
|
transfer = alloc_send_cmd28_transfer (dev, 0x03, data, data_len);
|
||||||
|
|
||||||
g_free (msg);
|
g_free (msg);
|
||||||
|
|
||||||
|
|
@ -1342,6 +1341,7 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data,
|
||||||
fp_dbg ("good image");
|
fp_dbg ("good image");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x1c: /* FIXME what does this one mean? */
|
||||||
case 0x0b: /* FIXME what does this one mean? */
|
case 0x0b: /* FIXME what does this one mean? */
|
||||||
case 0x23: /* FIXME what does this one mean? */
|
case 0x23: /* FIXME what does this one mean? */
|
||||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
||||||
|
|
@ -1351,14 +1351,6 @@ v_handle_resp00 (FpDevice *dev, unsigned char *data,
|
||||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER);
|
error = fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1c: /* swipe too fast */
|
|
||||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_FAST);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1d: /* too much horizontal movement */
|
|
||||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1e: /* swipe too short */
|
case 0x1e: /* swipe too short */
|
||||||
error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
|
error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1447,7 +1439,7 @@ verify_rd2800_cb (FpDevice *dev, enum read_msg_type msgtype,
|
||||||
do_verify_stop (dev,
|
do_verify_stop (dev,
|
||||||
FPI_MATCH_ERROR,
|
FPI_MATCH_ERROR,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Response had wrong command sequence"));
|
"Response hat wrong command sequence"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#define FP_COMPONENT "uru4000"
|
#define FP_COMPONENT "uru4000"
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <nss.h>
|
||||||
#include <openssl/err.h>
|
#include <pk11pub.h>
|
||||||
|
|
||||||
#include "drivers_api.h"
|
#include "drivers_api.h"
|
||||||
|
|
||||||
|
|
@ -148,7 +148,10 @@ struct _FpiDeviceUru4000
|
||||||
int fwfixer_offset;
|
int fwfixer_offset;
|
||||||
unsigned char fwfixer_value;
|
unsigned char fwfixer_value;
|
||||||
|
|
||||||
EVP_CIPHER_CTX *cipher_ctx;
|
CK_MECHANISM_TYPE cipher;
|
||||||
|
PK11SlotInfo *slot;
|
||||||
|
PK11SymKey *symkey;
|
||||||
|
SECItem *param;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
|
|
@ -243,29 +246,13 @@ response_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *e
|
||||||
fpi_ssm_mark_failed (ssm, error);
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GError *
|
|
||||||
openssl_device_error (void)
|
|
||||||
{
|
|
||||||
char buf[256];
|
|
||||||
unsigned long e;
|
|
||||||
|
|
||||||
e = ERR_get_error ();
|
|
||||||
if (e == 0)
|
|
||||||
return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"unexpected OpenSSL error");
|
|
||||||
|
|
||||||
ERR_error_string_n (e, buf, G_N_ELEMENTS (buf));
|
|
||||||
|
|
||||||
return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "OpenSSL error: %s",
|
|
||||||
buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
|
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||||
unsigned char respdata[CR_LENGTH * 2];
|
unsigned char respdata[CR_LENGTH];
|
||||||
|
PK11Context *ctx;
|
||||||
int outlen;
|
int outlen;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
|
|
@ -274,39 +261,17 @@ challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transfer->actual_length != CR_LENGTH)
|
|
||||||
{
|
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Unexpected buffer length (%" G_GSIZE_FORMAT
|
|
||||||
"instead of %d)",
|
|
||||||
transfer->actual_length, CR_LENGTH);
|
|
||||||
fpi_ssm_mark_failed (ssm, g_steal_pointer (&error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* submit response */
|
/* submit response */
|
||||||
/* produce response from challenge */
|
/* produce response from challenge */
|
||||||
if (!EVP_EncryptUpdate (self->cipher_ctx, respdata, &outlen, transfer->buffer, CR_LENGTH))
|
ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT,
|
||||||
|
self->symkey, self->param);
|
||||||
|
if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess ||
|
||||||
|
PK11_Finalize (ctx) != SECSuccess)
|
||||||
{
|
{
|
||||||
fpi_ssm_mark_failed (ssm, openssl_device_error ());
|
fp_err ("Failed to encrypt challenge data");
|
||||||
return;
|
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data");
|
||||||
}
|
|
||||||
|
|
||||||
if (outlen != CR_LENGTH)
|
|
||||||
{
|
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
|
||||||
"Unexpected encrypted buffer length (%d"
|
|
||||||
"instead of %d)",
|
|
||||||
outlen, CR_LENGTH);
|
|
||||||
fpi_ssm_mark_failed (ssm, g_steal_pointer (&error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EVP_EncryptFinal_ex (self->cipher_ctx, respdata + outlen, &outlen))
|
|
||||||
{
|
|
||||||
fpi_ssm_mark_failed (ssm, openssl_device_error ());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
PK11_DestroyContext (ctx, PR_TRUE);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
write_regs (FP_IMAGE_DEVICE (dev), REG_RESPONSE, CR_LENGTH, respdata, response_cb, ssm);
|
write_regs (FP_IMAGE_DEVICE (dev), REG_RESPONSE, CR_LENGTH, respdata, response_cb, ssm);
|
||||||
|
|
@ -352,7 +317,6 @@ irq_handler (FpiUsbTransfer *transfer,
|
||||||
if (urudev->irqs_stopped_cb)
|
if (urudev->irqs_stopped_cb)
|
||||||
urudev->irqs_stopped_cb (imgdev);
|
urudev->irqs_stopped_cb (imgdev);
|
||||||
urudev->irqs_stopped_cb = NULL;
|
urudev->irqs_stopped_cb = NULL;
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (error)
|
else if (error)
|
||||||
|
|
@ -587,7 +551,7 @@ image_transfer_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->img_data = g_memdup2 (transfer->buffer, sizeof (struct uru4k_image));
|
self->img_data = g_memdup (transfer->buffer, sizeof (struct uru4k_image));
|
||||||
self->img_data_actual_length = transfer->actual_length;
|
self->img_data_actual_length = transfer->actual_length;
|
||||||
fpi_ssm_next_state (ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
}
|
}
|
||||||
|
|
@ -738,9 +702,9 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
|
||||||
case IMAGING_DECODE:
|
case IMAGING_DECODE:
|
||||||
key = self->last_reg_rd[0];
|
key = self->last_reg_rd[0];
|
||||||
key |= (uint32_t) self->last_reg_rd[1] << 8;
|
key |= self->last_reg_rd[1] << 8;
|
||||||
key |= (uint32_t) self->last_reg_rd[2] << 16;
|
key |= self->last_reg_rd[2] << 16;
|
||||||
key |= (uint32_t) self->last_reg_rd[3] << 24;
|
key |= self->last_reg_rd[3] << 24;
|
||||||
key ^= self->img_enc_seed;
|
key ^= self->img_enc_seed;
|
||||||
|
|
||||||
fp_dbg ("encryption id %02x -> key %08x", img->key_number, key);
|
fp_dbg ("encryption id %02x -> key %08x", img->key_number, key);
|
||||||
|
|
@ -1305,6 +1269,8 @@ dev_init (FpImageDevice *dev)
|
||||||
g_autoptr(GPtrArray) interfaces = NULL;
|
g_autoptr(GPtrArray) interfaces = NULL;
|
||||||
GUsbInterface *iface = NULL;
|
GUsbInterface *iface = NULL;
|
||||||
guint64 driver_data;
|
guint64 driver_data;
|
||||||
|
SECStatus rv;
|
||||||
|
SECItem item;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
|
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
|
||||||
|
|
@ -1376,6 +1342,20 @@ dev_init (FpImageDevice *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable loading p11-kit's user configuration */
|
||||||
|
g_setenv ("P11_KIT_NO_USER_CONFIG", "1", TRUE);
|
||||||
|
|
||||||
|
/* Initialise NSS early */
|
||||||
|
rv = NSS_NoDB_Init (".");
|
||||||
|
if (rv != SECSuccess)
|
||||||
|
{
|
||||||
|
fp_err ("could not initialise NSS");
|
||||||
|
fpi_image_device_open_complete (dev,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||||
|
"Could not initialise NSS"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_URU4000 (dev);
|
self = FPI_DEVICE_URU4000 (dev);
|
||||||
|
|
||||||
g_clear_pointer (&self->rand, g_rand_free);
|
g_clear_pointer (&self->rand, g_rand_free);
|
||||||
|
|
@ -1388,17 +1368,35 @@ dev_init (FpImageDevice *dev)
|
||||||
self->interface = g_usb_interface_get_number (iface);
|
self->interface = g_usb_interface_get_number (iface);
|
||||||
|
|
||||||
/* Set up encryption */
|
/* Set up encryption */
|
||||||
if (!(self->cipher_ctx = EVP_CIPHER_CTX_new ()))
|
self->cipher = CKM_AES_ECB;
|
||||||
|
self->slot = PK11_GetBestSlot (self->cipher, NULL);
|
||||||
|
if (self->slot == NULL)
|
||||||
{
|
{
|
||||||
fpi_image_device_open_complete (dev, openssl_device_error ());
|
fp_err ("could not get encryption slot");
|
||||||
|
fpi_image_device_open_complete (dev,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||||
|
"Could not get encryption slot"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
item.type = siBuffer;
|
||||||
if (!EVP_EncryptInit_ex (self->cipher_ctx, EVP_aes_128_ecb (), NULL, crkey, NULL))
|
item.data = (unsigned char *) crkey;
|
||||||
|
item.len = sizeof (crkey);
|
||||||
|
self->symkey = PK11_ImportSymKey (self->slot,
|
||||||
|
self->cipher,
|
||||||
|
PK11_OriginUnwrap,
|
||||||
|
CKA_ENCRYPT,
|
||||||
|
&item, NULL);
|
||||||
|
if (self->symkey == NULL)
|
||||||
{
|
{
|
||||||
fpi_image_device_open_complete (dev, openssl_device_error ());
|
fp_err ("failed to import key into NSS");
|
||||||
|
PK11_FreeSlot (self->slot);
|
||||||
|
self->slot = NULL;
|
||||||
|
fpi_image_device_open_complete (dev,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||||
|
"Failed to import key into NSS"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self->param = PK11_ParamFromIV (self->cipher, NULL);
|
||||||
|
|
||||||
fpi_image_device_open_complete (dev, NULL);
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -1409,8 +1407,12 @@ dev_deinit (FpImageDevice *dev)
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||||
|
|
||||||
g_clear_pointer (&self->cipher_ctx, EVP_CIPHER_CTX_free);
|
if (self->symkey)
|
||||||
|
PK11_FreeSymKey (self->symkey);
|
||||||
|
if (self->param)
|
||||||
|
SECITEM_FreeItem (self->param, PR_TRUE);
|
||||||
|
if (self->slot)
|
||||||
|
PK11_FreeSlot (self->slot);
|
||||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
self->interface, 0, &error);
|
self->interface, 0, &error);
|
||||||
g_clear_pointer (&self->rand, g_rand_free);
|
g_clear_pointer (&self->rand, g_rand_free);
|
||||||
|
|
|
||||||
|
|
@ -581,7 +581,7 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||||
/* Initialize fingerprint buffer */
|
/* Initialize fingerprint buffer */
|
||||||
g_free (self->lines_buffer);
|
g_free (self->lines_buffer);
|
||||||
self->memory = VFS_USB_BUFFER_SIZE;
|
self->memory = VFS_USB_BUFFER_SIZE;
|
||||||
self->lines_buffer = g_malloc0 (self->memory);
|
self->lines_buffer = g_malloc (self->memory);
|
||||||
self->bytes = 0;
|
self->bytes = 0;
|
||||||
|
|
||||||
/* Finger is on the scanner */
|
/* Finger is on the scanner */
|
||||||
|
|
@ -589,15 +589,12 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increase buffer size while it's insufficient */
|
/* Increase buffer size while it's insufficient */
|
||||||
while (self->memory < self->bytes + VFS_USB_BUFFER_SIZE)
|
while (self->bytes + VFS_USB_BUFFER_SIZE > self->memory)
|
||||||
{
|
{
|
||||||
int pre_memory = self->memory;
|
self->memory <<= 1;
|
||||||
self->memory += VFS_USB_BUFFER_SIZE;
|
|
||||||
self->lines_buffer =
|
self->lines_buffer =
|
||||||
(struct vfs_line *) g_realloc (self->lines_buffer,
|
(struct vfs_line *) g_realloc (self->lines_buffer,
|
||||||
self->memory);
|
self->memory);
|
||||||
memset ((guint8 *) self->lines_buffer + pre_memory, 0,
|
|
||||||
VFS_USB_BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive chunk of data */
|
/* Receive chunk of data */
|
||||||
|
|
|
||||||
|
|
@ -432,7 +432,7 @@ img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int l
|
||||||
usb_send (dev, data, len, NULL); \
|
usb_send (dev, data, len, NULL); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAW_DATA(x) g_memdup2 (x, sizeof (x)), sizeof (x)
|
#define RAW_DATA(x) g_memdup (x, sizeof (x)), sizeof (x)
|
||||||
|
|
||||||
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))
|
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,7 @@ on_stream_read_cb (GObject *source_object,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
// g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Got empty data");
|
||||||
"Got empty data");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -526,8 +526,8 @@ dev_verify (FpDevice *dev)
|
||||||
|
|
||||||
if (scan_id)
|
if (scan_id)
|
||||||
{
|
{
|
||||||
g_autoptr(FpPrint) new_scan = NULL;
|
|
||||||
GVariant *data = NULL;
|
GVariant *data = NULL;
|
||||||
|
FpPrint *new_scan;
|
||||||
FpPrint *print;
|
FpPrint *print;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
|
|
@ -556,7 +556,7 @@ dev_verify (FpDevice *dev)
|
||||||
self->match_reported = TRUE;
|
self->match_reported = TRUE;
|
||||||
fpi_device_verify_report (dev,
|
fpi_device_verify_report (dev,
|
||||||
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
||||||
g_steal_pointer (&new_scan),
|
new_scan,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -733,13 +733,7 @@ dev_deinit (FpDevice *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->keep_alive)
|
if (!self->keep_alive)
|
||||||
{
|
stop_listener (self);
|
||||||
stop_listener (self);
|
|
||||||
self->supports_cancellation = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->enroll_stages_passed = 0;
|
|
||||||
self->match_reported = FALSE;
|
|
||||||
|
|
||||||
fpi_device_close_complete (dev, NULL);
|
fpi_device_close_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +766,6 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||||
{
|
{
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
const char *hot_seconds;
|
|
||||||
|
|
||||||
object_class->finalize = fpi_device_virtual_device_finalize;
|
object_class->finalize = fpi_device_virtual_device_finalize;
|
||||||
|
|
||||||
|
|
@ -788,18 +781,5 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||||
dev_class->enroll = dev_enroll;
|
dev_class->enroll = dev_enroll;
|
||||||
dev_class->cancel = dev_cancel;
|
dev_class->cancel = dev_cancel;
|
||||||
|
|
||||||
if ((hot_seconds = g_getenv ("FP_VIRTUAL_DEVICE_HOT_SECONDS")) &&
|
|
||||||
*hot_seconds != '\0')
|
|
||||||
{
|
|
||||||
gint64 hot_seconds_value;
|
|
||||||
|
|
||||||
hot_seconds_value = g_ascii_strtoll (hot_seconds, NULL, 10);
|
|
||||||
if (hot_seconds_value >= G_MAXINT32 || hot_seconds_value < 0)
|
|
||||||
hot_seconds_value = -1;
|
|
||||||
|
|
||||||
dev_class->temp_hot_seconds = hot_seconds_value;
|
|
||||||
g_debug ("device hot seconds set to %d", dev_class->temp_hot_seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_device_class_auto_initialize_features (dev_class);
|
fpi_device_class_auto_initialize_features (dev_class);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -191,12 +191,12 @@ on_listener_connected (FpiDeviceVirtualListener *listener,
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||||
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
|
||||||
|
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||||
recv_image (self);
|
recv_image (self);
|
||||||
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_IDLE:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
|
||||||
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
|
||||||
case FPI_IMAGE_DEVICE_STATE_ACTIVATING:
|
case FPI_IMAGE_DEVICE_STATE_ACTIVATING:
|
||||||
case FPI_IMAGE_DEVICE_STATE_DEACTIVATING:
|
case FPI_IMAGE_DEVICE_STATE_DEACTIVATING:
|
||||||
|
|
@ -310,7 +310,6 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||||
{
|
{
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
const char *hot_seconds;
|
|
||||||
|
|
||||||
dev_class->id = FP_COMPONENT;
|
dev_class->id = FP_COMPONENT;
|
||||||
dev_class->full_name = "Virtual image device for debugging";
|
dev_class->full_name = "Virtual image device for debugging";
|
||||||
|
|
@ -322,17 +321,4 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||||
|
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
if ((hot_seconds = g_getenv ("FP_VIRTUAL_IMAGE_HOT_SECONDS")) &&
|
|
||||||
*hot_seconds != '\0')
|
|
||||||
{
|
|
||||||
gint64 hot_seconds_value;
|
|
||||||
|
|
||||||
hot_seconds_value = g_ascii_strtoll (hot_seconds, NULL, 10);
|
|
||||||
if (hot_seconds_value >= G_MAXINT32 || hot_seconds_value < 0)
|
|
||||||
hot_seconds_value = -1;
|
|
||||||
|
|
||||||
dev_class->temp_hot_seconds = hot_seconds_value;
|
|
||||||
g_debug ("device hot seconds set to %d", dev_class->temp_hot_seconds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,26 +67,32 @@ enum {
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
get_drivers_allowlist_env (void)
|
get_drivers_whitelist_env (void)
|
||||||
{
|
{
|
||||||
return g_getenv ("FP_DRIVERS_ALLOWLIST");
|
return g_getenv ("FP_DRIVERS_WHITELIST");
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_driver_allowed (const gchar *driver)
|
is_driver_allowed (const gchar *driver)
|
||||||
{
|
{
|
||||||
g_auto(GStrv) allowlisted_drivers = NULL;
|
g_auto(GStrv) whitelisted_drivers = NULL;
|
||||||
const char *fp_drivers_allowlist_env;
|
const char *fp_drivers_whitelist_env;
|
||||||
|
int i;
|
||||||
|
|
||||||
g_return_val_if_fail (driver, TRUE);
|
g_return_val_if_fail (driver, TRUE);
|
||||||
|
|
||||||
fp_drivers_allowlist_env = get_drivers_allowlist_env ();
|
fp_drivers_whitelist_env = get_drivers_whitelist_env ();
|
||||||
|
|
||||||
if (!fp_drivers_allowlist_env)
|
if (!fp_drivers_whitelist_env)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
allowlisted_drivers = g_strsplit (fp_drivers_allowlist_env, ":", -1);
|
whitelisted_drivers = g_strsplit (fp_drivers_whitelist_env, ":", -1);
|
||||||
return g_strv_contains ((const gchar * const *) allowlisted_drivers, driver);
|
|
||||||
|
for (i = 0; whitelisted_drivers[i]; ++i)
|
||||||
|
if (g_strcmp0 (driver, whitelisted_drivers[i]) == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -285,10 +291,11 @@ fp_context_finalize (GObject *object)
|
||||||
FpContext *self = (FpContext *) object;
|
FpContext *self = (FpContext *) object;
|
||||||
FpContextPrivate *priv = fp_context_get_instance_private (self);
|
FpContextPrivate *priv = fp_context_get_instance_private (self);
|
||||||
|
|
||||||
|
g_clear_pointer (&priv->devices, g_ptr_array_unref);
|
||||||
|
|
||||||
g_cancellable_cancel (priv->cancellable);
|
g_cancellable_cancel (priv->cancellable);
|
||||||
g_clear_object (&priv->cancellable);
|
g_clear_object (&priv->cancellable);
|
||||||
g_clear_pointer (&priv->drivers, g_array_unref);
|
g_clear_pointer (&priv->drivers, g_array_unref);
|
||||||
g_clear_pointer (&priv->devices, g_ptr_array_unref);
|
|
||||||
|
|
||||||
g_slist_free_full (g_steal_pointer (&priv->sources), (GDestroyNotify) g_source_destroy);
|
g_slist_free_full (g_steal_pointer (&priv->sources), (GDestroyNotify) g_source_destroy);
|
||||||
|
|
||||||
|
|
@ -354,11 +361,9 @@ fp_context_init (FpContext *self)
|
||||||
FpContextPrivate *priv = fp_context_get_instance_private (self);
|
FpContextPrivate *priv = fp_context_get_instance_private (self);
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
g_debug ("Initializing FpContext (libfprint version " LIBFPRINT_VERSION ")");
|
|
||||||
|
|
||||||
priv->drivers = fpi_get_driver_types ();
|
priv->drivers = fpi_get_driver_types ();
|
||||||
|
|
||||||
if (get_drivers_allowlist_env ())
|
if (get_drivers_whitelist_env ())
|
||||||
{
|
{
|
||||||
for (i = 0; i < priv->drivers->len;)
|
for (i = 0; i < priv->drivers->len;)
|
||||||
{
|
{
|
||||||
|
|
@ -421,7 +426,6 @@ void
|
||||||
fp_context_enumerate (FpContext *context)
|
fp_context_enumerate (FpContext *context)
|
||||||
{
|
{
|
||||||
FpContextPrivate *priv = fp_context_get_instance_private (context);
|
FpContextPrivate *priv = fp_context_get_instance_private (context);
|
||||||
gboolean dispatched;
|
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_CONTEXT (context));
|
g_return_if_fail (FP_IS_CONTEXT (context));
|
||||||
|
|
@ -560,19 +564,8 @@ fp_context_enumerate (FpContext *context)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Iterate until 1. we have no pending devices, and 2. the mainloop is idle
|
while (priv->pending_devices)
|
||||||
* This takes care of processing hotplug events that happened during
|
g_main_context_iteration (NULL, TRUE);
|
||||||
* enumeration.
|
|
||||||
* This is important due to USB `persist` being turned off. At resume time,
|
|
||||||
* devices will disappear and immediately re-appear. In this situation,
|
|
||||||
* enumerate could first see the old state with a removed device resulting
|
|
||||||
* in it to not be discovered.
|
|
||||||
* As a hotplug event is seemingly emitted by the kernel immediately, we can
|
|
||||||
* simply make sure to process all events before returning from enumerate.
|
|
||||||
*/
|
|
||||||
dispatched = TRUE;
|
|
||||||
while (priv->pending_devices || dispatched)
|
|
||||||
dispatched = g_main_context_iteration (NULL, !!priv->pending_devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ typedef struct
|
||||||
FpDeviceType type;
|
FpDeviceType type;
|
||||||
|
|
||||||
GUsbDevice *usb_device;
|
GUsbDevice *usb_device;
|
||||||
gchar *virtual_env;
|
const gchar *virtual_env;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
gchar *spidev_path;
|
gchar *spidev_path;
|
||||||
|
|
@ -111,6 +111,8 @@ typedef struct
|
||||||
GDestroyNotify enroll_progress_destroy;
|
GDestroyNotify enroll_progress_destroy;
|
||||||
} FpEnrollData;
|
} FpEnrollData;
|
||||||
|
|
||||||
|
void enroll_data_free (FpEnrollData *enroll_data);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FpPrint *enrolled_print; /* verify */
|
FpPrint *enrolled_print; /* verify */
|
||||||
|
|
@ -126,9 +128,7 @@ typedef struct
|
||||||
GDestroyNotify match_destroy;
|
GDestroyNotify match_destroy;
|
||||||
} FpMatchData;
|
} FpMatchData;
|
||||||
|
|
||||||
|
void match_data_free (FpMatchData *match_data);
|
||||||
void fpi_device_suspend (FpDevice *device);
|
|
||||||
void fpi_device_resume (FpDevice *device);
|
|
||||||
|
|
||||||
void fpi_device_configure_wakeup (FpDevice *device,
|
void fpi_device_configure_wakeup (FpDevice *device,
|
||||||
gboolean enabled);
|
gboolean enabled);
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,6 @@ fp_device_finalize (GObject *object)
|
||||||
|
|
||||||
g_clear_pointer (&priv->current_idle_cancel_source, g_source_destroy);
|
g_clear_pointer (&priv->current_idle_cancel_source, g_source_destroy);
|
||||||
g_clear_pointer (&priv->current_task_idle_return_source, g_source_destroy);
|
g_clear_pointer (&priv->current_task_idle_return_source, g_source_destroy);
|
||||||
g_clear_pointer (&priv->critical_section_flush_source, g_source_destroy);
|
|
||||||
|
|
||||||
g_clear_pointer (&priv->device_id, g_free);
|
g_clear_pointer (&priv->device_id, g_free);
|
||||||
g_clear_pointer (&priv->device_name, g_free);
|
g_clear_pointer (&priv->device_name, g_free);
|
||||||
|
|
@ -292,14 +291,14 @@ fp_device_get_property (GObject *object,
|
||||||
|
|
||||||
case PROP_FPI_UDEV_DATA_SPIDEV:
|
case PROP_FPI_UDEV_DATA_SPIDEV:
|
||||||
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||||
g_value_set_string (value, priv->udev_data.spidev_path);
|
g_value_set_string (value, g_strdup (priv->udev_data.spidev_path));
|
||||||
else
|
else
|
||||||
g_value_set_string (value, NULL);
|
g_value_set_string (value, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FPI_UDEV_DATA_HIDRAW:
|
case PROP_FPI_UDEV_DATA_HIDRAW:
|
||||||
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
if (cls->type == FP_DEVICE_TYPE_UDEV)
|
||||||
g_value_set_string (value, priv->udev_data.hidraw_path);
|
g_value_set_string (value, g_strdup (priv->udev_data.hidraw_path));
|
||||||
else
|
else
|
||||||
g_value_set_string (value, NULL);
|
g_value_set_string (value, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
@ -483,9 +482,6 @@ fp_device_class_init (FpDeviceClass *klass)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||||
|
|
||||||
/**
|
|
||||||
* FpDevice:open: (getter is_open):
|
|
||||||
*/
|
|
||||||
properties[PROP_OPEN] =
|
properties[PROP_OPEN] =
|
||||||
g_param_spec_boolean ("open",
|
g_param_spec_boolean ("open",
|
||||||
"Opened",
|
"Opened",
|
||||||
|
|
@ -952,6 +948,16 @@ fp_device_close_finish (FpDevice *device,
|
||||||
return g_task_propagate_boolean (G_TASK (result), error);
|
return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
complete_suspend_resume_task (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
|
g_assert (priv->suspend_resume_task);
|
||||||
|
|
||||||
|
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_device_suspend:
|
* fp_device_suspend:
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
|
|
@ -1002,7 +1008,48 @@ fp_device_suspend (FpDevice *device,
|
||||||
|
|
||||||
priv->suspend_resume_task = g_steal_pointer (&task);
|
priv->suspend_resume_task = g_steal_pointer (&task);
|
||||||
|
|
||||||
fpi_device_suspend (device);
|
/* If the device is currently idle, just complete immediately.
|
||||||
|
* For long running tasks, call the driver handler right away, for short
|
||||||
|
* tasks, wait for completion and then return the task.
|
||||||
|
*/
|
||||||
|
switch (priv->current_action)
|
||||||
|
{
|
||||||
|
case FPI_DEVICE_ACTION_NONE:
|
||||||
|
fpi_device_suspend_complete (device, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPI_DEVICE_ACTION_ENROLL:
|
||||||
|
case FPI_DEVICE_ACTION_VERIFY:
|
||||||
|
case FPI_DEVICE_ACTION_IDENTIFY:
|
||||||
|
case FPI_DEVICE_ACTION_CAPTURE:
|
||||||
|
if (FP_DEVICE_GET_CLASS (device)->suspend)
|
||||||
|
{
|
||||||
|
if (priv->critical_section)
|
||||||
|
priv->suspend_queued = TRUE;
|
||||||
|
else
|
||||||
|
FP_DEVICE_GET_CLASS (device)->suspend (device);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case FPI_DEVICE_ACTION_PROBE:
|
||||||
|
case FPI_DEVICE_ACTION_OPEN:
|
||||||
|
case FPI_DEVICE_ACTION_CLOSE:
|
||||||
|
case FPI_DEVICE_ACTION_DELETE:
|
||||||
|
case FPI_DEVICE_ACTION_LIST:
|
||||||
|
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
|
||||||
|
g_signal_connect_object (priv->current_task,
|
||||||
|
"notify::completed",
|
||||||
|
G_CALLBACK (complete_suspend_resume_task),
|
||||||
|
device,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1067,7 +1114,41 @@ fp_device_resume (FpDevice *device,
|
||||||
|
|
||||||
priv->suspend_resume_task = g_steal_pointer (&task);
|
priv->suspend_resume_task = g_steal_pointer (&task);
|
||||||
|
|
||||||
fpi_device_resume (device);
|
switch (priv->current_action)
|
||||||
|
{
|
||||||
|
case FPI_DEVICE_ACTION_NONE:
|
||||||
|
fpi_device_resume_complete (device, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPI_DEVICE_ACTION_ENROLL:
|
||||||
|
case FPI_DEVICE_ACTION_VERIFY:
|
||||||
|
case FPI_DEVICE_ACTION_IDENTIFY:
|
||||||
|
case FPI_DEVICE_ACTION_CAPTURE:
|
||||||
|
if (FP_DEVICE_GET_CLASS (device)->resume)
|
||||||
|
{
|
||||||
|
if (priv->critical_section)
|
||||||
|
priv->resume_queued = TRUE;
|
||||||
|
else
|
||||||
|
FP_DEVICE_GET_CLASS (device)->resume (device);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case FPI_DEVICE_ACTION_PROBE:
|
||||||
|
case FPI_DEVICE_ACTION_OPEN:
|
||||||
|
case FPI_DEVICE_ACTION_CLOSE:
|
||||||
|
case FPI_DEVICE_ACTION_DELETE:
|
||||||
|
case FPI_DEVICE_ACTION_LIST:
|
||||||
|
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
|
||||||
|
/* cannot happen as we make sure these tasks complete before suspend */
|
||||||
|
g_assert_not_reached ();
|
||||||
|
complete_suspend_resume_task (device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1091,23 +1172,14 @@ fp_device_resume_finish (FpDevice *device,
|
||||||
return g_task_propagate_boolean (G_TASK (result), error);
|
return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
enroll_data_free (FpEnrollData *data)
|
|
||||||
{
|
|
||||||
if (data->enroll_progress_destroy)
|
|
||||||
data->enroll_progress_destroy (data->enroll_progress_data);
|
|
||||||
data->enroll_progress_data = NULL;
|
|
||||||
g_clear_object (&data->print);
|
|
||||||
g_free (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_device_enroll:
|
* fp_device_enroll:
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @template_print: (transfer floating): a #FpPrint
|
* @template_print: (transfer floating): a #FpPrint
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
* @progress_cb: (nullable) (closure progress_data) (scope notified): progress reporting callback
|
* @progress_cb: (nullable) (scope notified): progress reporting callback
|
||||||
* @progress_data: user data for @progress_cb
|
* @progress_data: (closure progress_cb): user data for @progress_cb
|
||||||
* @progress_destroy: (destroy progress_data): Destroy notify for @progress_data
|
* @progress_destroy: (destroy progress_data): Destroy notify for @progress_data
|
||||||
* @callback: (scope async): the function to call on completion
|
* @callback: (scope async): the function to call on completion
|
||||||
* @user_data: the data to pass to @callback
|
* @user_data: the data to pass to @callback
|
||||||
|
|
@ -1117,11 +1189,10 @@ enroll_data_free (FpEnrollData *data)
|
||||||
* fp_device_enroll_finish().
|
* fp_device_enroll_finish().
|
||||||
*
|
*
|
||||||
* The @template_print parameter is a #FpPrint with available metadata filled
|
* The @template_print parameter is a #FpPrint with available metadata filled
|
||||||
* in and, optionally, with existing fingerprint data to be updated with newly
|
* in. The driver may make use of this metadata, when e.g. storing the print on
|
||||||
* enrolled fingerprints if a device driver supports it. The driver may make use
|
* device memory. It is undefined whether this print is filled in by the driver
|
||||||
* of the metadata, when e.g. storing the print on device memory. It is undefined
|
* and returned, or whether the driver will return a newly created print after
|
||||||
* whether this print is filled in by the driver and returned, or whether the
|
* enrollment succeeded.
|
||||||
* driver will return a newly created print after enrollment succeeded.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fp_device_enroll (FpDevice *device,
|
fp_device_enroll (FpDevice *device,
|
||||||
|
|
@ -1158,32 +1229,25 @@ fp_device_enroll (FpDevice *device,
|
||||||
|
|
||||||
if (!FP_IS_PRINT (template_print))
|
if (!FP_IS_PRINT (template_print))
|
||||||
{
|
{
|
||||||
|
g_warning ("User did not pass a print template!");
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
"User did not pass a print template!"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_get (template_print, "fpi-type", &print_type, NULL);
|
g_object_get (template_print, "fpi-type", &print_type, NULL);
|
||||||
if (print_type != FPI_PRINT_UNDEFINED)
|
if (print_type != FPI_PRINT_UNDEFINED)
|
||||||
{
|
{
|
||||||
if (!fp_device_has_feature (device, FP_DEVICE_FEATURE_UPDATE_PRINT))
|
g_warning ("Passed print template must be newly created and blank!");
|
||||||
{
|
g_task_return_error (task,
|
||||||
g_task_return_error (task,
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
|
return;
|
||||||
"A device does not support print updates!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!fp_print_compatible (template_print, device))
|
|
||||||
{
|
|
||||||
g_task_return_error (task,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
|
|
||||||
"The print and device must have a matching driver and device id"
|
|
||||||
" for a fingerprint update to succeed"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->current_action = FPI_DEVICE_ACTION_ENROLL;
|
||||||
|
priv->current_task = g_steal_pointer (&task);
|
||||||
|
setup_task_cancellable (device);
|
||||||
|
|
||||||
fpi_device_update_temp (device, TRUE);
|
fpi_device_update_temp (device, TRUE);
|
||||||
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
||||||
{
|
{
|
||||||
|
|
@ -1192,10 +1256,6 @@ fp_device_enroll (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_ENROLL;
|
|
||||||
priv->current_task = g_steal_pointer (&task);
|
|
||||||
setup_task_cancellable (device);
|
|
||||||
|
|
||||||
data = g_new0 (FpEnrollData, 1);
|
data = g_new0 (FpEnrollData, 1);
|
||||||
data->print = g_object_ref_sink (template_print);
|
data->print = g_object_ref_sink (template_print);
|
||||||
data->enroll_progress_cb = progress_cb;
|
data->enroll_progress_cb = progress_cb;
|
||||||
|
|
@ -1229,30 +1289,13 @@ fp_device_enroll_finish (FpDevice *device,
|
||||||
return g_task_propagate_pointer (G_TASK (result), error);
|
return g_task_propagate_pointer (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
match_data_free (FpMatchData *data)
|
|
||||||
{
|
|
||||||
g_clear_object (&data->print);
|
|
||||||
g_clear_object (&data->match);
|
|
||||||
g_clear_error (&data->error);
|
|
||||||
|
|
||||||
if (data->match_destroy)
|
|
||||||
data->match_destroy (data->match_data);
|
|
||||||
data->match_data = NULL;
|
|
||||||
|
|
||||||
g_clear_object (&data->enrolled_print);
|
|
||||||
g_clear_pointer (&data->gallery, g_ptr_array_unref);
|
|
||||||
|
|
||||||
g_free (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_device_verify:
|
* fp_device_verify:
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @enrolled_print: a #FpPrint to verify
|
* @enrolled_print: a #FpPrint to verify
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
* @match_cb: (nullable) (scope notified) (closure match_data): match reporting callback
|
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||||
* @match_data: user data for @match_cb
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||||
* @callback: the function to call on completion
|
* @callback: the function to call on completion
|
||||||
* @user_data: the data to pass to @callback
|
* @user_data: the data to pass to @callback
|
||||||
|
|
@ -1302,6 +1345,10 @@ fp_device_verify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->current_action = FPI_DEVICE_ACTION_VERIFY;
|
||||||
|
priv->current_task = g_steal_pointer (&task);
|
||||||
|
setup_task_cancellable (device);
|
||||||
|
|
||||||
fpi_device_update_temp (device, TRUE);
|
fpi_device_update_temp (device, TRUE);
|
||||||
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
||||||
{
|
{
|
||||||
|
|
@ -1310,10 +1357,6 @@ fp_device_verify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_VERIFY;
|
|
||||||
priv->current_task = g_steal_pointer (&task);
|
|
||||||
setup_task_cancellable (device);
|
|
||||||
|
|
||||||
data = g_new0 (FpMatchData, 1);
|
data = g_new0 (FpMatchData, 1);
|
||||||
data->enrolled_print = g_object_ref (enrolled_print);
|
data->enrolled_print = g_object_ref (enrolled_print);
|
||||||
data->match_cb = match_cb;
|
data->match_cb = match_cb;
|
||||||
|
|
@ -1377,8 +1420,8 @@ fp_device_verify_finish (FpDevice *device,
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
* @match_cb: (nullable) (scope notified) (closure match_data): match reporting callback
|
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||||
* @match_data: user data for @match_cb
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||||
* @callback: the function to call on completion
|
* @callback: the function to call on completion
|
||||||
* @user_data: the data to pass to @callback
|
* @user_data: the data to pass to @callback
|
||||||
|
|
@ -1429,13 +1472,9 @@ fp_device_identify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prints == NULL)
|
priv->current_action = FPI_DEVICE_ACTION_IDENTIFY;
|
||||||
{
|
priv->current_task = g_steal_pointer (&task);
|
||||||
g_task_return_error (task,
|
setup_task_cancellable (device);
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
|
|
||||||
"Invalid gallery array"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_device_update_temp (device, TRUE);
|
fpi_device_update_temp (device, TRUE);
|
||||||
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
||||||
|
|
@ -1445,10 +1484,6 @@ fp_device_identify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_IDENTIFY;
|
|
||||||
priv->current_task = g_steal_pointer (&task);
|
|
||||||
setup_task_cancellable (device);
|
|
||||||
|
|
||||||
data = g_new0 (FpMatchData, 1);
|
data = g_new0 (FpMatchData, 1);
|
||||||
/* We cannot store the gallery directly, because the ptr array may not own
|
/* We cannot store the gallery directly, because the ptr array may not own
|
||||||
* a reference to each print. Also, the caller could in principle modify the
|
* a reference to each print. Also, the caller could in principle modify the
|
||||||
|
|
@ -1562,6 +1597,10 @@ fp_device_capture (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->current_action = FPI_DEVICE_ACTION_CAPTURE;
|
||||||
|
priv->current_task = g_steal_pointer (&task);
|
||||||
|
setup_task_cancellable (device);
|
||||||
|
|
||||||
fpi_device_update_temp (device, TRUE);
|
fpi_device_update_temp (device, TRUE);
|
||||||
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
if (priv->temp_current == FP_TEMPERATURE_HOT)
|
||||||
{
|
{
|
||||||
|
|
@ -1570,10 +1609,6 @@ fp_device_capture (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_CAPTURE;
|
|
||||||
priv->current_task = g_steal_pointer (&task);
|
|
||||||
setup_task_cancellable (device);
|
|
||||||
|
|
||||||
priv->wait_for_finger = wait_for_finger;
|
priv->wait_for_finger = wait_for_finger;
|
||||||
|
|
||||||
cls->capture (device);
|
cls->capture (device);
|
||||||
|
|
@ -1946,8 +1981,8 @@ fp_device_enroll_sync (FpDevice *device,
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @enrolled_print: a #FpPrint to verify
|
* @enrolled_print: a #FpPrint to verify
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
* @match_cb: (nullable) (scope call) (closure match_data): match reporting callback
|
* @match_cb: (nullable) (scope call): match reporting callback
|
||||||
* @match_data: user data for @match_cb
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match: (out): Whether the user presented the correct finger
|
* @match: (out): Whether the user presented the correct finger
|
||||||
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
|
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
|
||||||
* @error: Return location for errors, or %NULL to ignore
|
* @error: Return location for errors, or %NULL to ignore
|
||||||
|
|
@ -1986,8 +2021,8 @@ fp_device_verify_sync (FpDevice *device,
|
||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
* @match_cb: (nullable) (scope call) (closure match_data): match reporting callback
|
* @match_cb: (nullable) (scope call): match reporting callback
|
||||||
* @match_data: user data for @match_cb
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
|
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
|
||||||
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
|
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
|
||||||
* @error: Return location for errors, or %NULL to ignore
|
* @error: Return location for errors, or %NULL to ignore
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ typedef enum {
|
||||||
* @FP_DEVICE_FEATURE_STORAGE_CLEAR: Supports clearing the whole storage
|
* @FP_DEVICE_FEATURE_STORAGE_CLEAR: Supports clearing the whole storage
|
||||||
* @FP_DEVICE_FEATURE_DUPLICATES_CHECK: Natively supports duplicates detection
|
* @FP_DEVICE_FEATURE_DUPLICATES_CHECK: Natively supports duplicates detection
|
||||||
* @FP_DEVICE_FEATURE_ALWAYS_ON: Whether the device can run continuously
|
* @FP_DEVICE_FEATURE_ALWAYS_ON: Whether the device can run continuously
|
||||||
* @FP_DEVICE_FEATURE_UPDATE_PRINT: Supports updating an existing print record using new scans
|
|
||||||
*/
|
*/
|
||||||
typedef enum /*< flags >*/ {
|
typedef enum /*< flags >*/ {
|
||||||
FP_DEVICE_FEATURE_NONE = 0,
|
FP_DEVICE_FEATURE_NONE = 0,
|
||||||
|
|
@ -72,7 +71,6 @@ typedef enum /*< flags >*/ {
|
||||||
FP_DEVICE_FEATURE_STORAGE_CLEAR = 1 << 6,
|
FP_DEVICE_FEATURE_STORAGE_CLEAR = 1 << 6,
|
||||||
FP_DEVICE_FEATURE_DUPLICATES_CHECK = 1 << 7,
|
FP_DEVICE_FEATURE_DUPLICATES_CHECK = 1 << 7,
|
||||||
FP_DEVICE_FEATURE_ALWAYS_ON = 1 << 8,
|
FP_DEVICE_FEATURE_ALWAYS_ON = 1 << 8,
|
||||||
FP_DEVICE_FEATURE_UPDATE_PRINT = 1 << 9,
|
|
||||||
} FpDeviceFeature;
|
} FpDeviceFeature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -113,8 +111,6 @@ typedef enum {
|
||||||
* @FP_DEVICE_RETRY_REMOVE_FINGER: The scan did not succeed due to quality or
|
* @FP_DEVICE_RETRY_REMOVE_FINGER: The scan did not succeed due to quality or
|
||||||
* pressure problems; the user should remove their finger from the scanner
|
* pressure problems; the user should remove their finger from the scanner
|
||||||
* before retrying.
|
* before retrying.
|
||||||
* @FP_DEVICE_RETRY_TOO_FAST: The scan did not succeed because the finger
|
|
||||||
* swipe or touch was too fast.
|
|
||||||
*
|
*
|
||||||
* Error codes representing scan failures resulting in the user needing to
|
* Error codes representing scan failures resulting in the user needing to
|
||||||
* retry.
|
* retry.
|
||||||
|
|
@ -124,7 +120,6 @@ typedef enum {
|
||||||
FP_DEVICE_RETRY_TOO_SHORT,
|
FP_DEVICE_RETRY_TOO_SHORT,
|
||||||
FP_DEVICE_RETRY_CENTER_FINGER,
|
FP_DEVICE_RETRY_CENTER_FINGER,
|
||||||
FP_DEVICE_RETRY_REMOVE_FINGER,
|
FP_DEVICE_RETRY_REMOVE_FINGER,
|
||||||
FP_DEVICE_RETRY_TOO_FAST,
|
|
||||||
} FpDeviceRetry;
|
} FpDeviceRetry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ fp_image_device_start_capture_action (FpDevice *device)
|
||||||
FpImageDevice *self = FP_IMAGE_DEVICE (device);
|
FpImageDevice *self = FP_IMAGE_DEVICE (device);
|
||||||
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
|
||||||
FpiDeviceAction action;
|
FpiDeviceAction action;
|
||||||
FpiPrintType print_type;
|
|
||||||
|
|
||||||
/* There is just one action that we cannot support out
|
/* There is just one action that we cannot support out
|
||||||
* of the box, which is a capture without first waiting
|
* of the box, which is a capture without first waiting
|
||||||
|
|
@ -125,9 +124,7 @@ fp_image_device_start_capture_action (FpDevice *device)
|
||||||
FpPrint *enroll_print = NULL;
|
FpPrint *enroll_print = NULL;
|
||||||
|
|
||||||
fpi_device_get_enroll_data (device, &enroll_print);
|
fpi_device_get_enroll_data (device, &enroll_print);
|
||||||
g_object_get (enroll_print, "fpi-type", &print_type, NULL);
|
fpi_print_set_type (enroll_print, FPI_PRINT_NBIS);
|
||||||
if (print_type != FPI_PRINT_NBIS)
|
|
||||||
fpi_print_set_type (enroll_print, FPI_PRINT_NBIS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->enroll_stage = 0;
|
priv->enroll_stage = 0;
|
||||||
|
|
@ -224,7 +221,6 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
|
||||||
fp_device_class->cancel = fp_image_device_cancel_action;
|
fp_device_class->cancel = fp_image_device_cancel_action;
|
||||||
|
|
||||||
fpi_device_class_auto_initialize_features (fp_device_class);
|
fpi_device_class_auto_initialize_features (fp_device_class);
|
||||||
fp_device_class->features |= FP_DEVICE_FEATURE_UPDATE_PRINT;
|
|
||||||
|
|
||||||
/* Default implementations */
|
/* Default implementations */
|
||||||
klass->activate = fp_image_device_default_activate;
|
klass->activate = fp_image_device_default_activate;
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,9 @@
|
||||||
|
|
||||||
#define FP_COMPONENT "image"
|
#define FP_COMPONENT "image"
|
||||||
|
|
||||||
#include "fpi-compat.h"
|
|
||||||
#include "fpi-image.h"
|
#include "fpi-image.h"
|
||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <nbis.h>
|
#include <nbis.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -160,65 +158,60 @@ fp_image_init (FpImage *self)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
GAsyncReadyCallback user_cb;
|
||||||
struct fp_minutiae *minutiae;
|
struct fp_minutiae *minutiae;
|
||||||
guchar *binarized;
|
gint width, height;
|
||||||
|
gdouble ppmm;
|
||||||
FpiImageFlags flags;
|
FpiImageFlags flags;
|
||||||
unsigned char *image;
|
guchar *image;
|
||||||
gboolean image_changed;
|
guchar *binarized;
|
||||||
} DetectMinutiaeNbisData;
|
} DetectMinutiaeData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_image_detect_minutiae_free (DetectMinutiaeNbisData *data)
|
fp_image_detect_minutiae_free (DetectMinutiaeData *data)
|
||||||
{
|
{
|
||||||
|
g_clear_pointer (&data->image, g_free);
|
||||||
g_clear_pointer (&data->minutiae, free_minutiae);
|
g_clear_pointer (&data->minutiae, free_minutiae);
|
||||||
g_clear_pointer (&data->binarized, g_free);
|
g_clear_pointer (&data->binarized, g_free);
|
||||||
|
|
||||||
if (data->image_changed)
|
|
||||||
g_clear_pointer (&data->image, g_free);
|
|
||||||
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DetectMinutiaeNbisData, fp_image_detect_minutiae_free)
|
static void
|
||||||
|
fp_image_detect_minutiae_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
static gboolean
|
gpointer user_data)
|
||||||
fp_image_detect_minutiae_nbis_finish (FpImage *self,
|
|
||||||
GTask *task,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
g_autoptr(DetectMinutiaeNbisData) data = NULL;
|
GTask *task = G_TASK (res);
|
||||||
|
FpImage *image;
|
||||||
|
DetectMinutiaeData *data = g_task_get_task_data (task);
|
||||||
|
|
||||||
data = g_task_propagate_pointer (task, error);
|
if (!g_task_had_error (task))
|
||||||
|
|
||||||
if (data != NULL)
|
|
||||||
{
|
{
|
||||||
self->flags = data->flags;
|
gint i;
|
||||||
|
image = FP_IMAGE (source_object);
|
||||||
|
|
||||||
if (data->image_changed)
|
image->flags = data->flags;
|
||||||
{
|
|
||||||
g_clear_pointer (&self->data, g_free);
|
|
||||||
self->data = g_steal_pointer (&data->image);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_pointer (&self->binarized, g_free);
|
g_clear_pointer (&image->data, g_free);
|
||||||
self->binarized = g_steal_pointer (&data->binarized);
|
image->data = g_steal_pointer (&data->image);
|
||||||
|
|
||||||
g_clear_pointer (&self->minutiae, g_ptr_array_unref);
|
g_clear_pointer (&image->binarized, g_free);
|
||||||
self->minutiae = g_ptr_array_new_full (data->minutiae->num,
|
image->binarized = g_steal_pointer (&data->binarized);
|
||||||
(GDestroyNotify) free_minutia);
|
|
||||||
|
|
||||||
for (int i = 0; i < data->minutiae->num; i++)
|
g_clear_pointer (&image->minutiae, g_ptr_array_unref);
|
||||||
g_ptr_array_add (self->minutiae,
|
image->minutiae = g_ptr_array_new_full (data->minutiae->num,
|
||||||
|
(GDestroyNotify) free_minutia);
|
||||||
|
|
||||||
|
for (i = 0; i < data->minutiae->num; i++)
|
||||||
|
g_ptr_array_add (image->minutiae,
|
||||||
g_steal_pointer (&data->minutiae->list[i]));
|
g_steal_pointer (&data->minutiae->list[i]));
|
||||||
|
|
||||||
/* Don't let free_minutiae delete the minutiae that we now own. */
|
/* Don't let it delete anything. */
|
||||||
data->minutiae->num = 0;
|
data->minutiae->num = 0;
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
if (data->user_cb)
|
||||||
|
data->user_cb (source_object, res, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -271,83 +264,70 @@ invert_colors (guint8 *data, gint width, gint height)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fp_image_detect_minutiae_nbis_thread_func (GTask *task,
|
fp_image_detect_minutiae_thread_func (GTask *task,
|
||||||
gpointer source_object,
|
gpointer source_object,
|
||||||
gpointer task_data,
|
gpointer task_data,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
g_autoptr(GTimer) timer = NULL;
|
g_autoptr(GTimer) timer = NULL;
|
||||||
g_autoptr(DetectMinutiaeNbisData) ret_data = NULL;
|
DetectMinutiaeData *data = task_data;
|
||||||
g_autoptr(GTask) thread_task = g_steal_pointer (&task);
|
struct fp_minutiae *minutiae = NULL;
|
||||||
g_autofree gint *direction_map = NULL;
|
g_autofree gint *direction_map = NULL;
|
||||||
g_autofree gint *low_contrast_map = NULL;
|
g_autofree gint *low_contrast_map = NULL;
|
||||||
g_autofree gint *low_flow_map = NULL;
|
g_autofree gint *low_flow_map = NULL;
|
||||||
g_autofree gint *high_curve_map = NULL;
|
g_autofree gint *high_curve_map = NULL;
|
||||||
g_autofree gint *quality_map = NULL;
|
g_autofree gint *quality_map = NULL;
|
||||||
g_autofree LFSPARMS *lfsparms = NULL;
|
g_autofree guchar *bdata = NULL;
|
||||||
FpImage *self = source_object;
|
|
||||||
FpiImageFlags minutiae_flags;
|
|
||||||
unsigned char *image;
|
|
||||||
gint map_w, map_h;
|
gint map_w, map_h;
|
||||||
gint bw, bh, bd;
|
gint bw, bh, bd;
|
||||||
gint r;
|
gint r;
|
||||||
|
g_autofree LFSPARMS *lfsparms = NULL;
|
||||||
image = self->data;
|
|
||||||
minutiae_flags = self->flags & ~(FPI_IMAGE_H_FLIPPED |
|
|
||||||
FPI_IMAGE_V_FLIPPED |
|
|
||||||
FPI_IMAGE_COLORS_INVERTED);
|
|
||||||
|
|
||||||
if (minutiae_flags != FPI_IMAGE_NONE)
|
|
||||||
image = g_memdup2 (self->data, self->width * self->height);
|
|
||||||
|
|
||||||
ret_data = g_new0 (DetectMinutiaeNbisData, 1);
|
|
||||||
ret_data->flags = minutiae_flags;
|
|
||||||
ret_data->image = image;
|
|
||||||
ret_data->image_changed = image != self->data;
|
|
||||||
|
|
||||||
/* Normalize the image first */
|
/* Normalize the image first */
|
||||||
if (self->flags & FPI_IMAGE_H_FLIPPED)
|
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
||||||
hflip (image, self->width, self->height);
|
hflip (data->image, data->width, data->height);
|
||||||
|
|
||||||
if (self->flags & FPI_IMAGE_V_FLIPPED)
|
if (data->flags & FPI_IMAGE_V_FLIPPED)
|
||||||
vflip (image, self->width, self->height);
|
vflip (data->image, data->width, data->height);
|
||||||
|
|
||||||
if (self->flags & FPI_IMAGE_COLORS_INVERTED)
|
if (data->flags & FPI_IMAGE_COLORS_INVERTED)
|
||||||
invert_colors (image, self->width, self->height);
|
invert_colors (data->image, data->width, data->height);
|
||||||
|
|
||||||
lfsparms = g_memdup2 (&g_lfsparms_V2, sizeof (LFSPARMS));
|
data->flags &= ~(FPI_IMAGE_H_FLIPPED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_COLORS_INVERTED);
|
||||||
lfsparms->remove_perimeter_pts = minutiae_flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE;
|
|
||||||
|
lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS));
|
||||||
|
lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE;
|
||||||
|
|
||||||
timer = g_timer_new ();
|
timer = g_timer_new ();
|
||||||
r = get_minutiae (&ret_data->minutiae, &quality_map, &direction_map,
|
r = get_minutiae (&minutiae, &quality_map, &direction_map,
|
||||||
&low_contrast_map, &low_flow_map, &high_curve_map,
|
&low_contrast_map, &low_flow_map, &high_curve_map,
|
||||||
&map_w, &map_h, &ret_data->binarized, &bw, &bh, &bd,
|
&map_w, &map_h, &bdata, &bw, &bh, &bd,
|
||||||
image, self->width, self->height, 8,
|
data->image, data->width, data->height, 8,
|
||||||
self->ppmm, lfsparms);
|
data->ppmm, lfsparms);
|
||||||
g_timer_stop (timer);
|
g_timer_stop (timer);
|
||||||
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
|
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
|
||||||
|
|
||||||
if (g_task_had_error (thread_task))
|
data->binarized = g_steal_pointer (&bdata);
|
||||||
return;
|
data->minutiae = minutiae;
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
fp_err ("get minutiae failed, code %d", r);
|
fp_err ("get minutiae failed, code %d", r);
|
||||||
g_task_return_new_error (thread_task, G_IO_ERROR,
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Minutiae scan failed with code %d", r);
|
||||||
G_IO_ERROR_FAILED,
|
g_object_unref (task);
|
||||||
"Minutiae scan failed with code %d", r);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret_data->minutiae || ret_data->minutiae->num == 0)
|
if (!data->minutiae || data->minutiae->num == 0)
|
||||||
{
|
{
|
||||||
g_task_return_new_error (thread_task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"No minutiae found");
|
"No minutiae found");
|
||||||
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_task_return_pointer (thread_task, g_steal_pointer (&ret_data),
|
g_task_return_boolean (task, TRUE);
|
||||||
(GDestroyNotify) fp_image_detect_minutiae_free);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -463,25 +443,21 @@ fp_image_detect_minutiae (FpImage *self,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
GTask *task;
|
||||||
|
DetectMinutiaeData *data = g_new0 (DetectMinutiaeData, 1);
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_IMAGE (self));
|
task = g_task_new (self, cancellable, fp_image_detect_minutiae_cb, user_data);
|
||||||
g_return_if_fail (callback != NULL);
|
|
||||||
|
|
||||||
task = g_task_new (self, cancellable, callback, user_data);
|
data->image = g_malloc (self->width * self->height);
|
||||||
g_task_set_source_tag (task, fp_image_detect_minutiae);
|
memcpy (data->image, self->data, self->width * self->height);
|
||||||
g_task_set_check_cancellable (task, TRUE);
|
data->flags = self->flags;
|
||||||
|
data->width = self->width;
|
||||||
|
data->height = self->height;
|
||||||
|
data->ppmm = self->ppmm;
|
||||||
|
data->user_cb = callback;
|
||||||
|
|
||||||
if (!g_atomic_int_compare_and_exchange (&self->detection_in_progress,
|
g_task_set_task_data (task, data, (GDestroyNotify) fp_image_detect_minutiae_free);
|
||||||
FALSE, TRUE))
|
g_task_run_in_thread (task, fp_image_detect_minutiae_thread_func);
|
||||||
{
|
|
||||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE,
|
|
||||||
"Minutiae detection is already in progress");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_task_run_in_thread (g_steal_pointer (&task),
|
|
||||||
fp_image_detect_minutiae_nbis_thread_func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -499,27 +475,7 @@ fp_image_detect_minutiae_finish (FpImage *self,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GTask *task;
|
return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
gboolean changed;
|
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_IMAGE (self), FALSE);
|
|
||||||
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
|
|
||||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
||||||
fp_image_detect_minutiae, FALSE);
|
|
||||||
|
|
||||||
task = G_TASK (result);
|
|
||||||
changed = g_atomic_int_compare_and_exchange (&self->detection_in_progress,
|
|
||||||
TRUE, FALSE);
|
|
||||||
g_assert (changed);
|
|
||||||
|
|
||||||
if (g_task_had_error (task))
|
|
||||||
{
|
|
||||||
gpointer data = g_task_propagate_pointer (task, error);
|
|
||||||
g_assert (data == NULL);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fp_image_detect_minutiae_nbis_finish (self, task, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ enum {
|
||||||
/* Private property*/
|
/* Private property*/
|
||||||
PROP_FPI_TYPE,
|
PROP_FPI_TYPE,
|
||||||
PROP_FPI_DATA,
|
PROP_FPI_DATA,
|
||||||
PROP_FPI_PRINTS,
|
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -134,10 +133,6 @@ fp_print_get_property (GObject *object,
|
||||||
g_value_set_variant (value, self->data);
|
g_value_set_variant (value, self->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FPI_PRINTS:
|
|
||||||
g_value_set_pointer (value, self->prints);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
|
|
@ -193,11 +188,6 @@ fp_print_set_property (GObject *object,
|
||||||
self->data = g_value_dup_variant (value);
|
self->data = g_value_dup_variant (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FPI_PRINTS:
|
|
||||||
g_clear_pointer (&self->prints, g_ptr_array_unref);
|
|
||||||
self->prints = g_value_get_pointer (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
}
|
}
|
||||||
|
|
@ -309,19 +299,6 @@ fp_print_class_init (FpPrintClass *klass)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
|
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
|
||||||
|
|
||||||
/**
|
|
||||||
* FpPrint::fpi-prints: (skip)
|
|
||||||
*
|
|
||||||
* This property is only for internal purposes.
|
|
||||||
*
|
|
||||||
* Stability: private
|
|
||||||
*/
|
|
||||||
properties[PROP_FPI_PRINTS] =
|
|
||||||
g_param_spec_pointer ("fpi-prints",
|
|
||||||
"Prints",
|
|
||||||
"Prints for internal use only",
|
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,7 +316,7 @@ fp_print_init (FpPrint *self)
|
||||||
* create a new print, fill in the relevant metadata, and then start
|
* create a new print, fill in the relevant metadata, and then start
|
||||||
* enrollment.
|
* enrollment.
|
||||||
*
|
*
|
||||||
* Returns: (transfer floating): A newly created #FpPrint
|
* Returns: (transfer floating): A newyl created #FpPrint
|
||||||
*/
|
*/
|
||||||
FpPrint *
|
FpPrint *
|
||||||
fp_print_new (FpDevice *device)
|
fp_print_new (FpDevice *device)
|
||||||
|
|
@ -721,12 +698,13 @@ fp_print_serialize (FpPrint *print,
|
||||||
|
|
||||||
result = g_variant_builder_end (&builder);
|
result = g_variant_builder_end (&builder);
|
||||||
|
|
||||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
GVariant *tmp;
|
{
|
||||||
tmp = g_variant_byteswap (result);
|
GVariant *tmp;
|
||||||
g_variant_unref (result);
|
tmp = g_variant_byteswap (result);
|
||||||
result = tmp;
|
g_variant_unref (result);
|
||||||
#endif
|
result = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
len = g_variant_get_size (result);
|
len = g_variant_get_size (result);
|
||||||
/* Add 3 bytes of header */
|
/* Add 3 bytes of header */
|
||||||
|
|
@ -799,11 +777,10 @@ fp_print_deserialize (const guchar *data,
|
||||||
if (!raw_value)
|
if (!raw_value)
|
||||||
goto invalid_format;
|
goto invalid_format;
|
||||||
|
|
||||||
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
value = g_variant_byteswap (raw_value);
|
value = g_variant_byteswap (raw_value);
|
||||||
#else
|
else
|
||||||
value = g_variant_get_normal_form (raw_value);
|
value = g_variant_get_normal_form (raw_value);
|
||||||
#endif
|
|
||||||
|
|
||||||
g_variant_get (value,
|
g_variant_get (value,
|
||||||
"(i&s&sbymsmsi@a{sv}v)",
|
"(i&s&sbymsmsi@a{sv}v)",
|
||||||
|
|
|
||||||
|
|
@ -65,31 +65,6 @@ fpi_byte_reader_new (const guint8 * data, guint size)
|
||||||
return ret;
|
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:
|
* fpi_byte_reader_free:
|
||||||
* @reader: (in) (transfer full): a #FpiByteReader instance
|
* @reader: (in) (transfer full): a #FpiByteReader instance
|
||||||
|
|
@ -125,30 +100,6 @@ fpi_byte_reader_init (FpiByteReader * reader, const guint8 * data, guint size)
|
||||||
reader->byte = 0;
|
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)
|
* fpi_byte_reader_peek_sub_reader: (skip)
|
||||||
* @reader: an existing and initialized #FpiByteReader instance
|
* @reader: an existing and initialized #FpiByteReader instance
|
||||||
|
|
@ -848,41 +799,6 @@ fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size,
|
||||||
return fpi_byte_reader_peek_data_inline (reader, size, val);
|
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:
|
* fpi_byte_reader_dup_data:
|
||||||
* @reader: a #FpiByteReader instance
|
* @reader: a #FpiByteReader instance
|
||||||
|
|
@ -1265,7 +1181,7 @@ fpi_byte_reader_dup_string_utf##bits (FpiByteReader * reader, type ** str) \
|
||||||
*str = NULL; \
|
*str = NULL; \
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
} \
|
} \
|
||||||
*str = g_memdup2 (reader->data + reader->byte, size); \
|
*str = g_memdup (reader->data + reader->byte, size); \
|
||||||
reader->byte += size; \
|
reader->byte += size; \
|
||||||
return TRUE; \
|
return TRUE; \
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "fpi-compat.h"
|
|
||||||
#include "fpi-byte-utils.h"
|
#include "fpi-byte-utils.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
@ -50,7 +49,6 @@ typedef struct {
|
||||||
|
|
||||||
FpiByteReader * fpi_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
|
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);
|
void fpi_byte_reader_free (FpiByteReader *reader);
|
||||||
|
|
||||||
|
|
@ -58,9 +56,6 @@ void fpi_byte_reader_free (FpiByteReader *reader);
|
||||||
void fpi_byte_reader_init (FpiByteReader *reader, const guint8 *data, guint size);
|
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,
|
gboolean fpi_byte_reader_peek_sub_reader (FpiByteReader * reader,
|
||||||
FpiByteReader * sub_reader,
|
FpiByteReader * sub_reader,
|
||||||
guint size);
|
guint size);
|
||||||
|
|
@ -222,21 +217,8 @@ 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 (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 (const FpiByteReader * reader, guint size, const guint8 ** val);
|
||||||
|
|
||||||
|
|
||||||
gboolean fpi_byte_reader_peek_data_static (const FpiByteReader * reader, guint size, guint8 * val);
|
|
||||||
|
|
||||||
|
|
||||||
GBytes * fpi_byte_reader_get_bytes (FpiByteReader *reader, guint size);
|
|
||||||
|
|
||||||
|
|
||||||
GBytes * fpi_byte_reader_peek_bytes (const FpiByteReader *reader, guint size);
|
|
||||||
|
|
||||||
|
|
||||||
#define fpi_byte_reader_dup_string(reader,str) \
|
#define fpi_byte_reader_dup_string(reader,str) \
|
||||||
fpi_byte_reader_dup_string_utf8(reader,str)
|
fpi_byte_reader_dup_string_utf8(reader,str)
|
||||||
|
|
||||||
|
|
@ -378,7 +360,7 @@ static inline guint8 *
|
||||||
fpi_byte_reader_dup_data_unchecked (FpiByteReader * reader, guint size)
|
fpi_byte_reader_dup_data_unchecked (FpiByteReader * reader, guint size)
|
||||||
{
|
{
|
||||||
gconstpointer data = fpi_byte_reader_get_data_unchecked (reader, size);
|
gconstpointer data = fpi_byte_reader_get_data_unchecked (reader, size);
|
||||||
return (guint8 *) g_memdup2 (data, size);
|
return (guint8 *) g_memdup (data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unchecked variants that should not be used */
|
/* Unchecked variants that should not be used */
|
||||||
|
|
@ -659,60 +641,6 @@ fpi_byte_reader_peek_data_inline (const FpiByteReader * reader, guint size, cons
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GBytes *
|
|
||||||
fpi_byte_reader_peek_bytes_inline (const FpiByteReader *reader, guint size)
|
|
||||||
{
|
|
||||||
const guint8 *data;
|
|
||||||
|
|
||||||
g_return_val_if_fail (reader != NULL, NULL);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
data = fpi_byte_reader_peek_data_unchecked (reader);
|
|
||||||
return g_bytes_new_static (data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GBytes *
|
|
||||||
fpi_byte_reader_get_bytes_inline (FpiByteReader *reader, guint size)
|
|
||||||
{
|
|
||||||
const guint8 *data;
|
|
||||||
|
|
||||||
g_return_val_if_fail (reader != NULL, NULL);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
data = fpi_byte_reader_get_data_unchecked (reader, size);
|
|
||||||
return g_bytes_new_static (data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
(fpi_byte_reader_get_data_inline_static) (FpiByteReader * reader, guint size, const guint8 * val)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (reader != NULL, FALSE);
|
|
||||||
g_return_val_if_fail (val != NULL, FALSE);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
memcpy ((void *) val, fpi_byte_reader_get_data_unchecked (reader, size), size);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
(fpi_byte_reader_peek_data_inline_static) (const FpiByteReader * reader, guint size, guint8 * val)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (reader != NULL, FALSE);
|
|
||||||
g_return_val_if_fail (val != NULL, FALSE);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (size > reader->size || fpi_byte_reader_get_remaining_unchecked (reader) < size))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
memcpy (val, fpi_byte_reader_peek_data_unchecked (reader), size);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
static inline guint
|
||||||
fpi_byte_reader_get_pos_inline (const FpiByteReader * reader)
|
fpi_byte_reader_get_pos_inline (const FpiByteReader * reader)
|
||||||
{
|
{
|
||||||
|
|
@ -743,38 +671,7 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes)
|
||||||
G_LIKELY(fpi_byte_reader_peek_data_inline(reader,size,val))
|
G_LIKELY(fpi_byte_reader_peek_data_inline(reader,size,val))
|
||||||
#define fpi_byte_reader_skip(reader,nbytes) \
|
#define fpi_byte_reader_skip(reader,nbytes) \
|
||||||
G_LIKELY(fpi_byte_reader_skip_inline(reader,nbytes))
|
G_LIKELY(fpi_byte_reader_skip_inline(reader,nbytes))
|
||||||
#define fpi_byte_reader_get_bytes(reader,size) \
|
|
||||||
fpi_byte_reader_get_bytes_inline(reader,size)
|
|
||||||
#define fpi_byte_reader_peek_bytes(reader,size) \
|
|
||||||
fpi_byte_reader_peek_bytes_inline(reader,size)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_byte_reader_get_data_static:
|
|
||||||
* @reader: a #FpiByteReader
|
|
||||||
* @val: fixed-size array (e.g. `uint8_t buf[32]`)
|
|
||||||
*
|
|
||||||
* Reads @size bytes from @reader directly into @val, where @size is
|
|
||||||
* deduced via `sizeof()` - only safe with true C arrays.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE on success, %FALSE otherwise.
|
|
||||||
*/
|
|
||||||
#define fpi_byte_reader_get_data_static(reader,val) \
|
|
||||||
(fpi_byte_reader_get_data_static) (reader,sizeof(val),val)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_byte_reader_peek_data_static:
|
|
||||||
* @reader: a #FpiByteReader
|
|
||||||
* @val: fixed-size array (e.g. `uint8_t buf[32]`)
|
|
||||||
*
|
|
||||||
* Like fpi_byte_reader_get_data_static() but does not advance the position.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE on success, %FALSE otherwise.
|
|
||||||
*/
|
|
||||||
#define fpi_byte_reader_peek_data_static(reader,val) \
|
|
||||||
(fpi_byte_reader_peek_data_static) (reader,sizeof(val),val)
|
|
||||||
|
|
||||||
#endif /* FPI_BYTE_READER_DISABLE_INLINES */
|
#endif /* FPI_BYTE_READER_DISABLE_INLINES */
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteReader, fpi_byte_reader_free);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,7 @@ fpi_byte_writer_new_with_size (guint size, gboolean fixed)
|
||||||
FpiByteWriter *ret = fpi_byte_writer_new ();
|
FpiByteWriter *ret = fpi_byte_writer_new ();
|
||||||
|
|
||||||
ret->alloc_size = size;
|
ret->alloc_size = size;
|
||||||
ret->parent.data = g_malloc0 (ret->alloc_size);
|
ret->parent.data = g_malloc (ret->alloc_size);
|
||||||
ret->parent.size = size;
|
|
||||||
ret->fixed = fixed;
|
ret->fixed = fixed;
|
||||||
ret->owned = TRUE;
|
ret->owned = TRUE;
|
||||||
|
|
||||||
|
|
@ -143,8 +142,7 @@ fpi_byte_writer_init_with_size (FpiByteWriter * writer, guint size,
|
||||||
|
|
||||||
fpi_byte_writer_init (writer);
|
fpi_byte_writer_init (writer);
|
||||||
|
|
||||||
writer->parent.data = g_malloc0 (size);
|
writer->parent.data = g_malloc (size);
|
||||||
writer->parent.size = size;
|
|
||||||
writer->alloc_size = size;
|
writer->alloc_size = size;
|
||||||
writer->fixed = fixed;
|
writer->fixed = fixed;
|
||||||
writer->owned = TRUE;
|
writer->owned = TRUE;
|
||||||
|
|
@ -211,44 +209,15 @@ fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer)
|
||||||
|
|
||||||
g_return_val_if_fail (writer != NULL, NULL);
|
g_return_val_if_fail (writer != NULL, NULL);
|
||||||
|
|
||||||
data = (guint8 *) g_steal_pointer (&writer->parent.data);
|
data = (guint8 *) writer->parent.data;
|
||||||
if (!writer->owned)
|
if (!writer->owned)
|
||||||
data = g_memdup2 (data, writer->parent.size);
|
data = g_memdup (data, writer->parent.size);
|
||||||
|
writer->parent.data = NULL;
|
||||||
fpi_byte_writer_reset (writer);
|
fpi_byte_writer_reset (writer);
|
||||||
|
|
||||||
return data;
|
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:
|
* fpi_byte_writer_free:
|
||||||
* @writer: (in) (transfer full): #FpiByteWriter instance
|
* @writer: (in) (transfer full): #FpiByteWriter instance
|
||||||
|
|
@ -632,15 +601,6 @@ CREATE_WRITE_STRING_FUNC (32, guint32);
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the value could be written
|
* 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:
|
* fpi_byte_writer_fill:
|
||||||
* @writer: #FpiByteWriter instance
|
* @writer: #FpiByteWriter instance
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,6 @@ void fpi_byte_writer_reset (FpiByteWriter *writer);
|
||||||
|
|
||||||
guint8 * fpi_byte_writer_reset_and_get_data (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:
|
* fpi_byte_writer_get_pos:
|
||||||
* @writer: #FpiByteWriter instance
|
* @writer: #FpiByteWriter instance
|
||||||
|
|
@ -114,17 +111,6 @@ fpi_byte_writer_set_pos (FpiByteWriter *writer, guint pos)
|
||||||
return fpi_byte_reader_set_pos (FPI_BYTE_READER (writer), pos);
|
return fpi_byte_reader_set_pos (FPI_BYTE_READER (writer), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
fpi_byte_writer_change_pos (FpiByteWriter *writer, gint pos)
|
|
||||||
{
|
|
||||||
pos = fpi_byte_writer_get_pos (writer) + pos;
|
|
||||||
|
|
||||||
if (pos < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return fpi_byte_reader_set_pos (FPI_BYTE_READER (writer), pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
static inline guint
|
||||||
fpi_byte_writer_get_size (const FpiByteWriter *writer)
|
fpi_byte_writer_get_size (const FpiByteWriter *writer)
|
||||||
{
|
{
|
||||||
|
|
@ -207,9 +193,6 @@ 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_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);
|
gboolean fpi_byte_writer_fill (FpiByteWriter *writer, guint8 value, guint size);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -344,18 +327,6 @@ fpi_byte_writer_put_data_inline (FpiByteWriter * writer, const guint8 * data,
|
||||||
return TRUE;
|
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
|
static inline void
|
||||||
fpi_byte_writer_fill_unchecked (FpiByteWriter * writer, guint8 value, guint size)
|
fpi_byte_writer_fill_unchecked (FpiByteWriter * writer, guint8 value, guint size)
|
||||||
{
|
{
|
||||||
|
|
@ -431,16 +402,9 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint size)
|
||||||
|
|
||||||
#define fpi_byte_writer_put_data(writer, data, size) \
|
#define fpi_byte_writer_put_data(writer, data, size) \
|
||||||
G_LIKELY (fpi_byte_writer_put_data_inline (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) \
|
#define fpi_byte_writer_fill(writer, val, size) \
|
||||||
G_LIKELY (fpi_byte_writer_fill_inline (writer, val, size))
|
G_LIKELY (fpi_byte_writer_fill_inline (writer, val, size))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiByteWriter, fpi_byte_writer_free);
|
|
||||||
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (FpiByteWriter, fpi_byte_writer_reset);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,25 @@
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 57, 0)
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GTypeClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GFlagsClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref);
|
||||||
|
#else
|
||||||
|
/* Re-define G_SOURCE_FUNC as we are technically not allowed to use it with
|
||||||
|
* the version we depend on currently. */
|
||||||
|
#undef G_SOURCE_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void))(f))
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 63, 3)
|
||||||
|
typedef struct _FpDeviceClass FpDeviceClass;
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpDeviceClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GDate, g_date_free);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __GNUC__ > 10 || (__GNUC__ == 10 && __GNUC_MINOR__ >= 1)
|
#if __GNUC__ > 10 || (__GNUC__ == 10 && __GNUC_MINOR__ >= 1)
|
||||||
#define FP_GNUC_ACCESS(m, p, s) __attribute__((access (m, p, s)))
|
#define FP_GNUC_ACCESS(m, p, s) __attribute__((access (m, p, s)))
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#define FP_COMPONENT "device"
|
#define FP_COMPONENT "device"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
|
|
||||||
|
|
@ -52,7 +51,6 @@ fp_device_get_instance_private (FpDevice *self)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_class_auto_initialize_features:
|
* fpi_device_class_auto_initialize_features:
|
||||||
* @device_class: An #FpDeviceClass to initialize
|
|
||||||
*
|
*
|
||||||
* Initializes the #FpDeviceClass @features flags checking what device vfuncs
|
* Initializes the #FpDeviceClass @features flags checking what device vfuncs
|
||||||
* are implemented.
|
* are implemented.
|
||||||
|
|
@ -118,10 +116,6 @@ fpi_device_retry_new (FpDeviceRetry error)
|
||||||
msg = "Please try again after removing the finger first.";
|
msg = "Please try again after removing the finger first.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_RETRY_TOO_FAST:
|
|
||||||
msg = "The swipe was too fast, please try again.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warning ("Unsupported error, returning general error instead!");
|
g_warning ("Unsupported error, returning general error instead!");
|
||||||
error = FP_DEVICE_RETRY_GENERAL;
|
error = FP_DEVICE_RETRY_GENERAL;
|
||||||
|
|
@ -527,6 +521,33 @@ fpi_device_get_driver_data (FpDevice *device)
|
||||||
return priv->driver_data;
|
return priv->driver_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enroll_data_free (FpEnrollData *data)
|
||||||
|
{
|
||||||
|
if (data->enroll_progress_destroy)
|
||||||
|
data->enroll_progress_destroy (data->enroll_progress_data);
|
||||||
|
data->enroll_progress_data = NULL;
|
||||||
|
g_clear_object (&data->print);
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
match_data_free (FpMatchData *data)
|
||||||
|
{
|
||||||
|
g_clear_object (&data->print);
|
||||||
|
g_clear_object (&data->match);
|
||||||
|
g_clear_error (&data->error);
|
||||||
|
|
||||||
|
if (data->match_destroy)
|
||||||
|
data->match_destroy (data->match_data);
|
||||||
|
data->match_data = NULL;
|
||||||
|
|
||||||
|
g_clear_object (&data->enrolled_print);
|
||||||
|
g_clear_pointer (&data->gallery, g_ptr_array_unref);
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_get_enroll_data:
|
* fpi_device_get_enroll_data:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
|
|
@ -600,14 +621,7 @@ fpi_device_get_verify_data (FpDevice *device,
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @prints: (out) (transfer none) (element-type FpPrint): The gallery of prints
|
* @prints: (out) (transfer none) (element-type FpPrint): The gallery of prints
|
||||||
*
|
*
|
||||||
* Get prints gallery for identification.
|
* Get data for identify.
|
||||||
*
|
|
||||||
* The @prints array is always non-%NULL and may contain a list of #FpPrint's
|
|
||||||
* that the device should match against.
|
|
||||||
*
|
|
||||||
* Note that @prints can be an empty array, in such case the device is expected
|
|
||||||
* to report the scanned print matching the one in its internal storage, if any.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_get_identify_data (FpDevice *device,
|
fpi_device_get_identify_data (FpDevice *device,
|
||||||
|
|
@ -852,16 +866,16 @@ fpi_device_critical_section_flush_idle_cb (FpDevice *device)
|
||||||
|
|
||||||
if (priv->suspend_queued)
|
if (priv->suspend_queued)
|
||||||
{
|
{
|
||||||
|
cls->suspend (device);
|
||||||
priv->suspend_queued = FALSE;
|
priv->suspend_queued = FALSE;
|
||||||
fpi_device_suspend (device);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->resume_queued)
|
if (priv->resume_queued)
|
||||||
{
|
{
|
||||||
|
cls->resume (device);
|
||||||
priv->resume_queued = FALSE;
|
priv->resume_queued = FALSE;
|
||||||
fpi_device_resume (device);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
@ -898,7 +912,6 @@ fpi_device_critical_leave (FpDevice *device)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
priv->critical_section_flush_source = g_idle_source_new ();
|
priv->critical_section_flush_source = g_idle_source_new ();
|
||||||
g_source_set_priority (priv->critical_section_flush_source, G_PRIORITY_HIGH);
|
|
||||||
g_source_set_callback (priv->critical_section_flush_source,
|
g_source_set_callback (priv->critical_section_flush_source,
|
||||||
(GSourceFunc) fpi_device_critical_section_flush_idle_cb,
|
(GSourceFunc) fpi_device_critical_section_flush_idle_cb,
|
||||||
device,
|
device,
|
||||||
|
|
@ -1047,41 +1060,34 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
|
||||||
static void
|
static void
|
||||||
fpi_device_task_return_data_free (FpDeviceTaskReturnData *data)
|
fpi_device_task_return_data_free (FpDeviceTaskReturnData *data)
|
||||||
{
|
{
|
||||||
switch (data->type)
|
if (data->result)
|
||||||
{
|
{
|
||||||
case FP_DEVICE_TASK_RETURN_INT:
|
switch (data->type)
|
||||||
case FP_DEVICE_TASK_RETURN_BOOL:
|
{
|
||||||
break;
|
case FP_DEVICE_TASK_RETURN_INT:
|
||||||
|
case FP_DEVICE_TASK_RETURN_BOOL:
|
||||||
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_OBJECT:
|
case FP_DEVICE_TASK_RETURN_OBJECT:
|
||||||
g_clear_object ((GObject **) &data->result);
|
g_clear_object ((GObject **) &data->result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
case FP_DEVICE_TASK_RETURN_PTR_ARRAY:
|
||||||
g_clear_pointer ((GPtrArray **) &data->result, g_ptr_array_unref);
|
g_clear_pointer ((GPtrArray **) &data->result, g_ptr_array_unref);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_DEVICE_TASK_RETURN_ERROR:
|
case FP_DEVICE_TASK_RETURN_ERROR:
|
||||||
g_clear_error ((GError **) &data->result);
|
g_clear_error ((GError **) &data->result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (data->device);
|
g_object_unref (data->device);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_device_return_task_in_idle:
|
|
||||||
* @device: The #FpDevice
|
|
||||||
* @return_type: The #FpDeviceTaskReturnType of @return_data
|
|
||||||
* @return_data: (nullable) (transfer full): The data to return.
|
|
||||||
*
|
|
||||||
* Completes a #FpDevice task in an idle source, stealing the ownership of
|
|
||||||
* the passed @returned_data.
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
fpi_device_return_task_in_idle (FpDevice *device,
|
fpi_device_return_task_in_idle (FpDevice *device,
|
||||||
FpDeviceTaskReturnType return_type,
|
FpDeviceTaskReturnType return_type,
|
||||||
|
|
@ -1113,7 +1119,7 @@ fpi_device_return_task_in_idle (FpDevice *device,
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @device_id: Unique ID for the device or %NULL
|
* @device_id: Unique ID for the device or %NULL
|
||||||
* @device_name: Human readable name or %NULL for driver name
|
* @device_name: Human readable name or %NULL for driver name
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing probe operation. If error is %NULL success is assumed.
|
* Finish an ongoing probe operation. If error is %NULL success is assumed.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1159,7 +1165,7 @@ fpi_device_probe_complete (FpDevice *device,
|
||||||
/**
|
/**
|
||||||
* fpi_device_open_complete:
|
* fpi_device_open_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing open operation. If error is %NULL success is assumed.
|
* Finish an ongoing open operation. If error is %NULL success is assumed.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1186,7 +1192,7 @@ fpi_device_open_complete (FpDevice *device, GError *error)
|
||||||
/**
|
/**
|
||||||
* fpi_device_close_complete:
|
* fpi_device_close_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing close operation. If error is %NULL success is assumed.
|
* Finish an ongoing close operation. If error is %NULL success is assumed.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1238,7 +1244,7 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
||||||
* fpi_device_enroll_complete:
|
* fpi_device_enroll_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @print: (nullable) (transfer full): The #FpPrint or %NULL on failure
|
* @print: (nullable) (transfer full): The #FpPrint or %NULL on failure
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing enroll operation. The #FpPrint can be stored by the
|
* Finish an ongoing enroll operation. The #FpPrint can be stored by the
|
||||||
* caller for later verification.
|
* caller for later verification.
|
||||||
|
|
@ -1304,14 +1310,12 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: A #GError if result is %FPI_MATCH_ERROR
|
* @error: A #GError if result is %FPI_MATCH_ERROR
|
||||||
*
|
*
|
||||||
* Finish an ongoing verify operation.
|
* Finish an ongoing verify operation. The returned print should be
|
||||||
|
* representing the new scan and not the one passed for verification.
|
||||||
*
|
*
|
||||||
* Note that @error should only be set for actual errors. In the case
|
* Note that @error should only be set for actual errors. In the case
|
||||||
* of retry errors, report these using fpi_device_verify_report()
|
* of retry errors, report these using fpi_device_verify_report()
|
||||||
* and then call this function without any error argument.
|
* and then call this function without any error argument.
|
||||||
*
|
|
||||||
* If @error is not set, we expect that a result (and print, in case)
|
|
||||||
* have been already reported via fpi_device_verify_report().
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_verify_complete (FpDevice *device,
|
fpi_device_verify_complete (FpDevice *device,
|
||||||
|
|
@ -1367,16 +1371,11 @@ fpi_device_verify_complete (FpDevice *device,
|
||||||
/**
|
/**
|
||||||
* fpi_device_identify_complete:
|
* fpi_device_identify_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing identify operation.
|
* Finish an ongoing identify operation. The match that was identified is
|
||||||
*
|
* returned in @match. The @print parameter returns the newly created scan
|
||||||
* Note that @error should only be set for actual errors. In the case
|
* that was used for matching.
|
||||||
* of retry errors, report these using fpi_device_identify_report()
|
|
||||||
* and then call this function without any error argument.
|
|
||||||
*
|
|
||||||
* If @error is not set, we expect that a match and / or a print have been
|
|
||||||
* already reported via fpi_device_identify_report()
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_identify_complete (FpDevice *device,
|
fpi_device_identify_complete (FpDevice *device,
|
||||||
|
|
@ -1433,7 +1432,7 @@ fpi_device_identify_complete (FpDevice *device,
|
||||||
* fpi_device_capture_complete:
|
* fpi_device_capture_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @image: The #FpImage, or %NULL on error
|
* @image: The #FpImage, or %NULL on error
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing capture operation.
|
* Finish an ongoing capture operation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1480,7 +1479,7 @@ fpi_device_capture_complete (FpDevice *device,
|
||||||
/**
|
/**
|
||||||
* fpi_device_delete_complete:
|
* fpi_device_delete_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing delete operation.
|
* Finish an ongoing delete operation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1509,7 +1508,7 @@ fpi_device_delete_complete (FpDevice *device,
|
||||||
* fpi_device_list_complete:
|
* fpi_device_list_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @prints: (element-type FpPrint) (transfer container): Possibly empty array of prints or %NULL on error
|
* @prints: (element-type FpPrint) (transfer container): Possibly empty array of prints or %NULL on error
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing list operation.
|
* Finish an ongoing list operation.
|
||||||
*
|
*
|
||||||
|
|
@ -1551,150 +1550,6 @@ fpi_device_list_complete (FpDevice *device,
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
update_attr (const char *attr, const char *value)
|
|
||||||
{
|
|
||||||
int fd, err;
|
|
||||||
gssize r;
|
|
||||||
char buf[50] = { 0 };
|
|
||||||
|
|
||||||
fd = open (attr, O_RDONLY);
|
|
||||||
err = -errno;
|
|
||||||
if (fd < 0)
|
|
||||||
return -err;
|
|
||||||
|
|
||||||
r = read (fd, buf, sizeof (buf) - 1);
|
|
||||||
err = errno;
|
|
||||||
close (fd);
|
|
||||||
if (r < 0)
|
|
||||||
return -err;
|
|
||||||
|
|
||||||
g_strchomp (buf);
|
|
||||||
if (g_strcmp0 (buf, value) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* O_TRUNC makes things work in the umockdev environment */
|
|
||||||
fd = open (attr, O_WRONLY | O_TRUNC);
|
|
||||||
err = errno;
|
|
||||||
if (fd < 0)
|
|
||||||
return -err;
|
|
||||||
|
|
||||||
r = write (fd, value, strlen (value));
|
|
||||||
err = -errno;
|
|
||||||
close (fd);
|
|
||||||
if (r < 0)
|
|
||||||
{
|
|
||||||
/* Write failures are weird, and are worth a warning */
|
|
||||||
g_warning ("Could not write %s to %s", value, attr);
|
|
||||||
return -err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
complete_suspend_resume_task (FpDevice *device)
|
|
||||||
{
|
|
||||||
g_autoptr(GTask) task = NULL;
|
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
|
||||||
|
|
||||||
g_assert (priv->suspend_resume_task);
|
|
||||||
task = g_steal_pointer (&priv->suspend_resume_task);
|
|
||||||
|
|
||||||
g_task_return_boolean (task, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fpi_device_suspend (FpDevice *device)
|
|
||||||
{
|
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
|
||||||
|
|
||||||
/* If the device is currently idle, just complete immediately.
|
|
||||||
* For long running tasks, call the driver handler right away, for short
|
|
||||||
* tasks, wait for completion and then return the task.
|
|
||||||
*/
|
|
||||||
switch (priv->current_action)
|
|
||||||
{
|
|
||||||
case FPI_DEVICE_ACTION_NONE:
|
|
||||||
fpi_device_suspend_complete (device, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPI_DEVICE_ACTION_ENROLL:
|
|
||||||
case FPI_DEVICE_ACTION_VERIFY:
|
|
||||||
case FPI_DEVICE_ACTION_IDENTIFY:
|
|
||||||
case FPI_DEVICE_ACTION_CAPTURE:
|
|
||||||
if (FP_DEVICE_GET_CLASS (device)->suspend)
|
|
||||||
{
|
|
||||||
if (priv->critical_section)
|
|
||||||
priv->suspend_queued = TRUE;
|
|
||||||
else
|
|
||||||
FP_DEVICE_GET_CLASS (device)->suspend (device);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
case FPI_DEVICE_ACTION_PROBE:
|
|
||||||
case FPI_DEVICE_ACTION_OPEN:
|
|
||||||
case FPI_DEVICE_ACTION_CLOSE:
|
|
||||||
case FPI_DEVICE_ACTION_DELETE:
|
|
||||||
case FPI_DEVICE_ACTION_LIST:
|
|
||||||
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
|
|
||||||
g_signal_connect_object (priv->current_task,
|
|
||||||
"notify::completed",
|
|
||||||
G_CALLBACK (complete_suspend_resume_task),
|
|
||||||
device,
|
|
||||||
G_CONNECT_SWAPPED);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fpi_device_resume (FpDevice *device)
|
|
||||||
{
|
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
|
||||||
|
|
||||||
switch (priv->current_action)
|
|
||||||
{
|
|
||||||
case FPI_DEVICE_ACTION_NONE:
|
|
||||||
fpi_device_resume_complete (device, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPI_DEVICE_ACTION_ENROLL:
|
|
||||||
case FPI_DEVICE_ACTION_VERIFY:
|
|
||||||
case FPI_DEVICE_ACTION_IDENTIFY:
|
|
||||||
case FPI_DEVICE_ACTION_CAPTURE:
|
|
||||||
if (FP_DEVICE_GET_CLASS (device)->resume)
|
|
||||||
{
|
|
||||||
if (priv->critical_section)
|
|
||||||
priv->resume_queued = TRUE;
|
|
||||||
else
|
|
||||||
FP_DEVICE_GET_CLASS (device)->resume (device);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
case FPI_DEVICE_ACTION_PROBE:
|
|
||||||
case FPI_DEVICE_ACTION_OPEN:
|
|
||||||
case FPI_DEVICE_ACTION_CLOSE:
|
|
||||||
case FPI_DEVICE_ACTION_DELETE:
|
|
||||||
case FPI_DEVICE_ACTION_LIST:
|
|
||||||
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
|
|
||||||
/* cannot happen as we make sure these tasks complete before suspend */
|
|
||||||
g_assert_not_reached ();
|
|
||||||
complete_suspend_resume_task (device);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
|
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
|
||||||
{
|
{
|
||||||
|
|
@ -1705,38 +1560,42 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
|
||||||
case FP_DEVICE_TYPE_USB:
|
case FP_DEVICE_TYPE_USB:
|
||||||
{
|
{
|
||||||
g_autoptr(GString) ports = NULL;
|
g_autoptr(GString) ports = NULL;
|
||||||
g_autoptr(GUsbDevice) dev = NULL;
|
GUsbDevice *dev, *parent;
|
||||||
const char *wakeup_command = enabled ? "enabled" : "disabled";
|
const char *wakeup_command = enabled ? "enabled" : "disabled";
|
||||||
guint8 bus;
|
guint8 bus, port;
|
||||||
g_autofree gchar *sysfs_wakeup = NULL;
|
g_autofree gchar *sysfs_wakeup = NULL;
|
||||||
g_autofree gchar *sysfs_persist = NULL;
|
g_autofree gchar *sysfs_persist = NULL;
|
||||||
int res;
|
gssize r;
|
||||||
|
int fd;
|
||||||
|
|
||||||
ports = g_string_new (NULL);
|
ports = g_string_new (NULL);
|
||||||
bus = g_usb_device_get_bus (priv->usb_device);
|
bus = g_usb_device_get_bus (priv->usb_device);
|
||||||
|
|
||||||
/* Walk up, skipping the root hub. */
|
/* Walk up, skipping the root hub. */
|
||||||
g_set_object (&dev, priv->usb_device);
|
dev = priv->usb_device;
|
||||||
while (TRUE)
|
while ((parent = g_usb_device_get_parent (dev)))
|
||||||
{
|
{
|
||||||
g_autoptr(GUsbDevice) parent = g_usb_device_get_parent (dev);
|
|
||||||
g_autofree gchar *port_str = NULL;
|
|
||||||
guint8 port;
|
|
||||||
|
|
||||||
if (!parent)
|
|
||||||
break;
|
|
||||||
|
|
||||||
port = g_usb_device_get_port_number (dev);
|
port = g_usb_device_get_port_number (dev);
|
||||||
port_str = g_strdup_printf ("%d.", port);
|
g_string_prepend (ports, g_strdup_printf ("%d.", port));
|
||||||
g_string_prepend (ports, port_str);
|
dev = parent;
|
||||||
g_set_object (&dev, parent);
|
|
||||||
}
|
}
|
||||||
g_string_set_size (ports, ports->len - 1);
|
g_string_set_size (ports, ports->len - 1);
|
||||||
|
|
||||||
sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str);
|
sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str);
|
||||||
res = update_attr (sysfs_wakeup, wakeup_command);
|
fd = open (sysfs_wakeup, O_WRONLY);
|
||||||
if (res < 0)
|
|
||||||
g_debug ("Failed to set %s to %s", sysfs_wakeup, wakeup_command);
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
/* Wakeup not existing appears to be relatively normal. */
|
||||||
|
g_debug ("Failed to open %s", sysfs_wakeup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = write (fd, wakeup_command, strlen (wakeup_command));
|
||||||
|
if (r < 0)
|
||||||
|
g_warning ("Could not configure wakeup to %s by writing %s", wakeup_command, sysfs_wakeup);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
/* Persist means that the kernel tries to keep the USB device open
|
/* Persist means that the kernel tries to keep the USB device open
|
||||||
* in case it is "replugged" due to suspend.
|
* in case it is "replugged" due to suspend.
|
||||||
|
|
@ -1744,9 +1603,20 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
|
||||||
* state. Instead, seeing an unplug and a new device makes more sense.
|
* state. Instead, seeing an unplug and a new device makes more sense.
|
||||||
*/
|
*/
|
||||||
sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str);
|
sysfs_persist = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/persist", bus, ports->str);
|
||||||
res = update_attr (sysfs_persist, "0");
|
fd = open (sysfs_persist, O_WRONLY);
|
||||||
if (res < 0)
|
|
||||||
g_warning ("Failed to disable USB persist by writing to %s", sysfs_persist);
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to open %s", sysfs_persist);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = write (fd, "0", 1);
|
||||||
|
if (r < 0)
|
||||||
|
g_message ("Could not disable USB persist by writing to %s", sysfs_persist);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1766,7 +1636,6 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
|
||||||
static void
|
static void
|
||||||
fpi_device_suspend_completed (FpDevice *device)
|
fpi_device_suspend_completed (FpDevice *device)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
/* We have an ongoing operation, allow the device to wake up the machine. */
|
/* We have an ongoing operation, allow the device to wake up the machine. */
|
||||||
|
|
@ -1776,18 +1645,17 @@ fpi_device_suspend_completed (FpDevice *device)
|
||||||
if (priv->critical_section)
|
if (priv->critical_section)
|
||||||
g_warning ("Driver was in a critical section at suspend time. It likely deadlocked!");
|
g_warning ("Driver was in a critical section at suspend time. It likely deadlocked!");
|
||||||
|
|
||||||
task = g_steal_pointer (&priv->suspend_resume_task);
|
|
||||||
|
|
||||||
if (priv->suspend_error)
|
if (priv->suspend_error)
|
||||||
g_task_return_error (task, g_steal_pointer (&priv->suspend_error));
|
g_task_return_error (g_steal_pointer (&priv->suspend_resume_task),
|
||||||
|
g_steal_pointer (&priv->suspend_error));
|
||||||
else
|
else
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_suspend_complete:
|
* fpi_device_suspend_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish a suspend request. Only return a %NULL error if suspend has been
|
* Finish a suspend request. Only return a %NULL error if suspend has been
|
||||||
* correctly configured and the current action as returned by
|
* correctly configured and the current action as returned by
|
||||||
|
|
@ -1797,7 +1665,7 @@ fpi_device_suspend_completed (FpDevice *device)
|
||||||
* current action will be cancelled before the error is forwarded to the
|
* current action will be cancelled before the error is forwarded to the
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* It is recommended to set @error to #FP_DEVICE_ERROR_NOT_SUPPORTED.
|
* It is recommended to set @error to #FP_ERROR_NOT_IMPLEMENTED.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_suspend_complete (FpDevice *device,
|
fpi_device_suspend_complete (FpDevice *device,
|
||||||
|
|
@ -1809,12 +1677,11 @@ fpi_device_suspend_complete (FpDevice *device,
|
||||||
g_return_if_fail (priv->suspend_resume_task);
|
g_return_if_fail (priv->suspend_resume_task);
|
||||||
g_return_if_fail (priv->suspend_error == NULL);
|
g_return_if_fail (priv->suspend_error == NULL);
|
||||||
|
|
||||||
priv->suspend_error = g_steal_pointer (&error);
|
priv->suspend_error = error;
|
||||||
priv->is_suspended = TRUE;
|
priv->is_suspended = TRUE;
|
||||||
|
|
||||||
/* If there is no error, we have no running task, return immediately. */
|
/* If there is no error, we have no running task, return immediately. */
|
||||||
if (!priv->suspend_error || !priv->current_task ||
|
if (error == NULL || !priv->current_task || g_task_get_completed (priv->current_task))
|
||||||
g_task_get_completed (priv->current_task))
|
|
||||||
{
|
{
|
||||||
fpi_device_suspend_completed (device);
|
fpi_device_suspend_completed (device);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1838,7 +1705,7 @@ fpi_device_suspend_complete (FpDevice *device,
|
||||||
/**
|
/**
|
||||||
* fpi_device_resume_complete:
|
* fpi_device_resume_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish a resume request.
|
* Finish a resume request.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1846,7 +1713,6 @@ void
|
||||||
fpi_device_resume_complete (FpDevice *device,
|
fpi_device_resume_complete (FpDevice *device,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
|
@ -1855,18 +1721,16 @@ fpi_device_resume_complete (FpDevice *device,
|
||||||
priv->is_suspended = FALSE;
|
priv->is_suspended = FALSE;
|
||||||
fpi_device_configure_wakeup (device, FALSE);
|
fpi_device_configure_wakeup (device, FALSE);
|
||||||
|
|
||||||
task = g_steal_pointer (&priv->suspend_resume_task);
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (g_steal_pointer (&priv->suspend_resume_task), error);
|
||||||
else
|
else
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_clear_storage_complete:
|
* fpi_device_clear_storage_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing clear_storage operation.
|
* Finish an ongoing clear_storage operation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1897,7 +1761,7 @@ fpi_device_clear_storage_complete (FpDevice *device,
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @completed_stages: The number of stages that are completed at this point
|
* @completed_stages: The number of stages that are completed at this point
|
||||||
* @print: (transfer floating): The #FpPrint for the newly completed stage or %NULL on failure
|
* @print: (transfer floating): The #FpPrint for the newly completed stage or %NULL on failure
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: (transfer full): The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Notify about the progress of the enroll operation. This is important for UI interaction.
|
* Notify about the progress of the enroll operation. This is important for UI interaction.
|
||||||
* The passed error may be used if a scan needs to be retried, use fpi_device_retry_new().
|
* The passed error may be used if a scan needs to be retried, use fpi_device_retry_new().
|
||||||
|
|
@ -2017,26 +1881,12 @@ fpi_device_verify_report (FpDevice *device,
|
||||||
* fpi_device_identify_report:
|
* fpi_device_identify_report:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @match: (transfer none): The #FpPrint from the gallery that matched
|
* @match: (transfer none): The #FpPrint from the gallery that matched
|
||||||
* @print: (transfer floating): The scanned #FpPrint, set in the absence
|
* @print: (transfer floating): The scanned #FpPrint
|
||||||
* of an error.
|
* @error: A #GError if result is %FPI_MATCH_ERROR
|
||||||
* @error: A #GError of %FP_DEVICE_RETRY type if @match and @print are unset.
|
|
||||||
*
|
*
|
||||||
* Report the results of an identify operation.
|
* Report the result of a identify operation. Note that the passed @error must be
|
||||||
*
|
* a retry error with the %FP_DEVICE_RETRY domain. For all other error cases,
|
||||||
* In case of successful identification @match is expected to be set to a
|
* the error should passed to fpi_device_identify_complete().
|
||||||
* #FpPrint that matches one from the provided gallery, while @print
|
|
||||||
* represents the scanned print and will be different.
|
|
||||||
*
|
|
||||||
* If there are no errors, it's expected that the device always reports the
|
|
||||||
* recognized @print even if there is no @match with the provided gallery (that
|
|
||||||
* can be potentially empty). This is required for application logic further
|
|
||||||
* up in the stack, such as for enroll-duplicate checking. @print needs to be
|
|
||||||
* sufficiently filled to do a comparison.
|
|
||||||
*
|
|
||||||
* In case of error, both @match and @print are expected to be %NULL.
|
|
||||||
* Note that the passed @error must be a retry error from the %FP_DEVICE_RETRY
|
|
||||||
* domain. For all other error cases, the error should passed to
|
|
||||||
* fpi_device_identify_complete().
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_identify_report (FpDevice *device,
|
fpi_device_identify_report (FpDevice *device,
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,9 @@
|
||||||
#include "fpi-print.h"
|
#include "fpi-print.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpiDeviceUdevSubtypeFlags:
|
* FpiDeviceUdevSubtype:
|
||||||
* @FPI_DEVICE_UDEV_SUBTYPE_SPIDEV: The device requires an spidev node
|
* @FPI_DEVICE_UDEV_SUBTYPE_SPIDEV: The device requires an spidev node
|
||||||
* @FPI_DEVICE_UDEV_SUBTYPE_HIDRAW: The device requires a hidraw node
|
* @FPI_DEVICE_UDEV_SUBTYPE_HIDRAW: The device requires a hidraw node
|
||||||
*
|
|
||||||
* Bitfield of required hardware resources for a udev-backed device.
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FPI_DEVICE_UDEV_SUBTYPE_SPIDEV = 1 << 0,
|
FPI_DEVICE_UDEV_SUBTYPE_SPIDEV = 1 << 0,
|
||||||
|
|
@ -38,13 +36,6 @@ typedef enum {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FpIdEntry:
|
* FpIdEntry:
|
||||||
* @pid: The USB product ID (for USB devices)
|
|
||||||
* @vid: The USB vendor ID (for USB devices)
|
|
||||||
* @virtual_envvar: Environment variable name (for virtual devices)
|
|
||||||
* @driver_data: Optional driver-specific data, defaults to 0
|
|
||||||
* @udev_types: Subtypes for udev-based devices
|
|
||||||
* @spi_acpi_id: ACPI ID (for SPI devices)
|
|
||||||
* @hid_id: HID device identifier (for HID devices)
|
|
||||||
*
|
*
|
||||||
* An entry in the table of supported hardware. For USB devices, the product ID
|
* An entry in the table of supported hardware. For USB devices, the product ID
|
||||||
* and vendor ID should be provided. The optional @driver_data field defaults
|
* and vendor ID should be provided. The optional @driver_data field defaults
|
||||||
|
|
|
||||||
|
|
@ -565,7 +565,7 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
|
||||||
/**
|
/**
|
||||||
* fpi_image_device_session_error:
|
* fpi_image_device_session_error:
|
||||||
* @self: a #FpImageDevice imaging fingerprint device
|
* @self: a #FpImageDevice imaging fingerprint device
|
||||||
* @error: (nullable) (transfer full): The #GError to report.
|
* @error: The #GError to report
|
||||||
*
|
*
|
||||||
* Report an error while interacting with the device. This effectively
|
* Report an error while interacting with the device. This effectively
|
||||||
* aborts the current ongoing action. Note that doing so will result in
|
* aborts the current ongoing action. Note that doing so will result in
|
||||||
|
|
@ -624,7 +624,7 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
||||||
/**
|
/**
|
||||||
* fpi_image_device_activate_complete:
|
* fpi_image_device_activate_complete:
|
||||||
* @self: a #FpImageDevice imaging fingerprint device
|
* @self: a #FpImageDevice imaging fingerprint device
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: A #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Reports completion of device activation.
|
* Reports completion of device activation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -663,7 +663,7 @@ fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
|
||||||
/**
|
/**
|
||||||
* fpi_image_device_deactivate_complete:
|
* fpi_image_device_deactivate_complete:
|
||||||
* @self: a #FpImageDevice imaging fingerprint device
|
* @self: a #FpImageDevice imaging fingerprint device
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: A #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Reports completion of device deactivation.
|
* Reports completion of device deactivation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -690,7 +690,7 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
|
||||||
/**
|
/**
|
||||||
* fpi_image_device_open_complete:
|
* fpi_image_device_open_complete:
|
||||||
* @self: a #FpImageDevice imaging fingerprint device
|
* @self: a #FpImageDevice imaging fingerprint device
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: A #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Reports completion of open operation.
|
* Reports completion of open operation.
|
||||||
*/
|
*/
|
||||||
|
|
@ -718,7 +718,7 @@ fpi_image_device_open_complete (FpImageDevice *self, GError *error)
|
||||||
/**
|
/**
|
||||||
* fpi_image_device_close_complete:
|
* fpi_image_device_close_complete:
|
||||||
* @self: a #FpImageDevice imaging fingerprint device
|
* @self: a #FpImageDevice imaging fingerprint device
|
||||||
* @error: (nullable) (transfer full): The #GError or %NULL on success
|
* @error: A #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Reports completion of close operation.
|
* Reports completion of close operation.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,8 @@
|
||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
|
|
||||||
#include <nbis.h>
|
#include <nbis.h>
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_PIXMAN
|
#if HAVE_PIXMAN
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -108,12 +107,12 @@ fpi_mean_sq_diff_norm (const guint8 *buf1,
|
||||||
return res / size;
|
return res / size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_PIXMAN
|
||||||
FpImage *
|
FpImage *
|
||||||
fpi_image_resize (FpImage *orig_img,
|
fpi_image_resize (FpImage *orig_img,
|
||||||
guint w_factor,
|
guint w_factor,
|
||||||
guint h_factor)
|
guint h_factor)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_PIXMAN
|
|
||||||
int new_width = orig_img->width * w_factor;
|
int new_width = orig_img->width * w_factor;
|
||||||
int new_height = orig_img->height * h_factor;
|
int new_height = orig_img->height * h_factor;
|
||||||
pixman_image_t *orig, *resized;
|
pixman_image_t *orig, *resized;
|
||||||
|
|
@ -146,9 +145,5 @@ fpi_image_resize (FpImage *orig_img,
|
||||||
pixman_image_unref (resized);
|
pixman_image_unref (resized);
|
||||||
|
|
||||||
return newimg;
|
return newimg;
|
||||||
#else
|
|
||||||
fp_err ("Libfprint compiled without pixman support, impossible to resize");
|
|
||||||
|
|
||||||
return g_object_ref (orig_img);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
#include "fp-image.h"
|
#include "fp-image.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,14 +28,12 @@
|
||||||
* @FPI_IMAGE_V_FLIPPED: the image is vertically flipped
|
* @FPI_IMAGE_V_FLIPPED: the image is vertically flipped
|
||||||
* @FPI_IMAGE_H_FLIPPED: the image is horizontally flipped
|
* @FPI_IMAGE_H_FLIPPED: the image is horizontally flipped
|
||||||
* @FPI_IMAGE_COLORS_INVERTED: the colours are inverted
|
* @FPI_IMAGE_COLORS_INVERTED: the colours are inverted
|
||||||
* @FPI_IMAGE_PARTIAL: the image is a partial scan
|
|
||||||
*
|
*
|
||||||
* Flags used in an #FpImage structure to describe the contained image.
|
* Flags used in an #FpImage structure to describe the contained image.
|
||||||
* This is useful for image drivers as they can simply set these flags and
|
* This is useful for image drivers as they can simply set these flags and
|
||||||
* rely on the image to be normalized by libfprint before further processing.
|
* rely on the image to be normalized by libfprint before further processing.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FPI_IMAGE_NONE = 0,
|
|
||||||
FPI_IMAGE_V_FLIPPED = 1 << 0,
|
FPI_IMAGE_V_FLIPPED = 1 << 0,
|
||||||
FPI_IMAGE_H_FLIPPED = 1 << 1,
|
FPI_IMAGE_H_FLIPPED = 1 << 1,
|
||||||
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
|
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
|
||||||
|
|
@ -69,8 +68,7 @@ struct _FpImage
|
||||||
guint8 *binarized;
|
guint8 *binarized;
|
||||||
|
|
||||||
GPtrArray *minutiae;
|
GPtrArray *minutiae;
|
||||||
|
guint ref_count;
|
||||||
gboolean detection_in_progress;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gint fpi_std_sq_dev (const guint8 *buf,
|
gint fpi_std_sq_dev (const guint8 *buf,
|
||||||
|
|
@ -79,6 +77,8 @@ gint fpi_mean_sq_diff_norm (const guint8 *buf1,
|
||||||
const guint8 *buf2,
|
const guint8 *buf2,
|
||||||
gint size);
|
gint size);
|
||||||
|
|
||||||
|
#if HAVE_PIXMAN
|
||||||
FpImage *fpi_image_resize (FpImage *orig,
|
FpImage *fpi_image_resize (FpImage *orig,
|
||||||
guint w_factor,
|
guint w_factor,
|
||||||
guint h_factor);
|
guint h_factor);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -79,16 +79,13 @@
|
||||||
*
|
*
|
||||||
* Uses fp_err() to print an error if the @condition is true.
|
* Uses fp_err() to print an error if the @condition is true.
|
||||||
*/
|
*/
|
||||||
#define BUG_ON(condition) \
|
#define BUG_ON(condition) G_STMT_START \
|
||||||
G_STMT_START \
|
if (condition) { \
|
||||||
if (condition) \
|
|
||||||
{ \
|
|
||||||
char *s; \
|
char *s; \
|
||||||
s = g_strconcat ("BUG: (", #condition, ")", NULL); \
|
s = g_strconcat ("BUG: (", #condition, ")", NULL); \
|
||||||
fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \
|
fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \
|
||||||
g_free (s); \
|
g_free (s); \
|
||||||
} \
|
} G_STMT_END
|
||||||
G_STMT_END
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BUG:
|
* BUG:
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ fpi_print_add_print (FpPrint *print, FpPrint *add)
|
||||||
g_return_if_fail (add->type == FPI_PRINT_NBIS);
|
g_return_if_fail (add->type == FPI_PRINT_NBIS);
|
||||||
|
|
||||||
g_assert (add->prints->len == 1);
|
g_assert (add->prints->len == 1);
|
||||||
g_ptr_array_add (print->prints, g_memdup2 (add->prints->pdata[0], sizeof (struct xyt_struct)));
|
g_ptr_array_add (print->prints, g_memdup (add->prints->pdata[0], sizeof (struct xyt_struct)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -196,7 +196,7 @@ fpi_print_add_from_image (FpPrint *print,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_print_bz3_match:
|
* fpi_print_bz3_match:
|
||||||
* @print_template: A #FpPrint containing one or more prints
|
* @template: A #FpPrint containing one or more prints
|
||||||
* @print: A newly scanned #FpPrint to test
|
* @print: A newly scanned #FpPrint to test
|
||||||
* @bz3_threshold: The BZ3 match threshold
|
* @bz3_threshold: The BZ3 match threshold
|
||||||
* @error: Return location for error
|
* @error: Return location for error
|
||||||
|
|
@ -210,17 +210,14 @@ fpi_print_add_from_image (FpPrint *print,
|
||||||
* Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned
|
* Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned
|
||||||
*/
|
*/
|
||||||
FpiMatchResult
|
FpiMatchResult
|
||||||
fpi_print_bz3_match (FpPrint *print_template,
|
fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GError **error)
|
||||||
FpPrint *print,
|
|
||||||
gint bz3_threshold,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
struct xyt_struct *pstruct;
|
struct xyt_struct *pstruct;
|
||||||
gint probe_len;
|
gint probe_len;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
/* XXX: Use a different error type? */
|
/* XXX: Use a different error type? */
|
||||||
if (print_template->type != FPI_PRINT_NBIS || print->type != FPI_PRINT_NBIS)
|
if (template->type != FPI_PRINT_NBIS || print->type != FPI_PRINT_NBIS)
|
||||||
{
|
{
|
||||||
*error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
*error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
"It is only possible to match NBIS type print data");
|
"It is only possible to match NBIS type print data");
|
||||||
|
|
@ -237,11 +234,11 @@ fpi_print_bz3_match (FpPrint *print_template,
|
||||||
pstruct = g_ptr_array_index (print->prints, 0);
|
pstruct = g_ptr_array_index (print->prints, 0);
|
||||||
probe_len = bozorth_probe_init (pstruct);
|
probe_len = bozorth_probe_init (pstruct);
|
||||||
|
|
||||||
for (i = 0; i < print_template->prints->len; i++)
|
for (i = 0; i < template->prints->len; i++)
|
||||||
{
|
{
|
||||||
struct xyt_struct *gstruct;
|
struct xyt_struct *gstruct;
|
||||||
gint score;
|
gint score;
|
||||||
gstruct = g_ptr_array_index (print_template->prints, i);
|
gstruct = g_ptr_array_index (template->prints, i);
|
||||||
score = bozorth_to_gallery (probe_len, pstruct, gstruct);
|
score = bozorth_to_gallery (probe_len, pstruct, gstruct);
|
||||||
fp_dbg ("score %d/%d", score, bz3_threshold);
|
fp_dbg ("score %d/%d", score, bz3_threshold);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ gboolean fpi_print_add_from_image (FpPrint *print,
|
||||||
FpImage *image,
|
FpImage *image,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
FpiMatchResult fpi_print_bz3_match (FpPrint *print_template,
|
FpiMatchResult fpi_print_bz3_match (FpPrint * template,
|
||||||
FpPrint *print,
|
FpPrint * print,
|
||||||
gint bz3_threshold,
|
gint bz3_threshold,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
/* Helpers to encode metadata into user ID strings. */
|
/* Helpers to encode metadata into user ID strings. */
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
struct _FpiSsm
|
struct _FpiSsm
|
||||||
{
|
{
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
char *name;
|
const char *name;
|
||||||
FpiSsm *parentsm;
|
FpiSsm *parentsm;
|
||||||
gpointer ssm_data;
|
gpointer ssm_data;
|
||||||
GDestroyNotify ssm_data_destroy;
|
GDestroyNotify ssm_data_destroy;
|
||||||
|
|
@ -81,7 +81,6 @@ struct _FpiSsm
|
||||||
int start_cleanup;
|
int start_cleanup;
|
||||||
int cur_state;
|
int cur_state;
|
||||||
gboolean completed;
|
gboolean completed;
|
||||||
gboolean silence;
|
|
||||||
GSource *timeout;
|
GSource *timeout;
|
||||||
GError *error;
|
GError *error;
|
||||||
FpiSsmCompletedCallback callback;
|
FpiSsmCompletedCallback callback;
|
||||||
|
|
@ -246,11 +245,10 @@ fpi_ssm_free (FpiSsm *machine)
|
||||||
|
|
||||||
/* Invoke the state handler */
|
/* Invoke the state handler */
|
||||||
static void
|
static void
|
||||||
__ssm_call_handler (FpiSsm *machine, gboolean force_msg)
|
__ssm_call_handler (FpiSsm *machine)
|
||||||
{
|
{
|
||||||
if (force_msg || !machine->silence)
|
fp_dbg ("[%s] %s entering state %d", fp_device_get_driver (machine->dev),
|
||||||
fp_dbg ("[%s] %s entering state %d", fp_device_get_driver (machine->dev),
|
machine->name, machine->cur_state);
|
||||||
machine->name, machine->cur_state);
|
|
||||||
machine->handler (machine, machine->dev);
|
machine->handler (machine, machine->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +275,7 @@ fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
|
||||||
ssm->cur_state = 0;
|
ssm->cur_state = 0;
|
||||||
ssm->completed = FALSE;
|
ssm->completed = FALSE;
|
||||||
ssm->error = NULL;
|
ssm->error = NULL;
|
||||||
__ssm_call_handler (ssm, TRUE);
|
__ssm_call_handler (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -348,7 +346,7 @@ fpi_ssm_mark_completed (FpiSsm *machine)
|
||||||
if (next_state < machine->nr_states)
|
if (next_state < machine->nr_states)
|
||||||
{
|
{
|
||||||
machine->cur_state = next_state;
|
machine->cur_state = next_state;
|
||||||
__ssm_call_handler (machine, TRUE);
|
__ssm_call_handler (machine);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,7 +460,7 @@ fpi_ssm_next_state (FpiSsm *machine)
|
||||||
if (machine->cur_state == machine->nr_states)
|
if (machine->cur_state == machine->nr_states)
|
||||||
fpi_ssm_mark_completed (machine);
|
fpi_ssm_mark_completed (machine);
|
||||||
else
|
else
|
||||||
__ssm_call_handler (machine, FALSE);
|
__ssm_call_handler (machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -539,7 +537,7 @@ fpi_ssm_jump_to_state (FpiSsm *machine, int state)
|
||||||
if (machine->cur_state == machine->nr_states)
|
if (machine->cur_state == machine->nr_states)
|
||||||
fpi_ssm_mark_completed (machine);
|
fpi_ssm_mark_completed (machine);
|
||||||
else
|
else
|
||||||
__ssm_call_handler (machine, FALSE);
|
__ssm_call_handler (machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -644,22 +642,6 @@ fpi_ssm_dup_error (FpiSsm *machine)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_silence_debug:
|
|
||||||
* @machine: an #FpiSsm state machine
|
|
||||||
*
|
|
||||||
* Turn off state change debug messages from this SSM. This does not disable
|
|
||||||
* all messages, as e.g. the initial state, SSM completion and cleanup states
|
|
||||||
* are still printed out.
|
|
||||||
*
|
|
||||||
* Use if the SSM loops and would flood the debug log otherwise.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fpi_ssm_silence_debug (FpiSsm *machine)
|
|
||||||
{
|
|
||||||
machine->silence = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_ssm_usb_transfer_cb:
|
* fpi_ssm_usb_transfer_cb:
|
||||||
* @transfer: a #FpiUsbTransfer
|
* @transfer: a #FpiUsbTransfer
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,6 @@ GError * fpi_ssm_get_error (FpiSsm *machine);
|
||||||
GError * fpi_ssm_dup_error (FpiSsm *machine);
|
GError * fpi_ssm_dup_error (FpiSsm *machine);
|
||||||
int fpi_ssm_get_cur_state (FpiSsm *machine);
|
int fpi_ssm_get_cur_state (FpiSsm *machine);
|
||||||
|
|
||||||
void fpi_ssm_silence_debug (FpiSsm *machine);
|
|
||||||
|
|
||||||
/* Callbacks to be used by the driver instead of implementing their own
|
/* Callbacks to be used by the driver instead of implementing their own
|
||||||
* logic.
|
* logic.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -344,8 +344,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
|
||||||
{
|
{
|
||||||
error = g_error_new (G_USB_DEVICE_ERROR,
|
error = g_error_new (G_USB_DEVICE_ERROR,
|
||||||
G_USB_DEVICE_ERROR_IO,
|
G_USB_DEVICE_ERROR_IO,
|
||||||
"Unexpected short error of %zd size (expected %zd)",
|
"Unexpected short error of %zd size (expected %zd)", transfer->actual_length, transfer->length);
|
||||||
transfer->actual_length, transfer->length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
callback = transfer->callback;
|
callback = transfer->callback;
|
||||||
|
|
@ -549,23 +548,3 @@ fpi_usb_transfer_submit_sync (FpiUsbTransfer *transfer,
|
||||||
|
|
||||||
return res;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2025 Marco Trevisan <marco.trevisan@canonical.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glib.h"
|
|
||||||
#include "fpi-context.h"
|
|
||||||
#include "fpi-device.h"
|
|
||||||
|
|
||||||
#define METAINFO_BASE \
|
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
|
|
||||||
"<component>\n" \
|
|
||||||
" <id>org.freedesktop.libfprint</id>\n" \
|
|
||||||
" <name>libfprint</name>\n" \
|
|
||||||
" <metadata_license>CC0-1.0</metadata_license>\n" \
|
|
||||||
" <project_license>LGPL-2.1-or-later</project_license>\n" \
|
|
||||||
" <url type=\"homepage\">https://fprint.freedesktop.org</url>\n" \
|
|
||||||
" <url type=\"vcs-browser\">https://gitlab.freedesktop.org/libfprint/libfprint</url>\n" \
|
|
||||||
" <url type=\"help\">https://fprint.freedesktop.org/libfprint-dev</url>\n" \
|
|
||||||
" <url type=\"bugtracker\">https://gitlab.freedesktop.org/libfprint/libfprint/-/issues</url>\n" \
|
|
||||||
" <summary>Async fingerprint readers library</summary>\n" \
|
|
||||||
" <description>\n" \
|
|
||||||
" <p>\n" \
|
|
||||||
" The fprint project aims to support for consumer fingerprint reader devices.\n" \
|
|
||||||
" </p>\n" \
|
|
||||||
" </description>\n" \
|
|
||||||
" <provides>\n" \
|
|
||||||
"%s\n" \
|
|
||||||
" </provides>\n" \
|
|
||||||
"</component>\n"
|
|
||||||
|
|
||||||
static int
|
|
||||||
driver_compare (gconstpointer p1, gconstpointer p2)
|
|
||||||
{
|
|
||||||
g_autoptr(FpDeviceClass) cls1 = g_type_class_ref (*(GType *) p1);
|
|
||||||
g_autoptr(FpDeviceClass) cls2 = g_type_class_ref (*(GType *) p2);
|
|
||||||
|
|
||||||
return g_strcmp0 (cls1->id, cls2->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usb_driver_devices_append (GPtrArray *devices_list,
|
|
||||||
const FpDeviceClass *cls)
|
|
||||||
{
|
|
||||||
const FpIdEntry *entry;
|
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (entry = cls->id_table; entry->vid != 0; entry++)
|
|
||||||
{
|
|
||||||
if (entry->vid == 0 || entry->pid == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_ptr_array_add (devices_list,
|
|
||||||
g_strdup_printf ("v%04xp%04x", entry->vid, entry->pid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
g_autoptr(GPtrArray) devices_list = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
g_autoptr(GArray) drivers = fpi_get_driver_types ();
|
|
||||||
g_autoptr(GString) provided_modules = g_string_new (NULL);
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
g_array_sort (drivers, driver_compare);
|
|
||||||
|
|
||||||
for (guint i = 0; i < drivers->len; ++i)
|
|
||||||
{
|
|
||||||
GType driver = g_array_index (drivers, GType, i);
|
|
||||||
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
usb_driver_devices_append (devices_list, cls);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (guint i = 0; i < devices_list->len; ++i)
|
|
||||||
{
|
|
||||||
const char *device_id = g_ptr_array_index (devices_list, i);
|
|
||||||
|
|
||||||
g_string_append (provided_modules, " ");
|
|
||||||
g_string_append_printf (provided_modules, "<modalias>usb:%s*</modalias>",
|
|
||||||
device_id);
|
|
||||||
|
|
||||||
if (i < devices_list->len - 1)
|
|
||||||
g_string_append_c (provided_modules, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
g_print (METAINFO_BASE, provided_modules->str);
|
|
||||||
}
|
|
||||||
|
|
@ -110,7 +110,7 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
g_print ("%% libfprint — Supported Devices\n");
|
g_print ("%% lifprint — Supported Devices\n");
|
||||||
g_print ("%% Bastien Nocera, Daniel Drake\n");
|
g_print ("%% Bastien Nocera, Daniel Drake\n");
|
||||||
g_print ("%% 2018\n");
|
g_print ("%% 2018\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
|
|
@ -132,7 +132,7 @@ main (int argc, char **argv)
|
||||||
g_print ("%s", (char *) l->data);
|
g_print ("%s", (char *) l->data);
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
|
|
||||||
g_list_free_full (g_steal_pointer (&usb_list), g_free);
|
g_list_free_full (usb_list, g_free);
|
||||||
|
|
||||||
g_print ("## SPI devices\n");
|
g_print ("## SPI devices\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
|
|
@ -146,7 +146,7 @@ main (int argc, char **argv)
|
||||||
g_print ("%s", (char *) l->data);
|
g_print ("%s", (char *) l->data);
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
|
|
||||||
g_list_free_full (g_steal_pointer (&spi_list), g_free);
|
g_list_free_full (usb_list, g_free);
|
||||||
|
|
||||||
|
|
||||||
g_hash_table_destroy (printed);
|
g_hash_table_destroy (printed);
|
||||||
|
|
|
||||||
|
|
@ -24,62 +24,33 @@
|
||||||
#include "fpi-context.h"
|
#include "fpi-context.h"
|
||||||
#include "fpi-device.h"
|
#include "fpi-device.h"
|
||||||
|
|
||||||
static const FpIdEntry allowlist_id_table[] = {
|
static const FpIdEntry whitelist_id_table[] = {
|
||||||
/* Currently known and unsupported devices.
|
/* Currently known and unsupported devices.
|
||||||
* You can generate this list from the wiki page using e.g.:
|
* You can generate this list from the wiki page using e.g.:
|
||||||
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
|
* gio cat https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md | sed -n 's!|.*\([0-9a-fA-F]\{4\}\):\([0-9a-fA-F]\{4\}\).*|.*! { .vid = 0x\1, .pid = 0x\2 },!p'
|
||||||
*/
|
*/
|
||||||
{ .vid = 0x0a5c, .pid = 0x5802 },
|
|
||||||
{ .vid = 0x047d, .pid = 0x00f2 },
|
|
||||||
{ .vid = 0x047d, .pid = 0x8054 },
|
|
||||||
{ .vid = 0x047d, .pid = 0x8055 },
|
|
||||||
{ .vid = 0x04e8, .pid = 0x730b },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x036b },
|
{ .vid = 0x04f3, .pid = 0x036b },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c00 },
|
{ .vid = 0x04f3, .pid = 0x0c00 },
|
||||||
|
{ .vid = 0x04f3, .pid = 0x0c4b },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c4c },
|
{ .vid = 0x04f3, .pid = 0x0c4c },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c57 },
|
{ .vid = 0x04f3, .pid = 0x0c57 },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c5e },
|
{ .vid = 0x04f3, .pid = 0x0c5e },
|
||||||
{ .vid = 0x04f3, .pid = 0x0c5a },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c60 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c6c },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c70 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c72 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c77 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c7c },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c7f },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c80 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c85 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c90 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x2706 },
|
{ .vid = 0x04f3, .pid = 0x2706 },
|
||||||
{ .vid = 0x04f3, .pid = 0x3032 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x3057 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x3104 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x310d },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x3128 },
|
|
||||||
{ .vid = 0x04f3, .pid = 0x0c8a },
|
|
||||||
{ .vid = 0x05ba, .pid = 0x000e },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x0051 },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x0081 },
|
{ .vid = 0x06cb, .pid = 0x0081 },
|
||||||
{ .vid = 0x06cb, .pid = 0x0088 },
|
{ .vid = 0x06cb, .pid = 0x0088 },
|
||||||
{ .vid = 0x06cb, .pid = 0x008a },
|
{ .vid = 0x06cb, .pid = 0x008a },
|
||||||
{ .vid = 0x06cb, .pid = 0x009a },
|
{ .vid = 0x06cb, .pid = 0x009a },
|
||||||
{ .vid = 0x06cb, .pid = 0x009b },
|
{ .vid = 0x06cb, .pid = 0x009b },
|
||||||
{ .vid = 0x06cb, .pid = 0x00a1 },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00a2 },
|
{ .vid = 0x06cb, .pid = 0x00a2 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00a8 },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00b7 },
|
{ .vid = 0x06cb, .pid = 0x00b7 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00bb },
|
{ .vid = 0x06cb, .pid = 0x00bb },
|
||||||
{ .vid = 0x06cb, .pid = 0x00bc },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00be },
|
{ .vid = 0x06cb, .pid = 0x00be },
|
||||||
|
{ .vid = 0x06cb, .pid = 0x00c4 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00cb },
|
{ .vid = 0x06cb, .pid = 0x00cb },
|
||||||
{ .vid = 0x06cb, .pid = 0x00c9 },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00d8 },
|
{ .vid = 0x06cb, .pid = 0x00d8 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00da },
|
{ .vid = 0x06cb, .pid = 0x00da },
|
||||||
{ .vid = 0x06cb, .pid = 0x00dc },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00e4 },
|
|
||||||
{ .vid = 0x06cb, .pid = 0x00e7 },
|
{ .vid = 0x06cb, .pid = 0x00e7 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00fd },
|
{ .vid = 0x06cb, .pid = 0x00e9 },
|
||||||
{ .vid = 0x06cb, .pid = 0x00ff },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5801 },
|
{ .vid = 0x0a5c, .pid = 0x5801 },
|
||||||
{ .vid = 0x0a5c, .pid = 0x5805 },
|
{ .vid = 0x0a5c, .pid = 0x5805 },
|
||||||
{ .vid = 0x0a5c, .pid = 0x5834 },
|
{ .vid = 0x0a5c, .pid = 0x5834 },
|
||||||
|
|
@ -89,21 +60,7 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||||
{ .vid = 0x0a5c, .pid = 0x5843 },
|
{ .vid = 0x0a5c, .pid = 0x5843 },
|
||||||
{ .vid = 0x0a5c, .pid = 0x5844 },
|
{ .vid = 0x0a5c, .pid = 0x5844 },
|
||||||
{ .vid = 0x0a5c, .pid = 0x5845 },
|
{ .vid = 0x0a5c, .pid = 0x5845 },
|
||||||
{ .vid = 0x0a5c, .pid = 0x5860 },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5863 },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5864 },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5865 },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5866 },
|
|
||||||
{ .vid = 0x0a5c, .pid = 0x5867 },
|
|
||||||
{ .vid = 0x0bda, .pid = 0x5812 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0x0007 },
|
{ .vid = 0x10a5, .pid = 0x0007 },
|
||||||
{ .vid = 0x10a5, .pid = 0x9200 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0x9201 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0x9800 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0xa120 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0xa900 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0xa921 },
|
|
||||||
{ .vid = 0x10a5, .pid = 0xe340 },
|
|
||||||
{ .vid = 0x1188, .pid = 0x9545 },
|
{ .vid = 0x1188, .pid = 0x9545 },
|
||||||
{ .vid = 0x138a, .pid = 0x0007 },
|
{ .vid = 0x138a, .pid = 0x0007 },
|
||||||
{ .vid = 0x138a, .pid = 0x003a },
|
{ .vid = 0x138a, .pid = 0x003a },
|
||||||
|
|
@ -116,74 +73,48 @@ static const FpIdEntry allowlist_id_table[] = {
|
||||||
{ .vid = 0x138a, .pid = 0x0097 },
|
{ .vid = 0x138a, .pid = 0x0097 },
|
||||||
{ .vid = 0x138a, .pid = 0x009d },
|
{ .vid = 0x138a, .pid = 0x009d },
|
||||||
{ .vid = 0x138a, .pid = 0x00ab },
|
{ .vid = 0x138a, .pid = 0x00ab },
|
||||||
{ .vid = 0x138a, .pid = 0x00a6 },
|
|
||||||
{ .vid = 0x147e, .pid = 0x1002 },
|
{ .vid = 0x147e, .pid = 0x1002 },
|
||||||
{ .vid = 0x1491, .pid = 0x0088 },
|
{ .vid = 0x1491, .pid = 0x0088 },
|
||||||
{ .vid = 0x16d1, .pid = 0x1027 },
|
{ .vid = 0x16d1, .pid = 0x1027 },
|
||||||
{ .vid = 0x1c7a, .pid = 0x0300 },
|
{ .vid = 0x1c7a, .pid = 0x0300 },
|
||||||
{ .vid = 0x1c7a, .pid = 0x0575 },
|
{ .vid = 0x1c7a, .pid = 0x0575 },
|
||||||
{ .vid = 0x1c7a, .pid = 0x0576 },
|
|
||||||
{ .vid = 0x1c7a, .pid = 0x0577 },
|
|
||||||
{ .vid = 0x1c7a, .pid = 0x057e },
|
|
||||||
{ .vid = 0x2541, .pid = 0x0236 },
|
|
||||||
{ .vid = 0x2541, .pid = 0x9711 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5042 },
|
{ .vid = 0x27c6, .pid = 0x5042 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5110 },
|
{ .vid = 0x27c6, .pid = 0x5110 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5117 },
|
{ .vid = 0x27c6, .pid = 0x5117 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5120 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5125 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5201 },
|
{ .vid = 0x27c6, .pid = 0x5201 },
|
||||||
{ .vid = 0x27c6, .pid = 0x521d },
|
{ .vid = 0x27c6, .pid = 0x521d },
|
||||||
{ .vid = 0x27c6, .pid = 0x5301 },
|
{ .vid = 0x27c6, .pid = 0x5301 },
|
||||||
{ .vid = 0x27c6, .pid = 0x530c },
|
{ .vid = 0x27c6, .pid = 0x530c },
|
||||||
{ .vid = 0x27c6, .pid = 0x532d },
|
{ .vid = 0x27c6, .pid = 0x532d },
|
||||||
{ .vid = 0x27c6, .pid = 0x5335 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x533c },
|
{ .vid = 0x27c6, .pid = 0x533c },
|
||||||
{ .vid = 0x27c6, .pid = 0x5381 },
|
{ .vid = 0x27c6, .pid = 0x5381 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5385 },
|
{ .vid = 0x27c6, .pid = 0x5385 },
|
||||||
{ .vid = 0x27c6, .pid = 0x538c },
|
{ .vid = 0x27c6, .pid = 0x538c },
|
||||||
{ .vid = 0x27c6, .pid = 0x538d },
|
{ .vid = 0x27c6, .pid = 0x538d },
|
||||||
{ .vid = 0x27c6, .pid = 0x5395 },
|
{ .vid = 0x27c6, .pid = 0x5395 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5503 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x550a },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x550c },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5584 },
|
{ .vid = 0x27c6, .pid = 0x5584 },
|
||||||
{ .vid = 0x27c6, .pid = 0x55a2 },
|
{ .vid = 0x27c6, .pid = 0x55a2 },
|
||||||
{ .vid = 0x27c6, .pid = 0x55a4 },
|
{ .vid = 0x27c6, .pid = 0x55a4 },
|
||||||
{ .vid = 0x27c6, .pid = 0x55b4 },
|
{ .vid = 0x27c6, .pid = 0x55b4 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5740 },
|
{ .vid = 0x27c6, .pid = 0x5740 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5e0a },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x581a },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x589a },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5f10 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x5f91 },
|
|
||||||
{ .vid = 0x27c6, .pid = 0x6382 },
|
|
||||||
{ .vid = 0x2808, .pid = 0x9338 },
|
{ .vid = 0x2808, .pid = 0x9338 },
|
||||||
{ .vid = 0x2808, .pid = 0x9348 },
|
|
||||||
{ .vid = 0x2808, .pid = 0x93a9 },
|
|
||||||
{ .vid = 0x2808, .pid = 0xa658 },
|
|
||||||
{ .vid = 0x2808, .pid = 0xc652 },
|
|
||||||
{ .vid = 0x2808, .pid = 0xa553 },
|
|
||||||
{ .vid = 0x298d, .pid = 0x2020 },
|
|
||||||
{ .vid = 0x298d, .pid = 0x2033 },
|
{ .vid = 0x298d, .pid = 0x2033 },
|
||||||
{ .vid = 0x2df0, .pid = 0x0003 },
|
|
||||||
{ .vid = 0x3274, .pid = 0x8012 },
|
|
||||||
{ .vid = 0x3538, .pid = 0x0930 },
|
{ .vid = 0x3538, .pid = 0x0930 },
|
||||||
{ .vid = 0 },
|
{ .vid = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpIdEntry denylist_id_table[] = {
|
static const FpIdEntry blacklist_id_table[] = {
|
||||||
{ .vid = 0x0483, .pid = 0x2016 },
|
{ .vid = 0x0483, .pid = 0x2016 },
|
||||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
||||||
{ .vid = 0x045e, .pid = 0x00bb },
|
{ .vid = 0x045e, .pid = 0x00bb },
|
||||||
{ .vid = 0 },
|
{ .vid = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpDeviceClass allowlist = {
|
static const FpDeviceClass whitelist = {
|
||||||
.type = FP_DEVICE_TYPE_USB,
|
.type = FP_DEVICE_TYPE_USB,
|
||||||
.id_table = allowlist_id_table,
|
.id_table = whitelist_id_table,
|
||||||
.id = "allowlist",
|
.id = "whitelist",
|
||||||
.full_name = "Hardcoded allowlist"
|
.full_name = "Hardcoded whitelist"
|
||||||
};
|
};
|
||||||
|
|
||||||
GHashTable *printed = NULL;
|
GHashTable *printed = NULL;
|
||||||
|
|
@ -202,7 +133,7 @@ print_driver (const FpDeviceClass *cls)
|
||||||
const FpIdEntry *bl_entry;
|
const FpIdEntry *bl_entry;
|
||||||
char *key;
|
char *key;
|
||||||
|
|
||||||
for (bl_entry = denylist_id_table; bl_entry->vid != 0; bl_entry++)
|
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++)
|
||||||
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -213,7 +144,7 @@ print_driver (const FpDeviceClass *cls)
|
||||||
|
|
||||||
if (g_hash_table_lookup (printed, key) != NULL)
|
if (g_hash_table_lookup (printed, key) != NULL)
|
||||||
{
|
{
|
||||||
if (cls == &allowlist)
|
if (cls == &whitelist)
|
||||||
g_warning ("%s implemented by driver %s",
|
g_warning ("%s implemented by driver %s",
|
||||||
key, (const char *) g_hash_table_lookup (printed, key));
|
key, (const char *) g_hash_table_lookup (printed, key));
|
||||||
g_free (key);
|
g_free (key);
|
||||||
|
|
@ -224,7 +155,7 @@ print_driver (const FpDeviceClass *cls)
|
||||||
|
|
||||||
if (num_printed == 0)
|
if (num_printed == 0)
|
||||||
{
|
{
|
||||||
if (cls != &allowlist)
|
if (cls != &whitelist)
|
||||||
g_print ("\n# Supported by libfprint driver %s\n", cls->id);
|
g_print ("\n# Supported by libfprint driver %s\n", cls->id);
|
||||||
else
|
else
|
||||||
g_print ("\n# Known unsupported devices\n");
|
g_print ("\n# Known unsupported devices\n");
|
||||||
|
|
@ -278,7 +209,7 @@ main (int argc, char **argv)
|
||||||
print_driver (cls);
|
print_driver (cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_driver (&allowlist);
|
print_driver (&whitelist);
|
||||||
|
|
||||||
g_hash_table_destroy (printed);
|
g_hash_table_destroy (printed);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,3 @@
|
||||||
spi_sources = []
|
|
||||||
spi_headers = []
|
|
||||||
|
|
||||||
if enabled_spi_drivers.length() > 0
|
|
||||||
spi_headers = ['fpi-spi-transfer.h']
|
|
||||||
spi_sources = ['fpi-spi-transfer.c']
|
|
||||||
endif
|
|
||||||
|
|
||||||
libfprint_sources = [
|
libfprint_sources = [
|
||||||
'fp-context.c',
|
'fp-context.c',
|
||||||
'fp-device.c',
|
'fp-device.c',
|
||||||
|
|
@ -24,7 +16,8 @@ libfprint_private_sources = [
|
||||||
'fpi-print.c',
|
'fpi-print.c',
|
||||||
'fpi-ssm.c',
|
'fpi-ssm.c',
|
||||||
'fpi-usb-transfer.c',
|
'fpi-usb-transfer.c',
|
||||||
] + spi_sources
|
'fpi-spi-transfer.c',
|
||||||
|
]
|
||||||
|
|
||||||
libfprint_public_headers = [
|
libfprint_public_headers = [
|
||||||
'fp-context.h',
|
'fp-context.h',
|
||||||
|
|
@ -48,8 +41,9 @@ libfprint_private_headers = [
|
||||||
'fpi-minutiae.h',
|
'fpi-minutiae.h',
|
||||||
'fpi-print.h',
|
'fpi-print.h',
|
||||||
'fpi-usb-transfer.h',
|
'fpi-usb-transfer.h',
|
||||||
|
'fpi-spi-transfer.h',
|
||||||
'fpi-ssm.h',
|
'fpi-ssm.h',
|
||||||
] + spi_headers
|
]
|
||||||
|
|
||||||
nbis_sources = [
|
nbis_sources = [
|
||||||
'nbis/bozorth3/bozorth3.c',
|
'nbis/bozorth3/bozorth3.c',
|
||||||
|
|
@ -125,10 +119,6 @@ driver_sources = {
|
||||||
[ 'drivers/etes603.c' ],
|
[ 'drivers/etes603.c' ],
|
||||||
'egis0570' :
|
'egis0570' :
|
||||||
[ 'drivers/egis0570.c' ],
|
[ 'drivers/egis0570.c' ],
|
||||||
'egismoc' :
|
|
||||||
[ 'drivers/egismoc/egismoc.c' ],
|
|
||||||
'egis_etu905' :
|
|
||||||
[ 'drivers/egismoc/egis_etu905.c' ],
|
|
||||||
'vfs0050' :
|
'vfs0050' :
|
||||||
[ 'drivers/vfs0050.c' ],
|
[ 'drivers/vfs0050.c' ],
|
||||||
'elan' :
|
'elan' :
|
||||||
|
|
@ -149,12 +139,6 @@ driver_sources = {
|
||||||
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
|
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
|
||||||
'goodixmoc' :
|
'goodixmoc' :
|
||||||
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
|
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
|
||||||
'fpcmoc' :
|
|
||||||
[ 'drivers/fpcmoc/fpc.c' ],
|
|
||||||
'realtek' :
|
|
||||||
[ 'drivers/realtek/realtek.c' ],
|
|
||||||
'focaltech_moc' :
|
|
||||||
[ 'drivers/focaltech_moc/focaltech_moc.c' ],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
helper_sources = {
|
helper_sources = {
|
||||||
|
|
@ -164,7 +148,7 @@ helper_sources = {
|
||||||
[ 'drivers/aesx660.c' ],
|
[ 'drivers/aesx660.c' ],
|
||||||
'aes3k' :
|
'aes3k' :
|
||||||
[ 'drivers/aes3k.c' ],
|
[ 'drivers/aes3k.c' ],
|
||||||
'openssl' :
|
'nss' :
|
||||||
[ ],
|
[ ],
|
||||||
'udev' :
|
'udev' :
|
||||||
[ ],
|
[ ],
|
||||||
|
|
@ -257,7 +241,6 @@ libnbis = static_library('nbis',
|
||||||
'-Wno-discarded-qualifiers',
|
'-Wno-discarded-qualifiers',
|
||||||
'-Wno-array-bounds',
|
'-Wno-array-bounds',
|
||||||
'-Wno-array-parameter',
|
'-Wno-array-parameter',
|
||||||
'-Wno-unused-but-set-variable',
|
|
||||||
]),
|
]),
|
||||||
install: false)
|
install: false)
|
||||||
|
|
||||||
|
|
@ -277,13 +260,8 @@ libfprint_drivers = static_library('fprint-drivers',
|
||||||
link_with: libfprint_private,
|
link_with: libfprint_private,
|
||||||
install: false)
|
install: false)
|
||||||
|
|
||||||
mapfile = files('libfprint.ver')[0]
|
mapfile = files('libfprint.ver')
|
||||||
if meson.version().version_compare('>=1.4')
|
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
|
||||||
mapfile_path = mapfile.full_path()
|
|
||||||
else
|
|
||||||
mapfile_path = meson.project_source_root() / '@0@'.format(mapfile)
|
|
||||||
endif
|
|
||||||
vflag = '-Wl,--version-script,@0@'.format(mapfile_path)
|
|
||||||
|
|
||||||
libfprint = shared_library(versioned_libname.split('lib')[1],
|
libfprint = shared_library(versioned_libname.split('lib')[1],
|
||||||
sources: [
|
sources: [
|
||||||
|
|
@ -335,21 +313,6 @@ udev_hwdb_generator = custom_target('udev-hwdb',
|
||||||
install: false,
|
install: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
metainfo = executable('fprint-list-metainfo',
|
|
||||||
'fprint-list-metainfo.c',
|
|
||||||
dependencies: libfprint_private_dep,
|
|
||||||
link_with: libfprint_drivers,
|
|
||||||
install: false)
|
|
||||||
|
|
||||||
metainfo_generator = custom_target('metainfo',
|
|
||||||
output: 'org.freedesktop.libfprint.metainfo.xml',
|
|
||||||
depend_files: drivers_sources,
|
|
||||||
capture: true,
|
|
||||||
command: [ metainfo ],
|
|
||||||
install: true,
|
|
||||||
install_dir: datadir / 'metainfo'
|
|
||||||
)
|
|
||||||
|
|
||||||
if install_udev_rules
|
if install_udev_rules
|
||||||
udev_rules = executable('fprint-list-udev-rules',
|
udev_rules = executable('fprint-list-udev-rules',
|
||||||
'fprint-list-udev-rules.c',
|
'fprint-list-udev-rules.c',
|
||||||
|
|
@ -367,19 +330,17 @@ if install_udev_rules
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
sync_udev_udb = custom_target('sync-udev-hwdb',
|
custom_target('sync-udev-hwdb',
|
||||||
depends: udev_hwdb_generator,
|
depends: udev_hwdb_generator,
|
||||||
output: 'sync-udev-hwdb',
|
output: 'sync-udev-hwdb',
|
||||||
install: false,
|
install: false,
|
||||||
command: [
|
command: [
|
||||||
'cp', '-v',
|
'cp', '-v',
|
||||||
udev_hwdb_generator.full_path(),
|
udev_hwdb_generator.full_path(),
|
||||||
meson.project_source_root() / 'data'
|
meson.source_root() / 'data'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
alias_target('sync-udev-hwdb', sync_udev_udb)
|
|
||||||
|
|
||||||
supported_devices = executable('fprint-list-supported-devices',
|
supported_devices = executable('fprint-list-supported-devices',
|
||||||
'fprint-list-supported-devices.c',
|
'fprint-list-supported-devices.c',
|
||||||
dependencies: libfprint_private_dep,
|
dependencies: libfprint_private_dep,
|
||||||
|
|
@ -413,7 +374,6 @@ if get_option('introspection')
|
||||||
'GObject-2.0',
|
'GObject-2.0',
|
||||||
'GUsb-1.0',
|
'GUsb-1.0',
|
||||||
],
|
],
|
||||||
fatal_warnings: true,
|
|
||||||
install : true)
|
install : true)
|
||||||
libfprint_gir = libfprint_girtarget[0]
|
libfprint_gir = libfprint_girtarget[0]
|
||||||
libfprint_typelib = libfprint_girtarget[1]
|
libfprint_typelib = libfprint_girtarget[1]
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
From 2584d440afc87d463cb8dc809d48c660e091c2c4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sam James <sam@gentoo.org>
|
|
||||||
Date: Thu, 23 Jun 2022 05:57:46 +0100
|
|
||||||
Subject: [PATCH] nbis: fix build on musl
|
|
||||||
|
|
||||||
Drop re-definition of stderr. There's no need for this anywhere
|
|
||||||
(including glibc). This breaks in particular on musl because
|
|
||||||
stderr (and stdin) are both const, and macros unlike in glibc.
|
|
||||||
|
|
||||||
Bug: https://bugs.gentoo.org/853811
|
|
||||||
---
|
|
||||||
nbis/include/bozorth.h | 2 --
|
|
||||||
1 file changed, 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/nbis/include/bozorth.h b/nbis/include/bozorth.h
|
|
||||||
index a705da98..fd8975bf 100644
|
|
||||||
--- a/nbis/include/bozorth.h
|
|
||||||
+++ b/nbis/include/bozorth.h
|
|
||||||
@@ -217,8 +217,6 @@ struct xytq_struct {
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Globals supporting command line options */
|
|
||||||
extern int verbose_threshold;
|
|
||||||
-/* Global supporting error reporting */
|
|
||||||
-extern FILE *stderr;
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/* In: BZ_GBLS.C */
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -217,6 +217,8 @@ struct xytq_struct {
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Globals supporting command line options */
|
/* Globals supporting command line options */
|
||||||
extern int verbose_threshold;
|
extern int verbose_threshold;
|
||||||
|
/* Global supporting error reporting */
|
||||||
|
extern FILE *stderr;
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* In: BZ_GBLS.C */
|
/* In: BZ_GBLS.C */
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,3 @@ patch -p0 < fix-scan-build-reports.patch
|
||||||
|
|
||||||
# Add pass to remove perimeter points
|
# Add pass to remove perimeter points
|
||||||
patch -p0 < remove-perimeter-pts.patch
|
patch -p0 < remove-perimeter-pts.patch
|
||||||
|
|
||||||
# Fix build on musl by dropping unnecessary redeclaration of stderr
|
|
||||||
patch -p0 < fix-musl-build.patch
|
|
||||||
|
|
|
||||||
93
meson.build
93
meson.build
|
|
@ -1,38 +1,26 @@
|
||||||
project('libfprint', [ 'c', 'cpp' ],
|
project('libfprint', [ 'c', 'cpp' ],
|
||||||
version: '1.94.10',
|
version: '1.94.1',
|
||||||
license: 'LGPLv2.1+',
|
license: 'LGPLv2.1+',
|
||||||
default_options: [
|
default_options: [
|
||||||
'buildtype=debugoptimized',
|
'buildtype=debugoptimized',
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'c_std=gnu99',
|
'c_std=gnu99',
|
||||||
],
|
],
|
||||||
meson_version: '>= 0.59.0')
|
meson_version: '>= 0.49.0')
|
||||||
|
|
||||||
fs = import('fs')
|
|
||||||
gnome = import('gnome')
|
gnome = import('gnome')
|
||||||
|
|
||||||
libfprint_conf = configuration_data()
|
libfprint_conf = configuration_data()
|
||||||
libfprint_conf.set_quoted('LIBFPRINT_VERSION', meson.project_version())
|
|
||||||
|
|
||||||
prefix = get_option('prefix')
|
|
||||||
libdir = prefix / get_option('libdir')
|
|
||||||
libexecdir = prefix / get_option('libexecdir')
|
|
||||||
datadir = prefix / get_option('datadir')
|
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
cpp = meson.get_compiler('cpp')
|
cpp = meson.get_compiler('cpp')
|
||||||
host_system = host_machine.system()
|
host_system = host_machine.system()
|
||||||
|
glib_min_version = '2.56'
|
||||||
libfprint_sanitizers = get_option('b_sanitize').split(',')
|
|
||||||
if libfprint_sanitizers == ['none']
|
|
||||||
libfprint_sanitizers = []
|
|
||||||
endif
|
|
||||||
|
|
||||||
glib_min_version = '2.68'
|
|
||||||
|
|
||||||
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
|
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
|
||||||
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
|
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
|
||||||
common_cflags = cc.get_supported_arguments([
|
common_cflags = cc.get_supported_arguments([
|
||||||
|
'-Wall',
|
||||||
'-Wcast-align',
|
'-Wcast-align',
|
||||||
'-Wformat-nonliteral',
|
'-Wformat-nonliteral',
|
||||||
'-Wformat-security',
|
'-Wformat-security',
|
||||||
|
|
@ -97,15 +85,11 @@ gusb_dep = dependency('gusb', version: '>= 0.2.0')
|
||||||
mathlib_dep = cc.find_library('m', required: false)
|
mathlib_dep = cc.find_library('m', required: false)
|
||||||
|
|
||||||
# The following dependencies are only used for tests
|
# The following dependencies are only used for tests
|
||||||
sh = find_program('sh', required: true)
|
|
||||||
cairo_dep = dependency('cairo', required: false)
|
cairo_dep = dependency('cairo', required: false)
|
||||||
|
|
||||||
# introspection scanning and Gio-2.0.gir
|
# introspection scanning and Gio-2.0.gir
|
||||||
gobject_introspection = dependency('gobject-introspection-1.0', required: get_option('introspection'))
|
gobject_introspection = dependency('gobject-introspection-1.0', required: get_option('introspection'))
|
||||||
|
|
||||||
# SPI
|
|
||||||
have_spi = host_machine.system() == 'linux'
|
|
||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
drivers = get_option('drivers').split(',')
|
drivers = get_option('drivers').split(',')
|
||||||
virtual_drivers = [
|
virtual_drivers = [
|
||||||
|
|
@ -130,8 +114,6 @@ default_drivers = [
|
||||||
'vfs0050',
|
'vfs0050',
|
||||||
'etes603',
|
'etes603',
|
||||||
'egis0570',
|
'egis0570',
|
||||||
'egismoc',
|
|
||||||
'egis_etu905',
|
|
||||||
'vcom5s',
|
'vcom5s',
|
||||||
'synaptics',
|
'synaptics',
|
||||||
'elan',
|
'elan',
|
||||||
|
|
@ -142,44 +124,16 @@ default_drivers = [
|
||||||
'upekts',
|
'upekts',
|
||||||
'goodixmoc',
|
'goodixmoc',
|
||||||
'nb1010',
|
'nb1010',
|
||||||
'fpcmoc',
|
|
||||||
'realtek',
|
|
||||||
'focaltech_moc',
|
|
||||||
]
|
|
||||||
|
|
||||||
spi_drivers = [
|
# SPI
|
||||||
'elanspi'
|
'elanspi',
|
||||||
]
|
]
|
||||||
|
|
||||||
if have_spi
|
|
||||||
default_drivers += spi_drivers
|
|
||||||
endif
|
|
||||||
|
|
||||||
# FIXME: All the drivers should be fixed by adjusting the byte order.
|
# FIXME: All the drivers should be fixed by adjusting the byte order.
|
||||||
# See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/236
|
# See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/236
|
||||||
endian_independent_drivers = virtual_drivers + [
|
endian_independent_drivers = virtual_drivers + [
|
||||||
'aes1610',
|
|
||||||
'aes1660',
|
|
||||||
'aes2550',
|
|
||||||
'aes2660',
|
|
||||||
'aes3500',
|
'aes3500',
|
||||||
'aes4000',
|
|
||||||
'egis0570',
|
|
||||||
'egismoc',
|
|
||||||
'egis_etu905',
|
|
||||||
'elanmoc',
|
|
||||||
'etes603',
|
|
||||||
'focaltech_moc',
|
|
||||||
'nb1010',
|
|
||||||
'realtek',
|
|
||||||
'synaptics',
|
'synaptics',
|
||||||
'upeksonly',
|
|
||||||
'upektc',
|
|
||||||
'upektc_img',
|
|
||||||
'upekts',
|
|
||||||
'vcom5s',
|
|
||||||
'vfs101',
|
|
||||||
'vfs7552',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
all_drivers = default_drivers + virtual_drivers
|
all_drivers = default_drivers + virtual_drivers
|
||||||
|
|
@ -192,17 +146,6 @@ if drivers == [ 'default' ]
|
||||||
drivers = default_drivers
|
drivers = default_drivers
|
||||||
endif
|
endif
|
||||||
|
|
||||||
enabled_spi_drivers = []
|
|
||||||
foreach driver : spi_drivers
|
|
||||||
if driver in drivers
|
|
||||||
enabled_spi_drivers += driver
|
|
||||||
endif
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
if enabled_spi_drivers.length() > 0 and not have_spi
|
|
||||||
error('SPI drivers @0@ are not supported'.format(enabled_spi_drivers))
|
|
||||||
endif
|
|
||||||
|
|
||||||
driver_helper_mapping = {
|
driver_helper_mapping = {
|
||||||
'aes1610' : [ 'aeslib' ],
|
'aes1610' : [ 'aeslib' ],
|
||||||
'aes1660' : [ 'aeslib', 'aesx660' ],
|
'aes1660' : [ 'aeslib', 'aesx660' ],
|
||||||
|
|
@ -211,7 +154,7 @@ driver_helper_mapping = {
|
||||||
'aes2660' : [ 'aeslib', 'aesx660' ],
|
'aes2660' : [ 'aeslib', 'aesx660' ],
|
||||||
'aes3500' : [ 'aeslib', 'aes3k' ],
|
'aes3500' : [ 'aeslib', 'aes3k' ],
|
||||||
'aes4000' : [ 'aeslib', 'aes3k' ],
|
'aes4000' : [ 'aeslib', 'aes3k' ],
|
||||||
'uru4000' : [ 'openssl' ],
|
'uru4000' : [ 'nss' ],
|
||||||
'elanspi' : [ 'udev' ],
|
'elanspi' : [ 'udev' ],
|
||||||
'virtual_image' : [ 'virtual' ],
|
'virtual_image' : [ 'virtual' ],
|
||||||
'virtual_device' : [ 'virtual' ],
|
'virtual_device' : [ 'virtual' ],
|
||||||
|
|
@ -268,13 +211,13 @@ foreach i : driver_helpers
|
||||||
|
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||||
optional_deps += imaging_dep
|
optional_deps += imaging_dep
|
||||||
elif i == 'openssl'
|
elif i == 'nss'
|
||||||
openssl_dep = dependency('openssl', version: '>= 3.0', required: false)
|
nss_dep = dependency('nss', required: false)
|
||||||
if not openssl_dep.found()
|
if not nss_dep.found()
|
||||||
error('OpenSSL is required for @0@ and possibly others'.format(driver))
|
error('nss is required for @0@ and possibly others'.format(driver))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
optional_deps += openssl_dep
|
optional_deps += nss_dep
|
||||||
elif i == 'udev'
|
elif i == 'udev'
|
||||||
install_udev_rules = true
|
install_udev_rules = true
|
||||||
|
|
||||||
|
|
@ -297,7 +240,7 @@ if install_udev_rules
|
||||||
udev_rules_dir = get_option('udev_rules_dir')
|
udev_rules_dir = get_option('udev_rules_dir')
|
||||||
if udev_rules_dir == 'auto'
|
if udev_rules_dir == 'auto'
|
||||||
udev_dep = dependency('udev')
|
udev_dep = dependency('udev')
|
||||||
udev_rules_dir = udev_dep.get_variable(pkgconfig: 'udevdir') + '/rules.d'
|
udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/rules.d'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -334,13 +277,15 @@ if not udev_hwdb.disabled()
|
||||||
|
|
||||||
if udev_hwdb_dir == 'auto'
|
if udev_hwdb_dir == 'auto'
|
||||||
udev_dep = dependency('udev')
|
udev_dep = dependency('udev')
|
||||||
udev_hwdb_dir = udev_dep.get_variable(pkgconfig: 'udevdir') + '/hwdb.d'
|
udev_hwdb_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/hwdb.d'
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
udev_hwdb_dir = ''
|
udev_hwdb_dir = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('gtk-examples')
|
if get_option('gtk-examples')
|
||||||
|
gnome = import('gnome')
|
||||||
|
|
||||||
gtk_dep = dependency('gtk+-3.0', required: false)
|
gtk_dep = dependency('gtk+-3.0', required: false)
|
||||||
if not gtk_dep.found()
|
if not gtk_dep.found()
|
||||||
error('GTK+ 3.x is required for GTK+ examples')
|
error('GTK+ 3.x is required for GTK+ examples')
|
||||||
|
|
@ -352,7 +297,9 @@ subdir('libfprint')
|
||||||
|
|
||||||
configure_file(output: 'config.h', configuration: libfprint_conf)
|
configure_file(output: 'config.h', configuration: libfprint_conf)
|
||||||
|
|
||||||
|
subdir('examples')
|
||||||
if get_option('doc')
|
if get_option('doc')
|
||||||
|
gnome = import('gnome')
|
||||||
subdir('doc')
|
subdir('doc')
|
||||||
endif
|
endif
|
||||||
if get_option('gtk-examples')
|
if get_option('gtk-examples')
|
||||||
|
|
@ -362,8 +309,6 @@ endif
|
||||||
subdir('data')
|
subdir('data')
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
|
|
||||||
subdir('examples')
|
|
||||||
|
|
||||||
pkgconfig = import('pkgconfig')
|
pkgconfig = import('pkgconfig')
|
||||||
pkgconfig.generate(
|
pkgconfig.generate(
|
||||||
name: versioned_libname,
|
name: versioned_libname,
|
||||||
|
|
@ -374,5 +319,3 @@ pkgconfig.generate(
|
||||||
subdirs: versioned_libname,
|
subdirs: versioned_libname,
|
||||||
filebase: versioned_libname,
|
filebase: versioned_libname,
|
||||||
)
|
)
|
||||||
|
|
||||||
summary({'Drivers': drivers, }, section: 'Drivers')
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,3 @@ option('doc',
|
||||||
description: 'Whether to build the API documentation',
|
description: 'Whether to build the API documentation',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true)
|
value: true)
|
||||||
option('installed-tests',
|
|
||||||
description: 'Whether to install the installed tests',
|
|
||||||
type: 'boolean',
|
|
||||||
value: true)
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ indent_func_proto_param false
|
||||||
indent_switch_case 0
|
indent_switch_case 0
|
||||||
indent_case_brace 2
|
indent_case_brace 2
|
||||||
indent_paren_close 1
|
indent_paren_close 1
|
||||||
pp_multiline_define_body_indent 2
|
|
||||||
|
|
||||||
# spacing
|
# spacing
|
||||||
sp_arith Add
|
sp_arith Add
|
||||||
|
|
@ -115,14 +114,13 @@ nl_create_for_one_liner False
|
||||||
nl_create_while_one_liner False
|
nl_create_while_one_liner False
|
||||||
nl_after_semicolon True
|
nl_after_semicolon True
|
||||||
nl_multi_line_cond true
|
nl_multi_line_cond true
|
||||||
nl_multi_line_define true
|
|
||||||
|
|
||||||
# mod
|
# mod
|
||||||
# I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike
|
# I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike
|
||||||
# Not clear what to do about that...
|
# Not clear what to do about that...
|
||||||
mod_full_brace_for Remove
|
mod_full_brace_for Remove
|
||||||
mod_full_brace_if Remove
|
mod_full_brace_if Remove
|
||||||
mod_full_brace_if_chain 1
|
mod_full_brace_if_chain True
|
||||||
mod_full_brace_while Remove
|
mod_full_brace_while Remove
|
||||||
mod_full_brace_do Remove
|
mod_full_brace_do Remove
|
||||||
mod_full_brace_nl 3
|
mod_full_brace_nl 3
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import cairo
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
gi.require_version('FPrint', '2.0')
|
gi.require_version('FPrint', '2.0')
|
||||||
from gi.repository import FPrint, GLib
|
from gi.repository import FPrint, GLib
|
||||||
|
import cairo
|
||||||
# Exit with error on any exception, included those happening in async callbacks
|
import sys
|
||||||
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
|
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print("Please specify exactly one argument, the output location for the capture image")
|
print("Please specify exactly one argument, the output location for the capture image")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
BUILDDIR='@BUILDDIR@'
|
BUILDDIR='@BUILDDIR@'
|
||||||
SRCDIR='@SRCDIR@'
|
SRCDIR='@SRCDIR@'
|
||||||
|
|
@ -44,7 +44,7 @@ if len(sys.argv) > 3:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
driver_name = sys.argv[1]
|
driver_name = sys.argv[1]
|
||||||
os.environ['FP_DRIVERS_ALLOWLIST'] = driver_name
|
os.environ['FP_DRIVERS_WHITELIST'] = driver_name
|
||||||
|
|
||||||
test_variant = None
|
test_variant = None
|
||||||
if len(sys.argv) == 3:
|
if len(sys.argv) == 3:
|
||||||
|
|
@ -105,11 +105,6 @@ process.wait()
|
||||||
# Run capture
|
# Run capture
|
||||||
# https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/
|
# https://osqa-ask.wireshark.org/questions/53919/how-can-i-precisely-specify-a-usb-device-to-capture-with-tshark/
|
||||||
|
|
||||||
print(f'### Reseting USB port (as descriptors could be missing in the dump otherwise)')
|
|
||||||
usb_device.open()
|
|
||||||
usb_device.reset()
|
|
||||||
usb_device.close()
|
|
||||||
|
|
||||||
print(f'### Starting USB capture on usbmon{bus_num}')
|
print(f'### Starting USB capture on usbmon{bus_num}')
|
||||||
capture_pid = os.fork()
|
capture_pid = os.fork()
|
||||||
assert(capture_pid >= 0)
|
assert(capture_pid >= 0)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
[Test]
|
|
||||||
Type=session
|
|
||||||
# We can't use TestEnvironment as per
|
|
||||||
# https://gitlab.gnome.org/GNOME/gnome-desktop-testing/-/issues/1
|
|
||||||
Exec=env @driver_env@ @installed_tests_execdir@/@umockdev_test_name@ @installed_tests_testdir@/@driver_test@
|
|
||||||
0
tests/egis0570/capture.pcapng
Normal file → Executable file
0
tests/egis0570/capture.pcapng
Normal file → Executable file
|
|
@ -24,64 +24,64 @@ E: ID_USB_INTERFACES=:ff0000:
|
||||||
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
|
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
|
||||||
E: ID_PATH=pci-0000:00:14.0-usb-0:9
|
E: ID_PATH=pci-0000:00:14.0-usb-0:9
|
||||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
|
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9
|
||||||
E: LIBFPRINT_DRIVER=Hardcoded allowlist
|
E: LIBFPRINT_DRIVER=Hardcoded whitelist
|
||||||
A: authorized=1\n
|
A: authorized=1
|
||||||
A: avoid_reset_quirk=0\n
|
A: avoid_reset_quirk=0
|
||||||
A: bConfigurationValue=1\n
|
A: bConfigurationValue=1
|
||||||
A: bDeviceClass=00\n
|
A: bDeviceClass=00
|
||||||
A: bDeviceProtocol=00\n
|
A: bDeviceProtocol=00
|
||||||
A: bDeviceSubClass=00\n
|
A: bDeviceSubClass=00
|
||||||
A: bMaxPacketSize0=8\n
|
A: bMaxPacketSize0=8
|
||||||
A: bMaxPower=100mA\n
|
A: bMaxPower=100mA
|
||||||
A: bNumConfigurations=1\n
|
A: bNumConfigurations=1
|
||||||
A: bNumInterfaces= 1\n
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=1041\n
|
A: bcdDevice=1041
|
||||||
A: bmAttributes=a0\n
|
A: bmAttributes=a0
|
||||||
A: busnum=1\n
|
A: busnum=1
|
||||||
A: configuration=\n
|
A: configuration=
|
||||||
H: descriptors=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003
|
H: descriptors=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003
|
||||||
A: dev=189:4\n
|
A: dev=189:4
|
||||||
A: devnum=5\n
|
A: devnum=5
|
||||||
A: devpath=9\n
|
A: devpath=9
|
||||||
L: driver=../../../../../bus/usb/drivers/usb
|
L: driver=../../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0570\n
|
A: idProduct=0570
|
||||||
A: idVendor=1c7a\n
|
A: idVendor=1c7a
|
||||||
A: ltm_capable=no\n
|
A: ltm_capable=no
|
||||||
A: manufacturer=EgisTec\n
|
A: manufacturer=EgisTec
|
||||||
A: maxchild=0\n
|
A: maxchild=0
|
||||||
L: port=../1-0:1.0/usb1-port9
|
L: port=../1-0:1.0/usb1-port9
|
||||||
A: power/active_duration=362352\n
|
A: power/active_duration=362352
|
||||||
A: power/async=enabled\n
|
A: power/async=enabled
|
||||||
A: power/autosuspend=2\n
|
A: power/autosuspend=2
|
||||||
A: power/autosuspend_delay_ms=2000\n
|
A: power/autosuspend_delay_ms=2000
|
||||||
A: power/connected_duration=5526124\n
|
A: power/connected_duration=5526124
|
||||||
A: power/control=auto\n
|
A: power/control=auto
|
||||||
A: power/level=auto\n
|
A: power/level=auto
|
||||||
A: power/persist=1\n
|
A: power/persist=1
|
||||||
A: power/runtime_active_kids=0\n
|
A: power/runtime_active_kids=0
|
||||||
A: power/runtime_active_time=365097\n
|
A: power/runtime_active_time=365097
|
||||||
A: power/runtime_enabled=enabled\n
|
A: power/runtime_enabled=enabled
|
||||||
A: power/runtime_status=active\n
|
A: power/runtime_status=active
|
||||||
A: power/runtime_suspended_time=5160752\n
|
A: power/runtime_suspended_time=5160752
|
||||||
A: power/runtime_usage=0\n
|
A: power/runtime_usage=0
|
||||||
A: power/wakeup=disabled\n
|
A: power/wakeup=disabled
|
||||||
A: power/wakeup_abort_count=\n
|
A: power/wakeup_abort_count=
|
||||||
A: power/wakeup_active=\n
|
A: power/wakeup_active=
|
||||||
A: power/wakeup_active_count=\n
|
A: power/wakeup_active_count=
|
||||||
A: power/wakeup_count=\n
|
A: power/wakeup_count=
|
||||||
A: power/wakeup_expire_count=\n
|
A: power/wakeup_expire_count=
|
||||||
A: power/wakeup_last_time_ms=\n
|
A: power/wakeup_last_time_ms=
|
||||||
A: power/wakeup_max_time_ms=\n
|
A: power/wakeup_max_time_ms=
|
||||||
A: power/wakeup_total_time_ms=\n
|
A: power/wakeup_total_time_ms=
|
||||||
A: product=EgisTec Touch Fingerprint Sensor\n
|
A: product=EgisTec Touch Fingerprint Sensor
|
||||||
A: quirks=0x0\n
|
A: quirks=0x0
|
||||||
A: removable=fixed\n
|
A: removable=fixed
|
||||||
A: rx_lanes=1\n
|
A: rx_lanes=1
|
||||||
A: serial=W700B41B\n
|
A: serial=W700B41B
|
||||||
A: speed=12\n
|
A: speed=12
|
||||||
A: tx_lanes=1\n
|
A: tx_lanes=1
|
||||||
A: urbnum=8040\n
|
A: urbnum=8040
|
||||||
A: version= 1.10\n
|
A: version= 1.10
|
||||||
|
|
||||||
P: /devices/pci0000:00/0000:00:14.0/usb1
|
P: /devices/pci0000:00/0000:00:14.0/usb1
|
||||||
N: bus/usb/001/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
N: bus/usb/001/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||||
|
|
@ -112,63 +112,63 @@ E: ID_PATH=pci-0000:00:14.0
|
||||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||||
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
|
||||||
E: TAGS=:seat:
|
E: TAGS=:seat:
|
||||||
A: authorized=1\n
|
A: authorized=1
|
||||||
A: authorized_default=1\n
|
A: authorized_default=1
|
||||||
A: avoid_reset_quirk=0\n
|
A: avoid_reset_quirk=0
|
||||||
A: bConfigurationValue=1\n
|
A: bConfigurationValue=1
|
||||||
A: bDeviceClass=09\n
|
A: bDeviceClass=09
|
||||||
A: bDeviceProtocol=01\n
|
A: bDeviceProtocol=01
|
||||||
A: bDeviceSubClass=00\n
|
A: bDeviceSubClass=00
|
||||||
A: bMaxPacketSize0=64\n
|
A: bMaxPacketSize0=64
|
||||||
A: bMaxPower=0mA\n
|
A: bMaxPower=0mA
|
||||||
A: bNumConfigurations=1\n
|
A: bNumConfigurations=1
|
||||||
A: bNumInterfaces= 1\n
|
A: bNumInterfaces= 1
|
||||||
A: bcdDevice=0508\n
|
A: bcdDevice=0508
|
||||||
A: bmAttributes=e0\n
|
A: bmAttributes=e0
|
||||||
A: busnum=1\n
|
A: busnum=1
|
||||||
A: configuration=\n
|
A: configuration=
|
||||||
H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C
|
||||||
A: dev=189:0\n
|
A: dev=189:0
|
||||||
A: devnum=1\n
|
A: devnum=1
|
||||||
A: devpath=0\n
|
A: devpath=0
|
||||||
L: driver=../../../../bus/usb/drivers/usb
|
L: driver=../../../../bus/usb/drivers/usb
|
||||||
A: idProduct=0002\n
|
A: idProduct=0002
|
||||||
A: idVendor=1d6b\n
|
A: idVendor=1d6b
|
||||||
A: interface_authorized_default=1\n
|
A: interface_authorized_default=1
|
||||||
A: ltm_capable=no\n
|
A: ltm_capable=no
|
||||||
A: manufacturer=Linux 5.8.0-59-generic xhci-hcd\n
|
A: manufacturer=Linux 5.8.0-59-generic xhci-hcd
|
||||||
A: maxchild=12\n
|
A: maxchild=12
|
||||||
A: power/active_duration=378024\n
|
A: power/active_duration=378024
|
||||||
A: power/async=enabled\n
|
A: power/async=enabled
|
||||||
A: power/autosuspend=0\n
|
A: power/autosuspend=0
|
||||||
A: power/autosuspend_delay_ms=0\n
|
A: power/autosuspend_delay_ms=0
|
||||||
A: power/connected_duration=5527220\n
|
A: power/connected_duration=5527220
|
||||||
A: power/control=auto\n
|
A: power/control=auto
|
||||||
A: power/level=auto\n
|
A: power/level=auto
|
||||||
A: power/runtime_active_kids=1\n
|
A: power/runtime_active_kids=1
|
||||||
A: power/runtime_active_time=377962\n
|
A: power/runtime_active_time=377962
|
||||||
A: power/runtime_enabled=enabled\n
|
A: power/runtime_enabled=enabled
|
||||||
A: power/runtime_status=active\n
|
A: power/runtime_status=active
|
||||||
A: power/runtime_suspended_time=5149253\n
|
A: power/runtime_suspended_time=5149253
|
||||||
A: power/runtime_usage=0\n
|
A: power/runtime_usage=0
|
||||||
A: power/wakeup=disabled\n
|
A: power/wakeup=disabled
|
||||||
A: power/wakeup_abort_count=\n
|
A: power/wakeup_abort_count=
|
||||||
A: power/wakeup_active=\n
|
A: power/wakeup_active=
|
||||||
A: power/wakeup_active_count=\n
|
A: power/wakeup_active_count=
|
||||||
A: power/wakeup_count=\n
|
A: power/wakeup_count=
|
||||||
A: power/wakeup_expire_count=\n
|
A: power/wakeup_expire_count=
|
||||||
A: power/wakeup_last_time_ms=\n
|
A: power/wakeup_last_time_ms=
|
||||||
A: power/wakeup_max_time_ms=\n
|
A: power/wakeup_max_time_ms=
|
||||||
A: power/wakeup_total_time_ms=\n
|
A: power/wakeup_total_time_ms=
|
||||||
A: product=xHCI Host Controller\n
|
A: product=xHCI Host Controller
|
||||||
A: quirks=0x0\n
|
A: quirks=0x0
|
||||||
A: removable=unknown\n
|
A: removable=unknown
|
||||||
A: rx_lanes=1\n
|
A: rx_lanes=1
|
||||||
A: serial=0000:00:14.0\n
|
A: serial=0000:00:14.0
|
||||||
A: speed=480\n
|
A: speed=480
|
||||||
A: tx_lanes=1\n
|
A: tx_lanes=1
|
||||||
A: urbnum=956\n
|
A: urbnum=956
|
||||||
A: version= 2.00\n
|
A: version= 2.00
|
||||||
|
|
||||||
P: /devices/pci0000:00/0000:00:14.0
|
P: /devices/pci0000:00/0000:00:14.0
|
||||||
E: DRIVER=xhci_hcd
|
E: DRIVER=xhci_hcd
|
||||||
|
|
@ -183,46 +183,46 @@ E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||||
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||||
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
|
||||||
E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller
|
E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller
|
||||||
A: ari_enabled=0\n
|
A: ari_enabled=0
|
||||||
A: broken_parity_status=0\n
|
A: broken_parity_status=0
|
||||||
A: class=0x0c0330\n
|
A: class=0x0c0330
|
||||||
H: config=86802F9D060490022130030C00008000040021A400000000000000000000000000000000000000000000000025108E11000000007000000000000000FF010000
|
H: config=86802F9D060490022130030C00008000040021A400000000000000000000000000000000000000000000000025108E11000000007000000000000000FF010000
|
||||||
A: consistent_dma_mask_bits=64\n
|
A: consistent_dma_mask_bits=64
|
||||||
A: d3cold_allowed=1\n
|
A: d3cold_allowed=1
|
||||||
A: dbc=disabled\n
|
A: dbc=disabled
|
||||||
A: device=0x9d2f\n
|
A: device=0x9d2f
|
||||||
A: dma_mask_bits=64\n
|
A: dma_mask_bits=64
|
||||||
L: driver=../../../bus/pci/drivers/xhci_hcd
|
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||||
A: driver_override=(null)\n
|
A: driver_override=(null)
|
||||||
A: enable=1\n
|
A: enable=1
|
||||||
A: irq=127\n
|
A: irq=127
|
||||||
A: local_cpulist=0-7\n
|
A: local_cpulist=0-7
|
||||||
A: local_cpus=ff\n
|
A: local_cpus=ff
|
||||||
A: modalias=pci:v00008086d00009D2Fsv00001025sd0000118Ebc0Csc03i30\n
|
A: modalias=pci:v00008086d00009D2Fsv00001025sd0000118Ebc0Csc03i30
|
||||||
A: msi_bus=1\n
|
A: msi_bus=1
|
||||||
A: msi_irqs/127=msi\n
|
A: msi_irqs/127=msi
|
||||||
A: numa_node=-1\n
|
A: numa_node=-1
|
||||||
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 9 10 2112 10\nxHCI ring segments 32 36 4096 36\nbuffer-2048 1 2 2048 1\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\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 9 10 2112 10\nxHCI ring segments 32 36 4096 36\nbuffer-2048 1 2 2048 1\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0
|
||||||
A: power/async=enabled\n
|
A: power/async=enabled
|
||||||
A: power/control=on\n
|
A: power/control=on
|
||||||
A: power/runtime_active_kids=1\n
|
A: power/runtime_active_kids=1
|
||||||
A: power/runtime_active_time=5524703\n
|
A: power/runtime_active_time=5524703
|
||||||
A: power/runtime_enabled=forbidden\n
|
A: power/runtime_enabled=forbidden
|
||||||
A: power/runtime_status=active\n
|
A: power/runtime_status=active
|
||||||
A: power/runtime_suspended_time=3373\n
|
A: power/runtime_suspended_time=3373
|
||||||
A: power/runtime_usage=1\n
|
A: power/runtime_usage=1
|
||||||
A: power/wakeup=enabled\n
|
A: power/wakeup=enabled
|
||||||
A: power/wakeup_abort_count=0\n
|
A: power/wakeup_abort_count=0
|
||||||
A: power/wakeup_active=0\n
|
A: power/wakeup_active=0
|
||||||
A: power/wakeup_active_count=0\n
|
A: power/wakeup_active_count=0
|
||||||
A: power/wakeup_count=0\n
|
A: power/wakeup_count=0
|
||||||
A: power/wakeup_expire_count=0\n
|
A: power/wakeup_expire_count=0
|
||||||
A: power/wakeup_last_time_ms=0\n
|
A: power/wakeup_last_time_ms=0
|
||||||
A: power/wakeup_max_time_ms=0\n
|
A: power/wakeup_max_time_ms=0
|
||||||
A: power/wakeup_total_time_ms=0\n
|
A: power/wakeup_total_time_ms=0
|
||||||
A: resource=0x00000000a4210000 0x00000000a421ffff 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: resource=0x00000000a4210000 0x00000000a421ffff 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
|
||||||
A: revision=0x21\n
|
A: revision=0x21
|
||||||
A: subsystem_device=0x118e\n
|
A: subsystem_device=0x118e
|
||||||
A: subsystem_vendor=0x1025\n
|
A: subsystem_vendor=0x1025
|
||||||
A: vendor=0x8086\n
|
A: vendor=0x8086
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,109 +0,0 @@
|
||||||
#!/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
|
|
||||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue