Compare commits

...

1648 Commits

Author SHA1 Message Date
Saeed/Ali Rk (PesarAmmehZa)
2bcb589abe Merge branch 'egiscalib' into 'master'
fix: calibration for egis0570

See merge request libfprint/libfprint!548
2025-10-29 19:39:11 +00:00
saeedark
37a7a65674 tmp: removing persistent api for now 2025-10-29 23:07:40 +03:30
saeedark
83952a76ad Revert "device: Add API for perstistent data storage"
This reverts commit 7c97dcd985.
2025-10-29 23:00:36 +03:30
saeedark
b0ce1291de test: edit to pass testes 2025-10-29 15:08:32 +03:30
Saeed/Ali Rk (PesarAmmehZa)
bef518281a Merge branch 'egiscalib-test-new' into 'egiscalib'
egis0570: add new test data

See merge request saeedark/libfprint!1
2025-10-29 11:32:14 +00:00
Jack Morton
8000439c5b egis0570: add new test data 2025-10-29 09:16:48 +00:00
saeedark
05f7631023 chore: clean up 2025-10-28 17:18:58 +03:30
saeedark
2050902767 fix: calibration for egis0570 2025-10-26 21:00:35 +03:30
Benjamin Berg
7c97dcd985 device: Add API for perstistent data storage
API consumers should fetch the persistent data when they are done and
store it to disk. It is undefined when this data is updated by the
driver, but in general, it should only be updated once the first time
a device is used.
2025-10-22 20:27:30 +03:30
Danny
596b5f8032 fpcmoc: add 10a5:a306 fingerprint reader 2025-08-08 21:30:32 +02:00
Aris Lin
7f5304d6ee synaptics: add new PID 0x019F, 0x109 and 0x10A 2025-07-31 23:56:39 +00:00
Aris Lin
bde868f05e synaptics: add usb reset in probe to recover stall condition 2025-07-31 23:56:39 +00:00
Marco Trevisan (Treviño)
a7448fbb4a ci: Only run pages step on push events 2025-08-01 01:47:17 +02:00
Marco Trevisan (Treviño)
f84ab3d104 gcovr: Add gcovr project configuration
And mark suspicious hits as warnings instead of failures
2025-08-01 01:42:01 +02:00
Benjamin Berg
da42268911 goodixmoc: fix crash in exit callback handler
If the button shield command cannot be executed due to an underlying
error then resp is NULL. Avoid the crash by adding the appropriate
check.

Closes: #694
2025-07-24 08:39:54 +02:00
Benjamin Berg
d83a785260 ci: permit coverage failures for now
gcovr seems to fail for unclear reasons. Permit failures to not block
merge requests.
2025-07-23 19:09:54 +02:00
Jordan Petridis
2b100a912b ci: Pin the version of the Flatpak template
In [1] the template broke due to the inclusion of
a sub-include which doesn't resolve across different
gitlab instances without the same group setup.

Pin the template for now to the previous working commit

[1] https://gitlab.gnome.org/GNOME/citemplates/-/merge_requests/104#note_2501085
2025-07-23 19:09:04 +02:00
Marco Trevisan (Treviño)
dc8b05f0a3 Release 1.94.9 2025-02-20 18:41:27 +01:00
Marco Trevisan (Treviño)
c37da8568f build: Use fs to get files basename
We can safely bump meson
2025-02-20 18:41:27 +01:00
Marco Trevisan (Treviño)
e401fc10e8 build: Do not use deprecated features in meson 2025-02-20 18:28:15 +01:00
Marco Trevisan (Treviño)
db48d1a4e4 build: Adapt meson version to requirements 2025-02-20 18:28:15 +01:00
Marco Trevisan (Treviño)
d1504a30b7 fp-device: Clarify docs about FP_DEVICE_RETRY_TOO_FAST
This is an error that is valid also for touch devices, so let's make it
more generic in description
2025-02-20 17:20:03 +01:00
Marco Trevisan (Treviño)
7208b29756 tests: Ignore testing external tools with valgrind 2025-02-20 15:50:46 +00:00
Marco Trevisan (Treviño)
e9dbfbec39 ci: Install appstream for testing metainfo 2025-02-20 15:50:46 +00:00
Marco Trevisan (Treviño)
c6ca915067 tests: Validate the generated metainfo if appstreamcli is available 2025-02-20 15:50:46 +00:00
Marco Trevisan (Treviño)
385bc5e384 libfprint/fprint-list-metainfo: Generate AppStream metainfo
UI tools can use this information to see what package provides support
for specific devices, so let's provide the data since we have it.
2025-02-20 15:50:46 +00:00
Marco Trevisan (Treviño)
ee73d67765 scripts/uncrustify: Use 2-spaces indentation for defines too 2025-02-20 15:50:46 +00:00
Marco Trevisan (Treviño)
4dd51f38c7 examples/clear-storage: Remove local storage for devices without storage 2025-02-20 16:37:11 +01:00
Marco Trevisan (Treviño)
5b300edbe5 examples/storage: Clear storage per device
We used to clear the whole storage file, but this has to be done
per-device, not globally
2025-02-20 16:35:58 +01:00
Marco Trevisan (Treviño)
817281f6fd examples/clear-storage: Cleanup code and use better error handling 2025-02-20 16:35:58 +01:00
Abhinav Baid
aa18595ec7 Add clear-storage example 2025-02-20 16:35:58 +01:00
Marco Trevisan (Treviño)
fa5828f8c0 fp-device: Fix introspection warnings in handling closure tag
It has to be defined in the callback, not on the data.
2025-02-20 14:34:13 +01:00
Marco Trevisan (Treviño)
fc3effd73b goodixmoc/proto: Use a byte-reader to parse the finger ID 2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
63b5908f38 goodix: Read the header using byte reader 2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
7b97bed91f ci: Add job testing libfprint using address and undefined sanitizers 2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
41949db6ce uru4000: Fix shifting using unsigned types
../libfprint/drivers/uru4000.c:743:35: runtime error: left shift of 138 by 24
places cannot be represented in type 'int'
    #0 0x7fa3e696e06d in imaging_run_state ../libfprint/drivers/uru4000.c:743
    #1 0x7fa3e6a366f6 in __ssm_call_handler ../libfprint/fpi-ssm.c:254
    #2 0x7fa3e6a38cc8 in fpi_ssm_next_state ../libfprint/fpi-ssm.c:465
    #3 0x7fa3e696bd07 in sm_read_reg_cb ../libfprint/drivers/uru4000.c:515
    #4 0x7fa3e6a3db74 in transfer_finish_cb ../libfprint/fpi-usb-transfer.c:352
    #5 0x7fa3ed9b9862 in g_task_return_now ../../glib/gio/gtask.c:1363
    #6 0x7fa3ed9b989c in complete_in_idle_cb ../../glib/gio/gtask.c:1377
    #7 0x7fa3ede4a70b in g_main_dispatch ../../glib/glib/gmain.c:3373
    #8 0x7fa3ede4c8de in g_main_context_dispatch_unlocked ../../glib/glib/gmain.c:4224
    #9 0x7fa3ede4c8de in g_main_context_iterate_unlocked ../../glib/glib/gmain.c:4289
    #10 0x7fa3ede4cfef in g_main_context_iteration ../../glib/glib/gmain.c:4354
    #11 0x7fa3e68d4a1b in fp_device_capture_sync ../libfprint/fp-device.c:2048
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
d8e0791554 goodixmoc/proto: Use FpiByteReader to parse the body
We had some read issues, so let's just use the safer reader that
makes things cleaner too

../libfprint/drivers/goodixmoc/goodix_proto.c:418:42: runtime error:
load of misaligned address 0x0000115ced29 for type 'uint16_t', which
requires 2 byte alignment
0x0000115ced29: note: pointer points here
 00 c0 3f  00 21 64 1c 00 00 00 00  64 00 43 01 01 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00
              ^
    #0 0x7f974ff9e868 in gx_proto_parse_body ../libfprint/drivers/goodixmoc/goodix_proto.c:418
    #1 0x7f974ff8ec79 in fp_cmd_receive_cb ../libfprint/drivers/goodixmoc/goodix.c:185
    #2 0x7f975003ca0c in transfer_finish_cb ../libfprint/fpi-usb-transfer.c:352
    #3 0x7f9756e57862 in g_task_return_now ../../glib/gio/gtask.c:1363
    #4 0x7f9756e5789c in complete_in_idle_cb ../../glib/gio/gtask.c:1377
    #5 0x7f97577f070b in g_main_dispatch ../../glib/glib/gmain.c:3373
    #6 0x7f97577f28de in g_main_context_dispatch_unlocked ../../glib/glib/gmain.c:4224
    #7 0x7f97577f28de in g_main_context_iterate_unlocked ../../glib/glib/gmain.c:4289
    #8 0x7f97577f2fef in g_main_context_iteration ../../glib/glib/gmain.c:4354
    #9 0x7f974fed4656 in fp_device_verify_sync ../libfprint/fp-device.c:1976
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
c7059dc61c goodixmoc: Use FpiByteReader to safely read the device CRC
This is was leading to a potential error due to misaligned memory:

../libfprint/drivers/goodixmoc/goodix.c:167:20: runtime error: load of
misaligned address 0x00001165c989 for type 'uint32_t', which requires 4 byte
alignment
0x00001165c989: note: pointer points here
 00 00 00  00 0a ac b3 09 00 00 00  00 00 00 55 53 42 00 00  00 00 00 56 42 53 00 00  00 00 00 30 30
              ^
    #0 0x7ff3ba98d190 in fp_cmd_receive_cb ../libfprint/drivers/goodixmoc/goodix.c:167
    #1 0x7ff3baa3b235 in transfer_finish_cb ../libfprint/fpi-usb-transfer.c:352
    #2 0x7ff3c18ca862 in g_task_return_now ../../glib/gio/gtask.c:1363
    #3 0x7ff3c18ca89c in complete_in_idle_cb ../../glib/gio/gtask.c:1377
    #4 0x7ff3c228470b in g_main_dispatch ../../glib/glib/gmain.c:3373
    #5 0x7ff3c22868de in g_main_context_dispatch_unlocked ../../glib/glib/gmain.c:4224
    #6 0x7ff3c22868de in g_main_context_iterate_unlocked ../../glib/glib/gmain.c:4289
    #7 0x7ff3c2286fef in g_main_context_iteration ../../glib/glib/gmain.c:4354
    #8 0x7ff3ba8d2fe5 in fp_device_open_sync ../libfprint/fp-device.c:1874
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
0c315b4f0a tests/goodixmoc: Add explicit test on print description
So that we can ensure that what we get from device matches
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
b04553cac9 goodix-proto: Do not memcpy NULL values
../libfprint/drivers/goodixmoc/goodix_proto.c:214:5: runtime error: null pointer passed as argument 2, which is declared to never be null
    #0 0x7f378839c3e5 in gx_proto_build_package ../libfprint/drivers/goodixmoc/goodix_proto.c:214
    #1 0x7f378838fd9e in alloc_cmd_transfer ../libfprint/drivers/goodixmoc/goodix.c:309
    #2 0x7f378838ffe4 in goodix_sensor_cmd ../libfprint/drivers/goodixmoc/goodix.c:336
    #3 0x7f378839a778 in gx_fp_template_delete_all ../libfprint/drivers/goodixmoc/goodix.c:1602
    #4 0x7f37882d3d59 in fp_device_clear_storage ../libfprint/fp-device.c:1820
    #5 0x7f37882d50af in fp_device_clear_storage_sync ../libfprint/fp-device.c:2132
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
c1dcaa805d goodixmoc: Fix potential invalid shift on integer type
../libfprint/drivers/goodixmoc/goodix_proto.c:111:26: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
    #0 0x7f6776799c2e in reflect ../libfprint/drivers/goodixmoc/goodix_proto.c:111
    #1 0x7f677679a0f3 in crc32_final ../libfprint/drivers/goodixmoc/goodix_proto.c:147
    #2 0x7f677679a3ee in gx_proto_crc32_calc ../libfprint/drivers/goodixmoc/goodix_proto.c:164
    #3 0x7f677679d7aa in gx_proto_init_sensor_config ../libfprint/drivers/goodixmoc/goodix_proto.c:464
    #4 0x7f6776797b40 in gx_fp_init ../libfprint/drivers/goodixmoc/goodix.c:1415
    #5 0x7f67766cc56e in fp_device_open ../libfprint/fp-device.c:866
    #6 0x7f67766d2fd4 in fp_device_open_sync ../libfprint/fp-device.c:1872
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
7b2895271d synaptics: Do not call memcpy with NULL data
../libfprint/drivers/synaptics/bmkt_message.c:260:5: runtime error: null pointer passed as argument 2, which is declared to never be null
    #0 0x7fd21f154592 in bmkt_compose_message ../libfprint/drivers/synaptics/bmkt_message.c:260
    #1 0x7fd21f14596c in synaptics_sensor_cmd ../libfprint/drivers/synaptics/synaptics.c:417
    #2 0x7fd21f14d93f in dev_probe ../libfprint/drivers/synaptics/synaptics.c:1329
    #3 0x7fd21f0ca61d in device_idle_probe_cb ../libfprint/fp-device.c:375
    #4 0x7fd21f21a431 in timeout_dispatch ../libfprint/fpi-device.c:336
    #5 0x7fd2269cf70b in g_main_dispatch ../../glib/glib/gmain.c:3373
    #6 0x7fd2269d18de in g_main_context_dispatch_unlocked ../../glib/glib/gmain.c:4224
    #7 0x7fd2269d18de in g_main_context_iterate_unlocked ../../glib/glib/gmain.c:4289
    #8 0x7fd2269d1fef in g_main_context_iteration ../../glib/glib/gmain.c:4354
    #9 0x7fd21f0c5a85 in fp_context_enumerate ../libfprint/fp-context.c:575
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
3e653fe85b build/tests: Increase timeout multiplier in valgrind
CI is quite slow these days, so let's give valgrind more time
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
830a9977c0 build: Support running tests with memory sanitizers
When memory sanitizers are set, tests may fail because we are indirectly
LD_PRELOAD'ing (through umockdev). While we could ensure that sanitizer
libraries are loaded first, it's just something we don't care because we
don't want to test the launcher wrappers themselves.

So, let's just ignore the link order and live with it
2025-02-13 23:51:52 +00:00
Marco Trevisan (Treviño)
6b914a2070 data: Update unsupported devices list 2025-02-14 00:40:16 +01:00
Marco Trevisan (Treviño)
22e6670aa0 elanspi: Add elanspi PID 0x2766
Patch by Z. A.

Closes: #571
2025-02-14 00:29:17 +01:00
Marco Trevisan (Treviño)
6723b74f86 elanspi: Add elanspi PID 0x3128
Patch by Alexey Vishnyakov

Closes: #650
2025-02-13 23:22:46 +01:00
Marco Trevisan (Treviño)
7d9638bc43 goodix: Add support for PID 0x60C2
Patch by Sergey Kokorin

Closes: #646
2025-02-13 22:01:02 +00:00
huan_huang
559c18785b realtek: modify the way to store userid in enroll flow
Signed-off-by: huan_huang <huan_huang@realsil.com.cn>
2025-02-13 20:40:49 +00:00
MrNerdHair
9e8dda5f17 upekts: fix typo 2025-02-13 19:20:10 +00:00
MrNerdHair
f906afb757 upekts: handle more retryable verify errors 2025-02-13 19:20:10 +00:00
MrNerdHair
1c4ed2e225 fp-device: add FP_DEVICE_RETRY_TOO_FAST error code 2025-02-13 19:20:10 +00:00
MrNerdHair
cdc22b4553 upekts: fix verify 2025-02-13 19:20:10 +00:00
Marco Trevisan (Treviño)
57c535d0cb libfprint.supp: Ignore libusb context init potential leak 2025-02-13 18:52:24 +00:00
Marco Trevisan (Treviño)
a94a55b8df ci: Use distro-provided umockdev
It's new enough nowadays
2025-02-13 18:52:24 +00:00
Marco Trevisan (Treviño)
133eaab061 uru4000: Use OpenSSL to perform AES-ECB encryption
Drop usage of NSS library now that openssl >= 3.0 has not anymore any
license incompatibility.

OpenSSL will provide us a better ground for further developments and
it's also the preferred crypto library by most distros these days
2025-02-13 18:52:24 +00:00
Dadoum
7a60912b61 Empty commit to hopefully fix the pipeline. 2025-02-13 18:52:24 +00:00
Marco Trevisan (Treviño)
6702c32b2b tests/meson: Ignore debug messages when generating hwdb 2025-02-13 19:31:16 +01:00
Marco Trevisan (Treviño)
b8ed4b5d63 tests/virtual-image: Use sleep multiplier when running under valgrind 2025-02-13 18:46:15 +01:00
Marco Trevisan (Treviño)
8433563602 tests: Do not enable virtual device hot seconds under valgrind
Valgrind tests may be slow, leading the devices to be considered hot.

We don't disable this for other tests, since we may still want to be
sure that the logic is fine for normal usage
2025-02-13 18:46:15 +01:00
Marco Trevisan (Treviño)
026c09d0b4 virtual-{image, device}: Make hot seconds value to be configurable 2025-02-13 18:46:15 +01:00
Marco Trevisan (Treviño)
3abdda4391 tests/virtual-image: Do not send images or retries if driver is not waiting finger 2025-02-13 03:36:52 +01:00
Marco Trevisan (Treviño)
981f8e0a42 virtual-image: Only receive image when waiting for finger
We may send an image when not waiting it, leading to a failure:

libfprint-image_device-DEBUG: 00:55:29.669: Image device internal state change
  from FPI_IMAGE_DEVICE_STATE_DEACTIVATING to FPI_IMAGE_DEVICE_STATE_INACTIVE
libfprint-image-DEBUG: 00:55:31.861: Minutiae scan completed in 2.204906 secs
libfprint-print-DEBUG: 00:55:56.902: score 1093/40
libfprint-device-DEBUG: 00:55:56.902: Device reported verify result
libfprint-device-DEBUG: 00:55:56.902: Device reported verify completion
libfprint-device-DEBUG: 00:55:56.903: Updated temperature model after 27.26
  seconds, ratio 0.69 -> 0.73, active 1 -> 1,
  FP_TEMPERATURE_WARM -> FP_TEMPERATURE_HOT
libfprint-device-DEBUG: 00:55:56.906: Completing action
  FPI_DEVICE_ACTION_VERIFY in idle!
libfprint-device-DEBUG: 00:55:56.906: Updated temperature model after 0.00
  seconds, ratio 0.73 -> 0.73, active 0 -> 0,
  FP_TEMPERATURE_HOT -> FP_TEMPERATURE_HOT
libfprint-device-DEBUG: 00:55:56.910: Updated temperature model after 0.00
  seconds, ratio 0.73 -> 0.73, active 1 -> 1,
  FP_TEMPERATURE_HOT -> FP_TEMPERATURE_HOT
libfprint-device-DEBUG: 00:55:56.910: Updated temperature model after 0.00
  seconds, ratio 0.73 -> 0.73, active 0 -> 0,
  FP_TEMPERATURE_HOT -> FP_TEMPERATURE_HOT
libfprint-virtual_image-DEBUG: 00:55:56.912: image data: 0xc8f6c10
libfprint-device-DEBUG: 00:55:56.916: Device reported finger status change:
  FP_FINGER_STATUS_PRESENT
libfprint-image_device-DEBUG: 00:55:56.917: Ignoring finger presence report as
  the device is not active!
libfprint-image_device-CRITICAL **: 00:55:56.918:
  fpi_image_device_image_captured: assertion
  'priv->state == FPI_IMAGE_DEVICE_STATE_CAPTURE' failed
2025-02-13 02:51:41 +01:00
Dadoum
f18e11b435 Empty commit to hopefully fix the pipeline. 2025-02-12 21:03:10 +00:00
Dadoum .
42d10118a3 Synaptics: add new PID 0x016C 2025-02-12 21:03:10 +00:00
Johnathon Clark
51d827fc74 Add support for the 10a5:c844 FPC fingerprint reader as found on
recent Lenovo Yoga i9 laptops.
2025-02-12 20:55:19 +00:00
wangyong
1859a1e5d1 add new pid: 0xa99a, 0xa57a, 0xa78a 2025-02-12 20:45:15 +00:00
Marco Trevisan (Treviño)
7292dd642c ci: Only run uncrustify check if source files have been changed 2025-02-12 20:36:46 +00:00
Marco Trevisan (Treviño)
8e22b2e22e ci: scan-build, ignore meson-built files
Like .gir introspection files that are generated are currently failing
2025-02-12 20:36:46 +00:00
Marco Trevisan (Treviño)
28b9ab7e37 tests: Ignore more python leaks 2025-02-12 20:36:46 +00:00
Marco Trevisan (Treviño)
9141014456 ci: Let's stick to fedora 41 for now
Rawhide seems to be a bit broken, so let's go with the stable version
2025-02-12 20:36:46 +00:00
Marco Trevisan (Treviño)
6f3ab36b2e ci: Enable running pipelines on schedules or to force rebuild 2025-02-12 20:36:46 +00:00
Marco Trevisan (Treviño)
d3035d5703 ci: Use rules to control when to run images build 2025-02-12 20:36:46 +00:00
Egor Ignatov
042365dbec elanmoc: Add new PID 0x0C98
Tested-on: Lenovo IdeaPad 5 2-in-1 16AHP9
Signed-off-by: Egor Ignatov <egori@altlinux.org>
2025-02-11 20:54:24 +00:00
Zihan Chen
0c7211329e synaptics: add new PID 0x0174
Found and tested on HP Omnibook Ultra Flip
2025-02-11 20:02:38 +00:00
herman lin
e1b6d8a461 elanmoc: Add new PID 0x0C9D and 0x0CA3 2025-02-10 13:49:05 +08:00
Aris Lin
09ec6e66e3 synaptics: Add new PID 0x0107 and 0x108, also fine tune PID sequence 2024-11-18 11:18:29 +08:00
SirCipherz
8ce356fccc Update autosuspend.hwdb 2024-09-05 11:05:02 +02:00
SirCipherz
98f5ad1f80 Add support for goodix 689a 2024-09-04 16:31:06 +02:00
Marco Trevisan (Treviño)
29f919b4eb build: Sum arrays instead of mixing them 2024-09-03 06:29:55 +02:00
Marco Trevisan (Treviño)
e57bab2f1e Release 1.94.8 2024-09-03 05:14:11 +02:00
huan_huang
a88582761f realtek: add support for rts5816
Signed-off-by: huan_huang <huan_huang@realsil.com.cn>
2024-09-03 04:44:04 +02:00
Marco Trevisan (Treviño)
75adfd37d1 egismoc: Add PID 0x0583
As per comment:
 - https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/630#note_2547528
2024-08-30 04:42:56 +02:00
Tamer Hassan
990bd40cbf egismoc: add 0586 support 2024-08-30 04:42:56 +02:00
Tamer Hassan
c7e95bb41f egismoc: add 0587 support (also supports 0586 but missing device file) 2024-08-30 04:42:56 +02:00
Nkaspers
4611cc4a1b Synaptics: add new PID 0x00C4
And drop it from the unsupported list
2024-08-30 04:34:34 +02:00
Marco Trevisan (Treviño)
78c78432b9 build: Generalize spi drivers detection
Don't be limited to elan only
2024-08-30 04:16:48 +02:00
Daniel Schaefer
10e1cd76aa Don't build SPI driver on non-Linux
Doesn't build on other operating systems.
With auto-detection we don't have to manually select all other drivers.

Signed-off-by: Daniel Schaefer <dhs@frame.work>
2024-08-30 04:06:43 +02:00
Daniel Schaefer
c84d3774cf libfprint: Don't build SPI backend if not SPI driver
The SPI backend only builds on Linux, this makes it work non non-Linux platforms, such as FreeBSD.

Signed-off-by: Daniel Schaefer <dhs@frame.work>
2024-08-30 02:00:16 +00:00
Haowei Lo
04a167b09b fpcmoc: Add PID 0x9524 and 0x9544
Change-Id: Id85116df233308297cf3d7b56146582a79f5fcdd
2024-08-30 01:33:03 +00:00
Aris Lin
538a18cf17 synaptics: Add new PID 0x00C6 2024-08-30 00:57:29 +00:00
Aris Lin
2e766904f0 synaptics: Add new PID 0x019D 2024-08-30 00:57:29 +00:00
haoweilo
9f55ef690d fpcmoc: fixed the error jumping to wrong state at end of custom enroll 2024-08-30 00:47:01 +00:00
herman lin
b6061c0af8 elanmoc: Add new PID 0x0C9F 2024-08-08 14:08:19 +08:00
Marco Trevisan (Treviño)
3f70bde21c fp-device: Do not duplicate udev paths strings
This is happening already internally when using g_value_set_string
2024-06-17 19:08:16 +00:00
Timo Schrader
dd6f020378 goodixmoc: Add PID 0x609A 2024-06-17 17:57:29 +00:00
2a4c05662a goodixmoc: Add PID 0x6512 2024-06-15 12:17:34 -05:00
Marco Trevisan (Treviño)
eaec2339cc libfprint-fprint-list-udev-hwdb: Add new broadcom device IDs 2024-05-22 17:09:38 +02:00
Marco Trevisan (Treviño)
83035be830 README: Add contact information 2024-05-03 15:35:11 +02:00
Marco Trevisan (Treviño)
4709efc678 fpi-device: Clarify transfer of errors in device complete tasks 2024-04-17 17:00:47 +00:00
Marco Trevisan (Treviño)
37ded921fd fpi-device: Simplify logic of fpi_device_task_return_data_free
The clear functions will do NULL checks already, so there's no need to
duplicate such effort
2024-04-17 17:00:47 +00:00
Haowei Lo
b7f3544e98 fpcmoc: Transfer error from autoptr before fpi_device_close_complete
Fixed coredump because of trying to free a null space

Change-Id: If5a23ba7b4f307580593712612e150d1ab893826
2024-04-18 00:38:44 +08:00
steven.chen
093f2fc0a6 fpcmoc: Modify ctrl timeout to fix identify return failed 2024-04-17 15:05:06 +00:00
Lee Jiajun
c5def9a528 goodixmoc: Add PID 0x609A 2024-04-17 09:37:25 +00:00
haoweilo
e71f3de786 fpcmoc: add error handling to evt_finger_dwn
Redo the current task state
if we got failed status from evt_finger_dwn
2024-04-17 08:33:24 +00:00
haoweilo
420fd7416d fpcmoc: fix incorrect immobile handling during enrollment
For the custom enrollment,
if the number of immobile touches have reached the maximum,
we should treat this touch as normal (valid) and increase
the enrollment progress.
2024-04-17 08:33:24 +00:00
Haowei Lo
f505158c04 fpcmoc: clean cmd_ssm before callback
fixed assertion of "cmd_ssm is not null"

Change-Id: I8f914468dc0e40c6cac33d680411a2d957cf2296
2024-04-16 21:46:19 +08:00
Jichi Zhang
fb13722629 goodixmoc: Add PID 0x650C 2024-03-13 05:16:16 -07:00
Marco Trevisan (Treviño)
666cd0c08d egismoc: Use FpiByteReader to compute the check bytes
We can read the values in the proper format without having to
deal with endianness ourself, so let's do this instead of manual
labor.
2024-02-20 18:07:18 +01:00
Marco Trevisan (Treviño)
e055781006 egismoc: Use FpiByteWriter to allocate the commit payload 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
48c8c539c7 egismoc: Use FpiByteWriter to generate the get check command 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
40c7599fb1 egismoc: Compute the delete command using FpiByteWriter 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
28c26c7d7e egismoc: Use FpiByteReader to read the enrolled IDs 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
dd5a71695f egismoc: Use FpiByteWriter to prepare the command message 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
977d324970 egismoc: Do not store twice the number of enrolled IDs
We already store it in the array, so let's just use that value
2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
4992110829 fpi-byte-writer: Zero-init the allocated data by default
This could have been done via fill method + pos reset, but it's just
something we normally want to do for safety, so let's do it all the
times.
2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
53f2539b6a fpi-byte-writer: Use nicer API to unset the parent data 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
18e2906d62 fpi-byte-writer: Initialize the parent size when initializing with size 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
19806546a2 fpi-byte-writer: Add change pos method
It allows to move the position of the cursor with a relative position.
2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
75559415fe fpi-byte-writer/reader: Add autopointers definitions 2024-02-20 17:57:46 +01:00
Marco Trevisan (Treviño)
7dbb21e77a build/tests: Skip a test if the test requires it during inspection
In case we don't have dependencies, we should skip the test, otherwise
we can just fail at test time
2024-02-20 08:25:53 +01:00
Marco Trevisan (Treviño)
4b72f27de6 build: Look for sh just once 2024-02-20 08:22:42 +01:00
Marco Trevisan (Treviño)
5ada931ede ci: Export coverage to pages
So that we can link it outside
2024-02-20 01:55:11 +01:00
Marco Trevisan (Treviño)
bebe8565cd Release 1.94.7 2024-02-20 01:09:54 +01:00
Marco Trevisan (Treviño)
5501dc7b47 build: Stop using deprecated dep.get_pkgconfig_variable() method
Use generic get_variable() instead
2024-02-20 01:02:00 +01:00
Marco Trevisan (Treviño)
3e5ab6fdad egismoc: Convert value check values to big endian only when needed
Since the driver seem to require a big-endian value it's just better
to use architecture native endianness to compute the check value and
eventually just convert to big endian as the chip wants.
2024-02-19 23:38:40 +01:00
Marco Trevisan (Treviño)
5462db9901 egismoc: Convert the check value to little endian
In this way we can support the big-endian architectures too.
2024-02-19 23:38:40 +01:00
Marco Trevisan (Treviño)
59dc585ccd egismoc: Simplify check bytes computation
We use big endian values for generating the check bytes, but we can do
the same logic in a simpler way.
2024-02-19 23:38:40 +01:00
Marco Trevisan (Treviño)
6768bd0ff4 egismoc: Use strictly sized types to hold check bytes contents
So we are sure about the size we're sending at compile time too.
2024-02-19 23:38:40 +01:00
Marco Trevisan (Treviño)
ed1815c3d9 build: Allow testing more drivers in both big and little endian
I've tested them in a s390x host and many more tests work fine, so let's
enable them.
2024-02-19 23:38:40 +01:00
Marco Trevisan (Treviño)
057c209beb build: Build-depend on glib 2.68
GLib 2.68 is now more than 3 years old, so we can definitely start
using it without thinking too much.

This allows us to drop lots of compat code that we had around.

And like the previous commit tells us, it will also help us to have
more correct code around.
2024-02-19 22:23:02 +01:00
Marco Trevisan (Treviño)
90c4afded4 cleanup: Use non-const pointers for non constant cases
We had various cases in which we were using const pointers for
non constant data, and in fact we were allocating and free'ing
them.

So let's handle all these case properly, so that we won't have
newer GLib complaining at us!
2024-02-19 22:14:14 +01:00
Marco Trevisan (Treviño)
f8f28a066b egismoc: Simplify fingerprint id and firmware reading
We can do copy and duplicate in oneshot since we are handling strings
after all.
2024-02-19 17:25:21 +01:00
Marco Trevisan (Treviño)
adc66edd8d egismoc: Implement suspension properly
In case of suspension we can't just cancel the operations but
also return when completed, and this may not happen immediately
if there are ongoing operations.

This is automagically handled by libfprint internals, but in order
to make it happen, we need to cancel the ongoing operations and then
mark it completed. libfprint will then wait for the task completion
before actually marking the device as suspended.
2024-02-19 17:21:58 +01:00
Marco Trevisan (Treviño)
9af211cc89 egismoc: Use device cancellable on transfers 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
904bddd988 egismoc: Use g_new0 instead of g_malloc to make the type clearer 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
8badfa84e9 egismoc: Assert that current transfer is unset when setting it
We need to ensure that we are not overwriting the instance transfer, so
that we can be sure that we are only doing one transfer at time.

Also we need to ensure that the ssm unsetting it, is the owner of it.
2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
b97efa6fed egismoc: Assert that task ssm is unset when setting it
We need to ensure that we are not overwriting the instance SSM, so that
we can be sure that we are only doing one operation at time.

Also we need to ensure that the task unsetting it, is the owner of it.
2024-02-19 17:12:12 +01:00
Joshua Grisham
591f9ad3cf egismoc: clear task pointers also after dev_init_done 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
6767cd1a4f egismoc: Ensure that the command callback is after SSM is completed
We need to make sure that we won't trigger a callback when a SSM is
already in progress or we may end up overwriting it
2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
226b6abfab egismoc: Use an autopointer to cleanup error on command done callback 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
9e2c14d64e egismoc: Clarify delete print ownership in delete callback 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
92aeb53ee8 egismoc: Simplify egismoc identification stage handling 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
87f68e3ac1 egismoc: Avoid gotos in init code, just handle the errors immediately 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
8073a5dc34 egismoc: Remove unused increments
This is also to please static analyzer
2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
eb09156244 egismoc: Clear enrolled IDs using nicer GLib api 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
b8cfb95b49 egismoc: Ensure we've enough null bytes at the end of strings 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
a7843add0f egismoc: Do not initialize to zero twice 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
b0f0322726 egismoc: Indentation and syntax fixes 2024-02-19 17:12:12 +01:00
Marco Trevisan (Treviño)
7476faba68 data, libfprint: Update list of unsupported drivers 2024-02-19 16:16:02 +01:00
Joshua Grisham
89ab54794e egismoc: added test and capture for 05a1 variant 2024-02-19 16:16:02 +01:00
Joshua Grisham
85da0e104b egismoc: add support for 1c7a:05a1 2024-02-19 16:16:02 +01:00
Joshua Grisham
47fe3668e4 egismoc: Return truncated text instead of null for description when using list 2024-02-19 16:16:02 +01:00
Joshua Grisham
7aae2181e2 egismoc: Add support for usernames longer than 8 chars 2024-02-19 16:16:02 +01:00
Joshua Grisham
a9269980eb egismoc: Fix crash during close 2024-02-19 16:16:02 +01:00
Joshua Grisham
0b9a64331f Initial commit of egismoc driver 2024-02-19 16:16:02 +01:00
Adam Jones
54ff730f0c Fix typo of libfprint in supported devices list
This also updates the title of the website page at https://fprint.freedesktop.org/supported-devices.html
2024-02-13 16:13:10 +00:00
Marco Trevisan (Treviño)
e05fbaa8ab realtek: Do not initialize variables in switch cases
Handles scan-build warning
2024-02-13 14:54:42 +00:00
Marco Trevisan (Treviño)
61f9346aaf realtek: Do not leak an error
Found by scan-build.
2024-02-13 14:54:42 +00:00
Marco Trevisan (Treviño)
d878148b5e ci: Expose scan build artifacts on failures
That's the only case we care about
2024-02-13 14:54:42 +00:00
Marco Trevisan (Treviño)
ee509c7ee6 libfprint/fprint-list-udev-hwdb: Update unsupported list from wiki 2024-02-13 15:28:53 +01:00
Marco Trevisan (Treviño)
2fa0975dec cleanup: Address some newer uncrustify syntax cleanups 2024-02-13 15:25:15 +01:00
Marco Trevisan (Treviño)
f3ab1f996f fp-context: use g_strv_contains instead of manual labor 2024-02-13 15:25:15 +01:00
Marco Trevisan (Treviño)
92c5fc4643 cleanup: Use allow/deny lists instead of color based ones
There was nothing racist on those names here (what? Do human races even
exist?!), but let's avoid any confusion.
2024-02-13 15:19:47 +01:00
Puspendu Banerjee
c64fa9c81b synaptics: Add new PID 0x0124 2024-02-13 14:45:47 +01:00
Marco Trevisan (Treviño)
85ec9ec5b2 ci: Allow flatpak failure
It's not a critical thing, so if it fails (as it does currently) we
should not block on that.
2024-02-13 14:42:18 +01:00
Marco Trevisan (Treviño)
b8933d8f81 fp-print: Do not check compile-time macros at runtime 2024-02-13 14:36:46 +01:00
xiaofei
631da4654f focaltechmoc:Support FocalTech moc devices
Supported UID: 0x2808
    Supported PIDs: 0x9E48, 0xD979, 0xa959
2024-02-13 14:34:12 +01:00
Mohammed Anas
1701d72ff9 tests: make mktemp command call work with Chimera Linux's mktemp
On Chimera Linux, which uses FreeBSD's userland tools, the original call
fails with the following error:

mktemp: mkstemp failed on /tmp/libfprint-XXXXXX.hwdb: Invalid argument

Moving the X's to the end of the template passed to `mktemp` fixes the
error, and also works with GNU's `mktemp`.
2024-01-22 15:52:46 +00:00
Mohammed Anas
d3ec9a80d3 tests: remove Bash dependency in favor of sh
The script works just fine with `sh`.

Also replace nonstandard `test` operator `==` with the standard `=`.

The other changes are mostly cosmetic.
2024-01-22 15:27:33 +00:00
Marco Trevisan (Treviño)
5a1253e37c fp-image: Do not start thread detection task thread if already running 2023-11-24 21:02:50 +01:00
Marco Trevisan (Treviño)
2b008b52d7 fp-image: Simplify minutiae detection tasks
We can just use a GTask to handle the detection while using the
finish function to process the results to the image, so that it
is more predictable when this happens and it does not depend on
a thread returning.

Also remove data duplication when possible, this class wasn't
fully safe anyway to be used concurrently, so there's no point
to copy data when not needed. Also added the hard constraint to
not proceed with minutiae detection if something else is already
doing this.

At the same time we can mark the task to finish early on
cancellation.
2023-11-21 16:43:04 +00:00
Marco Trevisan (Treviño)
83939abe10 fp-image: Add FP_IMAGE_NONE flags definition 2023-11-21 16:43:04 +00:00
Marco Trevisan (Treviño)
16d02b3ed5 fp-image: Remove unused ref_count flag
It's an object so we already ref-count it.
2023-11-21 16:43:04 +00:00
huan_huang
79be91831c drivers: add realtek rts5813 driver 2023-10-27 13:21:06 +00:00
Aris Lin
427139f347 synaptics: Add new PID 0x0106 2023-10-24 14:56:15 +08:00
Aris Lin
3ebd2c3f97 synaptics: Add new PID 0x0173 2023-10-19 14:25:09 +08:00
Marco Trevisan (Treviño)
2414dbdbd4 libfprint/fprint-list-udev-hwdb: Update unsupported devices from wiki 2023-09-27 19:44:37 +02:00
swbgdx
0eae0e8cc0 goodixmoc: Add PID 0x6582 2023-09-27 16:10:03 +00:00
Marco Trevisan (Treviño)
efba965b0c ci: Build flatpak using gnome master
Also bump dependencies versions
2023-09-27 17:47:38 +02:00
Marco Trevisan (Treviño)
26d2c77c3d ci: Allow manual flatpak build in any fork and MR 2023-09-27 17:29:24 +02:00
Marco Trevisan (Treviño)
eb01d7c97d ci: Fix building flatpak using GNOME 42 runtime
Use versioned ci template so we are sure what we're using
2023-09-27 17:10:31 +02:00
Vincent Huang
5bff5bfea6 synaptics: Add null check to prevent g_propagate_error assertion failure 2023-09-11 16:58:33 +08:00
Vincent Huang
206e92218c synaptics: fix enroll_identify problem after user reset database 2023-09-01 09:47:12 +00:00
Marco Trevisan (Treviño)
af3dca9003 tests/egis0570/capture.pcapng: Remove execution permission 2023-08-22 23:08:55 +00:00
Marco Trevisan (Treviño)
b924d715c9 ci: Move build dir during installed tests so we check that we don't use built artifacts 2023-08-21 14:19:27 +00:00
Marco Trevisan (Treviño)
1372d6f081 tests: Use native GTest utils to generate assets names 2023-08-21 14:19:27 +00:00
Marco Trevisan (Treviño)
135a015b6a Release 1.94.6 2023-08-17 05:08:04 +02:00
swbgdx
96645eaa7a goodixmoc: Add PID 0x633C and 0x6304 2023-08-17 01:37:56 +00:00
hermanlin
d37b255a11 elanmoc: add PID 0x0C99 2023-07-10 11:17:27 +08:00
Marco Trevisan (Treviño)
903ee43b2d ci: Do not force-rebuild if an image with such tag exists 2023-06-28 16:35:16 +02:00
Marco Trevisan (Treviño)
8562f8a964 ci: Use meson commands only to setup, compile and install
Old ones are semi-deprecated, so let's adjust to what upstream suggests
2023-06-28 16:35:16 +02:00
Marco Trevisan (Treviño)
5ff794c105 ci: Run installed tests 2023-06-28 16:35:16 +02:00
Marco Trevisan (Treviño)
f68e0972c2 ci: Auto-Retry jobs on infrastructure failures 2023-06-28 16:35:16 +02:00
Marco Trevisan (Treviño)
ba3cc04e84 tests: Add support for installed tests
They allow distrubtions to check whether libfprint continues working as
expected, in different contexts.
2023-06-28 16:35:16 +02:00
Marco Trevisan (Treviño)
3d4cf44f9b ci: Add gnome-desktop-testing to the image
It can be used to run the installed tests.
2023-06-28 16:23:45 +02:00
Marco Trevisan (Treviño)
8e702012fd ci: Use debuginfo-install to install debug symbols
dnf doesn't seem to handle the plugin well in rawhide:

  bash-5.2# dnf -y debuginfo-install glib2
    Unknown argument "debuginfo-install" for command "dnf5".
    Add "--help" for more information about the arguments.
2023-06-28 15:58:48 +02:00
Marco Trevisan (Treviño)
f49879b522 tests/virtual-image: Support passing specific FP_PRINTS_PATH env variable 2023-06-24 00:28:04 +02:00
Marco Trevisan (Treviño)
5e0bf2446b meson: Bump requirements to 0.56 and adapt deprecated functions 2023-06-24 00:28:04 +02:00
Marco Trevisan (Treviño)
4d96a3efaa tests/virtual-device: Check that removed devices are not in context anymore 2023-06-23 18:20:04 +02:00
Marco Trevisan (Treviño)
c27d72e3a1 tests/virtual-device: Do not preserve context on unplug tests
The unplug tests assume that the device is removed from the context once
they run, however we may have left the device around in a removed state
causing other tests to fail.

So isolate them in a new class where we create context and device
instances every time we run a test case.
2023-06-22 06:59:00 +02:00
Marco Trevisan (Treviño)
0819df6988 virtual-device: Reset transient parameters on deinit
Tests may change some options so we need to reset these values, even
though some may need not to be reserved when not in keep-alive mode.
2023-06-22 06:55:44 +02:00
Marco Trevisan (Treviño)
28579239a6 tests/virtual-device: Reset keep alive status when test is done
We don't want this to be preserved across tests, since it's meant to be
used inside a single test case.
2023-06-22 06:55:44 +02:00
Marco Trevisan (Treviño)
e48d2b467a tests/virtual-device: Restore default enroll steps on tearDown
When running the tests as a single script we may leave the device in an
inconsistent state, so reset the enroll steps when done.
2023-06-22 06:55:44 +02:00
Marco Trevisan (Treviño)
1c589336a2 meson: Remove duplicate gnome imports 2023-06-22 06:55:44 +02:00
Egor Ignatov
9546659c15 goodixmoc: add PID 0x60A4
Signed-off-by: Egor Ignatov <egori@altlinux.org>
2023-06-21 19:28:38 +03:00
haoweilo
c782298ae4 fpcmoc: Ensure the current SSM is never overwritten 2023-06-21 15:09:00 +00:00
Elytscha Smith
682fce6a5b goodixmoc: add PID 0x60BC 2023-03-28 15:59:48 +00:00
swbgdx
6ed1b707d5 goodixmoc: Add PID 0x6092 2023-03-15 15:45:56 +00:00
Marco Trevisan (Treviño)
9fd2ccff29 virtual-device-listener: Always return task even if we got zero bytes
See: https://gitlab.gnome.org/GNOME/glib/-/issues/1346
2023-03-15 15:26:37 +00:00
Marco Trevisan (Treviño)
b6223a9d0a test-fpi-device: Only push pragma -wdanging-pointer in newer GCC versions
It may not be supported and warn otherwise
2023-03-15 15:23:17 +00:00
Marco Trevisan (Treviño)
5e98f10011 ci: Do not require coverage to always happen
meson coverage could be broken in some cases, so let's ignore the error
for now if it happens.
2023-03-15 16:18:17 +01:00
Marco Trevisan (Treviño)
e7ca05e1bf ci: Use proper name for valgrind junit file 2023-03-15 16:18:17 +01:00
Marco Trevisan (Treviño)
677c50fc51 fprint-list-supported-devices: Do not double-free usb_list
We were leaking the spi_list instead.
2023-03-15 14:50:41 +01:00
Bastien Nocera
bb5feeca77 ci: Use detached pipelines
See https://gitlab.freedesktop.org/freedesktop/freedesktop/-/issues/438#what-it-means-for-me-a-maintainer-of-a-project-part-of-gitlabfreedesktoporg
2023-03-15 13:33:52 +01:00
wagner.oliveira
22683ec490 Fix AES4000 wrong IDs (swapped pid/vid) 2023-01-27 18:23:55 -05:00
Enrik Berkhan
0bf7d58c5e goodixmoc: cleanup enroll state machine
As suggested by @benzea, the following cleanup actions have been
performed:

  - let case order match enroll states enum

  - remove FP_ENROLL_IDENTIFY that is no longer used

  - finally use fpi_ssm_next_state instead of explicitly jumping to
    FP_ENROLL_CREATE

Additionally, all types/functions/variables referring to "enroll_init"
used for FP_ENROLL_CREATE have been renamed to match "enroll_create".
All other states use similar name matching.

Signed-off-by: Enrik Berkhan <Enrik.Berkhan@inka.de>
2023-01-19 20:30:05 +01:00
Enrik Berkhan
86566e8d0b goodixmoc: Fix missing "enroll create" state
After the driver internal duplicate check had been removed in
46669e9f53, all templates were saved with
an all-zeroes template ID.

By going through FP_ENROLL_CREATE before starting to capture, the
template ID returned from the device is taken into account again.

Signed-off-by: Enrik Berkhan <Enrik.Berkhan@inka.de>
2023-01-19 20:28:33 +01:00
Zoltán Böszörményi
7080a5ff8b Abort initialization if unknown sensor dimensions are reported
Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
2023-01-17 19:50:21 +00:00
Zoltán Böszörményi
5e52ad2ad1 upektc_img: Add new unit test for the TCS1s chip variant 2023-01-17 19:50:21 +00:00
Zoltán Böszörményi
bfaa9a9241 upektc_img: Fix asynchronous problem in init_read_data_cb() 2023-01-17 19:50:21 +00:00
Zoltán Böszörményi
9c900789de upektc_img: Add asserts for expected height reported by the device 2023-01-17 19:50:21 +00:00
Zoltán Böszörményi
29a24ba67f upektc_img: Add finger status changes 2023-01-17 19:50:21 +00:00
Zoltán Böszörményi
987f23698e upektc_img: Deduce sensor type from the information packet 2023-01-17 19:50:21 +00:00
Toni
cda4e6136c upektc_img: Fix protocol for area sensors 2023-01-17 19:50:21 +00:00
Toni
522b481297 upektc_img: Add sensor chip detection
Move setting up sensor type and image dimensions to
activation time.
2023-01-17 19:50:21 +00:00
Toni
fafe70f985 upektc_img: Fix CRC for upek2020_init_capture. 2023-01-17 19:50:21 +00:00
Vasily Khoruzhick
62818b9407 fpcmoc: fix use-after free in multiple callbacks
Drop if statement that retrieves internal ssm->error.
"error" is already a copied ssm->error, so it makes no sense to return
internal copy which will be freed when ssm is marked as done.

Fixes #526
2023-01-10 11:22:22 -08:00
Vasily Khoruzhick
db2fa81358 tests: valgrind: update python and libfprint suppressions list 2023-01-10 11:15:17 -08:00
Vasily Khoruzhick
d492901c3e tests: valgrind: generate suppressions list for new tests-suppress-new-valgrind-errors-in-python
That will help with updating suppresions lists in future
2023-01-10 11:14:51 -08:00
Vasily Khoruzhick
a5d52eb853 Fix indentation issues with uncrustify-0.76.0
Apparently older version didn't find this indentation issues
2023-01-08 23:36:18 -08:00
Bastien Nocera
89509c76f4 build: Print the list of enabled drivers
This saves us from having to figure out which drivers were enabled
during a build in some other way.
2022-11-02 12:04:34 +01:00
Marco Trevisan (Treviño)
6395dda012 fp-image: Remove config.h inclusion in fpi-header
And also avoid defining a function we expose depending on it's presency.
2022-10-13 20:35:52 +00:00
Marco Trevisan (Treviño)
54bb0c12e6 fpi-image: Check for PIXMAN presency using #ifdef
That's a defined variable that may be there or not, and currently we
warn with:
 - fpi-image.c:29:5: warning: "HAVE_PIXMAN" is not defined, evaluates to 0
2022-10-13 20:35:52 +00:00
Marco Trevisan (Treviño)
1f1ed80dbf test-device-fake: Add more logging showing the current device action 2022-10-13 20:31:28 +00:00
Marco Trevisan (Treviño)
36bcb24b3a fp-device: Move FpDevice private functions to public library
This these functions are not really needed by anything else than
FpDevice, so move them back to the cpp file, so that we don't expose
them in the private library, given that we don't need them
2022-10-13 20:31:28 +00:00
Marco Trevisan (Treviño)
ddacf07e3b meson: Actually bump the version to 1.94.5 2022-10-13 20:31:28 +00:00
Marco Trevisan (Treviño)
86961a9429 Release 1.94.5 2022-10-13 05:57:04 +02:00
Marco Trevisan (Treviño)
3ca20a8e70 ci: Do not run two image rebuild pipelines on schedules 2022-10-13 05:37:12 +02:00
Marco Trevisan (Treviño)
3100404419 ci: Install more debug symbols 2022-10-13 05:27:44 +02:00
Marco Trevisan (Treviño)
892c9767a2 tests: Be stricter on valgrind leak checks
We used to ignore leaks, and we are ending up in having various of them,
so let's make valgrind to exit with error when using the valgrind test
setup (so in CI) to catch them better.
2022-10-13 05:20:28 +02:00
Marco Trevisan (Treviño)
2718dc02e0 vfs0050: Initialize the usb transfer buffer when allocating it
Ensure that the memory that we're going to populate via USB transfer is
initialized, otherwise valgrind may complain about (even if that's not
really an issue).
2022-10-13 05:04:03 +02:00
Marco Trevisan (Treviño)
abd7c66833 fp-device: Do not setup current action before updating temperature
At every action we update the device temperature, and this can
potentially lead to a failure, if the temperature is too hot.

However in such case we were failing a task that we had just stolen,
causing an error, tasks never returning and the device was left in an
undefined state.

So, just return early in case temperature is too hot, as we don't really
need to have the current task or action set at this point because
there's no active action to cancel yet.

This was causing random errors when running tests under valgrind
2022-10-13 05:04:03 +02:00
Marco Trevisan (Treviño)
8716ddb07a fp-print: Fix a typo in documentation 2022-10-13 05:04:03 +02:00
Marco Trevisan (Treviño)
fd7d93e619 fpi-device: Do not leak suspend/resume tasks
We kept suspend/resume GTask's around but at the moment of completing
them we didn't unref them, leading to leaks.
2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
0592c0e5ad uru4000: Cleanup cancelled error before early return 2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
684e3c460a uru4000: Shutdown NSS on device close
We were allocating NSS during device opening but never closing it,
causing many leaks.
2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
4278668c8f egis0570: Cleanup the received image that is going to be resized
It's just temporary for us as we're providing the resized one instead.
2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
a86ab6c854 test-fpi-device: Cleanup the device ID / driver before overriding it
Otherwise we'd leak the one that was initially set.
2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
b04eed0aea test-device-fake: Consume the identify print if we're returning with error 2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
669e091b03 virtual-device: Use an autoptr to handle the new scan print
We may not use this print, so let's use an autoptr to handle its life
cycle to clean it up when not used.
2022-10-13 05:04:02 +02:00
Marco Trevisan (Treviño)
0b6a92150c tests/fpcmoc: Ensure python tests exit with error on every exception
We ignored assertions happening on callbacks as they only raise
exceptions that does not stop the execution.

So ensure that this is happening in all the tests as synaptics was
doing already

Same as commit: be8888431
2022-10-13 04:26:58 +02:00
Haowei Lo
cca2b6a624 fpcmoc: Support FPC moc devices
Supported PID: 0xFFE0/A305/D805/DA04/D205
2022-10-11 08:11:38 +00:00
ElectronicsArchiver
1d24037f14 README: Improved formatting 2022-10-10 23:35:24 +02:00
Lv Ying
6395228bb8 goodixmoc: add PID 0x6014
Signed-off-by: Lv Ying <lvying.system.thoughts@gmail.com>
2022-10-09 10:45:18 +08:00
Marco Trevisan (Treviño)
b718f4d567 tests/meson: Avoid searching for programs multiple times 2022-09-28 01:23:58 +02:00
Marco Trevisan (Treviño)
be88884315 tests: Ensure python tests exit with error on every exception
We ignored assertions happening on callbacks as they only raise
exceptions that does not stop the execution.

So ensure that this is happening in all the tests as synaptics was
doing already
2022-09-28 01:22:15 +02:00
Marco Trevisan (Treviño)
d2a0eda56c synaptics, goodix: Properly check for finger status during enroll progress
It may contain other values, but for sure we finger must be neeeded
2022-09-28 01:21:31 +02:00
Marco Trevisan (Treviño)
5d9fc8b3c8 fpi-device: Do not leak USB devices while iterating
To compute the device ports we walked up through the devices using
g_usb_device_get_parent(), but this is supposed to return a device with
transfer full, so we need to unref it when done with it.

To handle this nicely, use a mixture of autopointer's and g_set_object
to ensure we're doing the right thing when passing the ownership around.
2022-09-27 18:21:20 +02:00
Marco Trevisan (Treviño)
62f2f34655 fpi-device: Fix a small leak when configuring the wakeup 2022-09-27 17:38:51 +02:00
Marco Trevisan (Treviño)
171e65f73f libfprint: Use g_memdup2 everywhere
It's just safer when available.
2022-09-27 17:10:33 +02:00
Marco Trevisan (Treviño)
446cedbcfc fpi-compat: Add definition for g_memdup2 when not available or deprecated
It's suggested to use g_memdup2 everywhere, but since we've a max-glib
version set we'd get a "deprecation" warning.

Avoid it this by re-defininig it through a macro in both cases.
2022-09-27 17:10:33 +02:00
Marco Trevisan (Treviño)
4012a4fe6f fpi-device: Clarify identify prints gallery usage in drivers docs 2022-09-27 16:43:33 +02:00
Marco Trevisan (Treviño)
70dc61d647 libfprint: Add top-level sync-udev-hwdb target for updating DB 2022-09-27 16:32:09 +02:00
Marco Trevisan (Treviño)
ca481cce50 fprint-list-udev-hwdb: Update devices from wiki 2022-09-27 16:32:09 +02:00
Marco Trevisan (Treviño)
4d74838c50 ci: Generate Cobertura XML and use it to feed gitlab for MR integration
gitlab has coverage integration in MRs, but we need a cobertura
formatted XML files (each must be less than 10 MB) to show it, since
meson generates it already via gcovr, we can just inform gitlab about it

See https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html
2022-09-27 13:05:01 +02:00
Marco Trevisan (Treviño)
c429052e5e tests: Do not use deprecated declarations in virtual device tests 2022-09-27 12:52:38 +02:00
mbv06
1e55a066dc Update autosuspend.hwdb 2022-09-27 09:01:58 +00:00
mbv06
06abc256a4 upek: add PID 0x2017 2022-09-27 09:01:58 +00:00
Marco Trevisan (Treviño)
7ea2e55793 ci: Check for uncrustify changes in a safer way 2022-09-27 01:38:26 +02:00
Marco Trevisan (Treviño)
34e8655a08 ci: Use versioned image tags 2022-09-27 01:06:35 +02:00
Marco Trevisan (Treviño)
c512a47e8a ci: Install debuginfo packages for better valgrind debugging
Related-to: https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/507
2022-09-27 00:21:05 +02:00
Marco Trevisan (Treviño)
012d77ac41 libfprint-templates: Include exec commands 2022-09-27 00:15:16 +02:00
Marco Trevisan (Treviño)
2acd3ca571 ci: Rebuild the image in case deps changed 2022-09-27 00:15:16 +02:00
Paulo E. Castro
c74a1ab6d1 goodixmoc: add PID 6094 2022-09-06 07:59:57 +00:00
hermanlin
beac7f934d elanmoc: Fixed unreachable code
ISSUE=503

Signed-off-by: hermanlin <herman.lin@emc.com.tw>
2022-08-26 18:44:22 +08:00
Bastien Nocera
114097718a build: Fix run_command() warning
WARNING: You should add the boolean check kwarg to the run_command call.
         It currently defaults to false,
         but it will default to true in future releases of meson.
         See also: https://github.com/mesonbuild/meson/issues/9300
2022-08-26 11:48:32 +02:00
mahaosen
151551b52b goodixmoc: add PID 0x634C 2022-08-26 16:46:16 +08:00
Aris Lin
89a0d5f958 synaptics: Add new PID 0x0104 2022-08-16 15:45:13 +00:00
mahaosen
3a82991586 goodixmoc: add PID 0x631C 2022-08-16 15:30:47 +00:00
Bastien Nocera
08a90e911e flatpak: Remove obsolete libfprint branch 2022-08-16 17:14:07 +02:00
Bastien Nocera
3176eb8821 flatpak: Remove obsolete option
See 256c7cea07
2022-08-16 17:14:07 +02:00
Bastien Nocera
f74b3f7794 flatpak: Update libusb module 2022-08-16 17:14:07 +02:00
Bastien Nocera
fc6403899e flatpak: Only require X11 access on X11 2022-08-16 17:14:07 +02:00
Bastien Nocera
b10baf02ea flatpak: Build Flatpak using GNOME 42
So the old meson in the 3.36 runtime doesn't choke on:
tests/meson.build:46:7: ERROR: Unknown method "project_source_root" in object.
2022-08-16 17:14:07 +02:00
Bastien Nocera
96013a03c5 test-generated-hwdb: Add missing test dep
E: UDEV_HWDB (/run/build/libfprint/_flatpak_build/libfprint/fprint-list-udev-hwdb) unset or not executable.
2022-08-16 17:14:07 +02:00
Bastien Nocera
3b3fc573da test-generated-hwdb: Add more debug on error 2022-08-16 17:14:07 +02:00
Bastien Nocera
e782de3747 tests: Fix umockdev version detection
Traceback (most recent call last):
  File "/builds/libfprint/libfprint/tests/umockdev-test.py", line 17, in <module>
    version = tuple(int(_) for _ in umockdev_version.split(b'.'))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builds/libfprint/libfprint/tests/umockdev-test.py", line 17, in <genexpr>
    version = tuple(int(_) for _ in umockdev_version.split(b'.'))
                    ^^^^^^
ValueError: invalid literal for int() with base 10: b'g9049374\n'
2022-08-16 17:14:07 +02:00
Bastien Nocera
c3e88f6e46 context: Fix race when shutting down context
Fix possible race which would happen when freeing the devices array
before cancelling the initialisation:
(/builds/libfprint/libfprint/_build/tests/test-fp-context:1449): GLib-CRITICAL **: 14:00:19.640: g_ptr_array_add: assertion 'rarray' failed
2022-08-16 17:14:07 +02:00
Bastien Nocera
ac3b0d07ba hwdb: Add FT9201Fingerprint reader
To the unsupported list.
2022-08-16 15:58:53 +02:00
Bastien Nocera
9ca1564e2d hwdb: Add Lenovo ThinkPad E15 fingerprint reader
To the unsupported list.
2022-08-16 15:58:53 +02:00
Johnny Li
fb63c39750 elanmoc: add PID 0x0c8c & 0x0c8d 2022-07-25 14:11:37 +08:00
Marcus Pfeffer
f007161bcd goodixmoc: add PID 0x6384
Closes: #489
2022-07-21 11:37:40 +02:00
yangdi
489332c07d goodixmoc: add PID 0x659A 2022-07-19 11:37:46 +08:00
Marco Trevisan (Treviño)
15bee898b8 ci: Use junit test reports
They can be used to show test failure logs directly in the MR's
pipelines page.
2022-07-14 22:13:49 +02:00
Marco Trevisan (Treviño)
fb9e054637 test-fp-device: Add few tests to check identification init errors 2022-07-14 21:35:30 +02:00
Marco Trevisan (Treviño)
7f6ab61292 fp-device: Return an error if prints are invalid
We'd crash later otherwise, while it's better to return an error.
2022-07-14 21:14:29 +02:00
Marco Trevisan (Treviño)
f03d9361e3 fpi-device: Improve documentation for identify/verify report and complete
We still mentioned variables that are not accepted anymore since we
switched to match reporting API.
2022-07-14 21:13:35 +02:00
hermanlin
24e7e1f100 elanmoc: Make sure sensor in the right mode at identity
Signed-off-by: hermanlin <herman.lin@emc.com.tw>
2022-07-11 15:39:11 +00:00
Sam James
61f0f86904 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
2022-07-03 02:36:55 +01:00
Benjamin Berg
08da0eb1e1 goodix: Make fingerlist parse error non-fatal
Otherwise we cannot recover from the error by doing a device reset.
2022-06-22 15:40:12 +00:00
Benjamin Berg
8552290bec goodix: Reset device if storage listing fails
When opening the device, query the stored prints. This should usually
always succeed (and it should be fast). If it fails, then we are very
likely dealing with a corrupted template storage on the device. In that
case, emit the command to clear the storage in order to reset the device
and get it back into a usable state.
2022-06-22 15:40:12 +00:00
Benjamin Berg
42c9003f49 goodix: Lower poor capture warnings to debug message
It is completely fine for a capture to have a low quality or fail. No
need to warn about this. Main reason to remove it though is so that
recordings that contain such a message do not trigger a failure.
2022-06-22 15:40:12 +00:00
ArronYen
7899bf4240 elanmoc: add PID 0x0c88 2022-06-20 14:03:05 +08:00
Benjamin Berg
d1fbf34fdf scripts: Update uncrustify configuration
The mod_full_brace_if_chain option needs an integer (we want method 1)
rather than a boolean.
2022-06-09 15:36:10 +02:00
Benjamin Berg
9c12b762a7 print: Fix indentation 2022-06-09 15:36:10 +02:00
Benjamin Berg
f20b8bc311 Release 1.94.4 2022-05-24 14:53:52 +02:00
Benjamin Berg
8b8dc0fec2 hwdb: Sync with wiki to add more unknown devices 2022-05-24 14:38:10 +02:00
Aris Lin
82d0f4288a synaptics: Add new PID 0x015F 2022-05-23 21:06:23 +08:00
Benjamin Berg
e86c45c988 device: Add missing errno.h include
This made the flatpak build fail.
2022-05-18 09:09:48 +02:00
Benjamin Berg
56ae75d2b2 device: Fully re-evaluate suspend/resume logic when delayed
If we delayed the suspend(/resume) call, then the circumstances may have
changed. In particular, an active action may have completed already
which means that the driver handler should not be called anymore.
2022-05-17 20:29:00 +02:00
Benjamin Berg
54a98bb286 device: Run critical section flushing with a high priority
These delayed calls are pushed into the mainloop for consistency.
However, they should run immediately and not be delayed, as such, it
makes sense to run them at a higher priority.

This actually solves an issue inside the CI where an URB reply is played
back even though it should be cancelled by the client.
2022-05-17 20:29:00 +02:00
Benjamin Berg
bfbe24b172 synaptics: Correctly handle critical section during interrupt resubmit
We re-aquire the critical section at the start of the callback, however,
it needs to be dropped again (or not taken) if the interrupt transfer is
resubmitted.
2022-05-17 20:29:00 +02:00
Benjamin Berg
1f925fef7c tests: Test suspend/resume and sysfs attributes in synaptics 2022-05-17 20:29:00 +02:00
Benjamin Berg
7b0093b4c6 tests: Reset the USB device before testing
The kernel caches URBs to get descriptor values. Doing a reset before
starting the record ensures that we will see any descriptor reads in the
usbmon trace and can therefore correctly replay them (possibly not true
if they happen multiple times).
2022-05-17 20:29:00 +02:00
Benjamin Berg
0fd5a617ab device: Do not update sysfs attributes if value is correct
This avoids spurious warnings on e.g. SELinux enabled systems.
2022-05-17 20:29:00 +02:00
Matthew Mirvish
e7d041d258 elanspi: add 04f3:241f
Reported as working with this config in
https://github.com/mincrmatt12/elan-spi-fingerprint/issues/11.
2022-05-08 18:32:29 -04:00
Josh Chen
eda8d13927 elan: add PID 0x0c4b 2022-04-14 17:21:52 +08:00
Aris Lin
5ba7ff8be9 synaptics: Add new PID 0x0168 2022-04-11 12:01:17 +00:00
Benjamin Berg
da1a56a600 context: Log version number at startup
Having this should at least give us a slightly better idea about the
version that the user has installed. Obviously it is still not very
accurate (maybe a git hash would be good if available?), but it should
still be helpful overall.
2022-04-10 13:58:58 +02:00
ArronYen
2b760dfa38 elanmoc: add PID 0x0c82 2022-03-02 10:43:20 +08:00
Benjamin Berg
f1a61c060f device: Clear the critical section source on destruction 2022-02-17 10:20:55 +01:00
Benjamin Berg
5fb3b8b43a tests: Avoid -Wdangling-pointer warning
The code is correct, but gcc thinks the pointer is still NULL after the
call. As obvious workaround don't seem to work, just disable the warning
for now.
2022-02-14 17:57:59 +01:00
Benjamin Berg
8fad2652ee Release 1.94.3 2022-02-11 19:36:43 +01:00
Benjamin Berg
6f5ba3cbb5 udev-hwdb: Update unsupported device list 2022-02-11 19:36:22 +01:00
doomsdayrs
754ccfb865 Convert README to markdown
Just a minor change, but makes the file a bit more readable.
2022-02-11 19:36:22 +01:00
Doomsdayrs
d3014f1684 Delete TODO 2022-02-11 19:36:22 +01:00
Devyn Cairns
3568051686 goodixmoc: support for clear_storage
The internal storage of this device can get messed up by other operating
systems, so it's handy to be able to clear it.

I'm not 100% sure whether the commands I've sent to the device are
exactly what is supposed to be used (just a guess), but it did seem to
work, and it even fixed another issue I had.
2022-02-11 18:08:53 +00:00
Benjamin Berg
9ce6ed4164 goodixmoc: Report recognized print after a match failure
The API should return the recognized print, even if none of the prints
given in the gallery (or the one passed to verify) matched. Without this
the garbage-collection of left-over prints does not work, causing issues
after reinstall.

Fixes: #444
2022-02-03 14:49:49 +01:00
Benjamin Berg
e0fd178bec goodixmoc: Log which the ID that produced the duplicate 2022-02-03 14:49:49 +01:00
Benjamin Berg
168ab98021 examples: Check whether the returned date is valid
Prints may have an invalid date. Extend the checks so that this is also
caught in addition to a NULL date.
2022-02-03 14:49:49 +01:00
Benjamin Berg
ae5696a9bb goodixmoc: Change error message for corrupted headers
Otherwise you can't tell from the log whether parsing the body or header
failed.
2022-02-03 14:49:49 +01:00
Benjamin Berg
038c7108a6 goodixmoc: Further template parsing fixes
In commit 5c28654d9 ("goodixmoc: Fix print template parsing") the length
check for the verify and duplicate check responses by requiring two
extra bytes at the end of the message.

There were also issues in other places where the length was not checked
correctly, including a scenario that could cause a read beyond the end
of the buffer.

Related: #444
2022-02-03 14:49:44 +01:00
Aris Lin
eb1013cdb6 synaptics: Remove PID 0xC9 2022-01-28 19:25:24 +08:00
mincrmatt12
5beac0ded7 elanspi: Try to avoid cancellation problems 2021-12-23 05:35:38 +00:00
mincrmatt12
7565562903 elanspi: Adjust register tables (fixes #438)
New values taken from a newer version of the official driver.
2021-12-22 00:20:57 -05:00
Dmitrii Shcherbakov
999bca076c Allow FpPrint data to be extended on enrollment.
* Allow FPI_PRINT_NBIS to be extended rather than overridden if a user
  supplies an existing FpPrint template with data;
* Prints will only be extended if a device has the required feature.
  For image-based devices this feature is added by default since they
  typically do not have storage (this can be overridden at the child
  class level).

Extending an existing FpPrint requires passing a template print with
existing data during the enrollment process. This is done because the
caller is responsible for maintaining the fingerprint database and doing
the necessary deserialization operations if needed. The existing
example program is updated to show how to do that.
2021-12-16 12:53:41 +01:00
Benjamin Berg
e198b04222 elanspi: Silence some SSMs that may log excessively otherwise 2021-12-02 13:54:59 +01:00
Benjamin Berg
3981c42d3e ssm: Add API to silence most state change debug messages
Otherwise tightly looping SSMs (primarily SPI transfers), will flood the
logs in inappropriate ways.
2021-12-02 13:54:59 +01:00
Benjamin Berg
31afd3ba5c elanspi: Move debug print so that it contains all information
Two of the printed variables were only calculated after the message was
printed, making the logged information less useful than it could be.
2021-12-02 13:53:54 +01:00
Benjamin Berg
05fd2c58cb context: Ensure mainloop is idle before enumeration completes
This ensures that we have processed all hotplug events before
considering enumeration to be complete. This is important due to USB
persist being turned off. At resume time, devices will disappear and
immediately re-appear. In this situatoin, enumerate could first see the
old state with a removed device resulting in it to not be discovered.

As a hotplug event is semingly emitted by the kernel immediately, we
can simply make sure to process this hotplug event before returning
from enumerate.

Closes: fprintd#119
2021-12-01 15:29:18 +00:00
Matthew Mirvish
a033154b2e doc: Fix broken documentation for FpiDeviceUdevSubtypeFlags enum
Added description and fixed incorrect name in comment, so now gtkdoc
actually shows useful information.
2021-11-15 17:10:44 -05:00
Benjamin Berg
5e4bb26801 Release 1.94.2 2021-11-02 16:28:13 +01:00
Benjamin Berg
2cfff27729 udev-hwdb: Update unsupported device list 2021-11-02 16:28:13 +01:00
Marco Trevisan (Treviño)
378fae0ea2 doc: Add missing Drivers API SSM functions 2021-10-28 16:56:11 +02:00
Marco Trevisan (Treviño)
01b0f7aba0 doc: Include missing types (SPI) and functions to the Drivers API 2021-10-28 16:39:35 +02:00
Benjamin Berg
17ff49f85c goodixmoc: Fix template struct for required length calculation
The length is only a single byte in the transfer. However, the struct
had a uint32_t in that place, breaking the sizeof() calculation and
seemingly creating issues for certain lengths of user id strings (which
depend on the username).

Fix this by changing the type to uint8_t. Also add the initial 0x43
prefix byte and a byte of apparent padding that the struct contains.
Leave the two reserved bytes at the end, as they seem to actually have a
meaning (i.e. they are seemingly send in listings).

This effectively makes the struct one byte smaller, bringing it down to
127 bytes from 128 bytes.

Closes: #428, #404
2021-10-27 06:54:47 +00:00
Marco Trevisan (Treviño)
de46e1e4b8 tests: Add missing trailing new lines on devices attributes
This as per the same reasons of commit 63bfaf4, and without trailing new
lines such attributes aren't picked by umockdev in ubuntu and debian.
2021-10-27 02:01:50 +02:00
boger
5e934a4fa0 goodixmoc: add PID 63CC
63CC: Dell Latitude series fingerprint sensor
2021-10-20 20:11:05 +08:00
hermanlin
5d0a3eab5c elanmoc: add PID 0x0c7d
Signed-off-by: hermanlin <herman.lin@emc.com.tw>
2021-10-12 14:02:48 +08:00
Benjamin Berg
7efb860381 Release 1.94.1 2021-09-24 15:01:18 +02:00
Benjamin Berg
f9492d5345 NEWS: Fix 1.94.0 release date 2021-09-24 14:25:01 +02:00
Benjamin Berg
46669e9f53 goodixmoc: Do not run identify step during enroll
While useful, there are advantages for this to be done by the
surrounding code (i.e. fprintd). As such, remove the identify stage from
the goodix driver and rely on fprintd doing it for us.

One can probably argue that neither solution is perfect. Ideally, we
would probably return the information required to delete the old print
to the upper stack and let the driver/device handle the duplicate
checking.

However, for now this works well. We may need to reconsider this if we
get devices that do the duplicate checking transparently and just throw
an enroll error.

NOTE: The driver did not report any progress for the identify step. As
such, the number of enroll steps reported by the device remain the same.

Closes: #415
2021-09-24 14:24:47 +02:00
Benjamin Berg
a949594050 goodixmoc: Returned device print matched by verify/identify
This is needed for the fprintd duplicate checking code. The information
is needed to delete stale prints automatically from the device.

Related: #415
2021-09-21 19:13:02 +02:00
Benjamin Berg
20e8355c01 tests: Run custom.py from test creation helper when available
This allows creating tests both for image and non-image devices using
the same script.
2021-09-21 19:13:02 +02:00
boger
f579a77bfd goodixmoc: add PID 63BC
63BC: Dell XPS series fingerprint sensor
2021-09-17 19:28:51 +08:00
Benjamin Berg
03deb3011b udev-hwdb: Update unsupported device list 2021-09-17 12:54:02 +02:00
Benjamin Berg
c7650b6ec9 udev-hwdb: Set ID_PERSIST=0 in hwdb
See https://github.com/systemd/systemd/pull/20756
2021-09-17 12:46:29 +02:00
Aris Lin
128d809227 synaptics: add new PID 0x0123, 0x0126, and 0x0129 2021-09-17 12:42:51 +02:00
Benjamin Berg
9356e895a2 ci: Reference image directly for forks
Otherwise forks will not find the image and things fall apart (due to
the method of how we build the image).
2021-09-15 17:23:00 +02:00
Benjamin Berg
3c2883b992 ci: Pull in diffutils
It is needed by tests/test-generated-hwdb.sh and is not pulled in
indirectly anymore.
2021-09-15 16:27:17 +02:00
Benjamin Berg
eb568a62aa ci: Switch to newer CI templates 2021-09-15 16:27:17 +02:00
Benjamin Berg
d763f8f41a elanmoc: Fix warning
Really, it shouldn't matter, as there is no return. But adding the NULL
initializer does not harm either.
2021-09-15 15:54:25 +02:00
Benjamin Berg
df41ed56f6 meson: Use source_root() to not require meson 0.56
This fixes the flatpak build.
2021-09-15 15:43:33 +02:00
Bastien Nocera
aff063c23c tests: Simplify capture of driver behaviour for regression tests
And update instructions for the simpler method.

Co-authored-by: Benjamin Berg <bberg@redhat.com>
2021-09-15 13:24:08 +00:00
Bastien Nocera
e2511095d1 device: Export kernel device from FpDevice
This is inelegant, but allows API consumers to match the FpDevice with
an OS device.
2021-09-15 13:24:08 +00:00
Bastien Nocera
9515cc2e59 tests: Add U.are.U 4500 test 2021-09-09 10:54:48 +02:00
Bastien Nocera
b3cfc40dea tests: Add uru4000 test
This test requires control transfer replay fixes that will be contained
in umockdev 0.16.3. Bump the requirement accordingly.

Closes: #412
2021-09-08 20:37:00 +02:00
Benjamin Berg
c162b895c0 uru4000: Fix transfer type on interrupt endpoint
It appears the kernel automatically "fixes" this mistake and it works.
the transfer in question is an interrupt transfer and should be submitted
as such. Do that in order to make things more correct and so that the
test can run.
2021-09-08 20:37:00 +02:00
Bastien Nocera
40b3923ca6 tests: Add (another) elan driver replay test
This capture was made using a "COBO" branded device, and uses the new
pcapng format.
2021-09-08 15:36:35 +02:00
Bastien Nocera
d7e7d8e036 tests: Add aes2501 driver replay test 2021-09-08 15:25:14 +02:00
Bastien Nocera
ec53abfc3a tests: Simplify multiple tests per driver code 2021-09-08 15:24:59 +02:00
Bastien Nocera
83541a2ddc Revert "device: Export kernel device from FpDevice"
This reverts commit 8f93aef122.
2021-09-06 17:34:22 +02:00
Bastien Nocera
e22497d51b Revert "tests: Simplify capture of driver behaviour for regression tests"
This reverts commit 0dcb4be4d3.
2021-09-06 17:34:15 +02:00
Bastien Nocera
0dcb4be4d3 tests: Simplify capture of driver behaviour for regression tests
And update instructions for the simpler method.
2021-09-06 17:32:05 +02:00
Bastien Nocera
8f93aef122 device: Export kernel device from FpDevice
This is inelegant, but allows API consumers to match the FpDevice with
an OS device.
2021-09-06 17:32:05 +02:00
Bastien Nocera
8dfa12e41d fp-context: Fix typo in API docs 2021-09-03 20:58:25 +00:00
Marco Trevisan (Treviño)
88cb452e05 fpi-device: Do not include config.h in headers
It should be included in files requiring it only.
2021-09-03 18:49:45 +02:00
Benjamin Berg
909865ed8d Release 1.94.0 2021-08-20 14:36:18 +02:00
Benjamin Berg
39333a0642 doc: Add internal suspend/resume API 2021-08-20 14:36:14 +02:00
Benjamin Berg
4340be728c doc: Add public suspend/resume API 2021-08-20 14:36:06 +02:00
Benjamin Berg
dba5ca5535 doc: Add criticial section API 2021-08-19 19:16:03 +02:00
Benjamin Berg
2a70cd7e02 udev-hwdb: Update unsupported list (add synaptics PID 00e7) 2021-08-19 19:03:24 +02:00
Benjamin Berg
3108ac3144 virtual-device: Return empty no-match if unknown SCAN id is passed
This matches the expectation. i.e. we return no-match and we do not
return a scanned print as we don't have anything for it. If we did
indeed return a scanned print, then fprintd would try to delete it
during enroll and would then fail.

Note that we do *not* return a DATA_NOT_FOUND error in the storage
device if the print does not exist. This is because not all devices
support reporting this error. It is therefore more sensible to handle it
gracefully and expect test setups to set the error explicitly for
testing purposes.
2021-08-19 18:59:38 +02:00
Benjamin Berg
c928d7bd8f synaptics: Fix error handling when releasing the USB interface
The error may not be NULL, as such we need a second variable and then
we'll only forward any error from g_usb_device_release_interface if
there was none before.
2021-08-10 19:04:50 +02:00
hermanlin
ec42b2ade1 elanmoc: Increase of the timeout 2021-08-10 16:45:16 +08:00
hermanlin
4edfa48608 elanmoc: Fix the identify/verify error reporting in identify_status_report 2021-08-10 16:40:03 +08:00
hermanlin
1a5df96751 elanmoc: Return the correct error when the storage is full 2021-08-10 16:34:37 +08:00
hermanlin
62448492af elanmoc: Adjustments to protocol change (passing an empty user ID) 2021-08-10 16:22:54 +08:00
Benjamin Berg
874513e79a ci: Always expose job artifacts for tests
Not having the artifacts means not having the log on failures. So always
expose them (even if in some cases we might only need them on failure).
2021-08-09 16:08:27 +02:00
Benjamin Berg
5c89bda7f3 synaptics: Implement suspend/resume methods
We only allow suspending while we are in the interrupt transfer stage.
To suspend, we cancel the interrupt transfer and at resume time we
restart it.

This has been tested to work correctly on an X1 Carbon 8th Gen with
suspend mode set to "Windows 10" (i.e. S0ix [s2idle] and not S3 [suspend
to RAM]). With S3 suspend, the USB root hub appears to be turned off or
reset and the device will be unresponsive afterwards (if it returns). To
avoid issues, libfprint disables the "persist" mode in the kernel and
we'll see a new device instead after resume.
2021-08-09 16:08:27 +02:00
Benjamin Berg
8147372bdd tests: Add suspend/resume tests
Also update the critical section test to check the order in which the
requests are processed.
2021-08-09 16:08:21 +02:00
Benjamin Berg
43336a204f device: Implement suspend/resume methods
The assumption here is that in most cases, we will just cancel any
ongoing operation. However, if the device choses to implement
suspend/resume handling and it returns success, then operations will not
be cancelled.

Note that suspend/resume requests cannot be cancelled.

Closes: #256
2021-08-09 16:08:21 +02:00
Benjamin Berg
968331c383 tests: Add full USB device hierarchy
The suspend/resume code tries to set sysfs attributes. To do so, the
full hierarchy is needed in order to build the corresponding sysfs path.
2021-08-09 16:08:21 +02:00
Benjamin Berg
d547c000fc synaptics: Use critical section API
This is more for demonstration purposes. The only functional change here
would be that the delete command cannot be cancelled.
2021-08-09 16:08:21 +02:00
Benjamin Berg
ff6caca2e3 tests: Add test for critical section API 2021-08-09 16:08:17 +02:00
Benjamin Berg
77756e111d device: Add device critical section API 2021-08-09 16:08:17 +02:00
Benjamin Berg
23a4f5b77a tests: Add temperature and overheating cancellation tests 2021-08-09 16:08:17 +02:00
Benjamin Berg
5b7c5e7c09 device: Check for device overheating and abort when needed
Check if a device is too hot. If it is too hot already, refuse
operation. If it becomes too hot while an operation is ongoing, then
cancel the action and force a FP_DEVICE_ERROR_TOO_HOT return value.
2021-08-09 16:08:17 +02:00
Benjamin Berg
da28731adc device: Add feature flag for continuous scanning support
Devices that are considered to never run hot will have FEATURE_ALWAYS_ON
set. If set, the UI can safely assume that it is fine to run fingerprint
authentication in the background without other user interaction.

Closes: #346
2021-08-09 16:08:17 +02:00
Benjamin Berg
6440a7d12f device: Add new FP_DEVICE_ERROR_TOO_HOT
This error code will be thrown if we refuse an operation to protect the
device from overheating.
2021-08-09 16:08:17 +02:00
Benjamin Berg
71e0c29f28 device: Always use an internal cancellable for tasks
This will allow libfprint to cancel operations internally in the future.

If the internal cancellation method is used, then the private
current_cancellation_reason variable must be set to the GError. This
error will be returned when set.
2021-08-09 16:08:17 +02:00
Benjamin Berg
a2d950044d device: Add simple temperature model for devices
This temperature model has three states:
 * COLD
 * WARM
 * HOT

Device drivers can define the time it requires for the device to get HOT
and COLD. The underlying model assumes an exponential warming and
cooling process and enforces a cool-off time after the device has
reached the HOT state. This cool down period is however shorter than the
specified time in the driver.
2021-08-09 16:08:17 +02:00
Benjamin Berg
96e5888110 tests: Show error message in more failure cases
This just simplifies matters a bit when one messes up during test
development.
2021-08-09 16:08:10 +02:00
mozgovoy
dd476c0ccf elan: Add PID 0x0c58 2021-07-30 10:15:23 +02:00
Benjamin Berg
4cdca4da24 virtual-device: Do not time out when waiting for SCAN command
The timeout is designed to continue commands automatically that are
common (e.g. opening the device). This doesn't really make sense for
scan commands, and removing the timeout enables test setups where user
interaction with the device may happen at arbitrary times.

One exception is device removal/unplug, in which case the timeout will
be added anyway.
2021-07-26 20:05:12 +02:00
Benjamin Berg
a68fce0f2c Release 1.92.1 2021-07-19 12:50:13 +02:00
Benjamin Berg
1f5e0821e0 tests: Bump required version for pcap replay
Some tests require control transfer replay. This was added shortly after
the actual pcap replay, so simply require a new enough umockdev.
2021-07-12 17:13:43 +02:00
Benjamin Berg
d6b4adec73 tests: Add upektc_img test 2021-07-12 17:06:43 +02:00
Benjamin Berg
9e7bfa05b3 synaptics: Immediately succeed for empty identify
Such an empty identify can be run by fprintd intentionally for duplicate
checking at the start of an enroll operation, which currently runs into
an error from the driver.

Avoid this by simply returning success immediately. This is fine, as
synaptics is only checking the explicitly passed list of prints rather
than using all available prints from the storage.
2021-07-12 11:43:46 +00:00
Liran Piade
9ecd6236ee Added ELAN 0c6e (from ROG Flow X13) 2021-07-08 21:36:38 +02:00
Saeed/Ali Rk
a07011bac2 tests: Add test for egistec0570 2021-07-08 13:42:22 +02:00
Saeed/Ali Rk
f7290255e0 egistec: Add new driver
This supports 1c7a:0570

Co-Authored-By: Maxim Kolesnikov <kolesnikov@svyazcom.ru>
2021-07-08 13:42:22 +02:00
Benjamin Berg
29048c51db tests: Add elanmoc CI test 2021-07-07 13:35:59 +02:00
hermanlin
42676dd300 elanmoc: Add elanmoc driver
Signed-off-by: hermanlin <herman.lin@emc.com.tw>
2021-07-07 13:35:59 +02:00
Benjamin Berg
45c5d17f3b elanspi: Fix format string 2021-07-06 20:56:16 +00:00
Benjamin Berg
fc76db562e aesx660: Fix format strings 2021-07-06 20:56:16 +00:00
Benjamin Berg
9f93f5ded7 virtual-device: Fix format strings 2021-07-06 20:56:16 +00:00
Benjamin Berg
74c4125827 upekts: Fix format strings 2021-07-06 20:56:16 +00:00
Benjamin Berg
4f6d908390 upeksonly: Fix format string warning by using unsigned
There is no need to use size_t for num_rows as it is capped to NUM_ROWS
which is defined to 2048.
2021-07-06 20:56:16 +00:00
Benjamin Berg
575bd369d5 upektc: Fix format string on architectures where 64bit is not long 2021-07-06 20:56:16 +00:00
Benjamin Berg
304219b65c upektc_img: Fix warnings in debug format strings 2021-07-06 20:56:16 +00:00
Benjamin Berg
23bca2a8ac spi: Fix pointer cast on 32bit architectures 2021-07-06 20:56:16 +00:00
Benjamin Berg
4bf064d873 meson: Shuffle around driver/helper definition
This should make it clearer what supporting features each driver needs.
2021-07-01 13:19:42 +02:00
Benjamin Berg
d2c2410a6f meson: Move source generation into libfprint meson file 2021-07-01 13:19:03 +02:00
Benjamin Berg
e8f9cc1fce scripts: Speed up uncrustify by running 4 jobs in parallel
There are some large files, and in most setups (including CI runners) we
have multiple cores available. Use xargs to run multiple parallel
uncrustify jobs rather than one large one. Just hardcode 4 jobs and 4
files at the same time for now.
2021-07-01 13:19:03 +02:00
Benjamin Berg
0ee274946d print: Fix pspec of print type to match real default
The default is actually FPI_PRINT_UNDEFINED and not FPI_PRINT_RAW.
2021-07-01 13:19:03 +02:00
Benjamin Berg
0c26205a1e Release 1.92.0 2021-06-30 15:58:12 +02:00
Benjamin Berg
d957bbd0f4 synaptics: Fix warning about missing initialization
The compiler seems to (incorrectly) think that cleanup might happen
before the variable has been initialized.
2021-06-30 15:58:12 +02:00
Benjamin Berg
ec9e6f1947 meson: Fix udev rules directory detection
There was a copy/paste error and we postfixed it with hwdb.d rather than
rules.d.
2021-06-30 11:14:58 +02:00
Benjamin Berg
24658fb351 meson: Add elanspi to list of default drivers
Pretty much all downstream distributions just enable all drivers anyway.
Also, it should work well enough, so it seems right to simply add
elanspi into the list of drivers that are enabled by default.
2021-06-29 17:29:53 +00:00
Benjamin Berg
d5fda36bc0 tests: Detect tests by checking any matching file prefix
We were testing only for .ioctl files, but we may now have .pcap file
and ended up simply not running the synaptics test unless there was
still a .ioctl file present.
2021-06-28 16:17:56 +02:00
Benjamin Berg
cdaa3497d7 virtual-storage: Add variant without list support
Simply remove the feature flag for the NO_LIST environment variable.

This also removes the IDENT variant for now as it has never been
implemented as described.
2021-06-25 17:38:28 +02:00
Benjamin Berg
8a5bec6619 device: Add API to update features during probe
This allows updating the supported feature bitfield during probe.
2021-06-25 17:38:28 +02:00
Benjamin Berg
145f7287fa fprint-list: Add SPI devices to supported list
This will make them show up on the website.
2021-06-25 12:31:52 +02:00
Benjamin Berg
dbd89929b9 tests: Increase timeout of umockdev tests
The new elanspi driver in particular needs a lot of ioctl's during the
test. On a normal machine, this would run quite quickly (less than 5s),
however, in busy CI environments this can take longer than 30s, causing
timeouts currently.

Increase the timeout from 10s to 15s. For CI this means the timeout now
is 45s which is hopefully enough.
2021-06-25 08:39:17 +00:00
Bastien Nocera
01663c1fb5 tests: Allow multiple tests per driver
Allow multiple tests per driver by using the first section of the
directory name, before the separating '-', as the driver name.
2021-06-25 10:23:42 +02:00
Bastien Nocera
4ef13d971d uru4000: Use GLib's random functions
So we can set a static seed when running tests.
2021-06-25 10:23:42 +02:00
Bastien Nocera
a267e30fc6 uru4000: Don't throw warnings during "power on"
During startup, we'd always get:
(fprintd:151125): libfprint-uru4000-WARNING **: 12:16:56.724: ignoring unexpected interrupt 56aa

But we actually know what this interrupt is, and it's not unexpected, as
it tells us that the reader is now powered on.
2021-06-25 10:23:42 +02:00
Benjamin Berg
2ba60d0a52 tests: Improved umockdev version check
The new features will be added in 0.16, so match against that. Also,
match against CI_PROJECT_NAME to detect our CI environment (and assume
that umockdev has been patched to the point of supporting all tests).
2021-06-25 08:05:13 +00:00
Benjamin Berg
947420d2ce demo: Do not build udev_rules inside flatpak
This fixes flatpak generation after the new SPI related rule generation
has landet.
2021-06-25 09:54:00 +02:00
Benjamin Berg
793cad57f3 demo: Add libgudev into flatpak manifest
It is needed for SPI support.
2021-06-25 09:54:00 +02:00
Benjamin Berg
f37e20b8a0 meson: Permit disabling (and forcing) installation of udev rules
In some cases (e.g. inside the flatpak), it does not make sense to
generate and install udev rules.
2021-06-25 09:54:00 +02:00
Benjamin Berg
e2f199bb6a vfs301: Fix leak of USB transfer
vfs301_proto_peek_event would leak the returned transfer. Use a
g_autoptr to fix this.
2021-06-23 22:49:59 +02:00
Matthew Mirvish
059ab65081 tests: Add capture test for elanspi 2021-06-23 20:42:52 +00:00
Benjamin Berg
7893278cc6 tests: Add handling for SPI ioctl replay
This will only be supported with umockdev version 0.15.6.
2021-06-23 20:42:52 +00:00
Matthew Mirvish
0697191387 tests: Allow multiple mock devices per driver
Instead of only loading `DRIVER/device`, now we also load all files
matching device-*[!~] in the DRIVER folder..
2021-06-23 20:42:52 +00:00
Matthew Mirvish
8be666bb05 elanspi: Permit running in emulated environment
This removes the HID reset, which we cannot emulate currently and also
disabes the line timeout to as simulation might run too slowly at times.
2021-06-23 20:42:52 +00:00
Matthew Mirvish
019a294ec4 elanspi: Add driver supporting various ELAN SPI sensors
Closes: #339
2021-06-23 20:42:52 +00:00
Matthew Mirvish
f6e80456d9 ci: Add gudev to dependencies 2021-06-23 20:42:52 +00:00
Benjamin Berg
51cab75b1e assembling: Fix copying only partial tile on overhang
If the tile in question was hanging over the left edge we would not be
copying the full available width. Fix this and change the test to catch
the error condition (by forcing a too small image and overlap both
ways).

Simplify the code by only selecting the starting point inside the
image/frame and then just checking the both image and frame boundary in
the loop. Not quite as efficient, but it really shouldn't matter too
much here.
2021-06-23 22:33:07 +02:00
boger
1ed2b23902 goodixmoc: add PID 609C/6584/658C/6592/659C
add some new PID support,
609C: Framework fingerprint sensor
65xx: Thinkpad series fingerprint sensor
2021-06-23 15:30:28 +08:00
Benjamin Berg
9dd72611bf list-udev-rules: Add udev rule generation for SPI 2021-06-22 19:13:48 +00:00
Benjamin Berg
4bcb55e412 meson: Fix indentation
Change tab indented areas to 4 spaces.
2021-06-22 19:13:48 +00:00
Benjamin Berg
5bda7aef38 ci: Use --status-bugs option for scan-build
This removes the need to check the output directory for files.
2021-06-22 19:54:42 +02:00
Benjamin Berg
b4f564cafc spi-transfer: Keep CS asserted during long transfers
Long transfers need to be split into multiple chunks because of
limitations by the spidev kernel driver. If this happens, we need to
make sure that the CS line remains high between the different chunks.

Add code to split the transfer into chunks and ask the driver to not
deassert CS after the transfer. Technically, this is only an
optimization as concurrent access to another device might still cause
deselection. However, this should mean that devices work without having
to change the spidev module parameter.

Use the feature in the hope that it will work. However, print a message
(not a warning), to help with debugging in case someone does run into
issues because of this.
2021-06-21 22:24:58 +00:00
Matthew Mirvish
a3f568db3d fp-context: Check hidraw VID/PID with udev instead of an ioctl
Previously, we checked hidraw devices against drivers by using the
HIDIOCGRAWINFO ioctl. While this works, it's not ideal for doing unit
tests since umockdev would have to implement hidraw ioctls.

The new approach uses the HID_ID property on the parent hid device,
which contains the VID/PID pair.
2021-06-21 13:39:24 -04:00
Benjamin Berg
ba920aa41b goodixmoc: Remove internal cancellable
The driver has an internal cancellable that simply forwards the external
cancellation in the cancel callback. This is not really needed, we can
instead just use the external cancellable directly by fetching it using
fpi_device_get_cancellable().
2021-06-21 15:11:18 +00:00
Benjamin Berg
db1e88138b meson: Add dependency to gobject-introspection
We seem to need this to build the introspection bindings.

Closes: #385
2021-06-21 17:07:16 +02:00
Benjamin Berg
7ff95dc39a tests: Add clear_storage related tests
Closes: #382
2021-06-21 16:50:18 +02:00
Benjamin Berg
098ff97edd drivers: Fix upekts/upek_proto license
The (trivial) CRC code was copied from gstreamer. However, the license
stated here was LGPLv2 rather than LGPLv2.1+. Identical code can currently
be found upstream in gstreamer licensed under LGPLv2+. As such, update
the license, making it more compatible with the rest of libfprint.

Also add the "or any later version" to upekts.c. The library was already
LGPL2.1+ at the time and libthinkfinger authors approved a license
change.
2021-06-17 13:08:19 +00:00
Benjamin Berg
90cbcd7fb5 tests: Update README to describe pcapng replay 2021-06-17 14:35:47 +02:00
Benjamin Berg
182367a079 tests: Use pcap recording for synaptics and test clear_storage 2021-06-17 14:35:47 +02:00
Benjamin Berg
daaafc80c3 tests: Detect pcap vs. ioctl recording and run correct one 2021-06-17 14:21:08 +02:00
Benjamin Berg
c989cc4b95 ci: Build umockdev from git for pcap replay support 2021-06-17 14:21:08 +02:00
Vincent Huang
0edae7b641 synaptics: Remove PID 0xE9 2021-06-17 08:00:47 +00:00
Vincent Huang
49e3963783 synaptics: Return success when deleting a print that doesn't exist in
the database or database empty
2021-06-16 15:53:46 +00:00
Aris Lin
040d0d34fd synaptics: Send a cancel to sensor if it returns busy
fix #380
2021-06-16 15:40:02 +00:00
Nelson Jeppesen
82c406dace goodixmoc: Add PID 6A94 2021-06-07 10:40:45 +00:00
Benjamin Berg
046607add6 device: Add void return type tag to fp_device_delete_print_sync
This way it matches the other _sync functions that return a boolean just
to show that an error was set.
2021-05-14 15:28:54 +00:00
Benjamin Berg
9c0cd3fb23 device: Move fp_device_clear_storage_sync into _sync block
Just so that all the _sync functions are together.
2021-05-14 15:28:54 +00:00
Benjamin Berg
439223cac3 virtual-device-storage: Actually clear storage when requested 2021-05-14 15:28:54 +00:00
Benjamin Berg
992a207ede virtual-device: Refactor command handling and add CONT command
This command is useful to immediately continue rather than waiting for
input. It is only useful for non-scanning device actions and can be
important when steps need to be explicitly skipped (e.g. to inject an
error in the second command without a way to wait in between).
2021-05-14 15:28:54 +00:00
Benjamin Berg
ae6be6837b doc: Use includes from the source diretory
Before we try to use installed system includes, which is obviously not
the best idea.
2021-05-14 15:28:54 +00:00
Benjamin Berg
261ba3a4a4 meson: Add -Wswitch-enum
This would have caught the issue where we forgot to add
FPI_DEVICE_ACTION_CLEAR_STORAGE to fpi_device_action_error.
2021-05-14 15:28:54 +00:00
Benjamin Berg
e9dddcc87a virtual-image: Fix compilation with -Wswitch-enum 2021-05-14 15:28:54 +00:00
Benjamin Berg
7e02f3faf9 virtual-device: Avoid/Fix -Wswitch-enum warnings 2021-05-14 15:28:54 +00:00
Benjamin Berg
b61303500e utilities: Explicitly list default enum value 2021-05-14 15:28:54 +00:00
Benjamin Berg
668b3517a9 upeksonly: Explicit list default enum value 2021-05-14 15:28:54 +00:00
Benjamin Berg
657fe85c25 device: Add missing CLEAR_STORAGE to fpi_device_action_error
This was missed in the previous commit that added the support.
2021-05-14 15:28:54 +00:00
Aris Lin
4d5e2775b2 synaptics: add new PID 0xF0 and 0x103 2021-05-05 15:24:25 +08:00
Vincent Huang
8a04578847 synaptics: Add clear_storage() and remove list() 2021-04-29 11:49:27 +00:00
Vincent Huang
77e95aa545 fp-device: Add fp_device_clear_storage and clear_storage vfunc 2021-04-29 11:49:27 +00:00
Benjamin Berg
b9df7a4e70 device: Attach sources to correct main context
We were attaching the sources to the default main context. Instead, we
should be attaching them to the current tasks main context (or, failing
that, the current thread local main context).
2021-04-28 22:16:37 +02:00
Benjamin Berg
1ca56adff5 usb-transfer: Use fpi_device_add_timeout instead of g_idle_add
g_idle_add attaches to the default main context, but the rest of
libfprint is using the thread local main context. Switch to use the
internal fpi_device_add_timeout API for the workaround in order to
not rely on the default main context.
2021-04-28 22:16:37 +02:00
Benjamin Berg
d683b271d4 ssm: Remove delayed action GCancellable integration
Unfortunately, the implementation was not thread safe and was not
sticking to the thread local main context.

In addition to this, it is not entirely clear to me how this API should
behave. The current approach is to simply cancel the transition with the
state machine halting in its current state. Instead, it could also make
sense for cancellation to cause the state machine to return a
G_IO_ERROR_CANCELLED.

As such, simply remove the feature for now. If anyone actually has a
good use-case then we can add it again.
2021-04-28 22:16:37 +02:00
Benjamin Berg
94e86875ae context: Remove idle sources and use thread local context
libfprint uses the thread local context in almost all cases. Update
FpContext to also use it and make sure that any sources are removed when
the FpContext object is finalized. Otherwise we may run into
use-after-free issues.
2021-04-28 22:16:37 +02:00
Benjamin Berg
511d456006 context: Use g_signal_connect_object for removal handling
Technically the API user might not keep the FpContext around after getting
the device object. Really bad idea, but we shouldn't rely on that.
2021-04-28 22:16:34 +02:00
Benjamin Berg
11e379050f goodixmoc: Ensure power button shield is always turned off
Use the new cleanup feature of the SSM to ensure that the power button
shield is turned off again even if the operation is cancelled.
2021-04-28 20:10:20 +00:00
Benjamin Berg
9416f91c75 ssm: Add cleanup state feature
In some situations one may want to guarantee that the last steps of an
SSM are run even when the SSM is completed early or failed.

This can easily be done by making fpi_ssm_mark_completed jump to the
next cleanup stage when called (this also includes mark_failed). Due to
the mechanism, it is still possible to explicitly jump cleanup states by
using fpi_ssm_jump_to_state, including a jump to the final state in
order to skip all cleanup states.
2021-04-28 20:10:20 +00:00
Benjamin Berg
c4ae89575a ssm: Fix up the SSM documentation a bit 2021-04-28 20:10:20 +00:00
Benjamin Berg
04f6cac7ec elan: Add PID 0c63
Users are reporting that the sensor works fine.

Closes: #357
2021-04-28 22:04:16 +02:00
Benjamin Berg
d2981fc6a4 elan: Add PID 0c4f
Users are reporting that the sensor works fine.
2021-04-28 22:04:16 +02:00
Benjamin Berg
8c9167d836 elan: Add PID 0c3d
Users are reporting that the sensor works fine.

Closes: #214
2021-04-28 15:26:05 +02:00
Marco Trevisan (Treviño)
9aa3060d32 ci: Expose valgrind test logs 2021-04-13 19:39:50 +02:00
Marco Trevisan (Treviño)
9a1dcaa801 tests: Use native meson exec wrapper in test setups instead of our script
No need to provide a script that will break usage of `meson test --gdb`
when we can use a native and cleaner alternative.

We can then ignore LIBFPRINT_TEST_WRAPPER in basic tests, while it is
still needed by umockdev tests.
2021-04-13 19:38:58 +02:00
Marco Trevisan (Treviño)
683ac48e21 libfprint2-sections: Add missing FpFingerStatusFlags 2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
3b34fc9b5b ci: Expose coverage report and meson logs in MRs 2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
41f8737b48 device: Deprecate fp_device_{supports,has}_* functions for has_feature
We can avoid having multiple device feature-check functions now and
just rely on a few.

Add uncrustify config to properly handle begin/end deprecation macros.
2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
ef805f2341 device: Expose supported features publicly as FpDeviceFeature
It can be convenient for device users to check what it supports, without
having multiple functions to check each single feature.

So expose this and add tests.
2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
bd99f865d8 fp-device: Gracefully handle capture calls on devices with no support 2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
3717468a8a device: Make verification support optional
We always assumed a device can verify, but nothing prevents from having
a device that only can identify or capture.

So, given that we've more fine grained checks, let's stop the task if
this is the case.
2021-04-12 22:14:06 +02:00
Marco Trevisan (Treviño)
8d545a0b95 fpi-device: Add FpiDeviceFeature flags to FpDeviceClass
Allows drivers to define more fine grained features for devices, not
strictly depending on assumptions we can make depending on the
implemented vfuncs.

We keep this per class but could be in theory moved to each instance.

In any case, added an utility function to initialize it in the way we
can ensure that we've a consistent way for setting them across all the
devices.
2021-04-12 22:14:06 +02:00
Huan Wang
355957919e Add nb1010 driver 2021-04-12 20:24:13 +02:00
Matthew Mirvish
07778f6bfa upeksonly: fix double free in usb transfer cbs
Some USB transfer callbacks in this driver were freeing their transfer
buffer in their callbacks, which causes a double free since the transfer
itself frees them afterwards. Probably just got missed during the V2 api
changes.
2021-04-11 07:25:48 -04:00
Benjamin Berg
7fcce7891a spi-transfer: Add SPI transfer helper routines
These routines assume that any messages is composed of a write and/or
read part. While the API allows sending and receiving as part of one
messages/transfer, it does not permit full duplex operation where data is
both send and received at the same time.
2021-04-08 16:52:20 +00:00
Matthew Mirvish
b0d9d00762 Add support for udev based device discovery
This is primarily useful for SPI devices. These devices sometimes needs
a combination of an SPI and HID device, so discovery is a bit more
complicated.
2021-04-08 17:08:53 +02:00
mincrmatt12
e95056aa86 fpi-image-device: Allow overriding of enroll stages 2021-04-06 18:51:50 -04:00
Marco Trevisan (Treviño)
9321791d0e ci: Do not use verbose logging for tests, just rely on artifacts
Only print errors if any
2021-04-01 18:01:29 +02:00
Marco Trevisan (Treviño)
4031bb62d7 device: Gracefully handle identify on devices with no support
We were crashing as trying to still call the identify vfunc, so check if
identification is supported and if not return a relative error.

Added test as well
2021-04-01 17:44:56 +02:00
Marco Trevisan (Treviño)
59767af552 doc/libfprint-2.types: Also include fp-image-device to get image type 2021-04-01 17:13:11 +02:00
Aris Lin
3fb8860dc4 synaptics: add new PID 0x100 and remove PID 0xE7 2021-03-21 17:08:34 +08:00
Benjamin Berg
03e0efe7ea doc: Add a few missing functions to documentation 2021-03-17 10:51:32 +01:00
Benjamin Berg
df9483e723 doc: Remove symbol that does not exist
fpi_ssm_next_state_timeout_cb simply does not exist, remove it.
2021-03-17 10:44:29 +01:00
Benjamin Berg
870468c741 doc: Add .types file for signals and properties
Without this the signals/properties are simply missing from the
documentation, which is obviously not very useful.
2021-03-17 10:41:48 +01:00
Julius Piso
47223e551f Added test for vfs7552 2021-03-12 11:29:43 +01:00
Julius Piso
e0de8c67b6 Added driver for validity vfs7552 2021-03-12 11:29:43 +01:00
Benjamin Berg
4a700758a6 ssm: Add getter for the device
In some cases it can be useful to be able to retrieve the device. Add
the corresponding getter to do so.
2021-03-12 11:29:43 +01:00
Marco Trevisan (Treviño)
e8a7ff1033 tests/virtual-device: Add test checking close while we're still opening 2021-03-03 19:41:04 +01:00
Marco Trevisan (Treviño)
8ae27b4672 fpi-assemping: Do not include unneeded headers and do not use absolute search paths 2021-03-03 19:40:49 +01:00
Benjamin Berg
b81c6857f2 demo: Fix flatpak build after udev option rename 2021-03-03 18:19:43 +01:00
Aris Lin
dbd20ec669 synaptics: Remove usb reset
It will trigger firmware to do some activities, remove it in device open
and device probe.
2021-03-03 16:49:13 +00:00
Benjamin Berg
e7eaecedc6 meson: Autodetect whether autosuspend rules are provided by udev
Upstream systemd/udev is pulling our autosuspend hwdb, so if udev is new
enough, then there is no need to install the file. As such, add
auto-detection logic for the scenario.

This also changes the name of the option and the type to "feature".
2021-03-03 16:45:41 +00:00
Benjamin Berg
52d0409241 data: Add note that the unsupported device list needs a manual sync 2021-03-03 17:30:12 +01:00
Benjamin Berg
f2d0d0bc57 udev-hwdb: Update list of unsupported devices 2021-03-03 17:29:30 +01:00
Marco Trevisan (Treviño)
8fd1fcbe49 virtual-device: Move shared functions into the internal scope
We are currently exporting such functions in the library, even though
they are meant to be only private.
2021-02-22 21:08:57 +01:00
Marco Trevisan (Treviño)
e4a297887b virtual-image: Use explicit list of cases in which we want to listen
Depending on the enum order is ok, but not really maintainable so better
to explicitly list the states we want to listen.
2021-02-22 19:09:11 +01:00
Benjamin Berg
966703057d synaptics: Fix lost messages when sequence counter overflows
The device will always use sequence number 0 for certain messages. We
use this knowledge to filter the messages and assume that it is one of
these special messages rather than a response to a command.

However, we could end up sending a command with a sequence counter of 0
which would result in the response being ignored. Fix this by ensuring
we correctly wrap from 255 to 1 instead of 0.

Fixes: #358
2021-02-05 16:09:24 +01:00
weilei
9e164485f0 goodixmoc:Add new PID
Add PID 6594 used by LENOVO
2021-02-04 18:51:36 +08:00
fengqiangguo
3bb38e2ff6 goodixmoc: support power button shield feature
Some OEM will integrate fingerprint device with powerButton. It's
possible that a user may press the power button during fingerprint
enroll or identify. This would lead to unintended PC shutdown or
hibernation. We add pwr_btn_shield cmd  and related process to shield
the power button function when the fingerprint functionality (enroll and
identify) is used and restore power button function afterwards.
2021-02-02 09:04:45 +08:00
Marco Trevisan (Treviño)
6a62d32c81 goodix: Consume the retry errors during verify/identify reports
We should not pass such kind of errors to complete functions, or we'll
fail the identification without ability to retry immediately.
2021-01-29 20:02:15 +01:00
Marco Trevisan (Treviño)
b2a64cc980 virtual-device: Do actual errors codes checks instead of regex checks 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
88117c172e tests/virtual-device: Add enroll and verify script test 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
27a62443a1 virtual-device: Add SET_KEEP_ALIVE command, to keep the listener up
We may want to be able to talk with the device while it's closed to
queue commands to be performed once it opens (could be even a script),
so to do this we need to close the device first, send those commands and
eventually process them.

We used a trick to send an invalid command before that was ignored by
release, but having the device available is just easier to handle.

So, when keep alive is enabled we don't stop the listener when closing
but only on actual device disposition.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
2f7c78eb97 virtual-device: Make possible to use a script to perform enroll operations 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
74f8a8ee27 virtual-device: Handle cancelled state gracefully in should_wait_to_sleep 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
acd0a10e76 virtual-device: Add test that open fails with a busy error if is still ongoing
The idea of the test was just checking what happens when we're opening a
device multiple times while a first request is still going.

However, it actually ends up also checking the previous commit change
because without it we'd stop the close iteration before the device is
actually closed and stop the open iteration before the device is
actually opened, leading to an infinite loop.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
27c2466bda fpi-device: Mark the device as open and notify it on idle callback
We're delaying any completed operation until we've completed an idle,
but the open/close state is changed and notified as soon as the device
completes the operation.

While this can be true, it means that we notify earlier than the finish
callback is actually called, while iterations are still needed to get
the actual state completed, and the current_task reset.

So if we'd open/close and iterate till fp_device_is_open() returns TRUE
we'd end up in a state in which the device is marked as ready, but it's
actually still busy since it's priv->current_task isn't unset yet.
The same if we'd try to do any action on notify::opened.
2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
33ba248c44 virtual-device: Add test checking for early errors during dev API calls 2021-01-28 15:49:22 +01:00
Marco Trevisan (Treviño)
43cf28b9da fp-device: Do not try to deference potentially NULL task data
In case we do an early error return in verify and identify calls we
do not initialize the task data, but still in the finish functions we
still try to use it.

Avoid doing this, but just nullify the returned values.
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
4da52f78f6 virtual-device: Check properties match the getters 2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
e4e0937848 tests/virtual-*: Check for enrolled prints properties 2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
25a6c916aa fp-device: Fix property getters for enroll stages and driver ID
We were returning an invalid type for the enroll stages, while trying to
get the class from the private instance for the device driver
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
51009b48a0 virtual-device: Process supported commands on device open
When opening the device we can process commands that we left for that
after the previous close, to do that we only have to inject an invalid
command that will be processed (and ignored) while closing, so that at
next device opening we will be able to proceed with the previously
sent commands.

Add tests to finally check this case!
2021-01-28 15:39:48 +01:00
Marco Trevisan (Treviño)
e1e3f6955e virtual-device: Remove messages we can't process from queue when not scanning
Commands that are not valid for non-scan operations should be removed
from queue, or these may be re-proposed forever.
2021-01-28 15:38:57 +01:00
Marco Trevisan (Treviño)
c495b82000 virtual-device: Use python's with idiom to check GLib expected error messages
And we can properly provide a real traceback as well
2021-01-28 15:38:56 +01:00
Marco Trevisan (Treviño)
d90ee96df8 virtual-device: Return an duplicated data error if trying to re-enroll a print 2021-01-28 15:38:56 +01:00
Marco Trevisan (Treviño)
36304b736b tests/virtual-device: Properly handle exceptions on enroll callback
We need to get them back to the caller function to be caught by the test
suite.
2021-01-28 15:38:29 +01:00
Marco Trevisan (Treviño)
31e34bd4bd virtual-device: Emit data not found during verify/identify
If trying to identify a print not in the storage we emit data not found
error, this can be helpful to do further fprintd testing too
2021-01-28 15:38:29 +01:00
Marco Trevisan (Treviño)
ec4c7ca5a9 virtual-device-storage: Don't listed prints 2021-01-28 02:32:28 +01:00
Benjamin Berg
8d21a9c27c ssm: Catch more errors in FpiSsm without crashing 2021-01-27 17:03:59 +00:00
Marco Trevisan (Treviño)
c4069065f9 virtual-device: Ensure we've an error before dereferencing it 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
31541edc58 tests/virtual-device: Use a sleep multiplier when under valgrind 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
549718753f fpi-device: Fix argument name on report_finger_status() annotation 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
cfde050220 virtual-device: Add ability to close a device with delay or with error 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
88a38c38af virtual-device: Add support for sleeping and sending errors on list and delete 2021-01-26 16:54:14 +01:00
Marco Trevisan (Treviño)
7ffcc2f9e7 virtual-device: Make possible to inject sleep events while verifying/identifying
Each command should be separated by SLEEP to be considered as something
we want to perform during the current operation, otherwise will be used
by next operation consuming it.
2021-01-26 16:53:24 +01:00
Marco Trevisan (Treviño)
1dae6796f7 virtual-device: Report finger presency when we receive a 'SCAN' event 2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
0bb0492025 virtual-device: Mark finger as needed only after we start scanning
In case we sent a sleep event to the device we may want to wait it to
emit the finger needed state before the timeout is completed.

So add a function to manage this for all the scan cases
2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
3db0858fb0 tests/virtual-device: Add a class function to wait for a timeout 2021-01-26 04:49:50 +01:00
Marco Trevisan (Treviño)
2382506491 virtual-device: Add checks for verify reports 2021-01-26 04:49:50 +01:00
Benjamin Berg
08f4be707c uru4000: Call irq stop handler immediately if the transfer is cancelled
The irq handler may already be stopped if stop_irq_handler is called. In
that case, we should immediately call the handler rather than just never
calling it.

This fixes deactivation when the device is unexpectedly unplugged.

Closes: #355
2021-01-25 16:56:12 +00:00
Marco Trevisan (Treviño)
3693c39bc5 virtual-device: Make cancellation support toggable
We may want to have the device to sleep while releasing an operation,
this will allow to do it.
2021-01-25 17:40:49 +01:00
Marco Trevisan (Treviño)
993109a7f8 virtual-device: Implement cancel vfunc, to stop timeouts 2021-01-25 17:40:49 +01:00
Marco Trevisan (Treviño)
18db20d160 virtual-device: Add support for sleep command
It can be used to delay operations, simulating a busy device.
2021-01-25 17:40:48 +01:00
Marco Trevisan (Treviño)
89b4c4ee75 virtual-device: Test unplug operation while we're verifying 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
153b24a95a virtual-device: Use identify function for verify tests when possible 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
8c45c0952e virtual-device: Split verify check function in two parts to be reusable
We can so inject further operations in the middle, such as for the
finger status check
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
c3ece8621d virtual-device: Implement UNPLUG operation 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
67cb61cc18 tests/virtual-device: Add identification tests
Reusing most of the logic of the `check_verify` utility function
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
33ffadf402 tests/virtual-device: Cleanup device storage on teardown 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
162a83e484 tests/virtual-device: Add ability to enroll with a retry step and test it 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
dfb27222eb tests/virtual-device: Add function that figures out the command from type 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
81e53c422d virtual-device: Add support for changing the device scan type 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
be0b4ae2bb tests/virtual-device: Trigger new scans when we got progress callback 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
56bcf1ffdd virtual-device: Add command to change the number of enroll stages
As per this don't use the class value anymore at enroll phase, as it may
differ.
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
665de7813b fpi-device: Ensure we're receiving a valid number of enroll stages 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
a291d17f26 virtual-device: Properly cleanup the virtual devices data
Ensure we call the parent finalize function and cleanup local data
2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
e8886dbc6b virtual-device: Support all the configured enrolling stages 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
3d6fb15b5c virtual-device: Add API to change current finger status 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
43d0dfdd8f virtual-device-storage: Set needed finger state on enroll and verify 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
50f522583e virtual-device: Set needed finger state on enroll and verify 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
f0443ba2f3 virtual-device: Add support for reporting device Retry "errors" 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
546f35132c tests/virtual-device: Use FPrint.DeviceError values to send errors 2021-01-25 17:40:15 +01:00
Marco Trevisan (Treviño)
ce9527d2cb virtual-device: Wait for delayed commands to be processed
This allows to mimick the image device better, so that we can start an
operation and send the commands within some delay.
2021-01-25 17:40:13 +01:00
Benjamin Berg
89890dbd1f build: Explicitly mark libfprint as a shared library
While meson suggests to always use 'library' this leads to some unwanted
behaviors when it comes to generate pkg-config files for it, as they
will include `Libs.Private` / `Required.private` fields that should not
be really part of a shared library as libfprint is meant to be used.
2021-01-21 17:36:41 +01:00
fengqiangguo
e0c41c5444 goodixmoc: Fix some big/little endian support issues
Goodix driver is not working fine in BigEndian architectures. This
commit fixes some of these issues.

Related: #236
2021-01-21 16:21:06 +00:00
Marco Trevisan (Treviño)
3b83157e9b build: Skip the hwdb test if not all drivers are really enabled 2021-01-21 15:55:44 +00:00
Marco Trevisan (Treviño)
57f836a0f6 udev-hwdb: Generate autosuspend list using a sorted list 2021-01-21 15:55:44 +00:00
Marco Trevisan (Treviño)
170924ee4f test-generated-hwdb: Just use diff to compare for being more informative 2021-01-21 15:55:44 +00:00
Benjamin Berg
63bfaf4f60 tests: Add trailing newline to busname/devname sysfs attributes
libusb 1.0.24 now expects busnum/devnum to be \n terminated. Update the
device descriptions accordingly.

https://github.com/martinpitt/umockdev/issues/115
2021-01-21 11:28:47 +00:00
Marco Trevisan (Treviño)
2f6adce2fa data: Keep using versioned libname for hwdb file 2021-01-21 01:17:02 +01:00
Marco Trevisan (Treviño)
018641ad20 build: Ensure we process the data dir 2021-01-21 00:58:08 +01:00
Benjamin Berg
8ded064e65 tests: Add test based on the new virtual devices
Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:41 +01:00
Benjamin Berg
3f7a638eed virtual-device: Add non-image mock devices
There are two variants one with storage and identify support and the
other without storage.

It implements the following commands:
 * INSERT id
 * REMOVE id
 * SCAN id
 * ERROR error-code
 * LIST (returns saved print)

The INSERT/REMOVE/LIST commands are only available in the storage
driver. The SCAN command emulates presenting a finger.

These commands can be send ahead of time, and will be queued and
processed when appropriate. i.e. for INSERT/REMOVE that is immediately
when possible, for SCAN/ERROR processing is delayed.

The LIST command is always processed immediately.

Note that only a single command can be send per socket connection and
the command must be send in a single message. The socket will be closed
after the command has been processed.

Co-authored-by: Bastien Nocera <hadess@hadess.net>
Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:41 +01:00
Benjamin Berg
253750ec08 virtual-device-listener: Add a device socket handler class
Instead of repeating the same code in both the virtual-image and the
virtual-device drivers, implement a class to handle the socket listening
an data reading.

Co-authored-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
2021-01-20 23:21:04 +01:00
Benjamin Berg
5df14206d8 tests: Add support for creating other virtual readers
Add support for creating more virtual readers.

Co-authored-by: Bastien Nocera <hadess@hadess.net>
2021-01-20 23:21:04 +01:00
Marco Trevisan (Treviño)
2f2da87240 list-udev-hwdb: Add SPDX license to the generated file
And update it...
2021-01-20 22:03:40 +01:00
Marco Trevisan (Treviño)
533180a2e6 data: Use auto-generated but hardcoded autosuspend hwdb file
This solves various problems:
 1. It stays the same also if some drivers have been disabled
 2. It uses a stable path for being imported by systemd
 3. It is still checked for its validity by tests
 4. It can be auto-generated using a simple command
2021-01-20 21:17:42 +01:00
Marco Trevisan (Treviño)
99c269b3fe meson: Do not support drivers known to fail in Big Endian archs
When building in big endian architectures some device tests will fail,
as per this we're pretty sure that most of the drivers are not ready
to work in big-endian architectures.
Since we're aware of this, better to just stop supporting those drivers
instead of having each distribution to handle the problem.

So, add a list of supported drivers that is filled depending the
architecture type we're building on. Keep continue building those
drivers since we want to at least test-build them, but do not expose
them as libfprint drivers, so if a device in the system uses any of them
will be ignored.

At the same time, we keep track of the problem, so that we can fix the
drivers.

Related to #236
2021-01-20 18:29:05 +01:00
Benjamin Berg
66fc93eeff udev-hwdb: Prevent devices from being listed twice
The change to print a warning (for testing purposes) from commit
944e0d0383 (udev-rules: Print warning if an ID is supported) was
incorrect because it prevented duplicated to be suppressed if a device
is listed by two independent drivers.
2021-01-20 18:02:31 +01:00
Benjamin Berg
284f6f1ef8 ci: Add check that wiki and generator are in sync
Add a new test that checks that the unsupported list is not out of date.
As the wiki can be edited at any time, add this as a further optional
check into the CI pipeline.
2021-01-20 17:21:38 +01:00
Benjamin Berg
1f2d723485 Drop version from libfprint hwdb
As we are shipping a hwdb file now, we cannot have a collision with the
old libfprint version. Also, we are going to pull these rules into
systemd and they will not be installed via libfprint in the future. As
such, collisions will not happen again and it makes more sense like this
for systemd.
2021-01-20 17:21:38 +01:00
Benjamin Berg
f6179d6cc4 ci: Export hwdb into artefacts 2021-01-20 17:19:42 +01:00
Benjamin Berg
cbce56c142 meson: Always build hwdb file
We want systemd to pull our hwdb. In order to ease this, always build
the hwdb file, even if it is disabled.

Once systemd has merged the rules, downstream should turn off the rules
in libfprint. The default in libfprint will also be changed to not build
the hwdb (udev_rules option) eventually.
2021-01-19 14:22:05 +01:00
Benjamin Berg
55a2bb5536 Generate a hwdb instead of udev rules
We only use the rules/hwdb to enable auto-suspend. So, instead of
shipping our own rules, we can just use the existing autosuspend rules
and ship a hwdb that sets the appropriate flag.

Closes: #336
2021-01-19 14:21:44 +01:00
Benjamin Berg
16095a21fd tests: Add check that no supported device is whitelisted 2021-01-19 13:47:21 +01:00
Benjamin Berg
80dbc9c0cb udev-rules: Remove supported synaptics devices 2021-01-19 13:47:21 +01:00
Benjamin Berg
944e0d0383 udev-rules: Print warning if an ID is supported 2021-01-19 13:47:21 +01:00
Benjamin Berg
349fbeb834 drivers: Disable reindent and disable uncrustify for large headers
There are static data and take a long time to process. Also, the VFS301
fragments were really badly indented, fix that.
2021-01-18 16:25:25 +01:00
Benjamin Berg
17a8bacfaf usb-transfer: Remove incorrect statement from documentation
The string was still written without having the _full function in mind.
2021-01-18 14:37:53 +01:00
Benjamin Berg
6d4b498dae tests: Mark umockdev-test.py executable
This makes it easier to execute it for out-of-tree tests.
2021-01-13 14:45:07 +01:00
Benjamin Berg
7c2a67a954 Release 1.90.7 2021-01-13 13:28:45 +01:00
Aris Lin
a6c2509ca8 synaptics: check if current firmware supports during device probe
Fixes: #239 and #351
2021-01-12 18:49:36 +08:00
boger
8254b9e99e goodixmoc: support finger status report
there is no specific API for report finger status,
finger needed status is set when captrue sample cmd send, once cmd receive correct,
finger is pressing on sensor.
2021-01-05 13:36:17 +00:00
Vincent Huang
943c64d96f synaptics: modify the command to only identify the provided print list 2021-01-05 11:48:51 +00:00
Benjamin Berg
f852d972a5 goodix: Add missing return to fp_verify_capture_cb
Found by coverity. While quite bad in theory, proper safeguards are in
place, so it will only result in a g_return_val_if_fail to be hit rather
than causing more severe side effects.
2021-01-04 12:56:50 +00:00
Benjamin Berg
35d2d78e67 synaptics: Delay verify operation completion until finger remoal
We used to return early in the case where the print matched in order to
report the result more quickly. However, with the early reporting
mechanism and the fprintd side implementation of it, this is not
necessary anymore.

As such, only stop the "verify" and "identify" operations when the
finger is removed (or the operation is cancelled, which is actually what
will happen currently).
2021-01-04 11:14:16 +01:00
Benjamin Berg
3d5db6a391 synaptics: Improve identify handler and return a new print
It is easier (and more correct) to create a new print from the reported
data and match that against the prints in the gallery.

We continue to return NULL during verify as we cannot provide any
additional information in that case.
2021-01-04 10:11:00 +00:00
fengqiangguo
2ee0d16784 goodixmoc: fetch max_stored_prints from device
During updating configuration, device will send back the max_stored_prints
back. The number of max_stored_prints is different among different devices.
2021-01-04 10:29:55 +01:00
fengqiangguo
e6712fbcca goodixmoc: add two new Goodix PID support.
Add two new Goodix PID 0x63AC and 0x639C, to support two more Goodix fingerprint devices on Linux platform.
2021-01-04 09:22:04 +00:00
Torstein Husebø
ee928db5b2 treewide: Correct typos 2020-12-17 20:35:11 +01:00
Bastien Nocera
d6ca8ff2b0 tests: Fix typo in comment 2020-12-17 13:59:53 +01:00
Bastien Nocera
b1b20f8ab9 tests: Mention permissions in test docs 2020-12-17 13:59:53 +01:00
Bastien Nocera
7e2b89791e tests: Fix typo in instructions 2020-12-17 13:59:53 +01:00
Marco Trevisan (Treviño)
3560a0f1e7 vfs5011: Remove the stray ; 2020-12-14 18:16:43 +01:00
Marco Trevisan (Treviño)
ed5339c4f5 vfs5011: Unset the recorded rows list when freeing them
Ensure that we unset the rows list when closing the device, so that we
won't try to append to invalid rows list new ones again.
2020-12-14 18:15:37 +01:00
Benjamin Berg
2d10d864d8 nbis: Disable array-parameter and array-bounds warnings
NBIS just does weird things and while the array-parameter warning is
easy to fix, the other is not trivial. So disable these warnings so that
we can still build using newer GCC versions.
2020-12-09 15:53:26 +01:00
Benjamin Berg
c96958582f Release 1.90.6 2020-12-09 13:30:53 +01:00
Marco Trevisan (Treviño)
c02771d16b goodixmoc: Add async identification test using on-owned deseralized prints
This simulates what fprintd does
2020-12-09 13:30:37 +01:00
Marco Trevisan (Treviño)
989d498eb9 goodix: Don't leak the templates array during verify
When verifying we initialize a temporary templates array but we never
release it.
2020-12-09 12:55:26 +01:00
Benjamin Berg
91ee03eb7a device: Fix memory management of gallery passed to identify
We cannot make any assumptions about the passed GPtrArray. As such, we
must copy the content and grab our own reference for each of the prints.
2020-12-09 11:47:33 +01:00
Benjamin Berg
28ba6a0de9 test-fpi-device: Do deep comparison of gallery
The gallery needs to be copied, as such we must do a deep comparison
instead of comparing the pointers. We also can't do the comparison
afterwards, as the gallery is owned by the operation and that operation
is finished already.
2020-12-09 11:47:33 +01:00
Marco Trevisan (Treviño)
faade91c39 test-fpi-device: Add function to create fake FpPrint's and galleries 2020-12-09 11:47:33 +01:00
Benjamin Berg
499de3e442 print: Return sunk reference from deserialize function
This function was always documented to return a sunk reference, but it
did not do so. This change is technically backward incompatible.

However, it only has an effect if anything is doing a g_object_ref_sink.
Which may happen inside libfprint itself. With the change, most API
users (including fprintd) are fixed to do refcounting correctly. Any API
user which worked around this will have a memory leak now.

That is not ideal, but it is not really that bad overall. And returning
a floating reference for FpPrint creation was a bad idea in the first
place. And it really only makes sense for fp_print_new as the only
(public) use case is to create the template for enrollment.
2020-12-09 11:47:33 +01:00
fengqiangguo
0ff7a07671 goodixmoc: fix package crc error
fix package length type convert error
2020-12-09 10:07:39 +00:00
Marco Trevisan (Treviño)
0d9d7dcb46 fp-print: Don't deference the passed error, use g_set_error instead
It still may be NULL, but we don't protect from that.
2020-12-09 10:38:38 +01:00
Marco Trevisan (Treviño)
fb23f8690f fp-print: Return NULL on error
not really different from FALSE, but still..
2020-12-09 10:38:38 +01:00
Marco Trevisan (Treviño)
6ca8441df9 umockdev-tests: Don't fail when trying to save other errors 2020-12-09 10:26:58 +01:00
Marco Trevisan (Treviño)
8112da0358 umockdev-tests: Still raise an error when storing the exception output
Otherwise we won't ever fail
2020-12-09 10:26:58 +01:00
Marco Trevisan (Treviño)
f2ea3e784e fp-print: Delete not-defined anymore functions 2020-12-09 10:26:58 +01:00
Benjamin Berg
74810a8472 image: Fix warning about uninitialized variable
The variable is only initialized later in the function. This is
harmless, as there is no return, but it causes a warning due to the
automatic free.
2020-12-08 13:33:30 +01:00
Benjamin Berg
91fb8d8cb4 compat: Add GFlagsClass autopointer
It was added to GLib at the same time as GEnumClass. We did not list it
though and are now using it in a test.
2020-12-08 13:27:50 +01:00
Marco Trevisan (Treviño)
0688288c6d .git-blame-ignore-revs: Ignore formatting commit and add hint how to use it 2020-12-07 19:01:10 +01:00
Marco Trevisan (Treviño)
c1e832e7a7 fp-device: Return valid finger status value on error
Not that the two enums have different value, but indeed the type is
wrong.
2020-12-04 12:15:22 +00:00
Marco Trevisan (Treviño)
b5496fd257 fp-device: Ensure finger status is set to proper type on property getter
Finger status is a flag not an enum.

Add tests.
2020-12-04 12:15:22 +00:00
Marco Trevisan (Treviño)
de271a0e8d fp-print: Don't byte-swap two times the NBIS array contents
When serializing an image print in big endian machine we ended up
swapping the arrays contents two times, first when adding the values and
eventually when calling g_variant_byteswap which already handles this
properly.

With this, we get the test passing into s390x.

Fixes: #236
2020-12-02 16:40:10 +00:00
Marco Trevisan (Treviño)
12b0120a3d test-fpi-device: Always check the return values for the API calls
Ensure that the return value of the API calls match the expected one,
as we need to ensure that it also matches with the error/no-error case.
2020-12-02 16:28:36 +00:00
Marco Trevisan (Treviño)
2783ac3e60 fpi-device: Return proper type on identification success
Identify function is supposed to propagate a boolean value, but we make
it return an integer instead on idle, this can be normally the same in
most of architectures, but not in BE ones.

So, make it return the proper type.
Fixes test failures in s390x.

Related to #236
2020-12-02 16:28:36 +00:00
Aris Lin
abb0b1267c synaptics: add support PID 0xE7 2020-12-02 10:21:39 +08:00
Benjamin Berg
5cb91a4189 Release 1.90.5 2020-12-01 10:14:26 +01:00
Benjamin Berg
0bb132b167 NEWS: Fix release date of 1.90.4 2020-12-01 10:14:02 +01:00
Benjamin Berg
ce39f27b5e vfs301_proto: Remove usless break after return
Closes: #341
2020-11-30 20:22:18 +00:00
Benjamin Berg
7d0956513b upekts: Remove duplicated err handling path
Closes: #342
2020-11-30 20:22:17 +00:00
Marco Trevisan (Treviño)
2b7cfa751a list-udev-rules: Remove Wrongly added well-known USB controller vid/pid combo
This was causing USB controllers to use power-saving mode, breaking usb
devices usage.

Related to: https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/327
2020-11-30 20:03:32 +01:00
Vincent Huang
0eee6a56dd synaptics: add support to sensor PID 0xC9 2020-11-30 13:53:07 +08:00
Benjamin Berg
8962e14fde Release 1.90.4 2020-11-27 13:55:49 +01:00
tt83
e246e00ba3 elan: added 0c4d device to the array of supported devices 2020-11-26 12:39:19 +01:00
Marco Trevisan (Treviño)
fa3bdb874d udev-rules: Regenerate from wiki to include VFS495 2020-11-25 18:28:41 +01:00
Benjamin Berg
2caeb8cbb3 udev-rules: Add unsupported devices from wiki page to rules
This ensures we are putting all these devices (which are unusable) into
power save mode.
2020-11-25 14:56:06 +00:00
Marco Trevisan (Treviño)
dda3587b76 identify: Use stored print to show identify information
The stored print may contain more metadata, so let's use that for
device-stored print, if available.
2020-11-23 17:00:01 +00:00
Marco Trevisan (Treviño)
fb5854213a examples: Add Identify example
It was the only main action left in the examples, we use the gallery
from the device if available, otherwise the local one.
2020-11-23 17:00:01 +00:00
Benjamin Berg
21ee241f0c virtual-image: Add command to trigger device removal
This is primarily useful for fprintd testing.
2020-11-23 17:47:03 +01:00
Benjamin Berg
280f916ace image-device: Fix incorrect g_free of error
GError needs to be free'ed using g_error_free, fix this.
2020-11-23 17:47:03 +01:00
Benjamin Berg
1b5dd0057f tests: Add device removal test
This tests all relevant scenarios of device removal, i.e.:
 * device is not open
 * device is currently closing
 * device is open and idle
 * device is currently opening
 * device is open and active

The test ensures that in all scenarios the following holds true:
 * device "removed" signal is only emitted after the action completes
 * context "device-removed" signal is only emitted after the device has
   been closed

Note that the "opening" case is special. Here we confirm that a success
from "open" will not be overriden by a FP_DEVICE_ERROR_REMOVED error, in
order to correctly signal that the internal device state is open and it
needs to be closed.
2020-11-23 17:47:03 +01:00
Benjamin Berg
8a6f1932f8 virtual-image: Add a notify::removed handler
In general, we rely on the underlying transport layer to throw errors
which will abort the current operation. This does not work for the
virtual image device though, but we need it there for testing purposes.

Add a notify::removed handler that makes things work as expected. Let it
throw a protocol error which should not be visible to the outside.
2020-11-23 17:47:03 +01:00
Benjamin Berg
0051ff6352 device: Treat devices as closed even after a close failure
We require the close call, but as the underlying transport layer is
gone, it will generally just return an error.

In principle, it makes sense to think of close as a function that always
succeeds (i.e. it makes no sense to try again). Should the device be in
a bad state, then a subsequent open() will simply fail.
2020-11-23 17:47:03 +01:00
Benjamin Berg
b6dd522459 Rework device removal to have a nice API
This enhances the device removal to create a well defined behaviour.

Primarily, it means that:
 * "device-removed" will only be called for closed devices
 * "removed" will be called only when no operation is active

Note that all actions will fail with FP_DEVICE_ERROR_REMOVED, *except*
for open which will only return this error if it failed.

Resolves: #330
2020-11-23 17:47:03 +01:00
Benjamin Berg
656bf3d175 elan: Add a few comments that stopping/callibrating helps
Apparently stopping/callibrating helps with the reliability of these
sensors. Add a few comments so that this information is known.

See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/216#note_619467
2020-11-18 15:18:11 +01:00
Benjamin Berg
fe498c56c7 virtual-image: Fix race condition closing new connection
When a new connection came in we would close the old connection. This in
turn would trigger a receive error causing the *new* connection to be
closed from the error handler.

Fix this by simply cancelling any pending transfers when a new
connection comes in. Also change the error handling code to catch issues
like partial writes correctly.

This fixes an issue for the fprintd test where some tests were flaky.
2020-11-10 15:59:53 +01:00
Marco Trevisan (Treviño)
251ccef9ba fpi-device: Add debug information about the enrolled finger 2020-11-08 22:19:23 +01:00
Marco Trevisan (Treviño)
3b993fabb6 verify/enroll: Save and use locally saved prints also for devices with storage
Some devices have storage but that's is limited enough not to be able
to store all the metadata, but just a fingerprint id.

In such case we also need to use the local storage to be able to verify.
Fprintd does this already, but we don't do it in the libfprint examples.

So, in in case we enroll, always save the print information to the disk,
while in case we verify we try to load the print from disk and we use
that in case its private data matches the one provided by the device.
2020-11-08 22:19:23 +01:00
Marco Trevisan (Treviño)
0c56e0de6d synaptics: Report finger status to libfprint
The inactivation in case would be set back by libfprint
2020-11-07 13:23:30 +00:00
Marco Trevisan (Treviño)
893ff9c033 fp-image-device: Report finger status changes to the device
While the image device has its own finger status tracking, we use a simpler
version as public data information, so let's just report the finger-on/off
and when a finger is expected to the parent class.

Verify that this happens as expected using the virtual-image class
2020-11-07 13:23:30 +00:00
Marco Trevisan (Treviño)
3c382cac7f fp-device: Reset the finger status on complete
Devices should handle the finger status internally, but if they don't do it
we need to handle it on actions completion
2020-11-07 13:23:30 +00:00
Marco Trevisan (Treviño)
42e4506b1b fp-device: Add finger-status property
It can be used by drivers to report the state of the finger on sensor
2020-11-07 13:23:30 +00:00
Benjamin Berg
ae3baadcf9 tests: Add a new test for vfs301
See: #320
2020-11-05 15:55:09 +01:00
Benjamin Berg
4f29a32da8 tests: Store temporary directory on failure
It is not very useful to just delete the data again after a failure, as
it might be useful for debugging. Just store it into an "errors"
subdirectory of the PWD in the hope that this is a sane location.

Note that it'll error out if the directory already exists, but that
should be acceptable in all cases. i.e. it won't exist in the CI and
developers can just wipe the directory.
2020-11-05 15:52:54 +01:00
Benjamin Berg
e5fa54e8e7 vfs301: Start capture only on state change to AWAIT_FINGER_ON
Start the capture when the state changes to AWAIT_FINGER_ON instead of
assuming that the device should always be active.

Closes: #320
2020-11-04 14:13:00 +01:00
Benjamin Berg
d3076039d0 vfs301: Fix device pointer handling in callback
When porting the driver to the new libfprint 1.90.0 a mistake was made
where the device was not passed through user_data anymore but it was
still read from there. Stop using user_data in the callback to fix this.

See: #320
2020-11-04 14:13:00 +01:00
Benjamin Berg
a748f4d30f elan: Simplify elan driver internal state machine
The elan driver always "deactivates" the device after a cpature run. We
can simplify the while internal state into a single "active" state and
rely on the image device driving this state machine correctly.

i.e.:
 * We start a callibrate/capture/deactivate when we go into the
   AWAIT_FINGER_ON state
 * We only store the fact that we are active and want to deactivate
 * We rely on the image device never going into the AWAIT_FINGER_ON
   state without first waiting for the finger to be off (which implies
   deactivation).
2020-11-04 14:13:00 +01:00
Benjamin Berg
3ee5536a13 image-device: Redefine internal states and valid transitions
This adds a number of new internal states to better capture what is
going on. Also added are checks that all transitions we make are in the
set of expected and valid transitions.

Only three drivers use the state_change notification. These drivers are
updated accordingly.
2020-11-04 14:13:00 +01:00
Benjamin Berg
f56aacc7ef image-device: Remove cancelling boolean from private data
The boolean is just used to emit a warning for unexpected state
transitions. It is sufficient to pass it to the deactivate function
directly for that purpose.
2020-11-04 14:13:00 +01:00
Benjamin Berg
96fa0a96eb uru4000: Fix missing reference to image transfer
We might redo image transfers, but we only ever had one reference that
was implicitly removed after the transfer completed. Add a new reference
each time it is submitted and only free the last reference in the stop
handler.
2020-10-19 17:41:26 +02:00
Benjamin Berg
1754bd0204 synaptics: Always submit interrupt transfer without a timeout
For some reason we re-submitted the interrupt transfer with a timeout of
1s while the original submission was without a timeout. This looks like
typo, remove the timeout.
2020-10-19 17:14:24 +02:00
Benjamin Berg
90a1abf2f8 synaptics: Fix missing reference to interrupt transfer
When resubmitting the interrupt transfer we need to add a new reference
as the submit function will steal it again.
2020-10-19 17:13:58 +02:00
Benjamin Berg
59824d2122 synaptics: Remove useless code
There is never a fall through if error is not NULL.
2020-10-19 16:59:07 +02:00
Vincent Huang
31319d9c6f synaptics: add support to pid 0xF9, 0xFC, 0xC2 2020-10-15 12:25:34 +08:00
Vincent Huang
e27b65c930 synaptics: add identify function 2020-10-14 18:48:09 +08:00
Benjamin Berg
b03f9a502a tests: Remove old README-umockdev file
It has been superseeded by README.md.
2020-10-14 12:39:10 +02:00
Benjamin Berg
44ef20d5ac aesx660: Use convenience API to allocate USB receive buffer
This also fixes a memory leak of the data as the g_free was missing and
none of the callback handlers free the data either.
2020-10-07 13:38:59 +02:00
Benjamin Berg
4719b30f16 aes1610: Use convenience API to allocate USB receive buffer 2020-10-07 13:38:59 +02:00
Benjamin Berg
7eb361087a drivers: Add access annotations to USB helpers
Mostly for completeness sake, doing this did not find any errors (but
might catch some issues with fixed buffer lengths).
2020-10-07 13:38:59 +02:00
Benjamin Berg
33d50e4e30 usb: Annotate access to USB buffers
Annotate the USB transfer creation functions with the correct buffer
access attribute. Note that we only annotate them as read_only as the
functions may be used for sending and receiving.

Hopefully this will catch buffer overflows in drivers in the future.
2020-10-07 13:22:18 +02:00
Benjamin Berg
994690cfa3 virtual-image: Only read socket when active
Doing this avoids race conditions in testing code where the code might
try to submit errors/images before the device has been activated. This
would then (sometimes) trigger assertions in the image driver code.
2020-10-07 09:44:49 +00:00
Benjamin Berg
52b2d10887 image-device: Delay task completion until device is deactivated
The earlier image device code tried to hide deactivation from the
surrounding library. However, this does not make any sense anymore with
the early reporting feature present.

This changes the operation to complete only once the device is
deactivated. Also changed that in most cases (except for cancellation)
we wait for the finger to be removed before deactivating the device.
2020-10-07 09:44:49 +00:00
Benjamin Berg
81e0f4dfe5 aes3k: Re-send some commands for each capture
The driver seems to have relied on the device to be fully
deactivated and activated again for each capture. This is not the case
during enroll, and as such in can cause issues.

Try fixing this by splitting out the last few commands send to the
device and assuming that this starts the capture.

Fixes: #306
2020-10-07 11:34:12 +02:00
Benjamin Berg
c7cab77fc1 usb-transfer: Work around libgusb cancellation issue
We have plenty of code paths where a transfer may be cancelled before it
is submitted. Unfortunately, libgusb up to and including version 0.3.6
are not handling that case correctly (due to libusb ignoring
cancellation on transfers that are not yet submitted).

Work around this, but do so in a somewhat lazy fashion that is not
entirely race free.

Closes: #306
2020-10-01 00:19:35 +02:00
Benjamin Berg
a63dcc96d5 virtual_image: Open a window for race conditions during open/close
Delay the open/close callbacks by 100ms so that we have a window of
opportunity for race conditions. This is needed to test certain
conditiosn in fprintd.
2020-09-29 12:02:19 +00:00
Benjamin Berg
fab349f356 Remove trailing \n where they are not necessary
Adding a trailing \n to g_message, g_debug, g_warning and g_error is not
neccessary, as a newline will be added automatically by the logging
infrastructure.
2020-09-29 10:42:03 +02:00
Benjamin Berg
62edf93958 tests: Add AES3500 test case
Thanks for Federico Cupellini for providing test samples.
2020-09-29 10:35:48 +02:00
Benjamin Berg
8c4ff253cb aes3k: Fix transfer error path and cancellable lifetime
The cancellable needs to be free'ed at deactivation. Also free it if we
run into a fatal error, which then in turn indicates that the device is
deactivated already.
2020-09-29 10:35:25 +02:00
Benjamin Berg
3ce6a15547 image-device: Don't deactivate if deactivation was already started
The test only prevent deactivation after it completed. Also guard
against trying to deactivate a second time.
2020-09-28 19:12:28 +02:00
Benjamin Berg
174aa2c091 Release 1.90.3 2020-09-14 14:23:45 +02:00
Benjamin Berg
9efe25b91c ci: Disable flatpak building for forks
Also move to use a single rules set for flatpak rather than only/except
rules.
2020-09-14 14:17:25 +02:00
Benjamin Berg
bcce8876e2 aes3k: Fix cancellation logic of aes3k driver
The change_state function is called synchronously from the
image_captured callback. This means that deactivation of the device
happens during the img_cb function, causing the USB transfer to be
re-registered even though the device is already deactivating.

There are various ways to fix this, but it makes sense to directly bind
the cancellation to the deactivation. So create a cancellable that we
cancel at deactivation time, and make sure we always deactivate by going
through cancellation.

closes: #306
2020-09-14 11:23:38 +00:00
boger.wang
3962372f47 tests: add identify test for driver goodixmoc
add identify ioctl file, modify custom.py add identify test
2020-09-14 09:55:55 +00:00
boger.wang
f67f61c638 goodixmoc: Add identify function
this device support verify and identify both, actually call the same
interface.
2020-09-14 09:55:55 +00:00
boger.wang
d5f7f4dfaa goodixmoc: Prevent incorrect firmware type running
only firmware type:APP can function well, if device flash in a factory
or test firmware, report a error tips user update firmware by fwupd
2020-09-14 09:55:55 +00:00
Benjamin Berg
ce6961d165 image-device: Fix cancellation documentation
Image devices are simply deactivated suddenly. As such, the cancellation
logic of FpDevice is not really useful there, but the documentation was
apparently accidentally copied unmodified.
2020-09-07 12:12:34 +02:00
Benjamin Berg
30e1a68344 ci: Build flatpak using GNOME runner and template 2020-09-03 09:42:28 +02:00
Benjamin Berg
5b087ed848 demo: Switch to use GNOME 3.36 runtime 2020-09-03 09:41:11 +02:00
Benjamin Berg
5d0481b031 context: Lower severity of warning if USB fails to initialise
This is unlikely to happen in a real world scenario and currently breaks
running the CI test (not the umockdev based ones) while building the
flatpak. Lower the severity to avoid aborting because there is a
warning.
2020-09-03 09:41:11 +02:00
Benjamin Berg
596d22a449 context: Fix invalid accesses to GUsbContext if USB is missing
When USB cannot be initialised (inside the flatpak build environment),
then we would have invalid accesses to the NULL pointer. Fix those.
2020-09-03 09:41:11 +02:00
boger.wang
c85f385191 tests: add test for goodixmoc driver 2020-09-01 16:39:06 +08:00
boger.wang
eb2aaaaa20 drivers: add goodix moc sensor driver support 2020-09-01 16:39:06 +08:00
boger.wang
e3c009c5b3 fp-device: add new type FpDeviceError FP_DEVICE_ERROR_DATA_DUPLICATE 2020-09-01 16:39:06 +08:00
Vincent Huang
a4f7293f32 synaptics: retry get version command once when receiving non-success
status
2020-08-21 17:42:00 +08:00
Vincent Huang
8b64312f4b synaptics: support sensors pid 0xe9 & 0xdf 2020-07-31 09:47:35 +08:00
Marco Trevisan (Treviño)
b7e27bfdc6 demo: Handle the non-imaging mode also if we get a non-supported error
Image devices may return a FP_DEVICE_ERROR_NOT_SUPPORTED error once capture
is already started, in such case handle the error going in non imaging mode
2020-06-17 14:16:34 +02:00
Marco Trevisan (Treviño)
37b19674f1 verify: Use fast matching callback also for non-storage devices 2020-06-17 14:14:50 +02:00
Marco Trevisan (Treviño)
a5f4ad507a img-capture: Exit with error if the device doesn't support capture 2020-06-17 14:12:43 +02:00
Marco Trevisan (Treviño)
1f96077e36 examples: Don't try to save an image from a print without it
A device may produce both prints with image data and not, so only do it
in the case the prints contains image data
2020-06-17 14:00:19 +02:00
Marco Trevisan (Treviño)
ed26976ac5 fpi-usb-transfer: Use the same values of libusb for transfer types 2020-06-16 22:50:47 +02:00
Marco Trevisan (Treviño)
e4d292b595 fp-image-device: Properly include fp-device.h 2020-06-16 22:49:38 +02:00
Marco Trevisan (Treviño)
c6b8430c72 fpi-print: Improve debug on print score 2020-06-16 22:49:18 +02:00
Marco Trevisan (Treviño)
cbf1dcca29 fpi-image-device: Improve debugging messages 2020-06-16 22:48:51 +02:00
Marco Trevisan (Treviño)
7f7d099ba0 fpi-device: Don't double check for cancellable value
g_cancellable_is_cancelled already handles properly null values
2020-06-16 22:43:18 +02:00
Marco Trevisan (Treviño)
b6f965c1d9 fpi-device: Use the current action string instead of value 2020-06-16 22:42:34 +02:00
Vasily Khoruzhick
fd2875aa3e examples: add img-capture example
This one can be useful in scripts, e.g. for building fingerprint
dataset.
2020-06-13 09:20:28 -07:00
Benjamin Berg
4b2816db64 Update for 1.90.2 2020-06-08 11:40:02 +02:00
Benjamin Berg
4af3e59174 uru4000: Always detect whether encryption is in use
This is based on the patch and observation from Bastien that some
URU4000B devices do not use encryption by default (it is a configuration
stored within the firmware). As such, it makes sense to always detect
whether encryption is in use by inspecting the image.

The encryption option would disable flipping of the image for the
URU400B device. Retain this behaviour for backward compatibility.
2020-06-05 15:53:53 +00:00
Benjamin Berg
24b1faffde upeksonly: Add a comment that multiple URBs are needed 2020-06-05 17:44:36 +02:00
Benjamin Berg
49983c8ee7 upeksonly: Fix memory leak of register data helper struct 2020-06-05 17:44:36 +02:00
Vasily Khoruzhick
d276c3489e upeksonly: Fix register write value
The value was set after the transfer was submitting, causing the value
to always be zero.
2020-06-05 17:44:36 +02:00
Benjamin Berg
3f51e6dcb6 upeksonly: Pass required user data to write_regs_cb
The user data for write_regs_cb needs to be set to wrdata. This was
simply missing, add the appropriate argument.
2020-06-05 17:44:36 +02:00
Benjamin Berg
b4dbbd667a upeksonly: Avoid reading beyond received packet boundary
The code would just read 4096 bytes from the packet, without checking
the size and neither setting short_is_error. It is not clear whether
packets from the device are always 4096 bytes or not. But the code
assume we always get a full line, so enforce that and use the actual
packet size otherwise.
2020-06-05 17:44:36 +02:00
Benjamin Berg
7d9245505f upeksonly: Remove callback support after killing transfers
This seems to have been unused even before the v2 port.
2020-06-05 17:44:36 +02:00
Benjamin Berg
570daf2321 upeksonly: Remove ABORT_SSM constant
This was not used. The old driver used this if creating a USB transfer
failed, however, we delay any such failures (which cannot really happen)
into the callback today, where the error is handled differently.
2020-06-05 15:40:17 +00:00
Benjamin Berg
60d0f84294 upeksonly: Fix creation of image transfers
The GPtrArray needs to be created at some point. Also, reference
counting was wrong as submitting the transfer sinks the ref, but we rely
on it surviving.

Note that we really should change this to only have one in-flight
transfer and starting a new one after it finishes.

Co-authored-by: Vasily Khoruzhick <anarsoul@gmail.com>
2020-06-05 15:40:17 +00:00
Benjamin Berg
6633025437 vfs301: Allow freeing of data by copying it
When sending static data, it would not be copied. The function that
sends it assumed that it should be free'ed though.

Fix this by simply always making a copy.
2020-06-05 15:17:42 +00:00
Benjamin Berg
40ed353666 elan: Only queue state changes once
The driver would warn about the fact that a state change is queued, but
still queue it a second time. This would result in deactivation to run
twice.

See: #216
2020-06-05 15:13:18 +00:00
Benjamin Berg
32bdd8d5c4 image: Fix reporting of retry on activation timeout
The image driver may still be deactivating when a new activation request
comes in. This is because of a hack to do early reporting, which is
technically not needed anymore.

Fix the immediate issue by properly reporting the retry case. The proper
fix is to only finish the previous operation after the device has been
deactivated.
2020-06-05 15:07:05 +00:00
Benjamin Berg
ec4fc9aec5 ci: Put coverage regexp into CI description
One can set it in the project, but that doesn't get copied to forks. And
that means the coverage information isn't printed in MRs sometimes.

Just add it into .gitlab-ci.yml so that it always works.
2020-06-05 15:03:38 +00:00
Benjamin Berg
390611d5c9 tests: Improve the instructions to create new umockdev captures
Thanks to Evgeny for much of the work and suggestions from Boger Wang.

Co-authored-by: Evgeny Gagauz <evgenij.gagauz@gmail.com>
2020-06-05 15:03:38 +00:00
Benjamin Berg
685052c605 tests: Add test for vfs0050 driver
This test is based on data captured by Evgeny.

Co-authored-by: Evgeny Gagauz <evgenij.gagauz@gmail.com>
2020-06-05 15:03:38 +00:00
Benjamin Berg
4b83f8bfd9 vfs0050: Accept zero bytes read instead of timeout for emulation
This allows us to replace non-emulateable timeout conditions into zero
byte replies in the recording.
2020-06-05 15:03:38 +00:00
Benjamin Berg
b137807420 upekts: Fix error reporting during verify
We delayed the wrong error types for the early reporting mechanism.
2020-06-05 14:48:57 +00:00
Benjamin Berg
0936fc3597 upekts: Fix error handling in verify_stop_deinit_cb
The error memory management was incorrect possibly causing double free's
and critical warnings.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b7f436e8de upekts: Fix reading of fingerprint data for verification
the code tried to fetch the data from the device rather the print.
Obviously, this could never work.
2020-06-05 14:48:57 +00:00
Benjamin Berg
4f0b0fa526 tests: Ensure FpDevice checks enrolled prints for completeness
Enrolled prints need to have their type set. FpDevice should ensure that
is the case when a driver returns a print back.
2020-06-05 14:48:57 +00:00
Benjamin Berg
f0abefa9fa device: Ensure enrolled print as an appropriate type set
The driver might forget to set the type of the print. Catch that error a
bit earlier rather than failing when the API user tries to load it from
disk again.
2020-06-05 14:48:57 +00:00
Benjamin Berg
7f58556011 tests: An enrolled print needs to have a type set 2020-06-05 14:48:57 +00:00
Benjamin Berg
cecb01bcb9 upekts: Set the print type during enroll
The type of the print (RAW or NBIS) needs to be filled in by the driver.
For most drivers the image devices does this (NBIS), but the
corresponding call was missing in the upekts driver, rendering the
enrolled print unusable.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b95402bc72 upekts: Fix memory leak and remove unneeded copy
__handle_incoming_msg would copy the payload of the message into a newly
created buffer just to destroy it again immediately after calling the
callback. Just reference the correct address inside the original package
instead.

Also, in one case the extra buffer was leaked afterwards.
2020-06-05 14:48:57 +00:00
Benjamin Berg
484743f652 upekts: Assert correct packet length in __handle_incoming_msg
The surrounding code already checks this and reads the correct amount.
Add an assert to ensure we really never do an out of bounds read.
2020-06-05 14:48:57 +00:00
Benjamin Berg
a5cfc1644f upekts: Fix 9 byte buffer overflow while reading extended data
The driver would correctly calculate the amount of extra space needed to
receive the whole packet. It would also request the correct number of
bytes for this transfer.

However, the reallocated buffer to hold this data was directly derived
from the expected payload size and did not include the overhead.

Make the code more explicit and get rid of the confusing
MAX_DATA_IN_READ_BUF define that hides details on buffer allocation
calculation from the code.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b3565b83e1 upekts: Only release USB interface on exit
The device is already beeing de-initialised from the verify/enroll
commands. Trying it again will result in a timeout error as it is not
responding properly at that point.
2020-06-05 14:48:57 +00:00
Benjamin Berg
8f46de0a60 upekts: Fix reference counting in do_enroll_stop
The print passed to do_enroll_stop does not need to be ref'ed in the
function.
2020-06-05 14:48:57 +00:00
Benjamin Berg
b3c5fe4b82 upekts: Fix ownership transfer to fpi_device_enroll_complete
fpi_device_enroll_complete takes the ownership of the pointers. As such,
they need to be stolen from EnrollStopData.
2020-06-05 14:48:57 +00:00
Vasily Khoruzhick
4cf5f92a52 lib: re-add partial image flag
And activate perimeter points removal if this flag is set

This flag should be set for aes1610, aesx660, aes2501, aes2550
and upektc_img since these sensors may produce incomplete image.

Fixes: #142
2020-06-04 09:34:31 -07:00
Vasily Khoruzhick
297236b51a nbis: re-add step to remove perimeter points
This step helps to drop false minutiae for short sensors and
it was accidentally dropped during NBIS update. Re-add this step
and add a patch to update script to ensure that it's not dropped
during next update.

Fixes: 9fb789dc78 ("nbis: Update to NBIS 5.0.0")
2020-06-03 20:44:41 -07:00
Benjamin Berg
8626c64831 ci: Output diff of uncrustify check
Not having the diff is a bit painfull when the local version of
uncrustify differs from the one on the CI runner. So uncrustify in-place
and output the diff.
2020-06-02 11:56:19 +00:00
Benjamin Berg
e4f9935706 Uncrustify with newer version 2020-06-02 11:56:19 +00:00
Benjamin Berg
8ba29606bb Add MAINTAINERS file 2020-05-22 15:00:11 +02:00
Evgeny Gagauz
1b74813adf vfs0050: Stop capture after a timeout happens
If a transfer errors out then actual_length is negative. The only error
that is not caught is a timeout error, which should also result in the
SSM to move to the next state.
2020-05-13 09:51:23 +00:00
Benjamin Berg
07ff03970f libfprint: Fix a few issues with the documentation
This must have been broken all along. Get it into a better shape. Looks
like mostly cases of bad copy/paste.
2020-05-11 20:51:29 +02:00
Benjamin Berg
25ab4849a4 doc: Move sections and fix title for internal FpImageDevice
Otherwise the public API page (which is empty) is overwritten.
2020-05-11 20:51:29 +02:00
Benjamin Berg
840bcc77a5 ci: Export HTML documentation as artifacts
We build the HTML documentation. For feature branches, it is convenient
to be able to view the documentation easily. Expose them as artifacts
and add a link to the browser underneath the pipeline in the MR.

Unfortunately, it does not seem to be possible to link directly to the
HTML.
2020-05-11 20:51:29 +02:00
Benjamin Berg
a464f602ca nbis: Apply patch to fix scan-build warnings
Apply the newly added patch to the checkout.
2020-05-07 14:22:02 +00:00
Benjamin Berg
ad17011e68 nbis: Add patch to fix warnings reported by scan-build
This patch basically only adds annotations. None of the errors can be
hit in practice.
2020-05-07 14:22:02 +00:00
Benjamin Berg
744a71ce08 vfs301: Assert hex string has 2 or more characters
Otherwise static analysis thinks we may end up allocating a 0 byte
output buffer.
2020-05-07 14:22:02 +00:00
Benjamin Berg
422fc5facf tests: Add unused annotation
The variables exist for memory management but are unused otherwise. Tag
them as such.
2020-05-07 14:22:02 +00:00
Benjamin Berg
6d542edf8a test: Remove unused initialisers
Make the static analysis happy.
2020-05-07 14:22:02 +00:00
Benjamin Berg
8d4d56b1f1 tests: Annotate a few variables as unused
These solely exist for memory management, but the static analysis
complains.
2020-05-07 14:22:02 +00:00
Benjamin Berg
6e30a1ee45 print: Fix "possible leak" warning by moving initialization
For some reason static checkers report that the auto-free is not run if
the goto exists the loop. It seems to me like that should work fine, but
we can simply make the analysers happy by moving it.
2020-05-07 14:22:02 +00:00
Benjamin Berg
87c3b9c5ba upekts: Fix possible NULL pointer access
Reported by scan-build.
2020-05-07 14:22:02 +00:00
Benjamin Berg
0a08a6a7c0 ci: Run clang scan-build test as part of CI 2020-05-07 14:22:02 +00:00
Benjamin Berg
9db89e00d0 elan: Downgrade g_message to debug severity
See: #211
2020-05-07 13:55:35 +00:00
Benjamin Berg
3ad65b9589 vfs5011: Prevent too small images
We need more than 1 line for assembling, but in general, we should
have a reasonable amount of lines. So use the width in the hope we'll
get an image that is about square at least.

Closes: #135
2020-05-07 13:55:35 +00:00
Benjamin Berg
48aa6d0252 upekts: Fix regression during initialisation
The driver has two helper functions to format a command. In one case,
the function was accidentally changed during the port to the new driver
APIs.

See https://bugzilla.redhat.com/show_bug.cgi?id=1832229
2020-05-07 09:55:13 +02:00
Michal Prívozník
eefc954f91 context: Fix order of PID/VID in a debug message
When no driver is found for an USB device a debug message is
printed. However, it has PID and VID in wrong order - usually it
is Vendor ID which goes first. This is how 'lsusb' prints it.
Matching the order helps debugging.

Signed-off-by: Michal Privoznik <michal@privoznik.com>
2020-04-27 16:16:43 +02:00
Michal Prívozník
5bcf9ac008 print: Include "fpi-compact.h"
In the fpi_print_fill_from_user_id() GDate is defined using
g_autoptr(). However, this requires new enough GLib. For older
versions there's a definition provided locally in fpi-compact.h.
Include the file to fix build with older version of GLib.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-27 16:16:39 +02:00
Benjamin Berg
d2402309ee examples: Cancel verify operation on Ctrl+C
This makes it easier to do basic testing of cancellation paths in the
drivers.
2020-04-24 18:40:48 +00:00
Benjamin Berg
a651b65401 example: Cancel enroll operation on Ctrl+C
This makes it easier to do basic testing of cancellation paths in the
drivers.
2020-04-24 18:40:48 +00:00
Marco Trevisan (Treviño)
bc3f622b2a context: Factorize duplicated code 2020-04-24 20:21:01 +02:00
Marco Trevisan (Treviño)
5de49b33e6 image-device: Terminate the current action with error on print failure
If we fail when setting the scanned image to a print, we'll have a fatal
error, in such case we can terminate the current action and deactivate the
device.
2020-04-24 20:09:56 +02:00
Marco Trevisan (Treviño)
81e198c034 image: Return an error if we got an empty or NULL minutiae array
In some cases nbim's get_minutiae returns no minutiae without providing an
error code, and if this happens we would crash in the task callback function
as we would try to deference the data->minutiae pointer.

Related to: #251
2020-04-24 20:09:56 +02:00
Marco Trevisan (Treviño)
c0895a858d etes603: Return TOO_SHORT retry error for small images
If the image height is less than the sensor horizontal resolution, then
return a retry error rather than trying to submit the image for further
processing.

Related to: #251
2020-04-24 20:03:51 +02:00
Benjamin Berg
5d5995f201 image: Check for task success rather than just cancellation
The minutiae detection might fail and we must not copy any data at that
point. So check g_task_had_error to ensure that we only do so when the
task was successful.

Fixes: #251
2020-04-24 20:03:37 +02:00
Benjamin Berg
f71045b743 synaptics: Use the FpPrint ID generation functionality
As the functionality is now part of the internal FpPrint API, it makes
sene to use it.
2020-04-20 16:43:52 +02:00
Benjamin Berg
0274d0783b print: Add helpers to generate a unique print ID containing metadata
It makes sense to include this functionality in the core library as more
than one driver will be using it soon.
2020-04-20 16:43:52 +02:00
Bastien Nocera
5c5a4f6907 upekts: Fix memory leak
Don't allocate a new finger print structure,
the fpi_device_get_enroll_data() just below will overwrite it.
2020-04-15 15:55:39 +02:00
Bastien Nocera
5b6f5c9aad synaptics: Don't pass always-NULL value
No need to pass "error" to this report function, it will always be NULL.
2020-04-15 15:55:39 +02:00
Marco Trevisan (Treviño)
41e05b1133 test-fpi-device: Don't compare error pointers that have been cleared
During verify/identify complete we replace the error pointer that the driver
returned with another error we created, after clearing that one.

However, when we initialize a new error the compiler may reuse the same
allocation of the cleared one, and this might lead to a test failure.

So, don't be so fragile and ignore the pointer check
2020-04-15 14:19:53 +02:00
Bastien Nocera
579e01359b fp-print: Fix sign-compare warnings
libfprint/fp-print.c: In function ‘fp_print_equal’:
libfprint/fp-print.c:596:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Wsign-compare]
  596 |       for (i = 0; i < self->prints->len; i++)
      |                     ^
libfprint/fp-print.c: In function ‘fp_print_serialize’:
libfprint/fp-print.c:667:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Wsign-compare]
  667 |       for (i = 0; i < print->prints->len; i++)
      |                     ^
libfprint/fp-print.c: In function ‘fp_print_deserialize’:
libfprint/fp-print.c:823:21: warning: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Wsign-compare]
  823 |       for (i = 0; i < g_variant_n_children (prints); i++)
      |                     ^
2020-04-15 12:48:05 +02:00
Bastien Nocera
cc887c1a37 libfprint: Fix typos 2020-04-14 13:51:02 +02:00
Bastien Nocera
fdd2d6abf8 fprint-list: Fix typos in Copyright statements 2020-04-14 13:51:02 +02:00
Bastien Nocera
6bf29108a1 examples: Fix typo 2020-04-14 13:51:02 +02:00
Bastien Nocera
d0751ae06b tests/elan: Fix typos 2020-04-14 13:51:02 +02:00
Bastien Nocera
a218a5efdd virtual-image: Fix typo 2020-04-14 13:51:01 +02:00
Bastien Nocera
c6ae8e58a4 elan: Fix typo 2020-04-14 13:50:49 +02:00
Bastien Nocera
87c7894c28 synaptics: Fix typos 2020-04-14 13:47:48 +02:00
Marco Trevisan (Treviño)
e7ff4f705c tests: Import FPrint only during execution not when parsing
The unittest_parser script would try to import FPrint gi module, but it
would fail as per the fact that none is installed yet, so make sure that
we don't load any FPrint module until we try to actually run the tests
2020-03-27 21:19:09 +00:00
Marco Trevisan (Treviño)
c26588942a ci: Print coverage data once available so that gitlab can parse it 2020-03-27 00:00:07 +01:00
Laurent Bigonville
3d68cddfe7 Properly set the dependencies in the pkg-config file
The public API uses gio and gobject header, ensure that these are in the
list of Required pkg-config modules, otherwise they are added to
Required.private which is not OK.
2020-03-20 11:13:06 +00:00
Benjamin Berg
96fba323b9 meson: Fix linking issue of libfprint with newer gcc
It appears the order of linking is relevant in this case, change it to
fix some linking issues.

It may be that there are better solutions to this problem.
2020-03-20 12:05:14 +01:00
Benjamin Berg
bd4f118b5e ci: Update CI after the fdo template changes
The CI definition needs to be updated to work with the new fdo
templates.
2020-03-20 12:05:14 +01:00
Benjamin Berg
9d4b5ad682 Revert "ci: Fix CI syntax error"
This reverts commit bd500b2235.

The fix from the commit was not correct.

See https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/124
2020-03-20 12:05:08 +01:00
Benjamin Berg
ca788b6de2 Revert "ci: Fix unknown keys in CI"
This reverts commit ebe5cb58ba.

The fix from the commit was not correct.

See https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/124
2020-03-20 12:04:58 +01:00
Bastien Nocera
90ccf9a0af vfs0050: Fix incorrect destructor for GError 2020-03-13 10:23:52 +01:00
Bastien Nocera
2581f1aa32 aes1610: Fix memory leak
Fix small memory leak when reading some data that's not going to be
processed.
2020-03-13 10:23:52 +01:00
Bastien Nocera
ebe5cb58ba ci: Fix unknown keys in CI
Fix:
root config contains unknown keys: container_fedora_build
2020-03-13 10:14:59 +01:00
Bastien Nocera
bd500b2235 ci: Fix CI syntax error
Fix CI syntax error:
container_fedora_build: unknown keys in `extends` (.fedora@container-build)
Caused by changes in the wayland CI templates:
4a73f030d0
2020-03-13 10:08:58 +01:00
Bastien Nocera
8fa50d667c ci: s/flatpack/flatpak/
“Flatpack” is for IKEA furniture.
2020-03-13 10:08:58 +01:00
Marco Trevisan (Treviño)
2ae8b74e60 meson: Add fpi-compat.h to the private headers 2020-02-27 06:03:21 +01:00
Benjamin Berg
f4ec816a6b tests: Cast to correct pointer type rather than gpointer
This is just a small cleanup
2020-02-19 16:42:30 +01:00
Benjamin Berg
9e2a7235e3 tests: Fix reading of gboolean into pointer
Otherwise the payload will be lost later on when using GPOINTER_TO_INT
to cast it back.

See: #236
2020-02-19 16:42:30 +01:00
Benjamin Berg
66c9e4a829 Update for 1.90.1 release 2020-02-10 12:20:25 +01:00
Marco Trevisan (Treviño)
0bb8ad1313 tests: Make meson be aware of the single python unit tests
Scan for the unit tests in virtual-image suite and handle them individually
2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
6eb06697e9 tests/virtual-image: Use introspection names for errors 2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
355cae1bbd fp-device: Return error if trying to list a storage-less device
Devices with no storage don't allow listing prints, and if we try to do
that, we'd end up in trying to call a NULL function pointer, causing a crash

So always check if the device has storage before calling the list vfunc, and
if we fail, return an error.

Include an unit-test to verify this situation
2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
15a90eb451 meson: Use gnu99 as default C standard 2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
82ba69b1df meson: Depends on gusb 0.2.0, but only enable tests on 0.3.0 2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
ccd42bdece gitignore: Remove autotools ignores, add _build 2020-02-10 11:41:40 +01:00
Benjamin Berg
e19a1a6550 meson: Create include directories in build tree
Without this we get warnings like the following:

  cc1: warning: .../_build/libfprint/nbis/libfprint-include: No such file or directory [-Wmissing-include-dirs]
2020-02-10 11:41:40 +01:00
Benjamin Berg
5ac770c614 tests: Return skip error if import fails
Rather than backtracing, just print the exception and return a skip
error if the import fails.
2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
5faf8498d9 compat: Use new GDate autoptr and define if needed 2020-02-10 11:41:40 +01:00
Marco Trevisan (Treviño)
cfbd5d27b7 comapt: Add FpDeviceClass compatibility autoptr and use it 2020-02-10 11:41:37 +01:00
Benjamin Berg
169ca1ba77 compat: Add compatibility defines for older GLib
We are already using a number of defines and autoptrs from newer GLib
releases. Add the appropriate compatibility defines rather than removing
the corresponding code.

Closes: #222
2020-02-10 11:40:40 +01:00
Marco Trevisan (Treviño)
bb08d2e3c2 ci: Use extends to define extra libfprint variables
This allows to merge the values when included instead of replacing the whole
variables stanza.
2020-02-05 20:00:07 +01:00
Marco Trevisan (Treviño)
ca5143ffa5 ci: Exclude flatpak job from the schedules 2020-02-05 19:37:42 +01:00
Marco Trevisan (Treviño)
7eb10178b8 ci: Use a template to define libfprint dependencies
This allows to share the configuration with fprintd
2020-02-05 18:04:00 +01:00
Marco Trevisan (Treviño)
2c9e252ca4 meson: Use versioned name for autosuspend udev rules
Given distros may have the previous value around, let's rename this too
2020-01-23 17:25:38 +01:00
Marco Trevisan (Treviño)
23fab3a20a Change SONAME and all the library paths to libfprint-2
To avoid conflicts with previous libfprint version and make sure that the
target version is the correct one (plus to allow parallel install in some
distros), let's use a versioned naming for the library keeping the abi
version in sync.

Fixes #223
2020-01-23 17:09:58 +01:00
Marco Trevisan (Treviño)
24e9363a46 doc/meson: Use ignore_headers instead of scan_args 2020-01-23 17:00:08 +01:00
Marco Trevisan (Treviño)
a12d316aa4 meson: Use project name for log domain 2020-01-23 17:00:04 +01:00
Benjamin Berg
88461d53ec upekts: Fix use-after-free in an error condition
The callback function would continue processing even after having failed
the SSM already. This causes further invalid operations on the SSM.

This error was found using a coverity scan.
2020-01-21 14:19:33 +00:00
Marco Trevisan (Treviño)
3b47113122 synaptics: Immediately complete verification if finger removed
When quickly scanning a finger with the synaptic driver, it may wait forever
for finger removal even if this has already happened.

In fact we don't take care of the finger status when reporting the
verification.

To avoid this, add a function that delays the completion of the verification
until the finger removal if the finger is on sensor, otherwise it just
performs it.

Fixes #228
2020-01-20 18:24:16 +00:00
Marco Trevisan (Treviño)
7a7bec5a80 synaptics: Report a verify complete error on unexpected result
Also remove the unneeded verify report with match failure
2020-01-20 18:24:16 +00:00
Marco Trevisan (Treviño)
8be861b876 synaptics: Remove unneeded complete error/data parameters
Remove the never-used cmd_complete_data value and the repetition of
cmd_complete_error.

In fact now as per the fpi_device_verify_report() usage, we already pass
the match information to the device, such as the error and it will be
they will be used on completion if needed.

This allows to simplify cmd_ssm_done() as well.
2020-01-20 18:24:16 +00:00
Marco Trevisan (Treviño)
8893840ffa synaptics: Always report verify state early on non-match
In some cases we want to complete the verification after that the finger has
been removed, but we still need to promptly report the match state otherwise
fpi-device will complain about, and will eventually cause a match error
instead that reporting a non-match:

  synaptics: Finger is now on the sensor
  synaptics: Received message with 0 sequence number 0x91, ignoring!
  synaptics: interrupt transfer done
  synaptics: delaying match failure until after finger removal!
  synaptics: interrupt transfer done
  device: Driver reported successful verify complete but did not report the
          result earlier. Reporting error instead
  libfprint: Failed to verify print: An unspecified error occured!

Fixes #227
2020-01-20 18:24:16 +00:00
Marco Trevisan (Treviño)
4d6a7ec09d synaptics: Really check if a print is device database
Fix a typo causing the not-in-database print error to be fired, actually
checking the response result.
2020-01-20 18:24:16 +00:00
Benjamin Berg
b9e546f05b tests: Add missing NULL terminator to g_object_new
The g_object_new call had a NULL argument for a property. This meant
that the compiler could not warn about the lack of NULL termination for
the argument list.

Add the missing NULL termination.
2020-01-20 13:34:31 +01:00
Marco Trevisan (Treviño)
05df5e2822 test-fpi-device: Verify driver enroll errors 2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
58a9214610 test-fpi-device: Add tests for verify/identify warnings 2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
cdcc476325 examples/verify: Prompt match/no-match report in callback
Promptly show the match/no-match result in the match callback instead of
waiting the verification process to be finished.

Also exit in case of an hard error, while permit to try again in case of a
retry error.
2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
a87e9c546f test-fpi-device: Verify device action error operations 2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
ad514c3775 test-fpi-device: Fix file description 2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
3c5b7f8ea6 test-fpi-device: Add more probe tests with errors 2020-01-17 19:44:52 +01:00
Marco Trevisan (Treviño)
b09df0e40a test-fpi-device: Add tests for error message creation 2020-01-17 19:44:50 +01:00
Marco Trevisan (Treviño)
027ac8d843 fpi-device: Only mark a device as closed if the operation succeeded
We may fail during the close phase, in such case the device should not be
marked as closed.
2020-01-17 19:03:33 +01:00
Marco Trevisan (Treviño)
b3a4c2cf9a fpi-device: Improve logging and testing on report/complete 2020-01-17 19:03:33 +01:00
Marco Trevisan (Treviño)
9f3272f296 test-fpi-device: Use smart pointer to handle CB data 2020-01-17 18:43:01 +01:00
Marco Trevisan (Treviño)
456522397a verify: Add match callback report 2020-01-16 20:24:42 +01:00
Marco Trevisan (Treviño)
0889ec20a8 fp-device: Remove confusing success parameter on FpMatchCb
This was added as alias to the error check, but given we're passing to the
callback both the error and the match itself, we can just avoid adding an
extra parameter that could be confusing (as may imply that the matching
happened).

Also clarify the documentation and ensure that the match value is properly
set in tests.
2020-01-16 20:24:42 +01:00
Marco Trevisan (Treviño)
30c783cbeb examples: add FP_COMPONENT definitions 2020-01-16 14:37:07 +01:00
Marco Trevisan (Treviño)
078cea1709 verify: Add a verify_quit convenience function
It ends the loop if the device is not open, otherwise closes it and ends
the loop once done.
2020-01-16 14:36:41 +01:00
Marco Trevisan (Treviño)
bc8a5859e3 verify: Always close an open device before quitting the loop 2020-01-16 14:19:08 +01:00
Benjamin Berg
05bc2e1c80 image-device: Avoid invalid state transition on cancellation
Fixes: #226
2020-01-15 14:57:51 +01:00
Benjamin Berg
29a13a9b4a tests: Add error reporting tests based on virtual driver
We were not testing the image device error reporting functions yet
inside libfprint (fprintd already had such tests). Add tests to make
sure we catch errors earlier.
2020-01-13 17:58:41 +01:00
Benjamin Berg
54286c7603 image-device: Handle retry error propagation correctly
With the early reporting mechanism the retry error propagation needs to
be adjusted. Do the appropriate changes.
2020-01-13 17:58:41 +01:00
Benjamin Berg
db14995c31 image-device: Set cancelling when errors are reported
Allow the AWAIT_FINGER_ON to deactivation state transition after errors
are reported.
2020-01-13 17:58:41 +01:00
Benjamin Berg
7aaeec3d6a tests: Check that missing identify/verify result returns error 2020-01-13 14:37:39 +01:00
Benjamin Berg
0b8e2d6074 tests: Add tests for the verify/identify retry cases 2020-01-13 14:37:39 +01:00
Benjamin Berg
0c582230f3 tests: Add tests for the early reporting mechanism
This adds tests to check whether the verify/identify early reporting
mechanism is behaving correctly.
2020-01-13 14:37:39 +01:00
Benjamin Berg
829fb9f873 device: Add early match reporting to sync API
This makes the sync/async APIs more similar again. It also simplifies
testing as otherwise we would need the async methods for some tests.
2020-01-13 14:37:39 +01:00
Benjamin Berg
4d5c34e11a Introduce an early reporting mechanism for verify and match
It is a good idea to report match results early, to e.g. log in a user
immediately even if more device interaction is needed. Add new _full
variants for the verify/identify functions, with a corresponding
callback. Also move driver result reporting into new
fpi_device_{identify,verify}_report functions and remove the reporting
from the fpi_device_{identify,verify}_complete calls.

Basic updates to code is done in places. Only the upekts driver is
actually modified from a behaviour point of view. The image driver code
should be restructured quite a bit to split the reporting and only
report completion after device deactivation. This should simplifiy the
code quite a bit again.
2020-01-13 14:37:39 +01:00
Benjamin Berg
8292c449f7 device: Better define ownership passing for results
Some things were odd with regard to the ownership of passed objects. Try
to make things sane overall, in particular with the possible floating
FpPrint reference.
2020-01-13 13:45:05 +01:00
Benjamin Berg
3f3d4559b4 upekts: Remove unused argument from deinitsm_new 2020-01-09 10:45:54 +01:00
Benjamin Berg
fcdf1a1ff1 device: Fix potential memory leak of progress_cb user data
The progress report user data free func was not assigned and therefore
never called. Add the missing assign, potentially fixing memory leaks
(mostly relevant for bindings).
2020-01-09 10:45:54 +01:00
Benjamin Berg
ba07c74006 tests: Always add dummy skipping tests
Just hiding tests that cannot be run does not seem like the best idea.
So add dummy tests that are skipped, to denote that we could test more
than we actually do (even if it is just for drivers that are not
enabled).
2020-01-08 18:40:41 +01:00
Benjamin Berg
6716359fe8 tests: Add more notes about umockdev recording creation
umockdev recordings are usually not usable as is. Add some notes to the
README to summarise what kind of changes may be required.
2020-01-08 18:14:06 +01:00
Benjamin Berg
c27a4faeca elan: Add umockdev based test
Unfortunately, the timeout handling cannot be simulated properly. This
also adds a workaround in the driver to not consider it a protocol error
if this happens.
2020-01-08 18:14:06 +01:00
Benjamin Berg
8992e559f8 image-device: Fix enroll continuation after retry error
Continuing an enroll was broken in case of a retry error. Explicitly add
code to wait for the finger to go OFF after a retry error, and ensure
that the enroll will continue once that has happened.
2020-01-08 18:14:06 +01:00
Benjamin Berg
6c6df626c8 image-device: Fix reading default values from the class
We cannot copy information from the class in the _init routine, instead,
this needs to be done in _constructed. Move the relevant code into a new
_constructed function to fix importing the bz3_threshold override from
drivers.

Fixes: #206
2020-01-08 18:14:06 +01:00
Benjamin Berg
87dee93633 examples: Do not re-prompt the finger when repeating verification
Let's assume the user will want to re-scan the same finger rather than
being prompted again to change it.
2020-01-08 18:14:06 +01:00
Benjamin Berg
516c1593bb examples: Continue verification when return is pressed
The message says [Y/n], but will not do Y by default. Fix this.
2020-01-08 18:14:06 +01:00
Benjamin Berg
dcc7e6de90 examples: Save image even on match failure
Move the image saving out, so that it is always done when an image is
available. This allows viewing the image that corresponds to a match
failure.
2020-01-08 18:14:06 +01:00
Benjamin Berg
3c6ba0b678 storage: Do not free image data owned by FpPrint
The data returned by fp_print_get_image is owned by the FpPrint and
should not be free'ed.
2020-01-08 18:14:06 +01:00
Benjamin Berg
4db1b84c7a examples: Do not free data returned by g_variant_get_fixed_array
This data is owned by the variant, so do not free it.
2020-01-08 18:14:06 +01:00
Benjamin Berg
36108f9f82 examples: Fix possible use-after-free in storage code
The variant may need the buffer, so we should only free the buffer
together with the variant.
2020-01-08 18:14:06 +01:00
Benjamin Berg
19f239ce61 tests: Add some frame assembly unit tests 2020-01-08 18:14:06 +01:00
Benjamin Berg
f91e5310bb tests: Set MESON_SOURCE_ROOT to source root not build root 2020-01-02 13:46:46 +01:00
Benjamin Berg
0d604fa34e fpi-assembling: Fix offsets to be relative to the previous frame
The offset stored for a frame was not always relative to the previous
frame. This was the case for reverse movement, but for forwrad movement
the offset was the one to the next frame.

Make the offset handling consistent and alwasy store the offset to the
previous frame. Also update the frame assembling code to add the offset
before blitting the frame (i.e. making it relative to the previous frame
there too).

Note that fpi_assemble_lines already made the assumption that this was
the case as it forced the offset for the first frame to be zero. As
such, the code was inconsistent.

This could affect the AES drivers slightly as they use hardware reported
values which might not adhere to these assumptions.
2020-01-02 13:46:46 +01:00
Benjamin Berg
d9bcf9b9cc fpi-assembling: Accept error of zero
Rather than discarding a zero error, check that the constraints are
sane. This way a perfect match is possible.
2020-01-02 13:46:46 +01:00
Marco Trevisan (Treviño)
b8e558452a fp-print: Add FP_FINGER_IS_VALID
This is coming directly from fprintd, but being something generic is better
to have it insinde libfprint itself.
2019-12-19 14:20:00 +01:00
Marco Trevisan (Treviño)
c9e1a7f283 examples: Iterate through fingers via first/last refs 2019-12-18 12:23:14 +00:00
Marco Trevisan (Treviño)
c5aedc9970 fp-print: Add aliases for First and Last finger in our order
We might want to iterate through the supported fingers values, to do that we
were hardcoding FP_FINGER_LEFT_THUMB and FP_FINGER_RIGHT_LITTLE as first and
last fingers.

Not that we'd ever get more fingers (unless some weird radiation would do
the job), but it's logically nicer to read than random hardcoded values.
2019-12-18 12:23:14 +00:00
Benjamin Berg
5b17eda011 Prefix internal properties/signals with fpi- and annotate them
We prefixed them with fp- which is not as obvious as fpi-. Also,
explicitly mark them as private and to be skipped in the GObject
Introspection annotatinos.

Warning: FPrint: (Signal)fp-image-device-state-changed: argument object: Unresolved type: 'FpiImageDeviceState'
2019-12-18 12:25:06 +01:00
Marco Trevisan (Treviño)
022b4a75b1 meson: Bump dependency on 0.49.0
We're using some new features, and we may use more in future so better to
bump the version to the minimum required than look back given we're still
unstable.

Fixes #204
2019-12-17 20:44:37 +01:00
Marco Trevisan (Treviño)
bfc75de778 libfprint: Make sure we install fp-enums.h in the right folder
Since we were not explictly setting the install_dir, it was endind up in
$PREFIX/include by default, while we use our project name as subfolder.
2019-12-17 15:42:56 +01:00
Marco Trevisan (Treviño)
f3f768e738 meson: Fix syntax for fpi_enums generation call 2019-12-17 15:42:32 +01:00
Marco Trevisan (Treviño)
dbb26c5ade meson: Define enum dependency and ensure we generate them before using
Avoid setting the headers as sources everywhere, but instead use a dependency
to manage the headers creation in time
2019-12-17 14:38:20 +01:00
Marco Trevisan (Treviño)
0566f82219 tests: Add a reference to the enrolled print before returning it 2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
c8e1269f61 cleanup: Use FPI prefix for all the internal enum types 2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
2158c5e2d1 cleanup: Use #pragma once everywhere
Remove legacy header guards, and use compiler newer features.
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
10945f8546 cleanup: Remove fp_internal.h and update drivers_api.h
Remove the uneeded internal API, as we can now include each header directly
if needed, while move the assembling stuff to the drivers API.
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
806ad10673 meson: Add fp-image-device to public headers 2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
4562f9dae3 meson: Use soversion everywhere
Don't repeat the 2 version number hard-coding it, so we can easily track
updates
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
c57defda92 meson: Use more meson's project_name()
Not that libfprint is long to write, but in case we'll ever change the
basename, we do it once.
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
c806993cb9 meson: Don't install fpi-enums 2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
95cb62fd3b meson: No need to redefine default pkgconfig install dir
This value would be the default anyways
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
d255a91e97 meson: List deps in multiple lines, to have better diffs on changes 2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
9ebb3fd231 meson: Parse all private headers
So we don't have to list each one in case we add new enums.
Also, as per previous commit we can reorder them alphabetically.
2019-12-17 14:38:19 +01:00
Marco Trevisan (Treviño)
68b5c5d98f fpi-ssm, fpi-usb-transfer: Use fwd-declarations to avoid headers dependencies
Don't make headers inclusions dependent on each others, given that FpiSsm
depends on FpiUsbTransfer and vice-versa, so fix the dependency cycle by
using forwarded declarations.
2019-12-17 14:38:19 +01:00
Benjamin Berg
2af0531994 tests: Fix stack corruption in FpiSsm test
Using a function with a void return value for a g_timeout_add is not a
good idea after all.
2019-12-17 14:32:59 +01:00
Benjamin Berg
bfd68bbc01 meson: Add missing dependency on fp-enum.h for private library
The private library needs to indirectly include fp-enum.h. This
dependency was not listed anyway, resulting in a race condition during
the build process.
2019-12-16 11:42:51 +01:00
Benjamin Berg
9c806e60f4 elan: Do not leak converted frames
The elan driver converts frames into a different format. These frames
are only needed to assemable the image and should be free'ed afterwards.

Fixes: #213
2019-12-16 10:20:49 +00:00
Benjamin Berg
113bef8f3f examples: Fix double device closing in manage-prints
The manage-prints command would close the device twice when the user
hits an invalid number or 'n' and no prints need to be deleted.

Simply remove the erroneous call to fix the issue.
2019-12-16 10:20:49 +00:00
Benjamin Berg
1d1c39c234 tests: Ensure objects are free'ed at the end of tests
The objects may not be garbage collected otherwise.
2019-12-16 10:20:49 +00:00
Benjamin Berg
4948a85e97 synaptics: Use local variable rather than re-fetching usb device 2019-12-16 10:20:49 +00:00
Marco Trevisan (Treviño)
7e2db8e988 driver_ids.h: Remove the legacy ID file
This is not used anymore by drivers as they all use GType's, so remove it
and any (dead) reference to it.
2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
24d388f923 meson: Split single-line dependencies to reduce the diff on changes
Make it more readable and in case we add something else, it's easier to track
2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
af42b3e468 ci: Increase the timeout multiplier for tests
Change the FEDORA_TAG to the current date in order to rebuild the image
2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
edb09463f4 ci: Save coverage reports when running tests 2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
42b1deaeea tests: Add unit tests for fpi-ssm
Verify that the state machine actions are done as we expected, being the
main tool for drivers, better to check that is done as we expect.
2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
fe828d0bb2 fpi-ssm: Clear delayed actions for parent and child on subssm start
While timeout was already cleared for parent, we didn't properly delete the
cancellable.

Although we'd warn anyways when starting the SSM, is still better to clear
any delayed action also for the sub-SSM
2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
cf5473a55c fpi-ssm: Make clear that the completed callback owns the error 2019-12-14 17:20:47 +01:00
Marco Trevisan (Treviño)
0471edbf10 fpi-ssm: Add debug message when a delayed state change is cancelled 2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
299a797423 fpi-ssm: Bug on wrong state passed to jump_to_state_delayed
While remove the checks that are already part of the common function
fpi_ssm_set_delayed_action_timeout().
2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
c594863639 fpi-ssm: Define autoptr cleanup function 2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
3bb1840750 fpi-ssm: Use same argument names of header file
So we can mute a Gtk-doc parser warning
2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
f31b8483d4 tests: Add fpi device tests
Verify drivers operations simulating a fake driver to check that the lib
interaction is correct.
2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
324258bc8c tests/meson: Support unit-tests non depending on virtual driver
Since tests depending on the fake device don't depend on virtual-image
driver anymore, let's change the way we organize the things, by putting
everything in the test lib, but enabling unit-tests depending on what they
depend on.
2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
f578ebe82d test-device-fake: Add fake test driver to verify fpi functions 2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
98fa6efce3 fpi-device: Clarify ownership of parameters for progress call 2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
c7b7f78273 fp-device: Call identify device class method on identification
Identify on device was broken because we were calling verify device method
on devices instead of the right one.

Thank you unit tests! :)
2019-12-14 17:20:46 +01:00
Marco Trevisan (Treviño)
b4c3756ab0 tests: Add fp-device basic unit tests
Use the virtual image device as base for now, while the new setup allows
to create easily fake device drivers without including the driver in
libfprint itself and test all the fpi_device functionalities.
2019-12-14 17:20:45 +01:00
Marco Trevisan (Treviño)
da46f53e82 tests: Add basic unit tests for fp-context
Link the tests with the private library using an utils library that will
be useful to share other tests functions
2019-12-14 17:20:45 +01:00
Marco Trevisan (Treviño)
eeddd8c7bc fp-context, tools: Use auto-ptr to handle GTypeClass ownership
This also fixes a small leak we might have if reffing a type that was not a
virtual one.
2019-12-14 17:20:45 +01:00
Marco Trevisan (Treviño)
43a8c909bf fp-context: Use an env to define a whitelist of drivers to enable
This avoids that we pick unwanted drivers when running the tests in a
machine that has some supported device attached.
2019-12-14 17:20:45 +01:00
Marco Trevisan (Treviño)
09576e5209 fpi-context: Make fpi_get_driver_types to return an array
No need to create one all the times and the fill it with what we need.
2019-12-14 16:57:11 +01:00
Marco Trevisan (Treviño)
8184e33dd6 meson: Fix syntax in the auto-generated fpi-drivers file
Better to be nice everywhere :)
2019-12-14 16:56:56 +01:00
Marco Trevisan (Treviño)
6f2b1f97da fprint: Move drivers to private internal library
This allows us to finally remove fpi_get_driver_types from the exported list
of symbols.
2019-12-12 19:03:57 +01:00
Marco Trevisan (Treviño)
c3bf6fe863 meson: Rely on libfprint dependency to get root_include
No need to redefine it in all our tools
2019-12-12 18:55:08 +01:00
Marco Trevisan (Treviño)
5bed81025e meson: Use files to track the map file presence 2019-12-11 20:07:13 +01:00
Marco Trevisan (Treviño)
d7100e41df fp-image, fp-print: Move private methods to own code units 2019-12-11 20:07:13 +01:00
Marco Trevisan (Treviño)
ae7021e529 fp-image-device: Move fpi code into its own unit that can be compiled a part
In order to be able to test the private device code (used by drivers) we
need to have that split a part in a different .c file so that we can compile
it alone and link with it both the shared library and the test executables.

Redefine fp_image_device_get_instance_private for private usage, not to move
the private struct as part of FpDevice.
2019-12-11 20:07:12 +01:00
Marco Trevisan (Treviño)
d9de941a47 fp-device: Move fpi code into its own unit that can be compiled a part
In order to be able to test the private device code (used by drivers) we
need to have that split a part in a different .c file so that we can compile
it alone and link with it both the shared library and the test executables.

Redefine fp_device_get_instance_private for private usage, not to move
the private struct as part of FpDevice.
2019-12-11 20:07:12 +01:00
Marco Trevisan (Treviño)
7114d97f25 libfprint: Introduce libfprint_private static library
Split the library into a private part with all the symbols that we can use
for unit-test all the fpi functions.
2019-12-10 20:19:55 +01:00
Marco Trevisan (Treviño)
92a5278a74 fp-device: Add a "open" property and method to check its state 2019-12-10 20:19:55 +01:00
Marco Trevisan (Treviño)
d01bb41b7c tests/meson: Set the typelib env var only if we have introspection 2019-12-10 19:20:21 +01:00
Marco Trevisan (Treviño)
ad88a5a78f docs: Don't ignore the deprecated API_EXPORTED definition 2019-12-10 19:20:21 +01:00
Marco Trevisan (Treviño)
ff0107fc0a fp-device: Use different pointers for device handlers
A Fp-device use an union to track the handle to the lower-level device, and
the value depends on the object type.

So in case of using a virtual device, the priv->usb_device location matches
the priv->virtual_env string location, and thus we'd end up unreffing a
string location as it was a GObject, while we'd leak the string.

To avoid such errors, instead of just checking the device type when we
finalize the device, let's just use different pointers to avoid other
possible clashes.
2019-12-10 19:20:21 +01:00
Vincent Huang
107fdfde32 synaptics: Fix problem after match is failed
This fixes the the problem that the sensor becomes unresponsive after
pressing the wrong fingerprint. We fix the problem by making sure that
the non-match report is delayed until the finger is removed. With this
we cannot run into the situation that the next match request fails
immediately as the finger is still present.

Fixes: #208
2019-12-10 09:38:54 +01:00
Marco Trevisan (Treviño)
bb0ef04b85 ci: Partially hardcode the fedora image path 2019-12-05 17:31:46 +01:00
Benjamin Berg
0a475196e0 ci: Use CI generated build image 2019-12-05 14:38:46 +01:00
Benjamin Berg
1dee7985b9 ci: Remove Dockerfile as it is replaced by new logic 2019-12-05 14:38:46 +01:00
Benjamin Berg
a1a3933191 ci: Add fedora image builder target for schedule 2019-12-05 14:38:46 +01:00
Benjamin Berg
9c8360ad67 ci: Do not run usual targets from a scheduled job
This is in preparation to building docker images automatically.
2019-12-05 14:14:13 +01:00
Benjamin Berg
0c7d2d8ecd ci: Define a variable for the fedora docker image 2019-12-05 13:56:12 +01:00
Benjamin Berg
6209b22e3b print: Fix match error propagation
The FPI_MATCH_ERROR constant was set to 0, however it is propagated to
the task completion using g_task_propagate_int. As g_task_propagate_int
will always return -1 on error, we either need to add an explicit -1
check or we just need to match the semantics.

Change the constant to -1, also rearange FP_MATCH_SUCCESS so that it
does not end up being 0.
2019-12-05 11:46:11 +00:00
Benjamin Berg
f404a69b73 tests: Test finger removal after minutiae scan completion 2019-12-04 19:49:07 +00:00
Benjamin Berg
50a837573d tests: Update helper functions for new virtual-image features
This also changes the code to keep the connection open and adds
automatic mainloop iteration to ensure the driver processes the request.
This is important so we will not deadlock when we send multiple
requests.
2019-12-04 19:49:07 +00:00
Benjamin Berg
3e958ab7b4 virtual-image: Allow fine control over the finger state
Add commands to disable automatic finger reporting for images and to
send a specific finger report. This is useful to test more code paths
inside the image-device code.
2019-12-04 19:49:07 +00:00
Benjamin Berg
a8a2a757ed virtual-image: Only print warnings for actual errors
No need to warn for lost connections (if we don't expect more data) or
cancellations.
2019-12-04 19:49:07 +00:00
Benjamin Berg
702255b182 image-device: Print warning for incorrect deactivation
Drivers may not handle deactivation properly when they are awaiting a
finger. This should be prevented by the internal FpImageDevice state
machine.
2019-12-04 19:49:07 +00:00
Marco Trevisan (Treviño)
a64ac2296b vfs0051: Use named SSMs for usb async exchanges 2019-12-04 20:43:53 +01:00
Marco Trevisan (Treviño)
a522e3fd6f fpi-ssm: Improve debugging of SSM using driver infos
Always mention the driver that is triggering it
2019-12-04 20:43:53 +01:00
Marco Trevisan (Treviño)
65828e0e56 fpi-ssm: Support named SSMs and use a fallback macro
Add fpi_ssm_new_full() that allows to pass a name to the state-machine
constructor, not to change all the drivers, provide a fpi_ssm_new() macro
that stringifies the nr_parameters value (usually an enum value) as the name
so that we can use it for better debugging.
2019-12-04 20:43:53 +01:00
Marco Trevisan (Treviño)
fe967d0ac2 ci: Build flatpak automatically only on master and tagso
While allowing to build it manually in other cases
2019-12-04 19:49:40 +01:00
Benjamin Berg
10c5bdade7 uru4000: Fix control transfer request type
During porting the request type was accidentally changed from VENDOR to
DEVICE. Change the type back to VENDOR.

See: #205
2019-12-04 18:00:02 +00:00
Benjamin Berg
8f21aa1b26 uru4000: Fix state change from IRQ handler
The IRQ handler will re-register itself automatically. However, if this
happens after the callback is called, then the check whether the IRQ
handler is running fails.

Re-start the IRQ handler before calling the callback. This way the state
changes happening from the callback will see the correct IRQ handler
registration state.

See: #205
2019-12-04 18:00:02 +00:00
Benjamin Berg
7b68344394 image-device: Prevent deactivation when waiting for finger
At the end of enroll, the image device would put the driver into the
AWAIT_FINGER_ON state and then deactivate the device afterwards. Doing
this adds additional complexity to drivers which would need to handle
both cancellation and normal deactivation from that state.

Only put the device into the AWAIT_FINGER_ON state when we know that
another enroll stage is needed. This avoids the critical state
transition simplifying the driver state machine.

Fixes: #203
Fixes: 689aff0232
2019-12-04 18:00:02 +00:00
Benjamin Berg
dccb5b3ab2 elan: Fix internal state machine to ensure correct deactivation
During calibration, the internal state was stored as INACTIVE. This is
not true though, the device is actively running state machines.

Move the state update to the start of the operation, therefore ensuring
we don't deactivate without completing the SSM.

Note that this will prevent a crash, but the driver still does not
behave quite correctly when such a state change does happen. However,
this is just a safety measure as the state change should not happen in
the first place.

See: #203
2019-12-04 18:00:02 +00:00
Marco Trevisan (Treviño)
2fcc2deb43 ci: Use --werror by default in meson at build time 2019-12-04 18:52:20 +01:00
Marco Trevisan (Treviño)
c678b9021c meson: Use stricter C arguments to compile libfprint
These are based on what mutter does, being a quite strict project on c code
quality.
2019-12-04 18:52:20 +01:00
Marco Trevisan (Treviño)
b2e55308d6 meson: Move generated source to fpi- prefix and use more readable code
Instead of concatenating strings, use an array of strings and finally join
them using newline.
2019-12-04 18:52:20 +01:00
Marco Trevisan (Treviño)
a176fa1d34 meson: Include fpi-context.h in generated fp-drivers.c 2019-12-04 18:52:19 +01:00
Marco Trevisan (Treviño)
cacce50ef9 vfs0050: Use proper casting summing pointers first
Cast the pointers as what fpi usb transfer expects.
2019-12-04 18:52:19 +01:00
Marco Trevisan (Treviño)
5ab4d6c454 vfs5011: Cast gpointer data values to proper type to do math operations 2019-12-04 18:52:19 +01:00
Marco Trevisan (Treviño)
0c655be159 gtk-demo: Use G_DECLARE to avoid missing declarations 2019-12-04 18:52:19 +01:00
Marco Trevisan (Treviño)
2b8c524928 cleanup: Use static functions for non-declared methods 2019-12-04 18:52:19 +01:00
Marco Trevisan (Treviño)
2f2ea65d32 fp-device: Remove unused timeout function and source data
These were probably added in previous iterations, but they are not uneeded
anymore as the GSource embeds already a callback function.

So make just this clearer in the dispatch function.
2019-12-04 18:52:18 +01:00
Marco Trevisan (Treviño)
1d48b70f38 storage: Include storage header so that we have declarations 2019-12-04 18:52:18 +01:00
Marco Trevisan (Treviño)
35e9f19c0c nbis: Make the extern global bozworth 'y' variable as bz_y
Othewise this could create issues with other 'y' variable definitions
shadowing it.

Add a cocci file that performs the change automatically
2019-12-04 18:52:18 +01:00
Marco Trevisan (Treviño)
70a0d6f0fe nbis/log: Don't use old-style function declarations 2019-12-04 18:52:18 +01:00
Marco Trevisan (Treviño)
7ed9b0c2f9 cleanup: Don't make nbis depend on libfprint built-sources
Now that nbis is a static library it should be possible to compile it
without any fprint-built dependency, although since it included fp_internal
there was a compile-time dependency on the fp-enums that can be generated at
later times.

So:
 - Move nbis-helpers to nbis includes (and remove inclusion in fp_internal)
 - Move the Minutiae definitions inside a standalone fpi-minutiae header
 - Include fpi-minutiae.h in fp_internal.h
 - Include nbis-hepers.h and fpi-minutiae.h in nbis' lfs.h
 - Adapt missing definitions in libfprint
2019-12-04 18:50:46 +01:00
Marco Trevisan (Treviño)
6a090656b6 nbis: Add a global include file with all the definitions ignoring erros
The nbis headers are full of redundant declarations, we can't fix them all
now, so in the mean time let's use an header using pragma to ignore such
errors.

Add the error to nbis private include folder that should be used only by
headers of libfprint-nbis.
2019-12-04 18:44:39 +01:00
Marco Trevisan (Treviño)
e1d181887f meson: Add the include directories to deps
So we don't have to repeat them everywhere.
2019-12-04 16:57:39 +01:00
Benjamin Berg
e143f12e57 meson: Build nbis separately to allow changing flags
As nbis is an external source bundle, it does not necessarily make sense
to enable/fix all warnings to the extend we do for our own library code.

As such, separate the build process into multiple stages.
2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
e64c18f8de cpp-test: Fix indentation 2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
7e70344b4a meson: Use add_project_arguments for common cflags
We were passing around the common cflags and setting them for each library
or executable, but this is just a repetition given we can just use
add_project_arguments for this.
2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
44af2173a8 fp-print: Clear the data not the description when setting the property 2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
e7c7f368c9 drivers, examples: Don't use -Wno-pointer-sign and fix relative errors 2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
a29586f398 fpi-usb: Use unsigned length for USB async transfers
Properly follow function signature using a temporary gsize variable address
to make the function use the same pointer type and avoid troubles at
deferencing it, while use automatic-casting to switch to signed one if
transfer succeeded.
2019-12-04 16:06:24 +01:00
Marco Trevisan (Treviño)
98cd1c2680 ci: Use a docker image for builds and tests
Avoid repeating the machine updates and deps installation at every stage,
just reuse the docker image

Registered images are at:
  https://gitlab.freedesktop.org/libfprint/libfprint/container_registry
2019-12-04 14:59:03 +00:00
Benjamin Berg
ae285e790d tests: Fix image writing on big endian
The code tried to only write the RGB bytes of FORMAT_RGB24, however, the
in-memory layout is different on big-endian which would result in the
wrong bytes being written.

Fix this by simply also writing the byte we do not care about.
2019-12-04 13:23:08 +01:00
Marco Trevisan (Treviño)
1e2f19ea3d fpi-ssm: Mark a fpi-ssm completed on delay 2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
b0effae990 fpi-ssm: Bug on handler set to a NULL function
We would crash otherwise, while this is quite obvious there was no code
enforcing this.
2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
ff67bf5a16 fpi-ssm: Make delayed actions cancellable
Add a GCancellable parameter to fpi_ssm_nex_state_delayed and
fpi_ssm_jump_to_state_delayed() so that it's possible to cancel an action
from the caller and in case the driver wants to cancel a delayed operation
when a device action has been cancelled.
2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
bac6382f67 drivers: Use SSM delayed actions when possible 2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
e12978f402 fpi-ssm: Clarify the ownership of error in fpi_ssm_mark_failed 2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
1ba95db379 drivers: Use fpi_ssm_next_state_delayed instead of custom callbacks
As per this fpi_ssm_next_state_timeout_cb can be removed
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
7ec2df2405 fpi-ssm: Add possibility to jump to a state (or next one) with delay
This allows to have an automatic cleanup of the timeout source when the
the callback is reached and to avoid to do further state changes in the
middle.
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
3ed73aa17c fpi-device: Make possible to set a DestroyNotify for timeout data
Since GSource data can be automatically cleaned up on source destruction, we
can mimic this for the devices timeout easily as well.

Add an extra parameter, and let's use this cocci file to adapt all the
drivers like magic:

	@@
	expression e1, e2, e3, e4;
	@@
	fpi_device_add_timeout (e1, e2, e3, e4
	+  , NULL
  	)
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
0241617713 fpi-ssm: Also bug-on negative state value
Being an integer, anything could happen.
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
20a52593eb vfs301: Use a transfer autopointer to cleanup it on sync submission
Partially revert commit a855c0cc7, since the driver uses a sync transfer
and in such case the caller still keeps the ownership.
2019-12-03 13:58:42 +00:00
Marco Trevisan (Treviño)
42db16364d synaptics: Close the usb device if reset failed
If reseting the device failed, we still need to close the usb device before
returning.
2019-12-03 13:58:42 +00:00
Marco Trevisan (Treviño)
ee606ae49e synaptics: Use an autoptr to handle the FpiUsbTransfer sync transfers
When using fpi_usb_transfer_submit_sync we still need to unref the transfer
once done with it, so let's use an auto pointer so we free it also on
errors and early returns without having to handle this manually.
2019-12-03 13:58:42 +00:00
Benjamin Berg
f9b2c7f9c3 virtual-image: Fix driver reading insufficient data
In rare occasions it could happen that the driver was reading
insufficient data. Fix this by using g_input_stream_read_all_async
which will ensure that incomplete data will not be misinterpreted.

This fixes rare test failures seen in fprintd.
2019-12-02 17:04:05 +01:00
Benjamin Berg
4115ae7ced Fix indentation issues using newer uncrustify
Seems like the older uncrustify versions did not find these indentation
issues. Fix them.

Old versions of uncrustify will leave things as is, so this is not a
problem if developers are using an old version of uncrustify.
2019-12-02 17:04:05 +01:00
Benjamin Berg
8cc0fd321f assembling: Use fixed point for image assembly
Using floating point causes architecture dependent results due to
accuracy/rounding differences. It is not hard to switch to fixed point,
and while this does cause quite different rounding errors, the
difference is small.

Fixes: #200
2019-11-28 20:41:45 +00:00
Benjamin Berg
a7541b1f76 tests: Fix endianness issue in test suite
The test suite needs to compare greyscale images and was picking an
undefined byte in the pixel data on big-endian. Select a byte that works
on any endian instead.

See: #200
2019-11-28 20:41:45 +00:00
Marco Trevisan (Treviño)
b9ff75c4e9 fp-print: Set the aligned_data as the data used by the cleanup function
g_variant_new_from_data() allows to destroy some other user_data passed as
parameter that might be different from the aligned_data itself.

But since in this case they match, pass it to be set as g_free parameter
or it won't be free'd.
2019-11-28 21:30:17 +01:00
Marco Trevisan (Treviño)
4447a0d183 ci: Add a test case where we run tests with valgrind 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
545af23536 tests: Use a loop for generating drivers tests and use suites
So we can just run drivers tests with --suite=drivers
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
db905a2048 fp-device: Use g_clear_error instead of check + free 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
712853d1e3 fp-device: Mark user data in FpEnrollProgress as transfer none
The data has its own DestroyNotify set, so while no generic DestroyNotify
exists for generic data, let's make it clear.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
c6298ede72 fp-device: Unref the print once we've notified the progress
When we notify the enroll progress with a print, this needs to be unreffed
once we're done, but this only was happening in case of error.

Since it's not up to the callback function to free it, let's do it at the
end of the function.

As per this, clarify the docs for FpEnrollProgress marking it as transfer
none.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
b1d99e7608 fp-device: Use an autopointer and steal the print when passed
Make it clearer that we're stealing the print when passing it away, instead
of just doing this silently.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
5927a205e3 virtual-image: Also unref the object when closing a the stream
While a stream is closed when completely unreffed, the other way around
isn't true, so always unref the object.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
8c05f3b78c fp-print: Unref print data and get static strings when deserializing 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
92db82e3d4 fp-print: Assert the prints aren't set when initialized 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
f6f689f9cd fp-print: Unref the prints on finalize 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
5dc3edf07c fp-context: Run dispose on the usb context to deal with circular refs
Ensure that we dispose the USB context before unreffing it, so that it will
release any reference it has and destroy the internal libusb context.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
71625ec1cf fp-device: Unref the usb device on finalize
Each device adds a ref to the underlying usb device, but it doesn't remove
the reference on finalization.

So clear the object to fix the leak
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
c9216cf96c tests: Add setup mode to run tests using valgrind
In such case we need to ignore the python errors, so including a suppression
file when using --setup=valgrind.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
53713c0098 tests: Add 'gdb' setup to run tests using gdb
When using --setup=gdb the tests will be running using gdb, however this
as per meson limitation allows only running a test when using verbose mode.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
222c33ec32 virtual-image: Re-run the test using the defined wrapper if any
In case a LIBFPRINT_TEST_WRAPPER is defined, execute again the script using
the same python processor but using the passed wrapper command.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
19a50cfdc3 umockdev-test: Make possible to use a wrapper to run tests
Support LIBFPRINT_TEST_WRAPPER env variable to run tests with a wrapper.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
9892eb1c03 fpi-ssm: Make clearer that data is unused in fpi_ssm_usb_transfer_cb 2019-11-27 21:02:20 +01:00
Marco Trevisan (Treviño)
587131a6bd drivers: Use more fpi_ssm_usb_transfer_cb when possible
Replace all the transfer callbacks where we just switch to the next state or
fail with fpi_ssm_usb_transfer_cb.
2019-11-27 21:02:20 +01:00
Marco Trevisan (Treviño)
65d0d5e3e0 fpi-ssm: Add a usb transfer callback with data as weak pointer
Allow to pass a double-pointer to be nullified as the transfer data in order
to mark it as NULL when the transfer is done.

This is useful if we're keeping the transfer around in order to check that
no one is currently running.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
2642fc6560 fpi-usb-transfer: Take ownership of the transfer when submitting it
When a transfer is completed, we automatically unref it since we can't
consider it valid anymore since this point.

Update the drivers not to free the transfer after submitting anymore.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
a855c0cc79 fpi-ssm: Take ownership of the SSM when completing it
When a machine is completed, we automatically free it since we can't
consider it valid anymore since this point.

Update the drivers not to free the SSM on completion callback anymore.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
876924df6a examples: Handle the cases where the print date is not set 2019-11-27 19:14:35 +01:00
Marco Trevisan (Treviño)
519b5acc91 synaptics: Initialize user_id autoptr to NULL 2019-11-27 18:54:21 +01:00
Marco Trevisan (Treviño)
e812653acd synaptics: Use GDate getters to retrieve the DMY values
As per commit 201b5a961 we use g_date_copy() to copy the date, however the
GLib implementation is done assuming that the GDate getters are always used
as the copy function doesn't preserve the original format of the date
(whether is using julian days or dmy), and the synaptics driver access to
the dmy values directly, without using the getter that would recompute the
proper values.
Causing a read error of unset values.

So, to avoid this, just use the g_date_get_* getters to retrieve the day
month and year for for defining the print enroll id.
2019-11-27 18:54:21 +01:00
Marco Trevisan (Treviño)
1b23f0efe1 drivers: Use clearer messages using parameters 2019-11-26 12:18:57 +00:00
Marco Trevisan (Treviño)
f6559ba8b1 fp-device: Support variadic arguments to error functions
Make possible to generate a formatted message when creating an error from
a device, without having save it first.
2019-11-26 12:18:57 +00:00
Marco Trevisan (Treviño)
3b72b925b0 gitlab-ci: Check indentation in an initial check-source stage 2019-11-25 19:08:31 +01:00
Marco Trevisan (Treviño)
15d218a112 fpi-log: Set fp_error as equal to g_critical 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
0a08a24896 fpi-ssm: Remove any reference to fpi_timeout_add()
This doesn't exist anymore, while fpi_device_add_timeout does exists.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
cca6d3b04b fp-image-device: Use a GObject signal to notify image state changed
This is more GObject-friendly and we have the automatic call of the vfunc if
one is set.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
be367988ae fp-image-device: Add private "fp-image-device-state" property
In this way drivers may get this without having to keep a copy of it
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
ea4da08af0 fp-image-device: Reactivate in idle on deactivation completed
This is the same logic we apply to fp-device by default: any completed
action should trigger the subsequent one when it is finished.
So in case we want reactivate after a deactivation, let's do it in an idle,
after removing the current pending timeout.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
60ad1ab9e3 fp-image-device: Clear the pending activation timeout on finalize 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
201b5a9614 fp-print: Use g_date_copy
As per previous commit we depend on glib 2.56, we can use this utility
function as well.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
8b270141f3 image-device: Use g_clear_handle_id for timeouts
As per this depend on glib 2.56: it has been released almost 2 years ago,
I suppose we're fine with that.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
ceb62d7617 meson: Avoid repeating the needed glib version multiple times
Just define once and modify its syntax when needed.
Use a more verbose definition for the min/max version (instead of just
join the split version) so that in case we may depend on a specifc glib
micro release during development.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
099fa9f005 meson: Use preferred syntax everywhere
Meson files are normally using 4-spaces to indent and functions use first
parameter on the same line while others at next indentation level, not
following the parenthesis indentation.

So adapt libfprint to follow the meson standard.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
dd7d1baece meson: Use multiline-array for default dirvers listing
It will make reviews and diffs nicer to handle when adding new drivers.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
d8efa336e5 fpi-ssm, fp-device: Add missing copyright 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
76dd4066f3 verify: Ensure we set set the autoptr value to NULL at definition 2019-11-25 18:59:46 +01:00
Benjamin Berg
9b48864c5b print: Ensure xyt struct is not leaked during deserialization
In the unlikely event of an error, the variable may have been leaked.
Fix this by using g_autoptr combined with a g_steal_pointer.
2019-11-25 18:46:14 +01:00
Benjamin Berg
14a41bdd48 print: Free temporary col variable
The variable was leaked during serialization. Free it.
2019-11-25 18:46:14 +01:00
Benjamin Berg
25bc89a4f5 image-device: Remove unused fpi_device_get_current_action call
There is a later call in the function which is sufficient. Simply remove
the first call.
2019-11-25 18:46:14 +01:00
Benjamin Berg
2f0824ab88 upeksonly: Add default clauses to switch statements
This effectively only annotates the code to make it clear that variables
set in the switch are always initialized.
2019-11-25 18:46:14 +01:00
Benjamin Berg
8ba6f4dad2 synaptics: Add an explicit assert on the response
The response must be non-NULL in the function. Add an explicit assert to
appease to static code analysis tools.
2019-11-25 18:46:14 +01:00
Benjamin Berg
ada5d488fa synaptics: Correctly unref pointer array
The pointer arrays were unref'ed using g_ptr_array_free rather than
g_ptr_array_unref from g_clear_pointer. Switch to the correct function.
2019-11-25 18:46:14 +01:00
Benjamin Berg
b16245ad58 elan: Fix switch in change_state
The switch in change_state had a useless break and a useless if clause.
Remove both.
2019-11-25 18:46:14 +01:00
Benjamin Berg
8b28133bee elan: Fix potential leak of dark frame
Dark frames would be leaked, add an explicit free to avoid this.
2019-11-25 18:46:14 +01:00
Benjamin Berg
7a4dd96406 udev-rules: Remove debug spew from udev rules
Some debug output was ending up inside the udev rules. Remove it again.
2019-11-22 17:07:56 +01:00
Benjamin Berg
81a446db82 Update NEWS for 1.90.0 release 2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
7bc62821ee ssm: Make possible to set data via function
Use the same approach of GTask, making possible to set the data from a
function. Givent the fact that a SSM has now a device parameter, it's
generally not needed to pass an extra data value.

In such case make it possible to set it and to define a destroy-notify
function to handle its destruction when freeing the SSM.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
1319daba54 examples: allow to select multiple devices
Since there might be external USB readers and embedded ones, better to allow
easily to select them all in examples.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
39e3e2b794 examples: Move discover_device function to utilities
While there are various functions which similar usage in all the examples,
I'd prefer to keep each example to be self-containing most of the things.
However some clearly repeated action can be moved to a single codebase.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
ab804f7f49 examples: Make possible to select the finger to enroll/verify
Move some common functions to an utilities file.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
f2b932960e lib: Use g_new0 rather than g_malloc0
Port some of the g_malloc0 users to g_new0.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
d1fb1e26f3 Uncrustify everything except for nbis 2019-11-20 20:38:06 +01:00
Benjamin Berg
fd5f511b33 nbis: Add patch to fix unused variable warning
With the spatch to use GLib memory functions a lot of error paths were
removed. This causes an unused variable warning, so drop in a further
patch to remove the unused variable.
2019-11-20 20:38:06 +01:00
Benjamin Berg
cddd0f4653 examples: Remove old verify_live example
The example has not been ported and it is not very useful as verify
already shows how everything works.
2019-11-20 20:38:06 +01:00
Benjamin Berg
256c7cea07 examples: Remove x11 based examples
These examples have not been ported. In addition, they are also not very
useful these days, as the demo application offers a much nicer view to
view images from a sensor.
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
d91ec2d044 examples: Add manage-prints test to list and delete prints
Simple example program to list prints in a device with own storage and that
allow to delete them (by manual selection or full deletion).
2019-11-20 20:38:06 +01:00
Marco Trevisan (Treviño)
ad920f9597 device: Complete driver operations in idle
When drivers signal that an action is completed, they might be still in the
middle of a SSM and so its callback might not be called properly as part of
the completion.

This could make impossible to chain operations like open->enroll/list with
some drivers (hey, synaptics, I'm looking at you!) when the next operation
is called from the GAsyncReadyCallback of the previous call.

To avoid this to happen, ensure that when a driver completes an operation,
we handle the notification to the caller in a next idle iteration, not to
end up in a possible broken state.

Abstract this by using a function that handles the task return for each
used task type to avoid duplicating similar functions doing all the same
thing
2019-11-20 20:38:06 +01:00
Benjamin Berg
728335581f ci: Run uncrustify in test mode
Add a simple check that no one introduced whitespace errors.
2019-11-20 13:53:45 +01:00
Benjamin Berg
9b37256175 tests: Only run tests when introspection bindings are build
The tests cannot work without the introspection bindings. So put them
into a corresponding if branch and also add the correct dependency on
libfprint_typelib for them to be run.
2019-11-20 13:53:45 +01:00
Benjamin Berg
951d482bc6 tests: Skip umockdev based test for missing dependencies
Also print a warning if umockdev-run is too old. Note that we still try
to run the unreliable tests as they are still useful for development.
2019-11-20 13:53:45 +01:00
Marco Trevisan (Treviño)
33530d62c7 device: Only connect to cancellable if device supports cancellation
We are actually using the cancel idle source in case the device supports
cancellation, so only connect to the cancellable in such case, and use an
utility function to do it and disconnect and reset the state everywhere.
2019-11-20 13:53:45 +01:00
Benjamin Berg
65e602d8c7 log: Re-indent fpi-log using uncrustify 2019-11-20 13:53:45 +01:00
Vincent Huang
6a1e7103f6 synaptics: Put sensor into lower power mode after closing 2019-11-20 13:53:45 +01:00
Bastien Nocera
f25d0a0dc9 lib: Remove num_stripes from fpi_assemble_frames() 2019-11-20 13:53:45 +01:00
Bastien Nocera
3b480caab1 lib: Remove num_stripes from fpi_do_movement_estimation() 2019-11-20 13:53:45 +01:00
Bastien Nocera
dcc04089d1 lib: Remove num_stripes from movement_estimation()
fpi_do_movement_estimation is always called with num_stripes set to the
length of the list. Rather than using the passed value, assume we should
consume all stripes from the list.

Closes: #132
2019-11-20 13:53:45 +01:00
Benjamin Berg
0b87b21d52 cocci: Remove spatch/cocci files again
They were just committed for archival purposes.
2019-11-20 13:53:45 +01:00
Benjamin Berg
b92e6d6acd tests: Add testing to the synaptics driver
As the driver is not a normal image device, we need to add a custom
script to test it. Note that the ioctl dump must also be manually
modified unfortunately as the state is tracked incorrectly for the
device by umockdev-record.
2019-11-20 13:53:45 +01:00
Benjamin Berg
538038867b tests: Add umockdev based testing
Initially only the vfs5011 driver is tested. Please note that these
tests will be unreliable before umockdev 0.13.2.

See also https://github.com/martinpitt/umockdev/pull/92
2019-11-20 13:53:45 +01:00
Benjamin Berg
e372311afe upekts: Port upekts driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
4a95f795cb upeksonly: Port upeksonly driver to the new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
fcfe82a7b8 upektc: Port upektc driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
a8d15bccba uru4000: Port URU4000 driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
aec1b7caad build: Add -Wtype-limits to default cflags 2019-11-20 13:53:45 +01:00
Benjamin Berg
5eba6067a3 elan: Port driver to new API
This changes the cancellation logic a bit to ensure we always deactivate
the device (equivalent to the AWAIT_OFF state in the driver). All
commands except for the deactivation command should be cancelled when an
operation is stopped, this is to ensure that the LED is turned off at
the end of an operation.
2019-11-20 13:53:45 +01:00
Benjamin Berg
664d18836e synaptics: Encode metadata into userid string
This allows us to properly extract metadata for prints that are stored
on the device. We could for example delete the oldest prints first with
this information.
2019-11-20 13:53:45 +01:00
Vincent Huang
ac65cf455e synaptics: Add synaptics driver
Heavily modified by Benjamin Berg <bberg@redhat.com> to port it to the
new libfprint API and adjust the coding style to follow more closely
other drivers.
2019-11-20 13:53:45 +01:00
Benjamin Berg
b8bb08649d lib: Add byte data reader/writer helpers
These helpers are directly copied from GStreamer and stripped down quite
a bit to e.g. always assume the machine does not support unaligned
access.
2019-11-20 13:53:45 +01:00
Benjamin Berg
57866c45cd vcom5s: Port vcom5s to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
fbf4b45e76 etes603: Chain into exit SM from other SMs when deactivating
When the device is deactivated while it is still active then the exit SM
needs to be executed from the SM that was active at the time. This is
signalled by is_active being set to FALSE while the active SM completes.

Call m_exit_start in those cases to ensure proper device deactivation.
2019-11-20 13:53:45 +01:00
Benjamin Berg
431ed7210b etes603: Port etes603 driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
043b31df70 vfs0050: Port vfs0050 driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
2e30572364 vfs301: Port driver to new API
This driver is synchronuous mostly, and the sync API is not well tested.
It should work, but there has been some re-shuffling of buffers, etc.
2019-11-20 13:53:45 +01:00
Benjamin Berg
fd64c46c74 vfs101: Port vfs101 driver to new API
This driver has a rather odd state machine and also used to mess iwth
the internal state of the image device. This code has been removed, but
is untested unfortunately due to a lack of hardware.

Most likely, this driver is not quite functional currently.
2019-11-20 13:53:45 +01:00
Benjamin Berg
61e49c2659 aes2550: Port aes2550 driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
441b1238a5 aes2501: Port aes2501 to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
0a47df7bb7 aesx660: Port aes1660 and aes2660 drivers to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
5e05afecf2 aes1610: Port driver to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
7ef64b5f5f aes3k: Port aes3500 and aes4000 drivers to new API 2019-11-20 13:53:45 +01:00
Benjamin Berg
0169fe8cf6 vfs5011: Port driver and add it back into build
There is still a warning where a USB transfer should be cancelled but it
not at this point.
2019-11-20 13:53:45 +01:00
Benjamin Berg
f119c273fd upektc_img: Port upektc_img and back in
Note that this port currently conflicts with with the upeksonly driver
as the revision check is non-functional right now.
2019-11-20 13:53:45 +01:00
Benjamin Berg
dac489b7f6 scripts: Add an uncrustify script
It currently will only uncrustify the new internal libfprint code, not
the drivers or other parts.
2019-11-20 13:53:45 +01:00
Benjamin Berg
6ec11a2b26 cocci: Add spatch/coccinelle patches for driver porting
This is an impartial set of transformations to help port the drivers to
the new interfaces.
2019-11-20 13:53:45 +01:00
Benjamin Berg
4640e3f5b0 demo: Use 3.32 runtime for flatpak
We do not need the master runtime environment and the stable 3.32 one is
more readily available to users.
2019-11-20 13:53:45 +01:00
Benjamin Berg
36777896c2 CI: Update dependencies and run tests 2019-11-20 13:53:45 +01:00
Benjamin Berg
6e25a27870 tests: Add basic unit test based on virtual_image device 2019-11-20 13:53:45 +01:00
Benjamin Berg
0b4f682233 demo: Add ability to cancel capture operation 2019-11-20 13:53:45 +01:00
Benjamin Berg
d184a7662c demo: Update flatpak manifest
Build libgusb and the current v2 development branch.
2019-11-20 13:53:45 +01:00
Benjamin Berg
3f0a143037 demo: Add UI for retry errors 2019-11-20 13:53:44 +01:00
Marco Trevisan (Treviño)
b46d336d2b examples: Add back examples using the async APIs
Add the examples back by using the new async API, support verification and
enroll for devices with own storage.
2019-11-20 13:53:44 +01:00
Benjamin Berg
7d6b0c1376 demo: Port to new API 2019-11-20 11:03:09 +01:00
Benjamin Berg
dd40aeaa79 examples: Add sendvirtimg.py script to send a print to virtual_imgdev
With this script it is possible to test libfprint/fprintd without any
hardware device. The image needs to be provides as a PNG with the alpha
channel storing the print data.

See the comment in the file on how the script can be used.
2019-11-20 11:03:09 +01:00
Benjamin Berg
2b6f22b84d virtual_image: Add new virtual image driver 2019-11-20 11:03:09 +01:00
Benjamin Berg
689aff0232 lib: Major rewrite of the libfprint core and API
This is a rewrite of the core based on GObject and Gio. This commit
breaks the build in a lot of ways, but basic functionality will start
working again with the next commits.
2019-11-20 11:03:09 +01:00
Benjamin Berg
30a449841c nbis: Use GLib memory management functions
Apply the previously added spatch/coccinell file to replace all
free/malloc/realloc calls with g_free/g_malloc/g_realloc. It also removes
all the error code paths that we do not need to check anymore.

This means that the returned data must be free'ed using g_free rather
than free, making memory management more consistent.
2019-11-19 21:07:58 +01:00
Benjamin Berg
56543e1311 nbis: Add spatch file to use GLib memory management functions
Add an spatch/coccinelle file to replace all free/malloc/realloc calls
with g_free/g_malloc/g_realloc. It also removes all the error code paths
that we do not need to check anymore.
2019-11-19 21:07:58 +01:00
Benjamin Berg
9b175a7681 examples: Add PNGs for NIST example prints
These PNGs were generated using gimp simply by using the greyscale image
itself as an alpha mask. The reason to do this is solely for easier
consumption together with cairo A8 surfaces.
2019-11-19 21:07:58 +01:00
Benjamin Berg
d67a801f1f examples: Add a few example prints from NIST
These prints are from NIST and are not copyrighted. They were sourced
via wikipedia.
2019-11-19 21:07:58 +01:00
Benjamin Berg
95d7c0e800 lib: Add dummy namespace versioning file 2019-11-19 21:07:58 +01:00
Benjamin Berg
059fc5ef7d examples: Disable existing examples
These examples will stop working with the following API changes. Updated
examples may be re-enabled again later.
2019-11-19 21:07:51 +01:00
Benjamin Berg
7fed33fb49 build: Disable all drivers
We will re-enable them again when they are ported.
2019-11-18 15:39:35 +01:00
Benjamin Berg
ce9702571b build: Add a "default" driver selection to exclude virtual drivers
We will not want to install virtual drivers by default, yet they should
be inside the "all" category. So add a new "default" category and also a
separate array for the future virtual drivers.
2019-11-18 15:39:35 +01:00
Benjamin Berg
01ec1c5777 build: Add dependency to GUsb rather than libusb
We will use GUsb rather than libusb directly in the future. This should
simplify a lot of the integration work and changes such as supporting
hotplugging. It will also require quite a lot of internal changes.
2019-11-18 15:39:35 +01:00
Benjamin Berg
ec8dd6410e build: Make glib a libfprint dependency
We are going to use GLib types in the public API now.
2019-11-18 15:39:35 +01:00
Benjamin Berg
45d7046f99 lib: Remove all deprecated API 2019-11-18 15:39:35 +01:00
Benjamin Berg
5fcd41b962 CI: Disable ABI check
As the ABI check is not useful for now until the API becomes stable
again. Disable it.
2019-11-18 15:39:35 +01:00
Benjamin Berg
6ba8a15d3a build: We are now working on version 2 of libfprint
Bump the version to 1.90.0, the soname to 2.0.0. Also rename the
pkgconfig file to libfprint2.pc.
2019-11-18 15:39:20 +01:00
worldofpeace
5b615e33a0 build: Don't hardcode /bin/echo
So that the shell builtin is used instead when available.
2019-09-20 15:01:52 +02:00
Bastien Nocera
823f2c1067 1.0 2019-08-08 14:54:06 +02:00
Bastien Nocera
19732341d6 lib: Fix overwriting action after deactivating callback
If one of the callbacks called from fpi_imgdev_deactivate_complete()
was reactivating the device, then we would be overwriting whichever
"action" got set in the callback, leading to
fpi_imgdev_activate_complete() failing as it doesn't handle the "none"
action.

Reset the action before calling the callbacks.
2019-08-08 12:43:03 +00:00
Bastien Nocera
0e44eb4c1c elan: Better debug when skipping commands 2019-08-08 12:43:03 +00:00
Bastien Nocera
50461b4d7d lib: Make fp_async_*_stop() not throw warning if already in right state
Make it possible to call fp_async_*_stop() multiple times without
penalty.
2019-08-08 12:43:03 +00:00
Bastien Nocera
c11126181e aeslib: Fix use-after-free in aeslib
If a USB transfer is started but not completed in one go, the wdata we
pass to continue_write_regv() will already be freed by the time we try
to use it again.

Only free() the wdata on error, or when the USB transfer is completed.

Closes: #180
2019-08-08 14:18:47 +02:00
Bastien Nocera
658c301e3c lib: Use memmove(), g_memmove() is deprecated 2019-08-05 18:12:06 +00:00
Bastien Nocera
dce52ed081 vfs5011: Use memmove(), g_memmove() is deprecated 2019-08-05 18:12:06 +00:00
Bastien Nocera
f309f586c9 ci: Add ABI check
Last ABI break was when we fixed the return value for fp_get_pollfds()
in commit 056ea54.
2019-08-05 20:05:13 +02:00
Igor Filatov
ae1b10dba8 elan: Fix frame leak in elan_submit_image 2019-08-05 18:43:04 +02:00
Bastien Nocera
860a256f4b HACKING: Clarify the intent of the license 2019-08-05 13:37:28 +02:00
Bastien Nocera
cb2f46ed08 HACKING: Fix a typo 2019-08-05 13:18:18 +02:00
Bastien Nocera
13deaa66fd lib: Fix a typo 2019-08-05 13:18:15 +02:00
Bastien Nocera
3597a5b0ed img: Fix a typo 2019-08-05 13:17:55 +02:00
Bastien Nocera
0352995cb3 data: Fix a number of typos 2019-08-05 13:17:33 +02:00
Bastien Nocera
e9041da7f4 uru4000: Fix a typo 2019-08-05 13:17:30 +02:00
Bastien Nocera
252180e088 upektc: Fix a typo 2019-08-05 13:17:08 +02:00
Bastien Nocera
6361c208bd upeksonly: Fix a number of typos 2019-08-05 13:16:18 +02:00
Bastien Nocera
2ef8ace543 etes603: Fix a typo 2019-08-05 13:16:14 +02:00
Bastien Nocera
0400bcc85e vfs*: Fix a number of typos 2019-08-05 13:13:10 +02:00
Bastien Nocera
76db6a5a16 aes*: Fix a number of typos 2019-08-05 13:12:45 +02:00
Bastien Nocera
5b171f9577 Add code of conduct document 2019-07-25 12:04:39 +02:00
Benjamin Berg
4cec28416e lib: Remove state from fp_img_driver activate handler
The state was always AWAIT_FINGER and it was never used by any driver
(except for error checking). So remove it, in particular as a correct
state change will be done after activation anyway.

The only driver with code that actually did anything based on this was
the URU4000 driver. However, all it did was an explicit state change
execution. This is not necessary, as the state_change handler is called
anyway (i.e. we now only write the AWAIT_FINGER register once rather
than twice).

Manual changes plus:

@ init @
identifier driver_name;
identifier activate_func;
@@
struct fp_img_driver driver_name = {
    ...,
    .activate = activate_func,
    ...,
};
@ remove_arg @
identifier dev;
identifier state;
identifier init.activate_func;
@@
activate_func (
	struct fp_img_dev *dev
-	, enum fp_imgdev_state state
	)
{
	<...
-	if (state != IMGDEV_STATE_AWAIT_FINGER_ON) { ... }
	...>
}
2019-06-18 18:19:38 +02:00
Benjamin Berg
3b32baccf6 fdu2000: Remove driver as it has been defunct for long
The driver was never ported to the new asynchronous model, meaning it
has been defunct since some time in 2008. Remove the driver, as
seemingly no one has complained about this and we have no proper way to
even verify a port is correct.
2019-06-18 15:54:57 +00:00
Benjamin Berg
16875d7776 examples: Port enroll and verify examples to new storage
This ports the enroll and verify examples to the new storage so that
they do not need any deprecated API anymore.
2019-06-13 13:12:15 +00:00
Benjamin Berg
a9600e23a1 examples: Link examples to the new GVariant based storage
For now just compile and link it, we do not yet use the new storage
code.
2019-06-13 13:12:15 +00:00
Benjamin Berg
a4b6813ebf examples: Add simple storage implementation using GVariant
This is useful so that the enroll and verify examples will not use the
deprecated API anymore.
2019-06-13 13:12:15 +00:00
Benjamin Berg
ef90938eb9 build: Bump GLib dependency to 2.50 and add guards
libfprint already uses G_DEBUG_HERE in a lot of places which requires
GLib 2.50. Also add the appropriate defines so that usage of newer API
will result in warnings.
2019-06-13 13:56:35 +02:00
Benjamin Berg
66891274a7 build: Remove header files from nbis_sources
There is no need to list them in the sources.
2019-06-12 16:10:04 +02:00
Benjamin Berg
f52276bd06 build: Remove header files from libfprint_sources
There is no need to list them in the sources.
2019-06-12 16:07:44 +02:00
Benjamin Berg
7dce8dbfaa build: Remove header files from drivers_sources
It is not necessary to list all the headers in the drivers_sources list,
so remove them.
2019-06-12 16:07:08 +02:00
Benjamin Berg
3b757ee738 build: Fix source files of upekts and upketc drivers
The upekts driver needs upek_proto.c while the upektc driver does not.
Move the corresponding source file entries so that both drivers compile
standalone.
2019-06-12 16:07:05 +02:00
Benjamin Berg
0a45ed7af6 data: Deprecate print storage API
The only API user currently seems to be the examples. fprintd has its
own storage and that will be a good idea in general.

So deprecate the API, we'll need to find a different solution for the
examples eventually.
2019-06-11 18:23:56 +02:00
Benjamin Berg
1db2dc3f58 core: Add guards to public API
Add appropriate g_return_val_if_fail macros to all public API functions
to guard against NULL pointers being passed into libfprint.
2019-06-11 18:23:56 +02:00
Benjamin Berg
953c75575b poll: Remove fpi_timeout_cancel_for_dev
The function was committed by accident as part of commit d18e1053
(lib: Add a way to name timeouts). It is not used anywhere and
fpi_timeout_cancel_all_for_dev exists, is exported and used and serves
the same purpose.
2019-06-11 16:00:19 +02:00
Dave
8c7ff259af elan: Add 04f3:0c42 to the supported devices
Now that all the quirks are in place to support it.
2019-06-06 12:19:31 +02:00
Dave
3e666130c2 elan: Skip more final frames to avoid bulging captures
If users put their finger on the sensor between the bulge and
"un-bulge" area first and then swipe, the captured image would
be bad.

Skipping more frames can reduce the impact, so bump
ELAN_SKIP_LAST_FRAMES to 2.
2019-06-06 12:19:31 +02:00
Dave
2babfa0625 elan: Simplify calibration check for ELAN_0C42
Check for the mean calibration being outside of range to know whether we
require a recalibration. Continue with the usual checks if the
calibration value is within range.
2019-06-06 12:19:31 +02:00
Dave
83af40679a elan: ELAN_0C42 always supports calibration
Split off calibration support checks into elan_supports_calibration()
2019-06-06 12:19:31 +02:00
Dave
ce31c1d704 elan: Work-around one-byte responses being two-bytes long
On the ELAN_0C42 device, one-byte responses are 2 bytes long.
Adapt our expected response length.
2019-06-06 12:19:31 +02:00
Dave
b20a74a22c elan: Work-around sensors returning incorrect dimensions
The dimensions some sensors return is the maximum zero-based index
rather than the number of pixels. Assuming every sensor has an
even number of pixels is safe.
2019-06-06 12:19:31 +02:00
Dave
66461e4c81 elan: Add quirk definition for device 04f3:0c42 2019-06-06 12:19:07 +02:00
Peter Maatman
6ba9439bbb examples: Remove sleep call in enroll examples
The call to sleep(1) inside of the enrollment loop caused a crash
on at least the etes603 driver.

Because in fp_enroll_finger_img the function enters an event
handling loop. This loop needs to start before the next libusb
event timeout. Which would not happen in the etes603 driver
because the timeout there was set to 1 second as well.
2019-05-14 11:38:33 +02:00
Peter Maatman
6764ec79ae etes603: Prevent hang during enroll process
This commit fixes a hang in gnome-settings when trying to enroll a finger.

The same issue could be seen in the enroll example. Previously the enroll
example would hang on "deactivating" because at some point dev->is_active
is set to false and m_exit_start is never called.
2019-05-14 11:37:19 +02:00
Diego
6f4c378933 vfs5011: Add support for Lenovo Preferred Pro Keyboard (KUF1256)
Add support for the Lenovo Preferred Pro USB Fingerprint Keyboard KUF1256
by declaring support for USB ID 138a:0015.

Closes: #125
2019-05-06 09:55:40 +02:00
Bastien Nocera
b121fa2cc9 uru4000: Work-around SELinux AVC warnings when driver starts
Work-around SELinux AVC warnings caused by p11-kit (which is an NSS
dependency) trying to load the root user's p11-kit configs. We disable
this feature using the P11_KIT_NO_USER_CONFIG envvar.

See https://bugzilla.redhat.com/show_bug.cgi?id=1688583
2019-03-21 16:54:06 +01:00
Seong-Joong Kim
ca26e85fd4 uru4000: Fix integer overflow in imaging_run_state()
‘img->key_number’ variable is originally from the device through bulk
endpoint of USB. The variable is immediately assigned to ‘buf[0]’ for
sending to control endpoint of the device. Here, integer overflow may
occur when the ‘img->key_number’ attempts to assign a value that is
outside of type range of ‘char’ to the ‘buf[0]’
2019-02-21 19:06:06 +09:00
Bastien Nocera
0714380360 build: Disable GTK+ demo app by default
Given that it's not usable yet.
2019-01-21 14:38:35 +00:00
Bastien Nocera
b9af7952a4 demo: Fix crash when there are no supported devices
Handle the empty list output from fp_discover_devs() when there are no
supported devices.

Closes: #146
2019-01-21 14:38:35 +00:00
Bastien Nocera
ea6820ed51 lib: Better docs for no devices case in fp_discover_devs()
Document the behaviour of fp_discover_devs() when there are no supported
devices, rather than errors listing the devices.
2019-01-21 14:38:35 +00:00
Bastien Nocera
a1e46de462 lib: Fix examples not working
Remove the sanity check added in commit b1afa9d, having a poll setup
isn't necessary to use timeouts, as long as only sync functions are
used.

Closes: #139
2018-12-30 16:35:33 +01:00
Bastien Nocera
1abe213844 0.99.0 2018-12-14 13:18:08 +01:00
Bastien Nocera
0372ae8ba5 mindtct: Check for multiplication overflow in alloc_power_stats()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #91
2018-12-13 15:48:25 +01:00
Bastien Nocera
a1e69a0e9d mindtct: Check for multiplication overflow in morph_TF_map()
Assert if any of the multiplications, which are then used to allocate
memory and run a loop, would overflow.

Closes: #92
2018-12-13 15:48:25 +01:00
Bastien Nocera
49e1e98914 mindtct: Check for multiplication overflow in pixelize_map()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #96
2018-12-13 15:48:25 +01:00
Bastien Nocera
34b316d7d5 mindtct: Check for multiplication overflow in allocate_contour()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #97
2018-12-13 15:48:25 +01:00
Bastien Nocera
9abc6791c7 mindtct: Check for multiplication overflow in gen_initial_maps()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #99
2018-12-13 15:48:25 +01:00
Bastien Nocera
5459823667 mindtct: Check for multiplication overflow in interpolate_direction_map()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #100
2018-12-13 15:48:25 +01:00
Bastien Nocera
4fa8c5ec47 mindtct: Check for multiplication overflow in gen_high_curve_map()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #101
2018-12-13 15:48:25 +01:00
Bastien Nocera
239034714f mindtct: Check for multiplication overflow in gen_quality_map()
Assert if any of the multiplications, which are then used to allocate
memory, would overflow.

Closes: #103
2018-12-13 15:48:25 +01:00
Bastien Nocera
8a3a974ea3 lib: Add helper for NBIS copy-paste library
This will allow us to segragate helper functions that we want to use
within NBIS. The first helper will be a macro checking for overflow in
multiplications.
2018-12-13 15:48:25 +01:00
Bastien Nocera
db607c4a6f mindtct: Fix memory leak in error path in find_neighbors()
libfprint/nbis/mindtct/ridges.c:284:13: warning: Potential leak of memory pointed to by 'nbr_list'
            free(nbr_sqr_dists);
            ^~~~
2018-12-13 11:59:24 +01:00
Bastien Nocera
a53f07a8f6 mindtct: Fix memory leak in error path in gen_image_maps()
Free the maps if we're not returning them.

libfprint/nbis/mindtct/maps.c:176:14: warning: Potential leak of memory pointed to by 'direction_map'
      return(ret);
             ^~~
libfprint/nbis/mindtct/maps.c:195:14: warning: Potential leak of memory pointed to by 'low_contrast_map'
      return(ret);
             ^~~
libfprint/nbis/mindtct/maps.c:195:14: warning: Potential leak of memory pointed to by 'low_flow_map'
      return(ret);
             ^~~
2018-12-13 11:33:39 +01:00
Bastien Nocera
c3e996b96c mindtct: Fix memory leak in error path in shape_from_contour()
libfprint/nbis/mindtct/shape.c:263:13: warning: Potential leak of memory pointed to by 'shape'
            fprintf(stderr,
            ^~~~~~~
2018-12-13 11:27:00 +01:00
Bastien Nocera
a218437cf4 mindtct: Fix uninitialised value usage in count_minutia_ridges()
libfprint/nbis/mindtct/ridges.c:153:7: warning: 1st function call argument is an uninitialized value
      free(nbr_list);
      ^~~~~~~~~~~~~~
2018-12-12 17:24:45 +01:00
Bastien Nocera
0add0ca9b1 bozorth3: Remove unused assignments in bz_match_score()
libfprint/nbis/bozorth3/bozorth3.c:704:1: warning: Value stored to 'kx' is never read
kx  = 0;
^     ~
libfprint/nbis/bozorth3/bozorth3.c:820:4: warning: Value stored to 'l' is never read
                        l = 1;
                        ^   ~
2018-12-12 17:17:35 +01:00
Bastien Nocera
eaa4aa964c mindtct: Fix memory leaks in get_centered_contour()
The first contour wasn't freed if we failed on the second contour.

libfprint/nbis/mindtct/contour.c:521:14: warning: Potential leak of memory pointed to by 'half1_ex'
      return(ret);
             ^~~
libfprint/nbis/mindtct/contour.c:521:14: warning: Potential leak of memory pointed to by 'half1_ey'
      return(ret);
             ^~~
libfprint/nbis/mindtct/contour.c:521:14: warning: Potential leak of memory pointed to by 'half1_x'
      return(ret);
             ^~~
libfprint/nbis/mindtct/contour.c:521:14: warning: Potential leak of memory pointed to by 'half1_y'
      return(ret);
             ^~~
2018-12-12 17:14:21 +01:00
Bastien Nocera
74bb899ce2 mindtct: Fix "garbage value" error in dft_dir_powers()
libfprint/nbis/mindtct/dft.c:212:30: warning: The left operand of '*' is a garbage value
      cospart += (rowsums[i] * wave->cos[i]);
                  ~~~~~~~~~~ ^
2018-12-12 17:06:36 +01:00
Bastien Nocera
69fe7a1b8c elan: Fix "garbage value" errors in elan_cmd_cb()
libfprint/drivers/elan.c:351:4: warning: 2nd function call argument is an uninitialized value
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:46:5: note: expanded from macro 'dbg_buf'
    fp_dbg("%02x", buf[0]);                                  \
    ^~~~~~~~~~~~~~~~~~~~~~
../../../../../../Projects/jhbuild/libfprint/libfprint/fpi-log.h:52:16: note: expanded from macro 'fp_dbg'
 #define fp_dbg g_debug
               ^
libfprint/drivers/elan.c:351:4: warning: The left operand of '<<' is a garbage value
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:48:27: note: expanded from macro 'dbg_buf'
    fp_dbg("%04x", buf[0] << 8 | buf[1]);                    \
                   ~~~~~~ ^
libfprint/drivers/elan.c:351:4: warning: The left operand of '<<' is a garbage value
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:50:41: note: expanded from macro 'dbg_buf'
    fp_dbg("%04x... (%d bytes)", buf[0] << 8 | buf[1], len)
                                 ~~~~~~ ^
2018-12-12 16:56:33 +01:00
Bastien Nocera
ce856efa25 elan: Assert on a possible division by zero in elan_need_calibration()
libfprint/drivers/elan.c:598:10: warning: Division by zero
        bg_mean /= frame_size;
        ~~~~~~~~^~~~~~~~~~~~~
2018-12-12 16:30:26 +01:00
Bastien Nocera
b54514df6e elan: Assert on a possible division by zero in elan_process_frame_linear()
libfprint/drivers/elan.c:249:26: warning: Division by zero
                px = (px - min) * 0xff / (max - min);
                     ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
2018-12-12 16:24:05 +01:00
Bastien Nocera
551616c3ab aesx660: Fix memory leak in process_stripe_data()
libfprint/drivers/aesx660.c:292:10: warning: Potential leak of memory pointed to by 'stripe'
                return 0;
                       ^
2018-12-12 16:19:20 +01:00
Bastien Nocera
cec307ce7f aeslib: Fix memory leak in aes_write_regv()
libfprint/drivers/aeslib.c:156:1: warning: Potential leak of memory pointed to by 'wdata'
}
^
2018-12-12 16:17:32 +01:00
Bastien Nocera
e7bc8e03fc upeksonly: Fix typos in upeksonly_get_deviation2() comment 2018-12-12 16:13:29 +01:00
Bastien Nocera
9a025bde8b upeksonly: Fix possible division by zero in upeksonly_get_deviation2()
By asserting if we have a zero line width.

libfprint/drivers/upeksonly.c:118:7: warning: Division by zero
        mean /= (ctx->line_width / 2);
        ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
2018-12-12 16:13:15 +01:00
Bastien Nocera
6845e400cd uru4000: Fix memory leak on error in dev_init()
libfprint/drivers/uru4000.c:1357:3: warning: Potential leak of memory pointed to by 'urudev'
                fp_err("could not get encryption slot");
                ^~~~~~
2018-12-12 16:06:03 +01:00
Bastien Nocera
25d0fa42e2 uru4000: Fix unused value in sm_read_regs()
We don't need to assign urudev if we only want the size of one of its
members.

libfprint/drivers/uru4000.c:554:20: warning: Value stored to 'urudev' during its initialization is never read
        struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
                          ^~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2018-12-12 16:04:35 +01:00
Bastien Nocera
52208a6606 lib: Fix baroque code in fp_discover_prints()
Use GPtrArray to simplify the implementation.

libfprint/fpi-data.c:777:13: warning: Access to field 'data' results in a dereference of a null pointer (loaded from variable 'elem')
                list[i] = elem->data;
                          ^~~~~~~~~~
2018-12-12 15:47:29 +01:00
Bastien Nocera
6725b22fd4 lib: Fix uninitialised value in fp_print_data_load()
libfprint/fpi-data.c:497:7: warning: 2nd function call argument is an uninitialized value
        if (!fp_dev_supports_print_data(dev, fdata)) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2018-12-12 15:47:29 +01:00
Bastien Nocera
21bac43015 lib: Fix memory leak on error in fp_print_data_save()
libfprint/fpi-data.c:393:3: warning: Potential leak of memory pointed to by 'buf'
                fp_err("couldn't create storage directory");
                ^~~~~~
libfprint/fpi-log.h:75:16: note: expanded from macro 'fp_err'
 #define fp_err g_warning
               ^~~~~~~~~
2018-12-12 15:47:29 +01:00
Bastien Nocera
0ddd11f81b lib: Fix unintialised variable warning in fp_get_next_timeout()
libfprint/fpi-poll.c:398:11: warning: The left operand of '==' is a garbage value
        else if (timercmp(&fprint_timeout, &libusb_timeout, <))
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/sys/time.h:162:17: note: expanded from macro 'timercmp'
  (((a)->tv_sec == (b)->tv_sec) ?                                             \
    ~~~~~~~~~~~ ^
2018-12-12 15:47:29 +01:00
Bastien Nocera
6d47c44335 lib: Fix possible dereference in fpi_ssm_next_state()
libfprint/fpi-ssm.c:244:9: warning: Access to field 'completed' results in a dereference of a null pointer (loaded from variable 'machine')
        BUG_ON(machine->completed);
               ^~~~~~~~~~~~~~~~~~
libfprint/fpi-log.h:84:6: note: expanded from macro 'BUG_ON'
        if (condition) {                        \
            ^~~~~~~~~
2018-12-12 15:47:29 +01:00
Bastien Nocera
3cbc908a6e lib: Add better guard against huge malloc
See dda6857fee
and https://bugzilla.redhat.com/show_bug.cgi?id=1656518

When the number of lines to assemble is 1, the median_filter() function
would be passed -1 as its size as it was calculated with:
(num_lines / 2) - 1
so (1 / 2) - 1 = 0 - 1 = -1

Add a guard to stop drivers trying to assemble single lines. This
doesn't however fix the vfs5011 driver that tried to do that.
2018-12-06 10:58:35 +01:00
Bastien Nocera
95b1e75f1b Revert "ci: Disable Flatpak generation for now"
This reverts commit bcfe0ad12c.
2018-12-04 17:43:19 +01:00
Bastien Nocera
bcfe0ad12c ci: Disable Flatpak generation for now
It's currently broken on our CI runners, we'll need to reactivate
it again in the future.
2018-12-04 17:09:00 +01:00
Vasily Khoruzhick
2088a6177f lib: Document assembling functions 2018-12-03 16:06:53 +01:00
Vasily Khoruzhick
c9733d27df lib: Add API docs for fpi_img comparison functions 2018-12-03 14:22:12 +01:00
Bastien Nocera
dd24cf57c6 README: Add links to historical resources 2018-11-30 17:57:40 +01:00
Bastien Nocera
451a4c0969 lib: Remove duplicated structs from fp_internal.h
They are already declared in fpi-core.h. Also move their API docs
to fpi-core.h.
2018-11-30 16:08:42 +01:00
Bastien Nocera
dabcae7b4d lib: Document fpi_imgdev_*() functions 2018-11-29 17:32:37 +01:00
Bastien Nocera
eae5721f8e vfs101: Add FIXME about fpi_imgdev_set_action_result usage
We shouldn't need to use fpi_imgdev_set_action_result(), because
as fpi_imgdev_image_captured() is already there.
2018-11-29 17:32:37 +01:00
Bastien Nocera
ce1a675dd5 lib: Reword "use the functions below" docs
Those usually appear in struct definitions which will be at the bottom
of the docs, so there's nothing but the bottom of the page below.
2018-11-29 17:32:37 +01:00
Bastien Nocera
6ba1016024 lib: Hide struct fp_minutiae from the docs
It's only used internally.
2018-11-29 17:32:37 +01:00
Bastien Nocera
b5f175b78e lib: Move action state functions to correct C file 2018-11-29 17:32:37 +01:00
Bastien Nocera
aff7efd891 lib: Remove upekts used headers from the docs
They're only used by this super quirky driver that stores data
internally.

See #127
2018-11-29 17:32:37 +01:00
Bastien Nocera
1d00c2d4b4 lib: Make 6 async reporting funcs private
As those aren't used in any driver.
2018-11-29 17:32:37 +01:00
Bastien Nocera
61483a4c47 lib: Make the fp_print_data structure private
And add a couple of helpers for the upekts driver to use.
2018-11-29 17:32:37 +01:00
Bastien Nocera
2b21430abe lib: Fix lack of description for fp_dscv_dev_get_driver_id()
We documented the return value, but without writing out the function
description.
2018-11-29 17:32:36 +01:00
Bastien Nocera
1781ad140e lib: Remove unused fp_imgdev_verify_state enum 2018-11-29 17:32:36 +01:00
Bastien Nocera
d2e3ad4dbc lib: Add API docs for 3 enums 2018-11-29 17:32:36 +01:00
Bastien Nocera
7615aaef7a lib: Document fp_img functions
And fix fpi_img_new_for_imgdev()'s argument names to match between the
header and the C file.
2018-11-29 13:15:03 +01:00
Bastien Nocera
92e3168309 lib: Add documentation for fp_driver_type 2018-11-25 12:42:11 +00:00
Bastien Nocera
ca148cbcf1 lib: Add documentation for usb_id 2018-11-25 12:42:11 +00:00
Bastien Nocera
e57f037a10 lib: Document FP_IMG_DEV
...and add "Returns" docs to fpi-dev.c

We might need to do this more, documenting what the function does in
prose, as well as a short explanation of the returned data.
2018-11-25 12:42:11 +00:00
Bastien Nocera
46ad86fab2 doc: Remove empty "poll" section
In commit 231b8f9, when porting from doxygen to gtk-doc, we created a
section for "poll" functions, but we renamed that section to "events"
during the porting process. We ended up with an empty "poll" section,
and a correctly migrated "events" section.
2018-11-25 12:42:11 +00:00
Bastien Nocera
511e164f17 lib: Add @short_description for all the sections
So gtk-doc doesn't warn about them any more.
2018-11-25 12:42:11 +00:00
Bastien Nocera
6f18fc4bf4 lib: Document all the internal symbols in fpi-dev.c 2018-11-25 12:42:11 +00:00
Bastien Nocera
8ca34303f2 lib: Transform fp_img_driver flags into a FpiImgDriverFlags enum
And document it.
2018-11-25 12:42:11 +00:00
Bastien Nocera
882fc8ab54 lib: Fix sloppy grammar in error output 2018-11-25 12:42:11 +00:00
Bastien Nocera
9e5ae25abf lib: Transform fp_img flags into a FpiImgFlags enum
And document it.
2018-11-25 12:42:11 +00:00
Bastien Nocera
9316dfed2e ci: Generate Flatpak and export it 2018-11-23 15:05:00 +01:00
Bastien Nocera
702932c69b demo: Add Flatpak manifest for the demo application 2018-11-23 15:05:00 +01:00
Bastien Nocera
29461fa910 demo: Add GTK+ test application 2018-11-23 15:05:00 +01:00
Bastien Nocera
f7173e6645 ci: Add GTK+ to the CI 2018-11-20 05:20:55 +01:00
Bastien Nocera
11b11a9d71 lib: Fix get_next_timeout_expiry
If get_next_timeout_expiry() fails, and libusb_get_next_timeout()
has no timeouts or failed, fprint_timeout will not be set, and
we cannot compare it to libusb_timeout.

Exit early if both failed or have empty queues.
2018-11-13 11:54:41 +01:00
Bastien Nocera
9da69dfc36 elan: Fix format mismatch warnings in debug output
libfprint/drivers/elan.c:351:12: warning: format specifies type 'unsigned short' but the argument has type 'unsigned char' [-Wformat]
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:46:21: note: expanded from macro 'dbg_buf'
    fp_dbg("%02hx", buf[0]);                                  \
    ~~~~~~~~~~~~~~~~^~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
libfprint/drivers/elan.c:351:12: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat]
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:48:21: note: expanded from macro 'dbg_buf'
    fp_dbg("%04hx", buf[0] << 8 | buf[1]);                    \
    ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
libfprint/drivers/elan.c:351:12: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat]
                        dbg_buf(elandev->last_read, transfer->actual_length);
                        ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/drivers/elan.c:50:35: note: expanded from macro 'dbg_buf'
    fp_dbg("%04hx... (%d bytes)", buf[0] << 8 | buf[1], len)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
libfprint/drivers/elan.c:413:10: warning: format specifies type 'unsigned short' but the argument has type 'unsigned char' [-Wformat]
        dbg_buf(cmd->cmd, 2);
        ~~~~~~~~^~~~~~~~~~~~
libfprint/drivers/elan.c:46:21: note: expanded from macro 'dbg_buf'
    fp_dbg("%02hx", buf[0]);                                  \
    ~~~~~~~~~~~~~~~~^~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
libfprint/drivers/elan.c:413:10: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat]
        dbg_buf(cmd->cmd, 2);
        ~~~~~~~~^~~~~~~~~~~~
libfprint/drivers/elan.c:48:21: note: expanded from macro 'dbg_buf'
    fp_dbg("%04hx", buf[0] << 8 | buf[1]);                    \
    ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
libfprint/drivers/elan.c:413:10: warning: format specifies type 'unsigned short' but the argument has type 'int' [-Wformat]
        dbg_buf(cmd->cmd, 2);
        ~~~~~~~~^~~~~~~~~~~~
libfprint/drivers/elan.c:50:35: note: expanded from macro 'dbg_buf'
    fp_dbg("%04hx... (%d bytes)", buf[0] << 8 | buf[1], len)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
include/glib-2.0/glib/gmessages.h:345:32: note: expanded from macro 'g_debug'
                               __VA_ARGS__)
                               ^~~~~~~~~~~
2018-11-13 11:54:41 +01:00
Bastien Nocera
e5f4021a4f vfs101: Fix warning about value truncation
libfprint/drivers/vfs101.c:854:6: warning: absolute value function 'abs' given an argument of type 'long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value]
        if (abs(count - VFS_IMG_BEST_CONTRAST) < abs(vdev->best_clevel - VFS_IMG_BEST_CONTRAST))
            ^
libfprint/drivers/vfs101.c:854:6: note: use function 'labs' instead
        if (abs(count - VFS_IMG_BEST_CONTRAST) < abs(vdev->best_clevel - VFS_IMG_BEST_CONTRAST))
            ^~~
            labs
2018-11-13 11:54:41 +01:00
Bastien Nocera
4dcbc6a3aa vfs101: Fix typo in "VFS_IMG_BEST_CONRAST" constant
It's contrast, says so above the definition.
2018-11-13 11:54:41 +01:00
Bastien Nocera
7a72d8fd58 lib: Fix uninitialised variable in fpi_imgdev_image_captured()
libfprint/fpi-dev-img.c:255:6: warning: variable 'print' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
        if (imgdev->action != IMG_ACTION_CAPTURE) {
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/fpi-dev-img.c:271:25: note: uninitialized use occurs here
        imgdev->acquire_data = print;
                               ^~~~~
libfprint/fpi-dev-img.c:255:2: note: remove the 'if' if its condition is always true
        if (imgdev->action != IMG_ACTION_CAPTURE) {
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libfprint/fpi-dev-img.c:232:29: note: initialize the variable 'print' to silence this warning
        struct fp_print_data *print;
                                   ^
                                    = NULL
2018-11-13 11:54:41 +01:00
Bastien Nocera
5edfd55e00 doc: Fix typo in chapter title 2018-11-12 12:10:11 +01:00
Bastien Nocera
2951daaa01 doc: Split driver docs into chapters 2018-11-09 15:32:39 +01:00
Bastien Nocera
23f7c4aaf7 doc: Hide G_LOG_DOMAIN from gtk-doc
It's only used internally, and doesn't need to be documented here,
as FP_COMPONENT which uses it already is.
2018-11-09 15:32:39 +01:00
Bastien Nocera
3dc5c4a6de doc: Add LIBFPRINT_DEPRECATED to the docs 2018-11-09 15:32:39 +01:00
Bastien Nocera
a97ae3bc35 doc: Add fpi-async section to the docs 2018-11-09 15:32:39 +01:00
Bastien Nocera
53d2fb3ad2 doc: Add more functions to fpi-dev section
And rename section to match that of fpi-dev-img
2018-11-09 15:32:39 +01:00
Bastien Nocera
4f7e507716 doc: Add fpi-dev-img section to the docs 2018-11-09 15:32:39 +01:00
Bastien Nocera
f2e3a840db doc: Add fpi-core and fpi-core-img sections to the docs 2018-11-09 15:32:39 +01:00
Bastien Nocera
f45c18116a doc: Add fpi-data section to the docs 2018-11-09 15:32:39 +01:00
Bastien Nocera
2365c608f9 lib: Change "unsigned" to "unsigned int"
To appease gtk-doc's struct parser, which chokes on the short name for
the data type.

See https://gitlab.gnome.org/GNOME/gtk-doc/issues/63
2018-11-09 14:20:19 +01:00
Bastien Nocera
6c6daaa619 doc: Add fpi-assembling section to the docs 2018-11-09 14:08:04 +01:00
Bastien Nocera
857a399bfa doc: Fix parameter names in fp_minutia_get_coords() docs
The API docs for fp_minutia_get_coords() as added in commit 1006467
had the parameters in the docs not match the actual names used.
2018-11-09 13:58:21 +01:00
Bastien Nocera
6e230f0a07 doc: Add missing fpi_timeout_set_name() to the docs 2018-11-09 13:58:21 +01:00
Bastien Nocera
7402401057 doc: Add fpi-img section to the docs 2018-11-09 13:58:21 +01:00
Bastien Nocera
fe17dfe01d lib: Rename fpi_im_resize() to fpi_img_resize()
Now that this name is free. This makes all the image manipulation
functions have the same "fpi_img_" prefix.
2018-11-09 13:36:52 +01:00
Bastien Nocera
4885b38be5 lib: Rename fpi_img_resize() to fpi_img_realloc()
To better match what it does. It does not resize an image, but
reallocate its internal data structure's size.
2018-11-09 13:35:40 +01:00
Bastien Nocera
5d4a5981d0 lib: Make fpi_poll_is_setup() private
As it's not used in other parts of the library after the changes in
commit 422f81b.
2018-11-09 13:33:02 +01:00
Bastien Nocera
0fcb4533b5 doc: Add more headers to ignore list
Those are not public headers, so don't need to be documented. This
removes 18 symbols from the undocumented symbols list.
2018-11-09 13:29:56 +01:00
Bastien Nocera
422f81b60c Revert "lib: Async functions cannot be started without a mainloop"
This reverts commit 700c5791f8.

We don't need a poll setup to be able to call sync functions, which then
use async functions for implementation internally.

Closes: #124

Conflicts:
	libfprint/fpi-async.c
2018-11-09 12:22:45 +01:00
Bastien Nocera
e0d2f3ae53 lib: Link to fp_enroll_finger_img() in fp_enroll_stage_cb() doc 2018-10-23 11:24:56 +02:00
Bastien Nocera
531d9048b3 lib: Fix up third-person usage in API docs 2018-10-23 11:24:56 +02:00
Bastien Nocera
18495d122d lib: Fix up @dev argument docs 2018-10-23 11:24:56 +02:00
Bastien Nocera
9bcacd97df lib: Require a callback for a number of async calls
Otherwise the caller won't be able to call the appropriate _finish()
calls when done.

See https://gitlab.freedesktop.org/libfprint/libfprint/issues/119 for
the long-term plan
2018-10-23 11:24:56 +02:00
Bastien Nocera
d91eae26e5 lib: Add API docs for the async functions 2018-10-23 11:24:56 +02:00
Bastien Nocera
d113ed9d83 docs: Update API docs style
No period at the end of parameter docs.
2018-10-23 11:24:56 +02:00
Bastien Nocera
e113754312 docs: Add "struct #fp_dev" to the API docs 2018-10-23 11:24:56 +02:00
Bastien Nocera
b1afa9da5d lib: No mainloop, no timeouts either 2018-10-23 10:59:15 +02:00
Bastien Nocera
700c5791f8 lib: Async functions cannot be started without a mainloop
No mainloop, no async.
2018-10-23 10:59:15 +02:00
Bastien Nocera
97d0a6dfe6 lib: Add fpi_poll_is_setup() sanity check
This checks whether polling was correctly setup for integration with a
mainloop.
2018-10-23 10:59:15 +02:00
Bastien Nocera
a54d020c97 lib: Make fp_get_pollfds() fail when fp_init() wasn't called
So things can't be called out-of-order.
2018-10-23 10:59:15 +02:00
Bastien Nocera
36b696f433 lib: Fix error messages in async capture functions
They mentioned verification instead of capture.
2018-10-23 10:59:15 +02:00
Bastien Nocera
f42cd6eefd lib: Add fp_driver_supports_imaging()
So we don't need to open a device before checking whether it supports
imaging.
2018-10-23 10:59:15 +02:00
Bastien Nocera
46ebb39f65 lib: Throw an error if fp_init() wasn't called
You can't call fp_discover_devs() without calling fp_init() and having
it not fail, otherwise there's nothing to discover...
2018-10-23 10:59:15 +02:00
Bastien Nocera
c88a51cce8 build: Refuse to build without any drivers 2018-10-23 10:59:15 +02:00
Bastien Nocera
3a7b03f022 lib: Fix crash when too many minutiae were detected
struct xyt_struct uses a fixed-sized array to fit MAX_BOZORTH_MINUTIAE (200)
minutiae. MAX_FILE_MINUTIAE is 1000. So if we detected more than
MAX_BOZORTH_MINUTIAE, we would crash copying the data from the capture
to the structure.

We might want to use dynamically allocated arrays in the future (or
bigger ones) so that we don't lose minutiae.

Closes: #116
2018-10-12 12:27:37 +02:00
Bastien Nocera
94450a1d74 lib: Fix fpi_img_is_sane()
The checks weren't:
- checking whether the width or height were negative
- whether img->width * img->height would overflow, or
  was bigger than G_MAXINT
- whether img->width * img->height was bigger than the total
  length of the buffer

The last one looks like a thinko, it checked for:
(img->length * img->height) < img->length
which is equivalent to:
img->height < 1
which we already check for earlier.

Closes: #85
2018-10-12 00:54:39 +00:00
Bastien Nocera
c35ad20249 mindtct: Fix a memory leak in morph_TF_map()
cimage is leaked when mimage fails to allocate.

Spotted by Seth Arnold

Closes: #82
2018-10-12 00:54:39 +00:00
Bastien Nocera
5e8b4a81e9 mindtct: Fix leak in pixelize_map()
pmap was not freed in error cases.

Spotted by Seth Arnold

Closes: #83
2018-10-12 00:54:39 +00:00
Bastien Nocera
21a779235d mindtct: Fix powmax_dirs leak on error
A copy/paste error meant we were trying to free a variable we only just
failed to allocate.

Spotted by Seth Arnold

Closes: #81
2018-10-12 00:54:39 +00:00
Bastien Nocera
1006467f33 lib: Add accessor for minutia coordinates
Add fp_minutia_get_coords() so that debugging applications can show the
detected minutiae along with the captured image.

This will also help fix the positively ancient fprint_demo.

See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=907470
2018-10-08 16:50:59 +02:00
Bastien Nocera
cffe49de5c build: Fix "already configured" meson warning 2018-10-08 16:50:59 +02:00
Bastien Nocera
7962d8cdab build: Fix build with no drivers using imaging_dep
Closes: #109
2018-09-28 15:59:45 +02:00
Bastien Nocera
36dba33808 build: Test builds with a single driver with no deps
So that we can be sure that the build doesn't break when those drivers
are not built.
2018-09-28 15:55:56 +02:00
Bastien Nocera
c273908471 lib: Tidy fp_internal.h
Group global variables, structure definitions, and functions, and
group functions by which C source they're defined in.

This also removes the FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE
definition that's already available in the drivers API-accessible
fpi-core.h
2018-09-28 15:12:39 +02:00
Bastien Nocera
bf8661bf45 lib: Include "fpi-dev.h" in drivers header 2018-09-28 15:12:39 +02:00
Bastien Nocera
499b522183 lib: Remove titles from headers
The purpose of the headers is (or will be) explained in more details
inside each one of the matching C files.
2018-09-28 15:12:39 +02:00
Bastien Nocera
13bfe7a65c lib: Move driver definitions to fpi-core.h 2018-09-28 15:12:39 +02:00
Bastien Nocera
e90ec04441 lib: Move fp_minutiae to fpi-img.h 2018-09-28 15:12:39 +02:00
Bastien Nocera
a59a5caaf3 lib: Add missing includes
Headers for size_t and ssize_t, as used in the header itself.
2018-09-28 15:12:39 +02:00
Bastien Nocera
5b9f81fb46 lib: Move fp_dev helpers to fpi-dev.h from fpi-core.h 2018-09-28 15:12:39 +02:00
Bastien Nocera
d3aaebb352 lib: Add include guards to fpi-dev.h 2018-09-28 15:12:39 +02:00
Bastien Nocera
a99f920fe0 lib: Add include guards to fpi-poll.h 2018-09-28 15:12:39 +02:00
Bastien Nocera
fb5527c58c lib: Split off imgdev functions
They now live in fpi-dev-img.[ch]
2018-09-28 15:12:39 +02:00
Bastien Nocera
fcd3c1dd89 lib: Split off core.c drivers API 2018-09-28 15:12:39 +02:00
Bastien Nocera
3a9500be67 lib: Move fpi-img utils to fpi-img's header 2018-09-28 15:12:39 +02:00
Bastien Nocera
1d93b86569 lib: Rename assembling.[ch]
This is already self-contained.
2018-09-28 15:12:39 +02:00
Bastien Nocera
aca2cd41d8 lib: Rename sync.c to fpi-sync.c
All the functions there are public, so no matching header.
2018-09-28 15:12:39 +02:00
Bastien Nocera
1035f733aa lib: Split off async functions
And don't add the new fpi-async.h to the driver imports, it will only
be used by the upekts driver.
2018-09-28 15:12:39 +02:00
Bastien Nocera
2818d94010 lib: Split off fp_img helpers
And rename img.c to fpi-img.c, as well as pixman.c to fpi-img-pixman.c
2018-09-28 15:12:39 +02:00
Bastien Nocera
1d1c34eb60 lib: Make fpi_print_data_item_free() static 2018-09-28 15:12:39 +02:00
Bastien Nocera
ca06fae22e lib: Split off fpi_print_data helpers
And rename data.c to fpi-data.c
2018-09-28 15:12:39 +02:00
Bastien Nocera
36f527269b Revert "lib: Mark fpi_ssm_get_user_data as deprecated"
This reverts commit 1fd82b5162.

This was causing too many warnings at this stage of porting. We'll add
it again when most of the drivers are ported.
2018-09-28 15:12:39 +02:00
Bastien Nocera
7cfe20e07f lib: Fix gtk-doc warning
warning: no link for: "timeval" -> (<code class="literal">timeval</code>)
2018-09-27 16:08:21 +02:00
Bastien Nocera
1fd82b5162 lib: Mark fpi_ssm_get_user_data as deprecated 2018-09-27 16:07:58 +02:00
Bastien Nocera
0ace5f64f8 elan: Fix use-after-free if USB transfer is cancelled 2018-09-27 15:19:00 +02:00
Bastien Nocera
e532524c7e elan: Name our timeouts 2018-09-27 15:17:15 +02:00
Bastien Nocera
ebd96f892e lib: Make fpi_timeout_add() never fail
It will now assert if the monotonic clock isn't available. If that's the
case, we'll have bigger problems anyway.
2018-09-27 15:14:05 +02:00
Bastien Nocera
4b9b34fa4d elan: Use USB helpers 2018-09-27 15:09:59 +02:00
Bastien Nocera
bcc1e7ae73 aes2501: Use USB helpers
Nice little cleanups.
2018-09-27 14:49:50 +02:00
Bastien Nocera
27accf42f2 uru4000: Port URU4000 driver to USB helpers
Doesn't look very useful.
2018-09-27 14:49:50 +02:00
Bastien Nocera
96f2e07cdd lib: Add USB transfer helpers
Those helpers will provide more arguments in their callbacks, and handle
the libusb_transfer lifecycle, making it easier to use for drivers.
2018-09-27 14:49:50 +02:00
Bastien Nocera
192c4f3cfc aesx660: Use constants for buffer sizes 2018-09-27 14:49:50 +02:00
Bastien Nocera
cb274032da aes2501: Use constants for buffer sizes 2018-09-27 14:49:50 +02:00
Bastien Nocera
b890fa56d8 aes1610: Use constants for buffer sizes 2018-09-27 14:49:50 +02:00
Bastien Nocera
b817b46494 lib: Remove home-grown min() implementation
And use GLib's.
2018-09-27 14:49:50 +02:00
Bastien Nocera
49ba59369a aesx660: Remove home-grown min() implementation
And use GLib's.
2018-09-27 14:49:50 +02:00
Bastien Nocera
d09cb88e9a uru4000: Fix typos in comments 2018-09-27 14:49:50 +02:00
Bastien Nocera
44c3f4f772 lib: Cancel pending timeouts on close
So that the drivers don't call back into themselves once freed.
2018-09-27 14:49:50 +02:00
Bastien Nocera
948a67a51f lib: Add internal fpi_timeout_cancel_all_for_dev()
This will be used to disable all timeouts for a device that's about
to be closed, and freed.
2018-09-27 14:49:50 +02:00
Bastien Nocera
de79609550 lib: Use timeout name in debug messages when available 2018-09-27 14:49:41 +02:00
Bastien Nocera
d18e10535e lib: Add a way to name timeouts
To make it easier to print debug information about where timeouts are
coming from.
2018-09-27 14:49:41 +02:00
Bastien Nocera
2954583373 lib: Fix memory leak in fpi_poll_exit()
The active_timers list was freed, but not the elements themselves.
2018-09-27 14:36:06 +02:00
Bastien Nocera
ccdecdea11 lib: Document fpi_ssm_jump_to_state() 2018-09-26 15:57:25 +02:00
Bastien Nocera
946388d1e9 lib: Fix incorrect guard in FP_IMG_DEV()
The check for the DRIVER_IMAGING type was reversed.
2018-09-26 15:53:52 +02:00
Bastien Nocera
10ae8ffb55 drivers: Simplify libusb_alloc_transfer(0) calls
By using our new, never-failing, USB allocation wrapper. As it can never
fail, we can also remove all the error paths for the allocations
failing.
2018-09-19 17:06:17 +02:00
Bastien Nocera
bdba9990fb lib: Add libusb allocation helper 2018-09-19 17:04:55 +02:00
Bastien Nocera
50166e88c0 lib: Add fpi_ssm_next_state_timeout_cb() helper
To be used in 5 drivers.
2018-09-19 15:46:29 +02:00
Bastien Nocera
f2bc826a20 lib: Move aeslib.[ch] to the drivers directory
As it's used by drivers, and isn't a set of generic helpers.
2018-09-19 15:16:40 +02:00
Bastien Nocera
ac48d66203 lib: Mention that fpi_timeout gets freed 2018-09-18 20:02:14 +02:00
Bastien Nocera
f68e7fcb9f lib: Add fp_dev argument to timeout callback
To cut down on the fpi_ssm_get_user_data() usage again.
2018-09-18 20:00:59 +02:00
Bastien Nocera
0c3a22758b drivers: Simplify FP_INSTANCE_DATA(FP_DEV()) calls
When fp_dev is already available, don't use the fp_img_dev struct to get
to fp_dev with FP_DEV(), use the fp_dev directly.
2018-09-18 18:30:42 +02:00
Bastien Nocera
9cc859a318 drivers: Diminish fpi_ssm_get_user_data() usage
Can't remove it yet, as libusb transfers and timeouts don't pass the
fp_dev or fp_img_dev separately.
2018-09-18 18:30:42 +02:00
Bastien Nocera
7dfc8f3364 lib: Remove fpi_ssm_get_dev()
Usually by passing the dev it from an fpi_ssm callback, or simply
using that callback argument.
2018-09-18 14:02:23 +02:00
Bastien Nocera
e397571f83 lib: Add more args to fpi_ssm callbacks
Pass the struct fp_dev and user_data to fpi_ssm callbacks, so that we
might be able to get rid of the fpi_ssm_get_user_data(), and
fpi_ssm_get_dev() as most drivers just get those from the ssm anyway
in their callbacks.
2018-09-18 13:46:39 +02:00
Bastien Nocera
d34d7c26de lib: Remove fpi_ssm_set_user_data()
And pass the user_data in fpi_ssm_new() instead.
2018-09-18 13:45:33 +02:00
Bastien Nocera
77defa1d8b lib: Remove fpi_dev_get_nr_enroll_stages()
It's the same as fp_dev_get_nr_enroll_stages()
2018-09-15 01:23:02 +02:00
Bastien Nocera
5d01497b8b lib: Remove dev_to_img_dev() helper
We can access the img_dev struct member directly, and we don't have
to double check that the img_dev member is actually an img_dev type,
as it always is.
2018-09-15 01:20:59 +02:00
Bastien Nocera
cb8732b255 lib: Remove priv struct member in fp_driver
It's unused.
2018-09-15 01:18:14 +02:00
Bastien Nocera
3f64b2ea5a lib: Remove fpi_imgdev_get_usb_dev()
We now use fpi_get_usb_dev(FP_DEV()) instead.
2018-09-15 01:12:18 +02:00
Bastien Nocera
57b38a2876 lib: Remove fpi_imgdev_get_dev()
This is now handled by FP_DEV()
2018-09-15 01:12:18 +02:00
Bastien Nocera
058f91909d lib: Remove fp_img_dev->priv
And use the new instance data helper.
2018-09-15 01:12:18 +02:00
Bastien Nocera
4f75e63e25 lib: Remove fp_dev->priv
Not precise enough, and it was only used in upekts to get/set the
instance private struct and keep it around, so add a new, more precisely
defined field to fp_dev for that.
2018-09-15 01:12:18 +02:00
Bastien Nocera
2e50ff5e7c lib: Add some TODO items to fp_dev struct 2018-09-15 01:09:50 +02:00
Bastien Nocera
0b7477e72c lib: Use fp_dev to access USB device
Instead of having own own pointer in fp_img_dev
2018-09-15 01:09:50 +02:00
Bastien Nocera
4dc8aa6dfa docs: Add fpi-dev helpers to API docs 2018-09-15 01:09:50 +02:00
Bastien Nocera
161c3ccf1c lib: Link fp_dev to fp_img_dev and back
So it's easy to switch between the 2 structs, and remove fp_img_dev->dev
direct access, as well as fp_dev->priv "user data" usage.
2018-09-15 01:09:39 +02:00
Bastien Nocera
170da7fec1 lib: Move fp_dev definition and helpers to separate header 2018-09-15 01:09:39 +02:00
Bastien Nocera
d7af9a4498 Merge branch 'wip/hadess/fpi-log-docs' into 'master'
Logging API docs

See merge request libfprint/libfprint!16
2018-09-07 10:59:56 +00:00
Bastien Nocera
3cb3b1d63a lib: Add Logging API documentation 2018-09-06 14:44:45 +02:00
Bastien Nocera
fc66919e1f lib: Make BUG_ON() use fp_err()
So that when we change fp_err() to an assertion, BUG_ON() is changed as
well.
2018-09-06 14:42:33 +02:00
Bastien Nocera
de5b4e7dcb lib: Split off logging helpers 2018-09-06 13:24:41 +02:00
Bastien Nocera
561576961c Merge branch 'wip/hadess/fpi-timeout-docs' into 'master'
fpi_timeout API docs

See merge request libfprint/libfprint!15
2018-09-05 15:53:15 +00:00
Bastien Nocera
2946dabd24 lib: Typedef fpi_timeout 2018-09-05 17:49:02 +02:00
Bastien Nocera
969eefc81f lib: Add fpi_timeout API documentation 2018-09-05 17:48:43 +02:00
Bastien Nocera
efee7262b6 lib: Split off timeout helpers
And rename poll.c to fpi-poll.c
2018-09-05 17:15:20 +02:00
Bastien Nocera
1102d6e478 Merge branch 'wip/hadess/fpi-ssm-docs' into 'master'
Add fpi_ssm API docs

See merge request libfprint/libfprint!14
2018-09-05 14:37:09 +00:00
Bastien Nocera
603aab0a81 lib: Rename fpi_ssm_mark_aborted to fpi_ssm_mark_failed 2018-09-05 16:29:26 +02:00
Bastien Nocera
10e934e234 lib: Add fpi_ssm API documentation 2018-09-05 16:25:34 +02:00
Bastien Nocera
48b9e6c517 lib: Typedef fpi_ssm 2018-09-05 15:40:34 +02:00
Bastien Nocera
5ae2ef5407 lib: Split off fpi_ssm functions
Rename drv.c to something more fitting to its contents, and move state
machine code to its own header.
2018-09-05 15:40:01 +02:00
Bastien Nocera
cafa05dab5 doc: Add include to each section rather than globally
So that we can document internal driver APIs and mention the correct
include.
2018-09-05 15:39:05 +02:00
Bastien Nocera
6345835b02 doc: %NULL changes 2018-09-04 15:58:23 +02:00
Bastien Nocera
1d453b5732 doc: Fix warning about fp_capture_result
The enum values need to be documented before the enum itself, otherwise
this warning is thrown:
warning: Value descriptions for fp_capture_result are missing in source code comment block.
2018-09-04 15:57:46 +02:00
Bastien Nocera
d3a1b86ea4 doc: Fix warnings about user_data
Such as:
warning: Parameter description for *::user_data is missing in source code comment block.
2018-09-04 15:56:32 +02:00
Bastien Nocera
bb27ca5720 lib: Work-around gtk-doc's handling of the short type
gtk-doc thinks "short" is only a modifier, not a type of its own (short
== short int). This work-around does not change the ABI.

See https://gitlab.gnome.org/GNOME/gtk-doc/issues/44
2018-09-04 15:45:18 +02:00
Bastien Nocera
065c0b6202 fdu2000: This comment is not API docs
So format it in a way that gtk-doc doesn't think it's API docs.
2018-09-04 15:44:26 +02:00
Bastien Nocera
b4819701b4 doc: Fix warning about fp_print_data
It was listed twice in the sections declaration.
2018-09-04 15:42:57 +02:00
Bastien Nocera
daed05755a lib: Remove unused fp_imgdev_verify_state from drivers API 2018-09-04 14:46:25 +02:00
Bastien Nocera
fb192f706c lib: Remove unused fp_dev_state from drivers API 2018-09-04 14:45:49 +02:00
Bastien Nocera
350b0a38e2 drivers: De-duplicate udf_crc() helper
Was in both the upektc_img and upekts drivers
2018-09-04 14:05:37 +02:00
Bastien Nocera
9ccbda4a40 Merge branch 'wip/hadess/update-nbis-5-0-0' into 'master'
Update to NBIS 5.0.0

See merge request libfprint/libfprint!12
2018-08-28 09:35:46 +00:00
Bastien Nocera
821cbae187 loop: Remove unused variable
mindtct/loop.c: In function ‘process_loop_V2’:
mindtct/loop.c:713:8: warning: variable ‘halfway’ set but not used [-Wunused-but-set-variable]
    int halfway;
        ^~~~~~~
2018-08-27 20:01:00 +02:00
Bastien Nocera
528f3556ea vfs301: Use vfs301_proto_deinit()
Even though it does nothing, make sure to use it so it's useful once it
does something.
2018-08-27 20:01:00 +02:00
Bastien Nocera
489afea605 lib: Remove unused fpi_dev_get_dev_state()
This internal-only function was never used.
2018-08-27 20:01:00 +02:00
Bastien Nocera
688a133f3f morph: Fix misleading indentation
mindtct/morph.c: In function ‘get_south8_2’:
mindtct/morph.c:173:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
    if (row >= ih-1) /* catch case where image is undefined southwards   */
    ^~
mindtct/morph.c:176:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
       return *(ptr+iw);
       ^~~~~~
mindtct/morph.c: In function ‘get_north8_2’:
mindtct/morph.c:197:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
    if (row < 1)     /* catch case where image is undefined northwards   */
    ^~
mindtct/morph.c:200:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
       return *(ptr-iw);
       ^~~~~~
mindtct/morph.c: In function ‘get_east8_2’:
mindtct/morph.c:221:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
    if (col >= iw-1) /* catch case where image is undefined eastwards    */
    ^~
mindtct/morph.c:224:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
       return *(ptr+ 1);
       ^~~~~~
mindtct/morph.c: In function ‘get_west8_2’:
mindtct/morph.c:243:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
    if (col < 1)     /* catch case where image is undefined westwards     */
    ^~
mindtct/morph.c:246:7: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
       return *(ptr- 1);
       ^~~~~~
2018-08-27 20:01:00 +02:00
Bastien Nocera
0cd37b0142 block: Remove unused variable
mindtct/block.c: In function ‘block_offsets’:
mindtct/block.c:108:18: warning: variable ‘ph’ set but not used [-Wunused-but-set-variable]
    int pad2, pw, ph;
                  ^~
2018-08-27 20:01:00 +02:00
Bastien Nocera
9fb789dc78 nbis: Update to NBIS 5.0.0
This updates NBIS to its latest 5.0.0 version, dated 04/03/2015, from a
1.x version, dated 2007.

Original sources are available at:
https://www.nist.gov/itl/iad/image-group/products-and-services/image-group-open-source-server-nigos#Releases

And full change log at:
https://www.nist.gov/sites/default/files/documents/2016/12/14/changelog.txt
2018-08-27 20:01:00 +02:00
Bastien Nocera
770444af55 nbis: Add script to update NBIS and apply changes
NBIS is pretty complicated to update, seeing as we've made quite a few
changes to get it to compile as a library. With those scripts, we can
easily trim headers to remove functions we don't use, rename global
variables, and do any sort of fixups that are necessary right now.

In the future, removing unused NBIS functions might be as easy as
updating that script, re-running it, and pushing the changes.

Note that remove-function.lua is a very crude parser that only supports
NBIS' style of declaration, with the return type on the same line as the
function name. I wouldn't recommend trying to use it in another project.

Callcatcher (https://github.com/caolanm/callcatcher) was also used to
remove additional unused functions.
2018-08-27 20:01:00 +02:00
Bastien Nocera
703d9b2a07 img: Remove remove_perimeter_pts setting
It's gone in NBIS 5.0.0, and will need to be replaced after the update.
2018-08-24 16:11:07 +02:00
Bastien Nocera
a96509f286 Merge branch 'iafilatov/libfprint-elan-prepare-merge' into 'master'
elan: Send stop cmd and recalibrate after each capture

See merge request libfprint/libfprint!11
2018-08-10 12:36:01 +00:00
Igor Filatov
8553f2e41c elan: Send stop cmd and recalibrate after each capture
This seems to fix the lock-up issue with 0903
2018-08-10 14:21:36 +02:00
Bastien Nocera
56c96dde8b Merge branch 'wip/hadess/elan-update' into 'master'
Update Elan driver

See merge request libfprint/libfprint!10
2018-08-10 12:06:35 +00:00
Bastien Nocera
9793d60c5a elan: Remove unused string.h include 2018-08-10 13:45:29 +02:00
Igor Filatov
4ff97e7cbd elan: Increase bz3 threshold to 24
Based on experience. Values more than 24 seem to work just after
enrollment, but it becomes very hard to verify in a day or so.
2018-08-10 13:45:29 +02:00
Igor Filatov
75fe328f64 elan: Don't rotate frames on 0x0c03
There has been a report that a 0x0c03 was installed straight (other
readers so far have produced images that are 90 degrees rotated). There
is no way for the dirver to know how a device is installed, so for now just
make an exception.
2018-08-10 13:45:29 +02:00
Igor Filatov
b28b006d61 elan: Use IMGDEV_STATE_* events instead of pre-set capture path 2018-08-10 13:45:29 +02:00
Igor Filatov
c3b1c982bc elan: Set max frame height to 50, add note about performance
Frame height is a loosely experience-backed guesstimation. 50 seems to be
a good middle ground between swipe speed and quality.
2018-08-10 13:45:29 +02:00
Igor Filatov
b098399bbc elan: Support 0x0c01~0x0c33 2018-08-10 13:45:29 +02:00
Igor Filatov
65bbdff3fc elan: Stop doing sensor reset, change calibration and frame logic
Sensor reset code has been removed because it is not needed during normal
operation.

Calibration and frame processing logic has been improved according to
recommendations from Elantech.
2018-08-10 13:45:29 +02:00
Igor Filatov
fba3e682ea elan: Remove supported devices from udev whitelist 2018-08-09 14:45:15 +02:00
Igor Filatov
bccff4ffef elan: Change command structs, support more devices
Make each command a separate struct to get finer control over which
commands are called on which devices. Update ssm's accordingly. Add
sensor_reset and fuse_load commands.

Support 0x0903, 0x0c03, 0x0c16, 0x0c1a, 0x0c26
2018-08-09 14:42:25 +02:00
Bastien Nocera
9843c2d764 Merge branch 'wip/hadess/gtk-doc-meson-regression' into 'master'
build: Fix build with newer meson

See merge request libfprint/libfprint!9
2018-07-20 10:36:28 +00:00
Bastien Nocera
c9abbec48a build: Fix build with newer meson
The gtk-doc meson helper regressed in that it didn't expect the
libfprint.types file to not exist, as earlier versions did. Remove
the --rebuild-types call so that it is not generated, and meson carries
on compiling the rest of the library.

See https://gitlab.gnome.org/GNOME/gtk-doc/issues/48
See https://github.com/mesonbuild/meson/issues/3892
See https://bugzilla.redhat.com/show_bug.cgi?id=1604585
2018-07-20 12:22:50 +02:00
Bastien Nocera
bc79f9504b Merge branch 'wip/hadess/more-string-h' into 'master'
lib: Include more standard headers for drivers to use

See merge request libfprint/libfprint!8
2018-07-18 09:08:41 +00:00
Bastien Nocera
626b0f1a8f lib: Include more standard headers for drivers to use
Such as string.h and stdlib.h, to be able to compile on older
toolchains like that of Fedora 27.
2018-07-17 16:14:09 +02:00
Bastien Nocera
da95af0f48 0.8.2 2018-07-17 13:48:13 +02:00
Bastien Nocera
28b6f643d8 Merge branch 'wip/hadess/downgrade-assert-2' into 'master'
Another assert downgrade

See merge request libfprint/libfprint!7
2018-07-17 11:47:10 +00:00
Bastien Nocera
22277c7277 build: Downgrade meson in CI script
It failed to finish the build otherwise:
https://github.com/mesonbuild/meson/issues/3892
2018-07-17 13:43:00 +02:00
Bastien Nocera
19e7b217c1 lib: Downgrade fp_err() to be non-fatal
Similarly to b1ac865abd, downgrade
fp_err() to be non-fatal. A number of drivers would spit out an error
when encountering this call, but not crash, carry on and most of the
time recover.

Make sure we don't assert in those cases.
2018-07-16 16:08:54 +02:00
Bastien Nocera
29d3541b74 lib: Downgrade BUG* assertions to work-around crashes #2
Same as b1ac865abd but for the drivers
API.
2018-07-16 16:07:25 +02:00
Bastien Nocera
b9e5b3a55c Merge branch 'wip/hadess/downgrade-assert' into 'master'
lib: Downgrade BUG* assertions to work-around crashes

Closes #77

See merge request libfprint/libfprint!6
2018-07-03 09:44:56 +00:00
Bastien Nocera
b1ac865abd lib: Downgrade BUG* assertions to work-around crashes
BUG() and BUG_ON() didn't use to assert, but only print an error if
debugging was enabled. This was hiding a lot of state bugs in drivers,
and transforming those into assertions causes crashes.

Downgrade the assertion to only print a warning, and hope that those
eventually get fixed in the drivers so we can re-enable them.

Closes: #77
2018-07-03 11:40:25 +02:00
Bastien Nocera
21504c0621 Merge branch 'wip/hadess/poll-retval' into 'master'
poll: Fix fp_get_pollfds retval type

See merge request libfprint/libfprint!5
2018-06-26 13:18:40 +00:00
Bastien Nocera
056ea541dd poll: Fix fp_get_pollfds retval type
fp_get_pollfds() is supposed to return a negative value on failure, but
size_t is an unsigned integer. Use ssize_t instead.
2018-06-26 14:53:53 +02:00
Bastien Nocera
871fddf5fb Merge branch 'wip/hadess/more-upekts-statuses' into 'master'
upekts: Fix enrollment never finishing on some upekts devices

See merge request libfprint/libfprint!3
2018-06-20 17:16:08 +00:00
Bastien Nocera
c284858d06 upekts: Fix enrollment never finishing on some upekts devices
Add support for more device status codes, brought back from the
now-removed UPEKE2 driver.

See 3bf55a3e07/libfprint/drivers/upeke2.c (L1013)
2018-06-19 11:11:04 +02:00
Bastien Nocera
bb4d888661 elan: Fix typo in comment 2018-06-18 18:07:24 +02:00
Bastien Nocera
ff77cfc9b5 doc: Update more website links 2018-06-18 14:56:40 +02:00
Bastien Nocera
80f91ecb7b Merge branch 'master' into 'master'
elan: Add USB ID for TNP Nano USB Fingerprint Reader (04f3:0c26)

See merge request libfprint/libfprint!1
2018-06-13 20:09:47 +00:00
Corentin Noël
6cb77465ab elan: Add USB ID for TNP Nano USB Fingerprint Reader (04f3:0c26)
The device works without any additional changes to the driver.

https://www.amazon.co.uk/gp/product/B075955HY7/
2018-06-13 20:22:29 +01:00
Bastien Nocera
6f6127cbb6 0.8.1 2018-06-12 16:05:45 +02:00
Bastien Nocera
e1d85fb636 build: Install udev rules in correct directory
The udevdir variable in udev.pc might not have a trailing slash.
2018-06-12 16:03:34 +02:00
Bastien Nocera
74b5c92787 0.8.0 2018-06-12 15:42:22 +02:00
Bastien Nocera
ac1f97e2eb lib: Supported devices list is for master, not stable 2018-06-12 12:46:19 +02:00
Bastien Nocera
40f486b108 HACKING: Update hacking file 2018-06-12 11:06:26 +02:00
Bastien Nocera
b62e67401c lib: Fix supported devices page title again
We need to call setlocale() so we run in UTF-8 mode, and can print that
sweet sweet em dash.
2018-06-08 16:23:35 +02:00
Bastien Nocera
dd0a0134a6 lib: Fix supported devices page title 2018-06-07 17:46:08 +02:00
Bastien Nocera
5e24000799 build: Remove unused meson rule
We're generating the supported-devices.md file in the website CI now.
2018-06-07 17:39:36 +02:00
Bastien Nocera
c5cdfcb120 lib: Sort supported devices list 2018-06-07 17:39:04 +02:00
Bastien Nocera
549a6694d2 build: Disable supported-devices.md generation for now
As added in e5393bf46a

It fails currently.
2018-06-04 16:13:08 +02:00
Bastien Nocera
14e34e1d15 build: Remove ported Makefile.am snippet 2018-06-03 14:41:02 +02:00
Bastien Nocera
e5393bf46a lib: Add script to print MarkDown page of supported devices 2018-06-03 14:40:34 +02:00
Bastien Nocera
878a201bb1 README: Update links to new website 2018-06-03 00:31:05 +02:00
Bastien Nocera
b0e4619e0a docs: Update links to new website 2018-06-03 00:31:05 +02:00
Bastien Nocera
aec65777a7 nbis: Update links to new website 2018-06-03 00:30:10 +02:00
Bastien Nocera
31bad8ddd2 build: Fix fprint.h install destination
Since the port to meson, fprint.h was installing to $includedir instead
of $includedir/libfprint/
2018-05-31 14:35:16 +02:00
Bastien Nocera
79d65c907f build: Add missing X11 deps for the examples 2018-05-31 12:30:48 +02:00
Bastien Nocera
92231d984f build: Add some missing build essentials 2018-05-31 12:23:30 +02:00
Bastien Nocera
2fbc77955e build: Add CI
Barebones, just compiles libfprint.
2018-05-31 12:18:17 +02:00
Bastien Nocera
c91819f551 lib: Remove drv->close absence support in fp_async_dev_close()
The driver will at least need to close its hardware resources, and
free memory, so it must have had one.

This case was never actually used as can be seen from the fact that
we would assert in fpi_drvcb_close_complete() if the state was wrong
but never set it to the expected value.
2018-05-31 11:06:31 +02:00
Bastien Nocera
b3f6ff5a36 lib: Add guard to async functions
To avoid having NULL devices being passed dereferenced.
2018-05-31 11:06:31 +02:00
Bastien Nocera
52f84bee3c vfs5011: Error out when no lines were captured
Which avoids passing zero lines to fpi_assemble_lines()

"gmem.c:130: failed to allocate 18446744073709551612 bytes"

 #3  0x00007fe4f6ef428f in g_log (log_domain=log_domain@entry=0x7fe4f6f3506e "GLib", log_level=log_level@entry=G_LOG_LEVEL_ERROR, format=format@entry=0x7fe4f6f3e610 "%s: failed to allocate %lu bytes") at gmessages.c:1398
 #4  0x00007fe4f6ef2ac4 in g_malloc0 (n_bytes=n_bytes@entry=18446744073709551612) at gmem.c:129
 #5  0x00007fe4f8052020 in median_filter (filtersize=25, size=-1, data=0x0) at assembling.c:309
 #6  fpi_assemble_lines (ctx=ctx@entry=0x7fe4f82ac3c0 <assembling_ctx>, lines=0x0, lines_len=0) at assembling.c:389
 #7  0x00007fe4f805f3db in submit_image (ssm=ssm@entry=0x16c3cba360, data=data@entry=0x16c3cb9cc0) at drivers/vfs5011.c:412

See https://bugzilla.redhat.com/show_bug.cgi?id=1484812

Closes: #42
2018-05-31 11:08:41 +02:00
Bastien Nocera
dda6857fee assembling: Add guards to fpi_assemble_lines()
With the goal of not crashing when we try to malloc MAXINT bytes of RAM.

See https://bugzilla.redhat.com/show_bug.cgi?id=1484812

Closes: #42
2018-05-31 11:06:31 +02:00
Timur Celik
0215483fb3 assembling: Fix assembling of last frame in reverse mode
The last image is always misplaced because the sign of the delta
vector isn't corrected.

This could result in false positives and verification failing.

https://bugs.freedesktop.org/show_bug.cgi?id=105027
2018-05-30 11:17:08 +02:00
Timur Celik
37bb59df13 assembling: Fix assembling of frames for non-reverse stripes
Every frame stores the delta from the previous frame, in reverse mode
it stores the delta to the next frame. This causes images to use the
wrong delta while assembling in forward mode.

The broken assembling in forward mode will create a small error for
linear motion, because the delta of all frames is approximately the
same in this case. But if you move your finger, stop and then continue
moving in a single scan, the misplaced frames should be visible in
the assembled output.

This could result in false positives and verification failing.

https://bugs.freedesktop.org/show_bug.cgi?id=105027
2018-05-30 11:15:17 +02:00
Bastien Nocera
db34837d2d lib: Simplify device discovery
Use GPtrArray instead of open-coding a NULL terminated array.

https://bugs.freedesktop.org/show_bug.cgi?id=106279
2018-05-29 13:45:27 +02:00
Bastien Nocera
ba49677794 vfs0050: Rename "udev" to "usb_dev"
To reduce confusion with possible future udev usage.
2018-05-29 13:37:19 +02:00
Bastien Nocera
1a376c1bfa lib: Remove 2 more functions from the drivers API 2018-05-29 13:34:18 +02:00
Bastien Nocera
ef807d9d0e lib: s/array_n_elements/G_N_ELEMENTS/ 2018-05-29 13:34:18 +02:00
Bastien Nocera
2a4893d946 lib: fp_imgdev_*() functions are only used in drivers 2018-05-29 13:34:18 +02:00
Bastien Nocera
cee061b363 lib: fpi_ssm_start_subsm() is only used in drivers 2018-05-29 13:34:18 +02:00
Bastien Nocera
1bbdf304ab lib: Remove never defined fpi_ssm_has_completed() 2018-05-29 13:34:18 +02:00
Bastien Nocera
6155068f9e lib: Split off some fp_img related functions
Some are internal, some are for drivers.
2018-05-29 13:34:18 +02:00
Bastien Nocera
0c4e3bb1c4 lib: Remove drivers definitions from drivers API 2018-05-29 13:34:18 +02:00
Bastien Nocera
4547ff0c19 lib: Remove a number of data types from drivers API
They're unused in drivers.
2018-05-29 13:34:18 +02:00
Bastien Nocera
b7cce4d91d lib: Make fp_minutiae opaque
And fp_minutia private.
2018-05-29 13:34:18 +02:00
Bastien Nocera
475250ce71 lib: Split off some polling related functions 2018-05-29 13:34:18 +02:00
Bastien Nocera
f40f231a63 lib: Make fp_img_dev structure opaque 2018-05-29 13:34:18 +02:00
Bastien Nocera
d83d92adf2 lib: Make fp_dev structure opaque 2018-05-29 13:34:18 +02:00
Bastien Nocera
d15282bff1 lib: Remove minutiae utils from internal header
It's only used by drivers.
2018-05-29 13:34:18 +02:00
Bastien Nocera
00637c4f0b lib: Remove fprint_get_drivers() from drivers API
Drivers don't need to get a list of drivers.
2018-05-29 13:34:18 +02:00
Bastien Nocera
2e035a7f45 lib: Make fpi_ssm opaque for drivers
We shouldn't access fpi_ssm struct fields directly in drivers, so add
accessor and setter functions for the common uses.
2018-05-29 13:34:18 +02:00
Bastien Nocera
17577175f8 lib: Remove fpi_driver_to_img_driver() from drivers API
It's only used internally to the library.
2018-05-29 13:34:18 +02:00
Bastien Nocera
933fab6ed4 lib: Remove array_n_elements() from internal header
It's unused.
2018-05-29 13:34:18 +02:00
Bastien Nocera
7e5661caff lib: Don't include assembling.h in internal header
It's not needed.
2018-05-29 13:34:18 +02:00
Bastien Nocera
19dfb138a6 drivers: Use new drivers_api.h in drivers 2018-05-29 13:34:18 +02:00
Bastien Nocera
0930f2614c lib: Use public header in helper files
aeslib.h and assembling.h don't need access to internal data structures,
so make them include the public fprint.h rather than the internal header
fp_internal.h.
2018-05-29 13:34:18 +02:00
Bastien Nocera
1b20521e5c lib: Add drivers_api.h file
This will hide library internals, for the purpose of making the drivers
API documentable.
2018-05-29 13:34:18 +02:00
Bastien Nocera
0e351db91a lib: Fix new BUG_ON() implementation again
This time, the macro didn't wrap the condition, resulting in calls
like BUG_ON(size > 100) being expanded to g_assert(!size > 100), when
what we wanted was BUG_ON(!(size > 100)).

See 9cca501650,
ff09456cf5, and egg on my face.
2018-05-25 17:38:40 +02:00
Bastien Nocera
9cca501650 lib: Fix new BUG_ON() implementation
A thinko reversed the meaning of the BUG_ON() condition. This fixes
the inverted implementation in commit
ff09456cf5.
2018-05-25 16:12:29 +02:00
Bastien Nocera
2481cbe4ab poll: Add some details about how mainloop integration works 2018-05-25 15:58:29 +02:00
Bastien Nocera
bc3959d1e0 lib: Fix internal deprecation warning
Remove deprecation warning that comes from an internal function, it
serves no purpose, and the function itself is deprecated.

Follow-up from commit 1f0079a274.
2018-05-25 13:45:13 +02:00
Bastien Nocera
1ac815e457 examples: Fix integer overflow warnings 2018-05-25 13:40:33 +02:00
Bastien Nocera
55b83062d0 img: Fix fd leaks
Spotted by maddin200@aol.com

https://bugs.freedesktop.org/show_bug.cgi?id=90197
2018-05-25 13:30:35 +02:00
Mark Harfouche
391f77ce5e aes1610: Fix compilation warning in aes1610
Fixes:
drivers/aes1610.c:736:34: warning: ‘stop_reader’ defined but not used [-Wunused-const-variable=]

https://bugs.freedesktop.org/show_bug.cgi?id=105429
2018-05-25 13:21:17 +02:00
Bastien Nocera
bc30a3d2e5 aes2501: Fix state machine never using "init_3" state
This fixes this warning by the same token:
drivers/aes2501.c:671:34: warning: ‘init_3’ defined but not used [-Wunused-const-variable=]

https://bugs.freedesktop.org/show_bug.cgi?id=105429
2018-05-25 13:21:17 +02:00
Bastien Nocera
ff5de4ff03 lib: Replace open-coded array_n_elements()
Replace it with glib's version, which already exists.

https://bugs.freedesktop.org/show_bug.cgi?id=106280
2018-05-25 13:20:34 +02:00
Bastien Nocera
f433a4d67c upekts: Fix compilation warning
libfprint/drivers/upekts.c: In function ‘alloc_send_cmd_transfer’:
libfprint/drivers/upekts.c:161:2: warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation]
  strncpy(buf, "Ciao", 4);
  ^~~~~~~~~~~~~~~~~~~~~~~

Replace with memcpy() to only copy the 4 bytes we need.

https://bugs.freedesktop.org/show_bug.cgi?id=106281
2018-05-25 13:19:31 +02:00
Bastien Nocera
994061af44 drivers: Simplify headers
Remove all the headers already included through "fp_internal.h" such as
<libusb.h> and <errno.h>, include "assembling.h" and "driver_ids.h" there
as well to avoid doing it in (almost) every driver.
2018-05-24 17:02:15 +02:00
Bastien Nocera
501020921e vfs301_proto: Use GLib helpers
No need to roll out own min() implementation, or use the bare assert().
2018-05-24 17:00:17 +02:00
Bastien Nocera
53c09405b2 etes603: Use GLib's g_assert()
Instead of requiring assert.h to be included.
2018-05-24 16:57:14 +02:00
Bastien Nocera
1f0079a274 data: Mark all the fp_dscv_print functions as deprecated
As this is pretty much copy/pasted in fprintd, and should instead be
implemented by whatever system actually stores the data, rather than
in a generic but not quite "fits-all-purpose" way.

https://bugs.freedesktop.org/show_bug.cgi?id=106550
2018-05-24 13:21:40 +02:00
Bastien Nocera
15afe43cf0 examples: Replace deprecated fp_set_debug() 2018-05-24 12:43:53 +02:00
Bastien Nocera
eb8f7ba3b2 lib: Mark fp_set_debug() as deprecated
As per the documentation.
2018-05-24 12:42:18 +02:00
Bastien Nocera
901a6f7fed lib: Add macro for deprecated functions 2018-05-24 12:41:35 +02:00
Bastien Nocera
fc92f62136 build: Remove the need to modify sources for new drivers
Instead of having to modify both fp_internal.h to list each driver
definition structure, and core.c to add those drivers to arrays we
can loop over, generate both of those using meson.
2018-05-24 12:23:39 +02:00
Bastien Nocera
ff09456cf5 lib: Use g_assert* to implement BUG() and BUG_ON() assertions 2018-05-23 19:14:33 +02:00
Bastien Nocera
32fcfde86b lib: Use GLib and libusb directly for debug output
Use GLib internally to output debug information, and tell about
libusb's LIBUSB_DEBUG envvar for libusb debug.

fp_set_debug() is now a no-op.

https://bugs.freedesktop.org/show_bug.cgi?id=106552
2018-05-23 19:13:08 +02:00
Bastien Nocera
363a1b3371 lib: Replace empty fp_dbg() calls
GLib won't like them, so use G_DEBUG_HERE() instead.
2018-05-23 19:11:07 +02:00
Bastien Nocera
c376c6fb02 lib: Fix type mismatch warnings in debug output 2018-05-23 19:11:05 +02:00
Bastien Nocera
8e6e23b8d0 build: Always enable debugging logging
We shouldn't need to specifically enable debug logging to get useful
data out of a compiled libfprint either, so always enable debugging
output. It will still be switched off at runtime, by default.
2018-05-23 19:11:02 +02:00
Bastien Nocera
63e5d56441 build: Always allow switching log level at runtime
There are no parts of libfprint that are so resource intensive that we'd
want to disable logging. This avoids (hopefully rare) cases where
compiled versions of libfprint are distributed with logging completely
disabled, and thus can't be debugged.
2018-05-23 19:10:58 +02:00
Bastien Nocera
e9bfd943fc docs: Mark a few FP_VERIFY_MATCH as constant
Add "%" prefix to mark it as a constant in the docs.
2018-05-23 15:18:34 +02:00
Bastien Nocera
614e2286c2 docs: Fix typo in fp_enroll_finger_img() API docs
Missing ":" after argument name.
2018-05-23 15:18:34 +02:00
Bastien Nocera
768a74c4bf docs: Remove transfer information from fp_dev_open()
There's no GObject usage in the public API.
2018-05-23 15:18:34 +02:00
Bastien Nocera
612e9e11de docs: Document async function callbacks 2018-05-23 15:18:34 +02:00
Bastien Nocera
06c72d54be poll: Add missing API docs for polling functions 2018-05-23 15:18:34 +02:00
Bastien Nocera
be68bacc94 lib: Merge two other async callback types
Merge fp_capture_cb and fp_verify_cb.

https://bugs.freedesktop.org/show_bug.cgi?id=106551
2018-05-23 15:18:34 +02:00
Bastien Nocera
317d7bc988 lib: Simplify fp_*_stop_cb callback definitions
They're all the same, so merge them into a single fp_operation_stop_cb.

https://bugs.freedesktop.org/show_bug.cgi?id=106551
2018-05-23 13:39:10 +02:00
Bastien Nocera
b44e417bca docs: Fix '\sa' doxygen references 2018-05-23 13:39:10 +02:00
Bastien Nocera
9d67ce484d lib: Make inline functions real functions
Otherwise they will not be parsed by gtk-doc and documented.
2018-05-23 13:39:10 +02:00
Bastien Nocera
78b8602cf6 lib: Make fp_minutia an opaque structure
Nothing uses the elements of the structure, so make it opaque.
2018-05-23 13:39:10 +02:00
Bastien Nocera
83a0a7681b img: Make fpi_img_detect_minutiae() static
It's unused outside img.c, so mark it as static.
2018-05-23 13:39:10 +02:00
Bastien Nocera
c5e0e41ce7 docs: Add documentation for opaque structures 2018-05-23 13:39:00 +02:00
Bastien Nocera
b3fe4a1e91 docs: Update API documentation
Fixes to layout, dead links, typography, and more.

Thanks to Benjamin Berg <bberg@redhat.com> for the thorough review
2018-05-18 05:51:58 +02:00
Bastien Nocera
f59bf389d9 INSTALL: Update for Meson 2018-05-18 01:16:30 +02:00
Bastien Nocera
231b8f9f92 doc: Port from Doxygen to gtk-doc
Split the introduction into separate chapters, add filler documentation
for async functions, fix mismatched function arguments.
2018-05-17 17:39:51 +02:00
Bastien Nocera
dac153d24a build: Port to meson
And remove the autotools. Faster, cleaner.

https://bugs.freedesktop.org/show_bug.cgi?id=106514
2018-05-15 10:46:54 +02:00
Bastien Nocera
3661d146a7 drivers: Remove UPEKE2 driver
The device is already handled by upektc_img driver, and its sources
still exist in git if needed.

https://bugs.freedesktop.org/show_bug.cgi?id=106514
2018-05-15 10:46:54 +02:00
Bastien Nocera
3bf55a3e07 examples: Fix compile-time warning
Fix "function declaration isn’t a prototype" warning
2018-05-14 17:35:51 +02:00
Bastien Nocera
5226467fc2 build: Make NSS (and URU4000) driver optional
In case NSS isn't available.

https://bugs.freedesktop.org/show_bug.cgi?id=106278
2018-05-11 11:13:25 +02:00
Mark Harfouche
54deaa1b24 mindtct: Fix compilation warnings
nbis/mindtct/morph.c:152:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
nbis/mindtct/morph.c:176:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
nbis/mindtct/morph.c:200:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
nbis/mindtct/morph.c:222:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]

https://bugs.freedesktop.org/show_bug.cgi?id=105429
2018-03-11 22:43:04 +01:00
Mark Harfouche
7ff667f58d examples: Fix memory leaked by device discovery
https://bugs.freedesktop.org/show_bug.cgi?id=105427
2018-03-11 13:46:00 +01:00
Mark Harfouche
58ba9b02ed lib: Fix memory leak patch in device discovery
libusb_free_device_list() needs to be called on the list of USB devices
obtained through libusb_get_device_list() or the list and its elements
will be leaked.

https://bugs.freedesktop.org/show_bug.cgi?id=105427
2018-03-11 13:43:58 +01:00
Hans de Goede
d35da0ce99 fprint-list-udev-rules: Add some unsupported Validity Sensors readers to the whitelist 2017-12-12 10:51:43 +01:00
Hans de Goede
041e6a1078 fprint-list-udev-rules: Add some unsupported Elantech readers to the whitelist 2017-12-12 10:51:43 +01:00
Hans de Goede
1c73c36ed7 fprint-list-udev-rules: Remove white-list entries which have a driver now
Remove 2 entries from the whitelist for finger-print models for which
we have a driver now, so they no longer need to be on the whitelist.
2017-12-12 10:51:43 +01:00
Anton Eliasson
69de32f700 vfs5011: Don't submit an image if there was an error capturing it 2017-12-03 13:12:53 -08:00
Alan Davidson
4bfee76ead Fix security hole: zero out memory when allocated 2017-12-03 13:11:48 -08:00
Vasily Khoruzhick
4d7afd9b4f uru4k: increase threshold to detect encryption
Otherwise we get false positives on devices without encryption
2017-12-03 13:10:13 -08:00
Igor Filatov
cfe60c0640 Add Elan driver 2017-12-03 21:17:26 +02:00
Vasily Khoruzhick
d82847a6b4 0.7.0 2017-05-14 09:26:30 -07:00
Vasily Khoruzhick
5a7e6e07ff etes603: fix compilation error caused by a0bbbd7d3 2016-11-07 08:10:44 -08:00
Vasily Khoruzhick
2162aa9f48 uru4k: decrypt image if necessary
Add naive detection of image encryption: if stddev between two
adjacent rows is higher than threshold assume that image is encrypted
and decrypt it.

Fixes fd.o bug 88945
2016-11-05 20:58:18 -07:00
Vasily Khoruzhick
a1f36c71c9 upeksonly: decrease bz3_threshold for 147e:1001
Its width is only 216 pixels, and it appears not to be enough for matching at
default threshold.
2016-11-05 20:58:18 -07:00
Vasily Khoruzhick
e4eedef27e upeksonly: use fpi_std_sq_dev() and fpi_mean_sq_diff_norm()
Use fpi_mean_sq_diff_norm() for blank line detection and
fpi_mean_sq_diff_norm() for duplicate line detection.
Fixes finger presence and removal detection.
2016-11-05 20:58:18 -07:00
Vasily Khoruzhick
5e29695969 lib: move some functions from vfs5011.c into img.c 2016-11-05 20:58:18 -07:00
Konstantin Semenov
49a46668ad lib: Add VFS0050 driver
New driver for 138a:0050 device

https://bugs.freedesktop.org/show_bug.cgi?id=91616
2016-11-05 20:58:18 -07:00
Bastien Nocera
76269decdd aes4000: Fix possible crash if USB init fails
The code was indented, but only the first call was actually in the
conditional, which meant that initialisation carried on as normal on top
of a failed USB device. Exit early and remove the conditional to fix
this.

https://bugzilla.gnome.org/show_bug.cgi?id=98594
2016-11-05 00:13:51 +01:00
Bastien Nocera
8454a25ecf aes3500: Fix possible crash if USB init fails
The code was indented, but only the first call was actually in the
conditional, which meant that initialisation carried on as normal on top
of a failed USB device. Exit early and remove the conditional to fix
this.
2016-11-05 00:11:30 +01:00
Bastien Nocera
a0bbbd7d32 drivers: Print USB error when libusb_claim_interface() fails
https://bugs.freedesktop.org/show_bug.cgi?id=98594
2016-11-05 00:10:17 +01:00
Bastien Nocera
12f6dae8cd build: Fix 9570c36 on Debian
Debian's ash doesn't implement pushd/popd.
2016-11-03 14:05:46 +01:00
Bastien Nocera
9570c36fd4 build: Fix running autogen.sh out-of-tree 2016-07-19 11:18:58 +02:00
Bastien Nocera
487dae0d2f Work-around kernel's lack of USB PM
The device is already supported by the vfs5011 driver and non-
blacklisted, so will show up in the udev rules, but for ease of
backporting to older versions, add it to the whitelist anyway.

https://bugzilla.redhat.com/show_bug.cgi?id=1173367
2016-04-12 16:39:39 +02:00
Vasily Khoruzhick
d71018bd8f vfs5011: add USB IDs of device found in some Toshiba laptops 2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
61fa57b05d aes1610: decrease bz3_threshold to 20 2015-12-16 13:24:39 -08:00
Volkau Siarhei
fc1781e317 vfs101: fix broken enrolling by prev commit to vfs101.c 2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
ffef6c2bcc vfs5011: add proper dev_deactivate() support
Driver is not able to cancel imaging process without this change
2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
67d29f7936 aes1610: improve gain settings 2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
9437c98d54 lib: frame assembling: flip image for non-reverse direction
It was here for aes2501 and aes1610 before moving assembling routines
into common code.
2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
f7d00a828d lib: use normalized error to make decision about movement direction
Height is not a good determinant in movement direction, normalized
error is much better. Should fix aes1610 and aes2501 driver issues.
2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
0f0a4b2da6 aes2660: set partial flag on an image
Set partial flag to remove false minutiae at the perimeter of a scan
2015-12-16 13:24:39 -08:00
Vasily Khoruzhick
c9cdbaf880 aes2550: set partial flag on an image
Set partial flag to remove false minutiae at the perimeter of a scan
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
83f29dad9f aes2501: set partial flag on an image
Set partial flag to remove false minutiae at the perimeter of a scan
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
c2a11c5918 aes1610: set partial flag on an image
Set partial flag to remove false minutiae at the perimeter of a scan
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
3746b2ad5c upeksonly: use line assembling routines to account variable swiping speed 2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
b51fa446e3 lib: move line assembling routines out of vfs5011 into common code 2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
6fc5293e83 upeksonly: add support for 147e:1001 device 2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
aab3daa28b upeksonly: move regwrite sequences into a header 2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
e40f7bd1f7 lib: move frame assembling routines into a separate file and make them usable by non-aes drivers
Frame assembling routines are not aes-specific, so move them into a separate file
and add an accessor for peeking a pixel.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
6664f87d8f aes1610: fix memory corruption introduced by a457658f1b 2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
6e8d5cd6a1 vfs5011: do duplicate line search for 30 lines
It seems that on faster devices, the driver can get more duplicate lines.
Without this change scan looks too stretched.

Suggested by: Thomas Rinsma <thomasrinsma@gmail.com>
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
9f7e1ecf40 vfs5011: make '5 scans per enroll' work with this driver
Restart scan if core did not ask to terminate it explicitly.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
d9567002e4 imgdev: reset action_result after reporting it
Otherwise we end up in reporting the same result on next iteration.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
a656a4a9f3 upektc_img: Handle scan status reported by sensor properly
Sensor can report "short scan" or "finger not centered" instead of image,
so it's necessary to handle them gracefully.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
2944a35e74 imgdev: Add fpi_imgdev_abort_scan() to abort scan gracefully from within the driver.
Smart sensors like Upek TouchChip Coprocessor can provide scan status instead
of image, as result we need to report such status as "short scan" or "finger not centered"
from within the driver, since it's not a session error.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
391373fb0c upektc_img: Fix copy/paste error
Replace upekts_img with upektc_img
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
985e8c4577 aes1660: set partial flag on an image
Sensor width seems to be only 128 pixels and that's not enough
for scanning whole finger surface. Lower bz3_threshold to 25,
since for wrong finger score never goes above 10, but sometimes
for right finger score is below 40.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
bd0d4258e4 upektc_img: set partial flag on an image
Sensor width seems to be only 128 pixels and that's not enough
for scanning whole finger surface. Lower bz3_threshold to 20,
since for wrong fingerprint score never goes above 10, but sometimes
for right finger score is below 40.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
9bbd9b208a lib: add partial image flag
And activate perimeter points removal if this flag is set.
2015-12-16 13:24:38 -08:00
Vasily Khoruzhick
59fe0fb699 nbis: add one more step of false minutia removal
Remove minutiae that are located on scan perimeter
2015-12-16 13:24:38 -08:00
Bastien Nocera
f1fdd71613 rules: Add driver name to the USB properties
Makes it easier to see which driver is being used.
2015-03-15 23:13:08 +01:00
Bastien Nocera
bb66780cb5 build: Document why some drivers are disabled
This avoids confusion when looking at the build logs
2015-03-15 23:10:03 +01:00
Carlos Olmedo Escobar
45fb6d7908 vfs101: Logical conjunction always evaluates to false. 2015-02-09 12:47:22 +01:00
Timo Teräs
9f408bf51b imgdev: fix enum mismatch for dev_change_state() call
This bug has existed long time, but it was uncovered by commit
e215b05094 which enabled multiple enrollment rounds.

In practice this broke (at least) URU4000 driver state machine
causing it to enter indefinite loop - due to the invalid state
change callback.

Patch originally posted at:
http://lists.freedesktop.org/archives/fprint/2014-June/000603.html

Test and verification results:
http://lists.freedesktop.org/archives/fprint/2014-June/000607.html

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
2015-02-03 18:26:33 +01:00
Bastien Nocera
ee32166267 0.6.0 2015-02-03 17:36:32 +01:00
Vasily Khoruzhick
a3c90f2b24 upektc_img: handle 0x28 message better 2015-01-31 13:19:24 +03:00
Arseniy Lartsev
dc537ef2c9 lib: Add VFS5011 driver
New driver for VFS5011 138a:0011 and 138a:0018

https://bugs.freedesktop.org/show_bug.cgi?id=61692

[vasilykh]:
	- use g_get_real_time() instead of non-portable time()
	- use g_free() instead of free()
	- comment out "RECV(VFS5011_IN_ENDPOINT_CTRL2, 8)"
2015-01-31 13:19:11 +03:00
Vasily Khoruzhick
061a457658 aeslib: improve frame-assembling routines
Some scanners provide hardware assistance in frame assemling, i.e.
horizontal and vertical offset to previous frame is provided. This
commit improves code to utilise that assistance. Sensors without
hardware assistance will use software algorithm, which was also
improved to do search in horizontal direction.
2015-01-31 13:18:23 +03:00
Vasily Khoruzhick
82ae7c1c09 aesx660: fix spelling of define name 2015-01-31 13:18:23 +03:00
Rex Dieter
79d79c3c87 lib: Test before applying power saving udev rules
add TEST=="power/control"... to test for the presence of the file
before setting it.

See https://bugzilla.redhat.com/show_bug.cgi?id=950205

https://bugs.freedesktop.org/show_bug.cgi?id=87414
2015-01-28 16:28:57 +01:00
Vasily Khoruzhick
35e356f625 build: add subdir-objects option to make automake happy
Without subdir-object automake throws warnings like this one:

Makefile.am warning: source file 'drivers/aes2550.c' is in a subdirectory,
Makefile.am but option 'subdir-objects' is disabled
2013-08-19 11:13:50 +03:00
Vasily Khoruzhick
948ab02d1a lib: use pixman for imaging utils
pixman is very lightweight library for pixel manipulation, and it
has no dependencies except glibc, so using it instead of gdkpixbuf/imagemagick
makes list for libfprint dependencies a bit shorter.
2013-08-19 11:13:50 +03:00
Patrick Marlier
a6101026d2 Add EgisTec ES603 driver
This driver handles EgisTec ES603 device, ID 1c7a:0603
2013-08-19 11:13:50 +03:00
Vasily Khoruzhick
e0966cb20f vfs101: drop nr_enroll_stages override
Imaging drivers aren't allowed to change number of enroll stages anymore,
all that imaging driver does is providing image to the upper layer.
Upper layer decides if it needs more scans.
2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
e278e8321c vfs301: drop nr_enroll_stages override
Imaging drivers aren't allowed to change number of enroll stages anymore,
all that imaging driver does is providing image to the upper layer.
Upper layer decides if it needs more scans.
2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
e1728e7c25 aes1660: remove unneeded lowering of bz3_threshold
Since 5 scans for enroll was introduced it's not necessary to lower
bz3_threshold anymore, there's a good probability that scan to verify matches
with at least one enrolled sample.
2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
e215b05094 imgdev: perform 5 scans for enrollment
This feature dramatically improves matching rate on devices with small
sensors.
2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
fe3fdd1f50 upeke2: disable by default, device is now handled by upektc_img driver 2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
5ff45658c0 upektc_img: add support for Upek Eikon 2 devices 2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
d12b294783 Add upektc_img driver
Imaging driver, handles UPEK 147e:2020 device
2013-08-19 11:13:49 +03:00
Vasily Khoruzhick
2bba4fb073 Implement image capture (both synchronous and asynchronous variants)
fp_dev_img_capture() is not implemented and returns -ENOTSUPP for all devices
since migration to asynchronous model. This commit implement missing functionality
2013-08-12 11:18:18 +03:00
Juvenn Woo
aeca32fc12 aes3k: add aes3500 driver
This driver supports AES3500 device (08ff:5731) and utilizes common routines from
AES4000.
2013-08-12 11:18:18 +03:00
Juvenn Woo
12c1088777 aes3k: extract common routines aes3k from aes4000
AES3500 and AES4000 are pretty similar devices, have same
command send, the only difference is in image size and init sequence.
Extract common routines from AES4K to be used later in AES3500 driver

https://bugs.freedesktop.org/show_bug.cgi?id=64351
2013-08-12 11:18:18 +03:00
Bastien Nocera
9e2f8b5e75 0.5.1 2013-08-11 17:53:21 +02:00
Bastien Nocera
c14ebd8b63 Add MS keyboard to the suspend blacklist
045e:00bb isn't a stand-alone fingerprint reader, but a keyboard
with a reader integrated.

https://bugs.freedesktop.org/show_bug.cgi?id=66659
2013-07-25 12:29:53 +02:00
Bastien Nocera
a6339a30ef Fix udev rules printing
The blacklisted devices weren't correctly checked for past the first
item, as we weren't using the right index to get the product ID
from the ID table.
2013-07-25 12:29:29 +02:00
Bastien Nocera
f3dd55815e lib: Use g_malloc0 instead of g_malloc+memset 2013-06-26 14:21:33 +02:00
Patrick Marlier
6d65bfcf80 lib: g_malloc never fails
Or rather, it never returns errors and aborts instead if
memory cannot be allocated, so remove code that handled
failures.

https://bugs.freedesktop.org/show_bug.cgi?id=57869
2013-06-26 14:18:40 +02:00
Jeremy Bicha
1acd647b29 build: Fix underlinking against glib
https://bugs.freedesktop.org/show_bug.cgi?id=63755
2013-06-26 14:14:49 +02:00
Vasily Khoruzhick
0e843ad6b3 build: fix autoreconf warnings
Replace AC_LANG_PROGRAM with AC_LANG_SOURCE and INCLUDES with AM_CFLAGS to fix
autoreconf warnings

https://bugs.freedesktop.org/show_bug.cgi?id=62748
2013-06-26 14:13:21 +02:00
Vasily Khoruzhick
7eafca7bab build: glib-2.28 or newer is a requirement
We're using g_slist_free_full which was introduced in glib-2.28

https://bugs.freedesktop.org/show_bug.cgi?id=59790
2013-01-30 17:52:54 +01:00
Vasily Khoruzhick
3b3679c900 upeke2: Add support for 147e:2020 ID
https://bugs.freedesktop.org/show_bug.cgi?id=59320
2013-01-13 19:02:52 +01:00
Vasily Khoruzhick
43eca622cd configure.ac: Use AC_CONFIG_HEADERS
AM_CONFIG_HEADER is obsolete, use AC_CONFIG_HEADERS instead of it.

https://bugs.freedesktop.org/show_bug.cgi?id=59320
2013-01-13 19:02:48 +01:00
Bastien Nocera
02509e1073 build: udev rules must be created when building from git
https://bugs.freedesktop.org/show_bug.cgi?id=59076
2013-01-07 12:36:45 +01:00
Timo Teräs
0b2d33c712 imgdev: fix cancelling of enrollment from stage_completed callback
Re-check device state after fpi_drvcb_enroll_stage_completed().
If enrollment was cancelled after non-completing stage, we must
not restart acquire as it would confuse the internal state machine.

https://bugs.freedesktop.org/show_bug.cgi?id=57829
2012-12-14 13:17:30 +01:00
Timo Teräs
7751fcb375 AUTHORS: Update
https://bugs.freedesktop.org/show_bug.cgi?id=57829
2012-12-14 13:17:24 +01:00
Timo Teräs
8a87ba448c uru4000: fix cancelling of imaging from error callback
Call error callback before resetting img_transfer to NULL. This
variable is internally used to detect if we are still in imaging
loop and the call to execute_state_change() needs to be postponed.
Since this is the final thing imaging_complete() we can't reset
img_transfer until just before this call.

https://bugs.freedesktop.org/show_bug.cgi?id=57829
2012-12-14 13:16:31 +01:00
Timo Teräs
7e1646c382 uru4000: fix race condition on waiting power up irq
It can come before we finish reading the status register on some
cases. Arm the irq handler early, and fix the state machine to
handle early irq properly.

https://bugs.freedesktop.org/show_bug.cgi?id=57834
2012-12-04 11:55:10 +01:00
Bastien Nocera
a5ec0b30e1 0.5.0 2012-12-03 16:28:00 +01:00
Bastien Nocera
29cf86a02e build: Fix configure-time warning
Due to missing quotes
2012-12-03 16:28:00 +01:00
Bastien Nocera
7892c943e6 build: Create .tar.xz distribution by default 2012-12-03 16:28:00 +01:00
Vasily Khoruzhick
a7d6b7c30a nbis: Fix crash in gen_initial_maps()
If the image is too small some coordinates can become negative.
Handle this to avoid memory corruption.

https://bugs.freedesktop.org/show_bug.cgi?id=57730
2012-12-03 15:36:25 +01:00
Bastien Nocera
258ac2d4da build: Build all the drivers by default 2012-12-01 15:10:13 +01:00
Vasily Khoruzhick
31cf7a9383 build: Add common routines to the dist
Fixes dist when aesX660 drivers are disabled from the build.

https://bugs.freedesktop.org/show_bug.cgi?id=57724
2012-12-01 15:04:47 +01:00
Vasily Khoruzhick
f335256cbe build: Don't build unneeded aesX660 routines
When neither of the AES drivers are built, no need to build the common
routines.

https://bugs.freedesktop.org/show_bug.cgi?id=57724
2012-12-01 15:02:59 +01:00
Vasily Khoruzhick
c02cb3083d AES-drivers: drop redudant type cast in g_slist_free_full call
https://bugs.freedesktop.org/show_bug.cgi?id=57688
2012-11-29 15:32:14 +01:00
Vasily Khoruzhick
2084724115 upektc: add support for Eikon Touch 300
https://bugs.freedesktop.org/show_bug.cgi?id=45197
2012-11-29 12:35:05 +01:00
Vasily Khoruzhick
59925d2027 Update AUTHORS file
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:52 +01:00
Vasily Khoruzhick
118c610e29 lib: add AES2660 driver
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:52 +01:00
Vasily Khoruzhick
313bfede77 lib: add AES1660 driver
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:52 +01:00
Vasily Khoruzhick
c1da647aed lib: add AES1660/AES2660 common routines
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:52 +01:00
Vasily Khoruzhick
22d204cc68 lib: Split fpi_im_resize factor into width/height
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:27 +01:00
Vasily Khoruzhick
bc497f1b26 aeslib: prevent integer overflow
AuthenTec devices send 4bpp images, but current code assumes 3bpp for
some reason.

https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:27 +01:00
Vasily Khoruzhick
8c5f2e6434 aes: unify image processing code for AuthenTec devices
Move overlap detection and assembling code into aeslib to prevent
code duplication

https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:59:22 +01:00
Vasily Khoruzhick
5b20892dd4 Thanks to Greg and Martin from AuthenTec
https://bugs.freedesktop.org/show_bug.cgi?id=57426
2012-11-29 09:51:55 +01:00
Colin Walters
b2a53a459c autogen.sh: Honor NOCONFIGURE=1
See http://people.gnome.org/~walters/docs/build-api.txt
2012-11-16 19:31:30 +01:00
Timo Teräs
45ac0eefb0 uru4000: Fix image capture error on ARM
http://www.mail-archive.com/fprint@lists.freedesktop.org/msg00294.html
2012-11-16 18:38:52 +01:00
Vasily Khoruzhick
ea6d5ba6d6 lib: Fix mess with driver IDs
ID is just a some magic number to make fingerprint from one scanner model
incompatible with another scanner model. Get rid of "magic", declare enum
and use it.

https://bugs.freedesktop.org/show_bug.cgi?id=56956
2012-11-16 17:57:47 +01:00
Vasily Khoruzhick
ed2c75842a upektc: Port to asynchronous model
https://bugs.freedesktop.org/show_bug.cgi?id=56955
2012-11-16 17:56:51 +01:00
Vasily Khoruzhick
b307dd1a6a aes2550: fix bug introduced by last commit
ssm->priv is not aesdev, but fp_img_dev

https://bugs.freedesktop.org/show_bug.cgi?id=56782
2012-11-16 17:46:27 +01:00
Vasily Khoruzhick
39902374ce aes2550: Harden against low finger pressure
Stop scan only after 3rd heartbeat message

https://bugs.freedesktop.org/show_bug.cgi?id=56782
2012-11-06 09:32:07 +01:00
Bastien Nocera
9e92d4cf2c examples: Fix compile-time warnings
A few signedness problems.
2012-11-06 09:30:40 +01:00
Vasily Khoruzhick
6b84c6664f AES1610: driver cleanup, part #2
Remove dead code

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-06 09:26:17 +01:00
Vasily Khoruzhick
f569d0bf44 AES1610: driver cleanup, part #1
Fix warnings reported by gcc

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-06 09:26:17 +01:00
Vasily Khoruzhick
1cfd14b7fe nbis: fix rest of warnings reported by gcc
https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-06 09:26:17 +01:00
Vasily Khoruzhick
5d32102efe nbis: prefix global variables with "g_"
It fixes a lot of warnings about shadowing global variable

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-06 09:26:17 +01:00
Bastien Nocera
9e10edd422 aes2501: Add year 2008 to the copyright.
https://bugs.freedesktop.org/show_bug.cgi?id=56715#c7
2012-11-05 19:52:46 +01:00
Vasily Khoruzhick
fecf6d6fe5 aes2501: Update copyright line
https://bugs.freedesktop.org/show_bug.cgi?id=56715
2012-11-05 19:51:19 +01:00
Vasily Khoruzhick
e32fa8cc38 aes2501: Improve image contrast
When scanning, check the histogram sum, and increase the
ADREFHI register value if the sum is too low, or decrease
it if it's too high.

https://bugs.freedesktop.org/show_bug.cgi?id=56715
2012-11-05 19:49:54 +01:00
Vasily Khoruzhick
d8aae30a67 aes2501: Harden against low finger pressure
Wait for 3 empty frames before stopping the scan

The driver used to stop the scan immediately after an empty frame
(by checking for hist sum == 0), but it is possible to get empty
frames in the middle of the scan due to low finger pressure.
Waiting for 3 empty frames stop the driver wrongly aborting the scan
too early.

https://bugs.freedesktop.org/show_bug.cgi?id=56715
2012-11-05 19:47:32 +01:00
Vasily Khoruzhick
84b97ea15b lib: Fix warning when debug logs are disabled
Fix warning in sync.c when debug logs are not enabled

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-05 19:24:55 +01:00
Vasily Khoruzhick
8f98743857 upeksonly: Fix build-time warnings
Fix warnings reported by gcc

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-05 19:24:44 +01:00
Vasily Khoruzhick
be29f27e25 upeke2: Fix build-time warnings
Fix warnings reported by gcc

https://bugs.freedesktop.org/show_bug.cgi?id=56439
2012-11-05 19:24:23 +01:00
Timo Teräs
d003f08855 lib: Add support for DigitalPersona URU4500
By adding native encryption support, rather than poking at
the firmware to disable it.

This also makes the URU4000B use native encryption.

https://bugs.freedesktop.org/show_bug.cgi?id=55351
2012-11-05 18:39:16 +01:00
Bastien Nocera
0f7ad00fc4 HACKING: Update with bugzilla link 2012-10-15 11:46:03 +02:00
Vasily Khoruzhick
83333bce3f lib: Add AES2550/AES2810 driver
Initial implementation of AES2550/AES2810 driver.
Does not support AES2810 crypto engine and external flash.

https://bugs.freedesktop.org/show_bug.cgi?id=50859
2012-10-11 15:24:14 +02:00
Bastien Nocera
132b178304 lib: Add driver names to the udev rules 2012-08-28 20:02:17 +01:00
Andrej Krutak
c3689665db lib: Add VFS300/VFS301 driver
https://bugs.freedesktop.org/show_bug.cgi?id=37574
2012-08-28 19:51:59 +01:00
Bastien Nocera
3d222ddda7 lib: Fix whitespace errors 2012-08-28 19:45:08 +01:00
Bastien Nocera
080c414ce9 build: Whitespace fixes in configure.ac 2012-08-28 19:45:08 +01:00
Vasily Khoruzhick
ff02115b0f lib: Fix global variables collision with libusb 2012-08-14 15:25:44 +01:00
Bastien Nocera
3b409c767c build: Allow disabling the update of udev rules
We can only create the udev rules file when we're not cross-compiling,
so allow people to disable updating the file when building from
tarballs.

If you run with --enable-udev-rules=no and the
60-fprint-autosuspend.rules doesn't exist, you're on your own.
2012-08-14 15:19:35 +01:00
Bastien Nocera
d05c69698c build: Fix distcheck'ing not working
We need to be able to override the udev rules directory for
distchecking to work.
2012-08-14 15:12:20 +01:00
Bastien Nocera
2d09b10a27 build: Include udev rules in tarball 2012-08-14 14:52:58 +01:00
Bastien Nocera
bc03d56186 build: Add list of drivers to include when distchecking 2012-08-14 14:51:23 +01:00
Bastien Nocera
96e7224a23 build: Fix distchecking of examples directory 2012-08-14 14:48:43 +01:00
Benedikt Morbach
0f4a75ff61 update udev rules dir location again
Instead of hardcoding whatever the new fashion is every few months, which might
even differ between distributions, just put the rules where udev says we should.

https://bugs.freedesktop.org/show_bug.cgi?id=50426
2012-05-28 14:12:55 +01:00
Bastien Nocera
dfff16f3e3 Don't print duplicate udev rules
https://bugs.freedesktop.org/show_bug.cgi?id=45513
2012-02-02 05:28:17 +00:00
Patrick Marlier
3d2e545264 Fix possible crash without a deactivate callback
We were checking for ->activate existing instead of ->deactivate.
2012-01-20 12:57:27 +00:00
Benedikt Morbach
c96fa32da4 Move udev rules to libdir
This moves the dir from /etc/udev/rules.d to /lib/udev/rules.d,
which is encouraged by upstream, as /etc is for user overrides only

https://bugs.freedesktop.org/show_bug.cgi?id=44507
2012-01-06 12:13:29 +00:00
Matthew Garrett
48ec64f683 Fix udev control path
Newer kernels uses power/control for USB suspend setup, not power/level.
Fix the udev rules generation.
2011-10-04 15:11:08 +01:00
368 changed files with 139642 additions and 22517 deletions

113
.ci/check-abi Executable file
View File

@@ -0,0 +1,113 @@
#!/usr/bin/python3
import argparse
import contextlib
import os
import shutil
import subprocess
import sys
def format_title(title):
box = {
'tl': '╔', 'tr': '╗', 'bl': '╚', 'br': '╝', 'h': '═', 'v': '║',
}
hline = box['h'] * (len(title) + 2)
return '\n'.join([
f"{box['tl']}{hline}{box['tr']}",
f"{box['v']} {title} {box['v']}",
f"{box['bl']}{hline}{box['br']}",
])
def rm_rf(path):
try:
shutil.rmtree(path)
except FileNotFoundError:
pass
def sanitize_path(name):
return name.replace('/', '-')
def get_current_revision():
revision = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
encoding='utf-8').strip()
if revision == 'HEAD':
# This is a detached HEAD, get the commit hash
revision = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')
return revision
@contextlib.contextmanager
def checkout_git_revision(revision):
current_revision = get_current_revision()
subprocess.check_call(['git', 'checkout', '-q', revision])
try:
yield
finally:
subprocess.check_call(['git', 'checkout', '-q', current_revision])
def build_install(revision):
build_dir = '_build'
dest_dir = os.path.abspath(sanitize_path(revision))
print(format_title(f'# Building and installing {revision} in {dest_dir}'),
end='\n\n', flush=True)
with checkout_git_revision(revision):
rm_rf(build_dir)
rm_rf(revision)
subprocess.check_call(['meson', build_dir,
'--prefix=/usr', '--libdir=lib',
'-Dx11-examples=false', '-Ddoc=false', '-Dgtk-examples=false'])
subprocess.check_call(['ninja', '-v', '-C', build_dir])
subprocess.check_call(['ninja', '-v', '-C', build_dir, 'install'],
env={'DESTDIR': dest_dir})
return dest_dir
def compare(old_tree, new_tree):
print(format_title(f'# Comparing the two ABIs'), end='\n\n', flush=True)
old_headers = os.path.join(old_tree, 'usr', 'include')
old_lib = os.path.join(old_tree, 'usr', 'lib', 'libfprint.so')
new_headers = os.path.join(new_tree, 'usr', 'include')
new_lib = os.path.join(new_tree, 'usr', 'lib', 'libfprint.so')
subprocess.check_call([
'abidiff', '--headers-dir1', old_headers, '--headers-dir2', new_headers,
'--drop-private-types', '--fail-no-debug-info', '--no-added-syms', old_lib, new_lib])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('old', help='the previous revision, considered the reference')
parser.add_argument('new', help='the new revision, to compare to the reference')
args = parser.parse_args()
if args.old == args.new:
print("Let's not waste time comparing something to itself")
sys.exit(0)
old_tree = build_install(args.old)
new_tree = build_install(args.new)
try:
compare(old_tree, new_tree)
except Exception:
sys.exit(1)
print(f'Hurray! {args.old} and {args.new} are ABI-compatible!')

10
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,10 @@
# The commits that did automated reformatting. You can ignore them
# during git-blame with `--ignore-rev` or `--ignore-revs-file`.
#
# $ git config --add 'blame.ignoreRevsFile' '.git-blame-ignore-revs'
#
d1fb1e26f3b79e54febc94496c1184763cf2af3d
e4f9935706be4c0e3253afe251c182019ff7ccef
65e602d8c72baa7020efb62d10bf28e621feb05d
4115ae7ced77d392ee11ea55212206d9404356f0

23
.gitignore vendored
View File

@@ -1,24 +1,3 @@
ltmain.sh
missing
stamp-h1
libtool
*.la
*.lo
*.o
*.swp
Makefile
Makefile.in
config.h*
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
.deps
.libs
compile
ChangeLog
_build

296
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,296 @@
include:
- local: '.gitlab-ci/libfprint-image-variables.yaml'
- local: '.gitlab-ci/libfprint-templates.yaml'
- project: 'freedesktop/ci-templates'
ref: master
file: '/templates/fedora.yml'
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/71e636e012ae0ab04c5e0fe40ca73ada91ae6bde/flatpak/flatpak_ci_initiative.yml'
default:
# Auto-retry jobs in case of infra failures
retry:
max: 1
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
variables:
extends: .libfprint_common_variables
FDO_DISTRIBUTION_TAG: $LIBFPRINT_IMAGE_TAG
FDO_DISTRIBUTION_VERSION: 41
FDO_UPSTREAM_REPO: "libfprint/$CI_PROJECT_NAME"
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_PIPELINE_SOURCE == 'push'
- if: $CI_PIPELINE_SOURCE == 'schedule'
- if: $CI_PROJECT_NAMESPACE == 'libfprint' && $LIBFPRINT_CI_ACTION != ''
stages:
- image-build
- check-source
- build
- test
- flatpak
- deploy
image: $FEDORA_IMAGE
.build_one_driver_template: &build_one_driver
script:
# Build with a driver that doesn't need imaging, or openssl
- meson setup _build --werror -Ddrivers=$driver
- meson compile -C _build
- rm -rf _build/
.build_template: &build
script:
# And build with everything
- meson setup _build --werror -Ddrivers=all
- meson compile -C _build
- meson install -C _build
.build_template: &check_abi
script:
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
.standard_job:
rules:
- when: on_success
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
build:
stage: build
extends:
- .standard_job
variables:
driver: virtual_image
<<: *build_one_driver
<<: *build
# <<: *check_abi
artifacts:
expose_as: "HTML Documentation"
paths:
- _build/doc/html
- _build/doc/html/index.html
expire_in: 1 week
test:
stage: test
extends:
- .standard_job
script:
- meson setup _build --werror -Ddrivers=all -Db_coverage=true
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
- ninja -C _build coverage || true
- cat _build/meson-logs/coverage.txt || true
artifacts:
reports:
junit: "_build/meson-logs/testlog.junit.xml"
coverage_report:
coverage_format: cobertura
path: _build/meson-logs/coverage.xml
expose_as: 'Coverage Report'
when: always
paths:
- _build/meson-logs
- _build/meson-logs/coveragereport/index.html
expire_in: 1 week
coverage: '/^TOTAL.*\s+(\d+\%)$/'
test_valgrind:
stage: test
extends:
- .standard_job
script:
- meson setup _build -Ddrivers=all
- meson compile -C _build
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
artifacts:
reports:
junit: "_build/meson-logs/testlog-valgrind.junit.xml"
expose_as: 'Valgrind test logs'
when: always
paths:
- _build/meson-logs
- _build/meson-logs/testlog-valgrind.txt
expire_in: 1 week
test_asan:
stage: test
extends:
- .standard_job
script:
- meson setup _build -Ddrivers=all -Db_sanitize=address,undefined
- meson test -C _build --print-errorlogs --no-stdsplit
artifacts:
reports:
junit: "_build/meson-logs/testlog.junit.xml"
expose_as: 'Sanitizers test logs'
when: always
paths:
- _build/meson-logs
- _build/meson-logs/testlog.txt
expire_in: 1 week
test_installed:
stage: test
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:
stage: test
extends:
- .standard_job
allow_failure: true
script:
- meson setup _build -Ddrivers=all
# Wrapper to add --status-bugs and disable malloc checker
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build
ninja -C _build scan-build
artifacts:
when: on_failure
paths:
- _build/meson-logs
expire_in: 1 week
test_indent:
stage: check-source
extends:
- .standard_job
script:
- scripts/uncrustify.sh
- git diff
- git diff-index --name-only --exit-code HEAD
rules:
- changes:
compare_to: 'refs/heads/master'
paths:
- '**/*.c'
- '**/*.h'
test_unsupported_list:
stage: check-source
extends:
- .standard_job
allow_failure: true
script:
- tests/hwdb-check-unsupported.py
flatpak:
stage: flatpak
extends: .flatpak@x86_64
variables:
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
FLATPAK_MODULE: "libfprint"
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:
- if: '$CI_PROJECT_PATH != "libfprint/libfprint"'
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
allow_failure: true
when: always
- if: '$CI_COMMIT_TAG'
allow_failure: true
when: always
# For any other (commit), allow manual run.
# This excludes MRs which would create a duplicate pipeline
- if: '$CI_COMMIT_BRANCH'
when: manual
allow_failure: true
- if: '$CI_MERGE_REQUEST_ID'
when: manual
allow_failure: true
# CONTAINERS creation stage
.container_fedora_build_base:
extends: .fdo.container-build@fedora
stage: image-build
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
# a list of packages to install
FDO_DISTRIBUTION_PACKAGES:
$LIBFPRINT_DEPENDENCIES
vala
libpcap-devel
libudev-devel
FDO_DISTRIBUTION_EXEC: |
$LIBFPRINT_EXEC
rules:
- when: never
.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
script:
- mkdir public
- mv _build/meson-logs/coveragereport public/coverage
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push"

View File

@@ -0,0 +1,2 @@
variables:
LIBFPRINT_IMAGE_TAG: v6

View File

@@ -0,0 +1,47 @@
# Bump image version on .gitlab-ci/libfprint-image-variables.yaml to trigger
# a rebuild on changes to this file
.libfprint_common_variables:
LIBFPRINT_DEPENDENCIES:
appstream
doxygen
dnf-plugins-core
flatpak-builder
gcc
gcc-c++
gcovr
git
glib2-devel
glibc-devel
gobject-introspection-devel
gnome-desktop-testing
gtk-doc
gtk3-devel
libabigail
libasan
libgusb-devel
libgudev-devel
libubsan
libX11-devel
libXv-devel
meson
openssl-devel
pixman-devel
python3-cairo
python3-gobject
systemd
umockdev
uncrustify
valgrind
clang-analyzer
diffutils
LIBFPRINT_EXEC: |
dnf -y install dnf-utils
debuginfo-install -y \
glib2 \
glibc \
libgusb \
libusb \
openssl \
pixman

4
.gitlab-ci/scan-build Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
# This wrapper just disables the malloc checker
exec /usr/bin/scan-build --status-bugs -disable-checker unix.Malloc --exclude "_build/meson-private" "$@"

View File

@@ -4,7 +4,8 @@ Copyright (C) 2006 Pavel Machek <pavel@suse.cz>
Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
Copyright (C) 2007 Cyrille Bagard
Copyright (C) 2007 Vasily Khoruzhick
Copyright (C) 2007-2008,2012 Vasily Khoruzhick <anarsoul@gmail.com>
Copyright (C) 2007 Jan-Michael Brummer <buzz2@gmx.de>
Copyright (C) 2007 Anthony Bretaudeau <wxcover@users.sourceforge.net>
Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com>
Copyright (C) 2012 Timo Teräs <timo.teras@iki.fi>

96
HACKING
View File

@@ -1,96 +0,0 @@
Copyright notices
=================
If you make a contribution substantial enough to add or update a copyright
notice on a file, such notice must be mirrored in the AUTHORS file. This is
to make it easy for people to comply to section 6 of the LGPL, which states
that a "work that uses the Library" must include copyright notices from
this library. By providing them all in one place, hopefully we save such
users some time.
USB
===
At the time of development, there are no known consumer fingerprint readers
which do not operate over the USB bus. Therefore the library is designed around
the fact that each driver drivers USB devices, and each device is a USB device.
If we were to ever support a non-USB device, some rearchitecting would be
needed, but this would not be a substantial task.
GLib
====
Although the library uses GLib internally, libfprint is designed to provide
a completely neutral interface to it's application users. So, the public
APIs should never return GLib data types or anything like that.
Two-faced-ness
==============
Like any decent library, this one is designed to provide a stable and
documented API to it's users: applications. Clear distinction is made between
data available internally in the library, and data/functions available to
the applications.
This library is confused a little by the fact that there is another 'interface'
at hand: the internal interface provided to drivers. So, we effectively end
up with 2 APIs:
1. The external-facing API for applications
2. The internal API for fingerprint drivers
Non-static functions which are intended for internal use only are prepended
with the "fpi_" prefix.
API stability
=============
No API stability has been promised to anyone: go wild, there's no issue with
breaking APIs at this point in time.
Portability
===========
libfprint is primarily written for Linux. However, I'm interested in
supporting efforts to port this to other operating systems too.
You should ensure code is portable wherever possible. Try and use GLib rather
than OS-specific features.
Endianness must be considered in all code. libfprint must support both big-
and little-endian systems.
Coding Style
============
This project follows Linux kernel coding style but with a tab width of 4.
Documentation
=============
All additions of public API functions must be accompanied with doxygen
comments.
All changes which potentially change the behaviour of the public API must
be reflected by updating the appropriate doxygen comments.
Contributing
============
Patches should be sent to the fprint mailing list detailed on the website.
A subscription is required.
Information about libfprint development repositories can be found here:
http://www.reactivated.net/fprint/Libfprint_development
If you're looking for ideas for things to work on, look at the TODO file or
grep the source code for FIXMEs.

73
HACKING.md Normal file
View File

@@ -0,0 +1,73 @@
# Contributing to libfprint
## GLib
Although the library uses GLib internally, libfprint is designed to provide
a completely neutral interface to its application users. So, the public
APIs should never return GLib data types.
## License clarification
Although this library's license could allow for shims that hook up into
proprietary blobs to add driver support for some unsupported devices, the
intent of the original authors, and of current maintainers of the library,
was for this license to allow _integration into_ proprietary stacks, not
_integration of_ proprietary code in the library.
As such, no code to integrate proprietary drivers will be accepted in libfprint
upstream. Proprietary drivers would make it impossible to debug problems in
libfprint, as we wouldn't know what the proprietary driver does behind the
library's back. The closed source nature of drivers is usually used to hide
parts of the hardware setup, such as encryption keys, or protocols, in order
to protect the hardware's integrity. Unfortunately, this is only [security through
obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity).
We however encourage potential contributors to take advantage of libfprint's
source availability to create such shims to make it easier to reverse-engineer
proprietary drivers in order to create new free software drivers, to the extent
permitted by local laws.
## Two-faced-ness
Like any decent library, this one is designed to provide a stable and
documented API to its users: applications. Clear distinction is made between
data available internally in the library, and data/functions available to
the applications.
This library is confused a little by the fact that there is another 'interface'
at hand: the internal interface provided to drivers. So, we effectively end
up with 2 APIs:
1. The [external-facing API for applications](libfprint/fprint.h)
2. The [internal API for fingerprint drivers](libfprint/drivers_api.h)
Non-static functions which are intended for internal use only are prepended
with the "fpi_" prefix.
## Documentation
All additions of public API functions must be accompanied with gtk-doc
comments.
All changes which potentially change the behaviour of the public API must
be reflected by updating the appropriate gtk-doc comments.
## Contributing
Patches should be sent as merge requests to the gitlab page:
https://gitlab.freedesktop.org/libfprint/libfprint/merge_requests
Drivers are not usually written by libfprint developers, but when they
are, we require:
- 3 stand-alone devices. Not in a laptop or another embedded device, as
space is scarce, unless the device has special integration with that
hardware.
- specifications of the protocol.
If you are an end-user, you can file a feature request with the "Driver Request"
tag on [libfprint's issue page](https://gitlab.freedesktop.org/libfprint/libfprint/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=Driver%20Request),
or subscribe to an existing feature request there.
If you are an enterprising hacker, please file a new merge request with
the driver patches integrated.

238
INSTALL
View File

@@ -1,234 +1,6 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
libfprint uses the Meson build system. See
http://mesonbuild.com/Quick-guide.html for details on how to
compile libfprint.
The "meson configure" command will give you a list of available
command-line options.

13
MAINTAINERS Normal file
View File

@@ -0,0 +1,13 @@
Current maintainers of libfprint are:
* Benjamin Berg <bberg@redhat.com>
* Marco Trevisan (Treviño) <mail@3v1n0.net>
Many drivers are not actively maintained and may not be fully functional.
We are happy to receive contributions, but the support we can give is
limitted unfortunately. For many drivers we may not even have test devices.
Maintained drivers are:
* synaptics:
Contributed and maintained by Synaptics Inc.
Contact: Vincent Huang <vincent.huang@tw.synaptics.com>

View File

@@ -1,22 +0,0 @@
AUTOMAKE_OPTIONS = dist-bzip2
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = THANKS TODO HACKING libfprint.pc.in
DISTCLEANFILES = ChangeLog libfprint.pc
SUBDIRS = libfprint doc
if BUILD_EXAMPLES
SUBDIRS += examples
endif
pkgconfigdir=$(libdir)/pkgconfig
pkgconfig_DATA=libfprint.pc
.PHONY: ChangeLog dist-up
ChangeLog:
git --git-dir $(top_srcdir)/.git log > ChangeLog || touch ChangeLog
dist-hook: ChangeLog
dist-up: dist
rsync $(distdir).tar.bz2 frs.sourceforge.net:uploads/

479
NEWS
View File

@@ -1,6 +1,485 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
2025-02-20: v1.94.9 release
Highlights:
* uru4000: Use OpenSSL to perform AES-ECB encryption, as per this libfprint
does not support on NSS, but on openssl (>= 3.0).
* goodixmoc: New PIDs 0x60C2, 0x689A
* synaptics: New PIDs 0x016C, 0x0174, 0x0107, 0x0108, 0x00C2, 0x00F0
* fpcmoc: New PID 0xC844
* focaltech_moc: New PIDs 0xA99A, 0xA57A, 0xA78A
* elanmoc: New PIDs 0x0C98, 0x0C9D, 0x0CA3
* elanspi: New PIDs 0x3128, 0x2766
* fp-device: Add FP_DEVICE_RETRY_TOO_FAST retry error
* data: AppStream meta info listing supported USB devices.
* fixed various memory issues in multiple devices
2024-09-03: v1.94.8 release
Highlights:
* build: Support building in non-linux unix environments (tested in FreeBSD)
* egismoc: New PIDs 0x0583, 0x0586, 0x0587.
* elanmoc: New PID 0x0C9F.
* fpcmoc: New PIDs 0x9524, 0x9544.
* goodixmoc: New PIDs 0x609A, 0x650A, 0x650C, 0x6512.
* realtek: New PID 0x5816.
* synaptics: New PIDs 0x00C4, 0x019D, 0x00C6.
* fpcmoc: fix incorrect immobile handling during enrollment.
* fpcmoc: fixed jumping to wrong state at end of custom enroll.
* egismoc: various code cleanups.
2024-02-20: v1.94.7 release
Highlights:
* 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
Highlights:
* Ship a simple script to create new CI tests using tshark
* Added CI tests for elan, uru4000, aes2501
* goodixmoc: Remove duplicate checking during enroll and let fprintd handle it
* uru4000: Fix USB transfer type
* synaptics: Support for new PIDs
* goodixmoc: Support for new PIDs
2021-08-20: v1.94.0 release
Highlights:
* Implement suspend/resume handling including USB wakeup configuration.
This requires writing the "persist" and "wakeup" sysfs attributes.
* Add simple temperature module to prevent devices from becoming too hot
* Add feature for continuous scanning
* New internal "critical section" API to simplify driver development
* elan: new PID 0x0c58
* elanmoc: Fixes for multi-user handling and FW changes
* virtual-device: Do not time out for SCAN command
2021-06-30: v1.92.1 release
Highlights:
* elanmoc: New driver for ELAN match-on-chip devices
* egis0570: New driver for some Egis Technology devices
* synaptics: Fix empty identify causing enroll issues
* elan: Support more PIDs
* misc: Architecture related bugfixes
2021-06-30: v1.92.0 release
Highlights:
* Support for SPI devices was added together with the elanspi driver
* Generate hwdb for autosuspend (which is now pulled by systemd)
* An API was added to clear the device storage.
Note: Devices may not implement the "list" API anymore.
* Device features can now be queried using a common API
New drivers:
* vfs7552
* nb1010
* elanspi
Driver changes:
* uru4000: Fix deactivation when unplugged unexpectedly
* goodixmoc: Correctly complete verify/identify after retry condition
* goodixmoc: Support power shield feature
* goodixmoc: Support new PIDs
* synaptics: Fix driver lockup when sequence counter overflows (#358)
* synaptics: Remove unnecessary device reset
* synaptics: Support new PIDs
* synaptics: Add clear_storage and remove list support
* synaptics: Fix initialization if the device is still busy when opening
* upeksonly: Fix double free in USB transfer callbacks
* elan: Support new PIDs
* vfs301: Fix leak of USB transfer
* uru4000: Silence warning happening during startup
Internal API changes:
* ssm: Add getter for the device
* ssm: Add cleanup state feature
* image-device: Allow overriding number of enroll stages
* context: Support udev based device discovery
* spi-transfer: Add SPI transfer helper routines
Other:
* Use pcap based USB replay for CI
* New virtual drivers for more advanced testing
* Ensure async operations are run in the thread local main context
* Disable drivers on big-endian unless they are verified to work
* Add missing gobject-introspection dependency
2020-12-01: v1.90.7 release
Highlights:
* vfs5011: Fix possible use-after-free
* goodixmoc: Add two new PIDs (0x63AC, 0x639C)
* goodixmoc: Support finger status API
* synaptics: Only identify within provided prints
* synaptics: Reject devices with old firmware during probe (#239)
2020-12-01: v1.90.6 release
This release is primarily a bugfix release for some older issues.
The major change is that fp_print_deserialize will now correctly return a
sunken reference rather than a floating one. Most API users will have
assumed this was true, and issues could happen at a later point.
If any API user worked around this libfprint bug, they will now leak the
returned print.
Highlights:
* Object reference management fixes for FpPrint and identify
* Fixed issues that caused problem on non-x86 machines (#236)
* Fix building with older GLib versions
* synaptics: Support PID 00e7
* goodix: Fix issue with long USB packages
2020-12-01: v1.90.5 release
The 1.90.4 release caused a major regression, as it included a USB hub in
UDEV the autosupend rule list.
Highlights:
* Remove USB hub from udev autosupend rules
* synaptics: Add PID 0x00c9 which is used in some HP laptops
2020-11-27: v1.90.4 release
This release contains a number of important bugfixes. On the feature side,
the USB hotplug support was improved. A lot of drivers received fixes and
improvements.
Highlights:
* Work around GUsb cancellation issue
* Redefine internal image device state machine for more robustness
* Add public finger-status reporting to FpDevice
* Rework device removal API to be convenient (#330)
* Enable powersave for unsupported USB devices
* Improvements to examples
* synaptics: Support identify operation
* synaptics: Fix possible crash when the interrupt transfer is resubmitted
* synaptics: Add support for PIDs 0x00f9, 0x00fc and 0x00c2
* elan: Add PID 0x0c4d to supported device list
* aes3k: Fix driver and add CI test (#306)
* uru4000: Fix reference counting of image transfer
* vfs301: Fix driver and add CI test (#320)
2020-06-08: v1.90.3 release
This release mostly contains support for a number of new match-on-chip
devices. Most notable is the addition of the new goodixmoc driver.
Currently the driver has the small caveat that we have no strategy to
garbage collect old prints yet (a simple strategy could be implemented
in fprintd).
Highlights:
* New goodixmoc driver supporting Goodix USB devices:
27C6:5840
27C6:6496
27C6:60A2
* Newly added support for Synaptics device:
06CB:00E9
06CB:00DF
* Fixed an issue with Synaptics devices sometimes not working at boot
* Fix issue with aes3k driver (#306)
2020-06-08: v1.90.2 release
This release contains a large amount of bug and regression fixes. These
are not listed explicitly, but affect the majority of drivers.
Highlights:
* A patch for nbis required for some sensors was accidentally dropped in
an earlier release. Users of these sensors/drivers (aes1610, aes2501,
aes2550, aes1660, aes2660, elan, upektc_img) need to re-enroll (#142).
2019-11-20: v1.90.1 release
This release fixes a lot of the regressions introduced in 1.90.0. Please note
that both the driver and external APIs have changed, as both the verify and
the identify functions now have early reporting mechanisms.
The soname for the library, as well as a number of file locations have also
changed. While this allows installation in parallel with the 1.0 version of
libfprint, we recommend installing only one, and migrating from version 1.0 to
version 2.0 alongside its main consumer (fprintd).
Only major changes are listed below. A lot of other cleanup work and small
fixes have also been merged.
* Library:
- Add support to run tests in gdb/valgrind
- Allow testing on all architectures
- Avoid image device AWAIT_FINGER_ON to deactivate state transitions
- Fix verify/identify error propagation to library user
- Correctly read image device information from class data
- Continue enroll after an image driver reported a retry error
- Change external API to allow reporting match results early
- A lot of new unit tests and integration tests have been added
* Drivers API
- Support variadic arguments in error functions
- Various re-definitions of ownership handling
- Add convenience API to change state after a timeout
- Add unit tests for all the drivers API
* Drivers:
- elan: Ensure correct deactivation of device
- uru4000: Fix IRQ handler registration and internal state handling
- uru4000: Fix control transfer request type
- synaptics: Ensure errors are only reported after finger removal
2019-11-20: v1.90.0 release
This release updates the core of the library to use GLib routines and Gio
style APIs. While the API both for library users remain similar in most
ways, there are some changes and all users will need to be ported.
A large motivation for the in-depth changes was the requirement to add
new API to support sensors that store the prints on the sensor. This
support is already used by the new synaptics driver, which will support
the current generation of the Prometheus MIS (match-in-sensor) chipset
by Synaptics (USB ID 06cb:00bd).
The current codebase is considered stable at this point. However, due to
the lack of wider testing it is only released as a 1.90.0 release which
can be considered a beta-release for 2.0.
With the rewrite, it is now also possible to support devices that are not
connected through USB (e.g. I2C). Another major improvement is that the
library has now a test suite, testing both the library core and allowing
tests of the drivers using umockdev.
2019-08-08: v1.0 release
* Library:
- Add guards to the public API and require GLib 2.50
- Deprecate print storage API
- Better documentation for fp_discover_devs()
- Remove unused internal fpi_timeout_cancel_for_dev()
- Remove state from fp_img_driver activate handler
- Bug fixes related to restarting a failed verification immediately
* Drivers:
- The Elan driver received a lot of bug fixes including a fix for a
hang when verifying prints with fprintd, quirks for some devices,
a memory leak fix and support for 04f3:0c42
- Fix a probable crash in all the AES drivers
- Add support for Lenovo Preferred Pro Keyboard (KUF1256) to vfs5011
- Prevent hang during enroll process in etes603 driver
- Fix possible integer overflow in uru4000
- Work-around SELinux AVC warnings when uru4000 driver starts
- Remove long-unmaintained and broken fdu2000 driver
* Tools/Examples:
- Fix examples not working due to an overly strict check
- Fix crash in GTK demo when there's no supported devices
- Disable GTK demo until we have a USB Flatpak portal
- Remove sleep() in enroll example which caused a crash in some drivers
- Add a simple storage implementation example
2018-12-14: v0.99.0 release
* Library:
- All the internal API for device driver writers is now covered by the
documentation and has been enhanced to make it easier to write drivers
- Update internal NBIS fingerprint data processing library to one that's
nearly 10 years newer
- Re-add accessor for minutia coordinates which was used in the very
old fprint_demo program, but also by our new GTK+ test program (see below)
- Fix a crash when too many minutiae were detected in a capture
* Drivers:
- Support more devices in the Elan driver, stability improvements
* Tools:
- Add a test GTK+ application that will eventually be used for testing
drivers without modifying the OS installed version. Note that this
application currently requires manually changing permissions of USB
devices, this will be fixed when the infrastructure exists to access
those devices without additional permissions, as a normal user.
2018-07-15: v0.8.2 release
* Drivers:
- Add USB ID for TNP Nano USB Fingerprint Reader
- Fix UPEKTS enrollment never finishing on some devices
* Library:
- Fix fp_get_pollfds() retval type, a small ABI change
- Downgrade fatal errors to run-time warnings, as a number of drivers
used to throw silent errors and we made them fatal. Those will now
be visible warnings, hopefully helping with fixing them.
2018-06-12: v0.8.1 release
- Brown paperbag release to install the udev rules file in the correct
directory if the udev pkg-config file doesn't have a trailing slash
2018-06-12: v0.8.0 release
- Port to meson as the build system
- Port documentation to gtk-doc
* Drivers:
- Add Elan driver
- Increase threshold to detect encryption on URU4000 devices
- Remove already replaced UPEKE2 driver
- Fix possible crash caused by vfs5011 when no lines were captured
* Library:
- Fix a number of memory and file descriptor leaks and warnings
- Make NSS (and URU4000) driver optional
- Fix assembling of frames for non-reverse and non reverse stripes
- Split internal private header to clarify drivers API
- Simplify logging system, now all the builds can be used to output
debug information
- Mark fp_dscv_print functions as deprecated
* Udev rules:
- Add some unsupported devices to the allowlist
2017-05-14: v0.7.0 release
* Drivers:
- Add VFS0050 driver
- Fix possible crash in AES3500 and AES4000
- Fix broken enrollment in VFS101
- Better verification with small sensor scanners
- Plenty of fixes in VFS5011
- Fix memory corruption in AES1610
- Improve calibration settings for AES1610
- Improve image assembling in upeksonly driver
- Autodetect whether image is encrypted in uru4k
* Library:
- NBIS: Remove false minutia at the edge of partial image
- Introduce routines to assemble image from lines (used in VFS5011 and upeksonly)
- Fix a bug that can cause driver state machine to enter into endless loop.
* Udev rules:
- Add driver name to the USB properties
* Plenty of build fixes
2015-02-03: v0.6.0 release
* Drivers:
- Reduce duplication between AES3500 and AES4000 drivers and
add support for AES3500 device
- Add support for UPEK 147e:2020 and Upek Eikon 2 devices
- Add EgisTec ES603 driver
- Add VFS5011 driver
- Always perform 5 scans for image enrollment
- Better verification with AES1660 driver
- Better verification for a number of AES drivers
* Library:
- Always use Pixman for image manipulation, gdk-pixbuf and ImageMagick
are not supported any more.
* Udev rules:
- Fix warning when USB hub or system does not support power management
2013-08-11: v0.5.1 release
* Drivers
- Add support for 147e:2020 to upeke2 driver
- Fix possible race condition, and cancellation in uru4000 driver
* Udev rules:
- Add Microsoft keyboard to the suspend denylist
* Plenty of build fixes
2012-12-03: v0.5.0 release
* Drivers:
- New VFS300/VFS301 driver
- New AES2550/AES2810 drivers
- New AES1660 driver
- New AES2660 driver
- New DigitalPersona URU4500 driver
- Avoid empty capture and improve image contrast in the
AES2501 and AES2550 drivers
- Update upektc driver, add support for Eikon Touch 300
- Fix UrU4000 image capture on ARM
* Library:
- Fix global variable collisions with libusb and other system headers
- Fix possible crash in NBIS image processing with some fingerprints
* Udev rules:
- Fix power control path for newer kernels
- Move udev rules to the correct directory
- Don't print duplicated udev rules
- Include udev rules in the tarball
- Allow disabling of udev rules for cross-compiling
- Add driver names in the generated rules
2011-04-18: v0.4.0 release
* Add support for Validity VFS101 (USB ID 138a:0001)
* Fix crasher when resizing a fingerprint image

41
README
View File

@@ -1,41 +0,0 @@
libfprint
=========
libfprint is part of the fprint project:
http://www.reactivated.net/fprint
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:
http://www.reactivated.net/fprint/Libfprint
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 http://reactivated.net/fprint/wiki/US_export_control

95
README.md Normal file
View File

@@ -0,0 +1,95 @@
<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

1
THANKS
View File

@@ -8,3 +8,4 @@ Toby Howard (University of Manchester)
Seemant Kulleen
Pavel Herrman
Bastien Nocera
Greg Kerr and Martin Konecny from AuthenTec Inc - hardware donations (AES2550 device), datasheets for AES2550 and AES2810

30
TODO
View File

@@ -1,30 +0,0 @@
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

View File

@@ -1,8 +0,0 @@
#!/bin/sh
libtoolize --copy --force || exit 1
aclocal || exit 1
autoheader || exit 1
autoconf || exit 1
automake -a -c || exit 1
./configure --enable-maintainer-mode --enable-examples-build \
--enable-x11-examples-build --enable-debug-log $*

3
code-of-conduct.md Normal file
View File

@@ -0,0 +1,3 @@
This project and its community follow the [Freedesktop.org code of conduct]
[Freedesktop.org code of conduct]: https://www.freedesktop.org/wiki/CodeOfConduct/

View File

@@ -1,288 +0,0 @@
AC_INIT([libfprint], [0.4.0])
AM_INIT_AUTOMAKE([1.11 dist-bzip2 no-dist-gzip check-news])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([libfprint/core.c])
AM_CONFIG_HEADER([config.h])
# Enable silent build when available (Automake 1.11)
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_PREREQ([2.50])
AC_PROG_CC
AC_PROG_LIBTOOL
AC_C_INLINE
AM_PROG_CC_C_O
AC_PROG_CXX
AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
# Library versioning
lt_major="0"
lt_revision="0"
lt_age="0"
AC_SUBST(lt_major)
AC_SUBST(lt_revision)
AC_SUBST(lt_age)
all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000 vfs101"
require_imaging='no'
require_aeslib='no'
enable_upeke2='no'
enable_upekts='no'
enable_upektc='no'
enable_upeksonly='no'
enable_vcom5s='no'
enable_uru4000='no'
enable_fdu2000='no'
enable_aes1610='no'
enable_aes2501='no'
enable_aes4000='no'
enable_vfs101='no'
AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers],
[List of drivers to enable])],
[drivers="$withval"],
[drivers="$all_drivers"])
for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do
case ${driver} in
upekts)
AC_DEFINE([ENABLE_UPEKTS], [], [Build UPEK TouchStrip driver])
enable_upekts="yes"
;;
upeke2)
AC_DEFINE([ENABLE_UPEKE2], [], [Build UPEK Eikon 2])
enable_upeke2="yes"
;;
upektc)
AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver])
enable_upektc="no"
# Driver not ported
;;
upeksonly)
AC_DEFINE([ENABLE_UPEKSONLY], [], [Build UPEK TouchStrip sensor-only driver])
enable_upeksonly="yes"
;;
uru4000)
AC_DEFINE([ENABLE_URU4000], [], [Build Digital Persona U.are.U 4000 driver])
enable_uru4000="yes"
;;
fdu2000)
AC_DEFINE([ENABLE_FDU2000], [], [Build Secugen FDU 2000 driver])
enable_fdu2000="no"
# Driver not ported
;;
vcom5s)
AC_DEFINE([ENABLE_VCOM5S], [], [Build Veridicom 5thSense driver])
enable_vcom5s="yes"
;;
aes2501)
AC_DEFINE([ENABLE_AES2501], [], [Build AuthenTec AES2501 driver])
require_aeslib="yes"
enable_aes2501="yes"
;;
aes1610)
AC_DEFINE([ENABLE_AES1610], [], [Build AuthenTec AES1610 driver])
require_aeslib="yes"
enable_aes1610="yes"
;;
aes4000)
AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver])
require_aeslib="yes"
require_imaging="yes"
enable_aes4000="yes"
;;
vfs101)
AC_DEFINE([ENABLE_VFS101], [], [Build Validity VFS101 driver])
enable_vfs101="yes"
;;
esac
done
AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" = "yes"])
AM_CONDITIONAL([ENABLE_UPEKE2], [test "$enable_upeke2" = "yes"])
#AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"])
AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" = "yes"])
AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"])
AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"])
AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" = "yes"])
AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"])
AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"])
AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"])
AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"])
AM_CONDITIONAL([ENABLE_VFS101], [test "$enable_vfs101" = "yes"])
PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1])
AC_SUBST(LIBUSB_CFLAGS)
AC_SUBST(LIBUSB_LIBS)
# check for OpenSSL's libcrypto
PKG_CHECK_MODULES(CRYPTO, nss)
AC_SUBST(CRYPTO_CFLAGS)
AC_SUBST(CRYPTO_LIBS)
PKG_CHECK_MODULES(GLIB, "glib-2.0")
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
imagemagick_found=no
gdkpixbuf_found=no
if test "$require_imaging" = "yes"; then
PKG_CHECK_MODULES(IMAGING, gthread-2.0 gdk-pixbuf-2.0, [gdkpixbuf_found=yes], [gdkpixbuf_found=no])
if test "$gdkpixbuf_found" != "yes"; then
PKG_CHECK_MODULES(IMAGING, ImageMagick, [imagemagick_found=yes], [imagemagick_found=no])
fi
fi
if test "$require_imaging" = "yes"; then
if test "$gdkpixbuf_found" != "yes" && test "$imagemagick_found" != "yes"; then
AC_MSG_ERROR([gdk-pixbuf or ImageMagick is required for imaging support])
fi
fi
AM_CONDITIONAL([REQUIRE_GDKPIXBUF], [test "$gdkpixbuf_found" = "yes"])
AM_CONDITIONAL([REQUIRE_IMAGEMAGICK], [test "$imagemagick_found" = "yes"])
AC_SUBST(IMAGING_CFLAGS)
AC_SUBST(IMAGING_LIBS)
# Examples build
AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build],
[build example applications (default n)])],
[build_examples=$enableval],
[build_examples='no'])
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# Examples build
AC_ARG_ENABLE([x11-examples-build], [AS_HELP_STRING([--enable-x11-examples-build],
[build X11 example applications (default n)])],
[build_x11_examples=$enableval],
[build_x11_examples='no'])
AM_CONDITIONAL([BUILD_X11_EXAMPLES], [test "x$build_x11_examples" != "xno"])
if test "x$build_x11_examples" != "xno"; then
# check for Xv extensions
# imported from Coriander
AC_DEFUN([AC_CHECK_XV],[
AC_SUBST(XV_CFLAGS)
AC_SUBST(XV_LIBS)
AC_MSG_CHECKING(for Xv extensions)
AC_TRY_COMPILE([
#include <X11/Xlib.h>
#include <X11/extensions/Xvlib.h>],[
int main(void) { (void) XvGetPortAttribute(0, 0, 0, 0); return 0; }
],xv=yes,xv=no);
AC_MSG_RESULT($xv)
if test x$xv = xyes; then
XV_LIBS="-lXv -lXext"
XV_CFLAGS=""
AC_DEFINE(HAVE_XV,1,[defined if XV video overlay is available])
else
AC_MSG_ERROR([XV is required for X11 examples])
fi
])
AC_CHECK_XV
fi
# Message logging
AC_ARG_ENABLE([log], [AS_HELP_STRING([--disable-log], [disable all logging])],
[log_enabled=$enableval],
[log_enabled='yes'])
if test "x$log_enabled" != "xno"; then
AC_DEFINE([ENABLE_LOGGING], 1, [Message logging])
fi
AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log],
[enable debug logging (default n)])],
[debug_log_enabled=$enableval],
[debug_log_enabled='no'])
if test "x$debug_log_enabled" != "xno"; then
AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Debug message logging])
fi
# Restore gnu89 inline semantics on gcc 4.3 and newer
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fgnu89-inline"
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="")
CFLAGS="$saved_cflags"
AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility])
AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow"
AC_SUBST(AM_CFLAGS)
if test "$require_imaging" = "yes"; then
if test x$gdkpixbuf_found != no; then
AC_MSG_NOTICE([** Using gdk-pixbuf for imaging])
else
AC_MSG_NOTICE([** Using ImageMagick for imaging])
fi
else
AC_MSG_NOTICE([ Imaging support disabled])
fi
if test x$enable_upekts != xno ; then
AC_MSG_NOTICE([** upekts driver enabled])
else
AC_MSG_NOTICE([ upekts driver disabled])
fi
if test x$enable_upeke2 != xno ; then
AC_MSG_NOTICE([** upeke2 driver enabled])
else
AC_MSG_NOTICE([ upeke2 driver disabled])
fi
if test x$enable_upektc != xno ; then
AC_MSG_NOTICE([** upektc driver enabled])
else
AC_MSG_NOTICE([ upektc driver disabled])
fi
if test x$enable_upeksonly != xno ; then
AC_MSG_NOTICE([** upeksonly driver enabled])
else
AC_MSG_NOTICE([ upeksonly driver disabled])
fi
if test x$enable_vcom5s != xno ; then
AC_MSG_NOTICE([** vcom5s driver enabled])
else
AC_MSG_NOTICE([ vcom5s driver disabled])
fi
if test x$enable_uru4000 != xno ; then
AC_MSG_NOTICE([** uru4000 driver enabled])
else
AC_MSG_NOTICE([ uru4000 driver disabled])
fi
if test x$enable_fdu2000 != xno ; then
AC_MSG_NOTICE([** fdu2000 driver enabled])
else
AC_MSG_NOTICE([ fdu2000 driver disabled])
fi
if test x$enable_aes1610 != xno ; then
AC_MSG_NOTICE([** aes1610 driver enabled])
else
AC_MSG_NOTICE([ aes1610 driver disabled])
fi
if test x$enable_aes2501 != xno ; then
AC_MSG_NOTICE([** aes2501 driver enabled])
else
AC_MSG_NOTICE([ aes2501 driver disabled])
fi
if test x$enable_aes4000 != xno ; then
AC_MSG_NOTICE([** aes4000 driver enabled])
else
AC_MSG_NOTICE([ aes4000 driver disabled])
fi
if test x$enable_vfs101 != xno ; then
AC_MSG_NOTICE([** vfs101 driver enabled])
else
AC_MSG_NOTICE([ vfs101 driver disabled])
fi
if test x$require_aeslib != xno ; then
AC_MSG_NOTICE([** aeslib helper functions enabled])
else
AC_MSG_NOTICE([ aeslib helper functions disabled])
fi
AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] [examples/Makefile] [doc/Makefile])
AC_OUTPUT

477
data/autosuspend.hwdb Normal file
View File

@@ -0,0 +1,477 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# This file has been generated using fprint-list-udev-hwdb with all drivers enabled
# Supported by libfprint driver aes1610
usb:v08FFp1600*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes1660
usb:v08FFp1660*
usb:v08FFp1680*
usb:v08FFp1681*
usb:v08FFp1682*
usb:v08FFp1683*
usb:v08FFp1684*
usb:v08FFp1685*
usb:v08FFp1686*
usb:v08FFp1687*
usb:v08FFp1688*
usb:v08FFp1689*
usb:v08FFp168A*
usb:v08FFp168B*
usb:v08FFp168C*
usb:v08FFp168D*
usb:v08FFp168E*
usb:v08FFp168F*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes2501
usb:v08FFp2500*
usb:v08FFp2580*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes2550
usb:v08FFp2550*
usb:v08FFp2810*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes2660
usb:v08FFp2660*
usb:v08FFp2680*
usb:v08FFp2681*
usb:v08FFp2682*
usb:v08FFp2683*
usb:v08FFp2684*
usb:v08FFp2685*
usb:v08FFp2686*
usb:v08FFp2687*
usb:v08FFp2688*
usb:v08FFp2689*
usb:v08FFp268A*
usb:v08FFp268B*
usb:v08FFp268C*
usb:v08FFp268D*
usb:v08FFp268E*
usb:v08FFp268F*
usb:v08FFp2691*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes3500
usb:v08FFp5731*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver aes4000
usb:v08FFp5501*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver egis0570
usb:v1C7Ap0570*
usb:v1C7Ap0571*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver egismoc
usb:v1C7Ap0582*
usb:v1C7Ap0583*
usb:v1C7Ap0586*
usb:v1C7Ap0587*
usb:v1C7Ap05A1*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver elan
usb:v04F3p0903*
usb:v04F3p0907*
usb:v04F3p0C01*
usb:v04F3p0C02*
usb:v04F3p0C03*
usb:v04F3p0C04*
usb:v04F3p0C05*
usb:v04F3p0C06*
usb:v04F3p0C07*
usb:v04F3p0C08*
usb:v04F3p0C09*
usb:v04F3p0C0A*
usb:v04F3p0C0B*
usb:v04F3p0C0C*
usb:v04F3p0C0D*
usb:v04F3p0C0E*
usb:v04F3p0C0F*
usb:v04F3p0C10*
usb:v04F3p0C11*
usb:v04F3p0C12*
usb:v04F3p0C13*
usb:v04F3p0C14*
usb:v04F3p0C15*
usb:v04F3p0C16*
usb:v04F3p0C17*
usb:v04F3p0C18*
usb:v04F3p0C19*
usb:v04F3p0C1A*
usb:v04F3p0C1B*
usb:v04F3p0C1C*
usb:v04F3p0C1D*
usb:v04F3p0C1E*
usb:v04F3p0C1F*
usb:v04F3p0C20*
usb:v04F3p0C21*
usb:v04F3p0C22*
usb:v04F3p0C23*
usb:v04F3p0C24*
usb:v04F3p0C25*
usb:v04F3p0C26*
usb:v04F3p0C27*
usb:v04F3p0C28*
usb:v04F3p0C29*
usb:v04F3p0C2A*
usb:v04F3p0C2B*
usb:v04F3p0C2C*
usb:v04F3p0C2D*
usb:v04F3p0C2E*
usb:v04F3p0C2F*
usb:v04F3p0C30*
usb:v04F3p0C31*
usb:v04F3p0C32*
usb:v04F3p0C33*
usb:v04F3p0C3D*
usb:v04F3p0C42*
usb:v04F3p0C4B*
usb:v04F3p0C4D*
usb:v04F3p0C4F*
usb:v04F3p0C63*
usb:v04F3p0C6E*
usb:v04F3p0C58*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver elanmoc
usb:v04F3p0C7D*
usb:v04F3p0C7E*
usb:v04F3p0C82*
usb:v04F3p0C88*
usb:v04F3p0C8C*
usb:v04F3p0C8D*
usb:v04F3p0C98*
usb:v04F3p0C99*
usb:v04F3p0C9D*
usb:v04F3p0C9F*
usb:v04F3p0CA3*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver etes603
usb:v1C7Ap0603*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver focaltech_moc
usb:v2808p9E48*
usb:v2808pD979*
usb:v2808pA959*
usb:v2808pA99A*
usb:v2808pA57A*
usb:v2808pA78A*
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*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver goodixmoc
usb:v27C6p5840*
usb:v27C6p6014*
usb:v27C6p6092*
usb:v27C6p6094*
usb:v27C6p609A*
usb:v27C6p609C*
usb:v27C6p60A2*
usb:v27C6p60A4*
usb:v27C6p60BC*
usb:v27C6p60C2*
usb:v27C6p6304*
usb:v27C6p631C*
usb:v27C6p633C*
usb:v27C6p634C*
usb:v27C6p6384*
usb:v27C6p639C*
usb:v27C6p63AC*
usb:v27C6p63BC*
usb:v27C6p63CC*
usb:v27C6p6496*
usb:v27C6p650A*
usb:v27C6p650C*
usb:v27C6p6582*
usb:v27C6p6584*
usb:v27C6p658C*
usb:v27C6p6592*
usb:v27C6p6594*
usb:v27C6p659A*
usb:v27C6p659C*
usb:v27C6p6A94*
usb:v27C6p6512*
usb:v27C6p689A*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver nb1010
usb:v298Dp1010*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver realtek
usb:v0BDAp5813*
usb:v0BDAp5816*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver synaptics
usb:v06CBp00BD*
usb:v06CBp00C2*
usb:v06CBp00C4*
usb:v06CBp00C6*
usb:v06CBp00DF*
usb:v06CBp00F0*
usb:v06CBp00F9*
usb:v06CBp00FC*
usb:v06CBp0100*
usb:v06CBp0103*
usb:v06CBp0104*
usb:v06CBp0106*
usb:v06CBp0107*
usb:v06CBp0108*
usb:v06CBp0109*
usb:v06CBp010A*
usb:v06CBp0123*
usb:v06CBp0124*
usb:v06CBp0126*
usb:v06CBp0129*
usb:v06CBp015F*
usb:v06CBp0168*
usb:v06CBp016C*
usb:v06CBp0173*
usb:v06CBp0174*
usb:v06CBp019D*
usb:v06CBp019F*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver upeksonly
usb:v147Ep2016*
usb:v147Ep1000*
usb:v147Ep1001*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver upektc
usb:v0483p2015*
usb:v0483p2017*
usb:v147Ep3001*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver upektc_img
usb:v147Ep2020*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver uru4000
usb:v045Ep00BC*
usb:v045Ep00BD*
usb:v045Ep00CA*
usb:v05BAp0007*
usb:v05BAp0008*
usb:v05BAp000A*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vcom5s
usb:v061Ap0110*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vfs0050
usb:v138Ap0050*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vfs101
usb:v138Ap0001*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vfs301
usb:v138Ap0005*
usb:v138Ap0008*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vfs5011
usb:v138Ap0010*
usb:v138Ap0011*
usb:v138Ap0015*
usb:v138Ap0017*
usb:v138Ap0018*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver vfs7552
usb:v138Ap0091*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Known unsupported devices
usb:v0A5Cp5802*
usb:v047Dp00F2*
usb:v047Dp8054*
usb:v047Dp8055*
usb:v04E8p730B*
usb:v04F3p036B*
usb:v04F3p0C00*
usb:v04F3p0C4C*
usb:v04F3p0C57*
usb:v04F3p0C5E*
usb:v04F3p0C5A*
usb:v04F3p0C60*
usb:v04F3p0C6C*
usb:v04F3p0C70*
usb:v04F3p0C72*
usb:v04F3p0C77*
usb:v04F3p0C7C*
usb:v04F3p0C7F*
usb:v04F3p0C80*
usb:v04F3p0C85*
usb:v04F3p0C90*
usb:v04F3p2706*
usb:v04F3p3032*
usb:v04F3p3057*
usb:v04F3p3104*
usb:v04F3p310D*
usb:v04F3p3128*
usb:v04F3p0C8A*
usb:v05BAp000E*
usb:v06CBp0051*
usb:v06CBp0081*
usb:v06CBp0088*
usb:v06CBp008A*
usb:v06CBp009A*
usb:v06CBp009B*
usb:v06CBp00A2*
usb:v06CBp00A8*
usb:v06CBp00B7*
usb:v06CBp00BB*
usb:v06CBp00BE*
usb:v06CBp00CB*
usb:v06CBp00C9*
usb:v06CBp00D8*
usb:v06CBp00DA*
usb:v06CBp00DC*
usb:v06CBp00E4*
usb:v06CBp00E7*
usb:v06CBp00E9*
usb:v06CBp00FD*
usb:v06CBp00FF*
usb:v0A5Cp5801*
usb:v0A5Cp5805*
usb:v0A5Cp5834*
usb:v0A5Cp5840*
usb:v0A5Cp5841*
usb:v0A5Cp5842*
usb:v0A5Cp5843*
usb:v0A5Cp5844*
usb:v0A5Cp5845*
usb:v0A5Cp5860*
usb:v0A5Cp5863*
usb:v0A5Cp5864*
usb:v0A5Cp5865*
usb:v0A5Cp5866*
usb:v0A5Cp5867*
usb:v0BDAp5812*
usb:v10A5p0007*
usb:v10A5p9200*
usb:v10A5p9800*
usb:v10A5pA120*
usb:v10A5pA900*
usb:v10A5pE340*
usb:v1188p9545*
usb:v138Ap0007*
usb:v138Ap003A*
usb:v138Ap003C*
usb:v138Ap003D*
usb:v138Ap003F*
usb:v138Ap0090*
usb:v138Ap0092*
usb:v138Ap0094*
usb:v138Ap0097*
usb:v138Ap009D*
usb:v138Ap00AB*
usb:v138Ap00A6*
usb:v147Ep1002*
usb:v1491p0088*
usb:v16D1p1027*
usb:v1C7Ap0300*
usb:v1C7Ap0575*
usb:v1C7Ap0576*
usb:v1C7Ap0584*
usb:v1C7Ap0577*
usb:v1C7Ap057E*
usb:v2541p0236*
usb:v2541p9711*
usb:v27C6p5042*
usb:v27C6p5110*
usb:v27C6p5117*
usb:v27C6p5120*
usb:v27C6p5125*
usb:v27C6p5201*
usb:v27C6p521D*
usb:v27C6p5301*
usb:v27C6p530C*
usb:v27C6p532D*
usb:v27C6p5335*
usb:v27C6p533C*
usb:v27C6p5381*
usb:v27C6p5385*
usb:v27C6p538C*
usb:v27C6p538D*
usb:v27C6p5395*
usb:v27C6p5503*
usb:v27C6p550A*
usb:v27C6p550C*
usb:v27C6p5584*
usb:v27C6p55A2*
usb:v27C6p55A4*
usb:v27C6p55B4*
usb:v27C6p5740*
usb:v27C6p5E0A*
usb:v27C6p581A*
usb:v27C6p589A*
usb:v27C6p5F10*
usb:v27C6p6382*
usb:v2808p9338*
usb:v2808p9348*
usb:v2808p93A9*
usb:v2808pA658*
usb:v2808pC652*
usb:v298Dp2020*
usb:v298Dp2033*
usb:v2DF0p0003*
usb:v3274p8012*
usb:v3538p0930*
ID_AUTOSUSPEND=1
ID_PERSIST=0

11
data/meson.build Normal file
View File

@@ -0,0 +1,11 @@
if udev_hwdb_dir != ''
# This file has to be updated using
# ninja -C <builddir> libfprint/sync-udev-hwdb
# Note that the unsupported device list needs to be manually synced from
# the wiki. See comment in libfprint/fprint-list-uev-hwdb.c
install_data('autosuspend.hwdb',
rename: '60-autosuspend-@0@.hwdb'.format(versioned_libname),
install_dir: udev_hwdb_dir,
)
endif

570
demo/gtk-libfprint-test.c Normal file
View File

@@ -0,0 +1,570 @@
/*
* Example libfprint GTK+ image capture program
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <gtk/gtk.h>
#include <libfprint/fprint.h>
struct _LibfprintDemo
{
GtkApplication parent;
};
G_DECLARE_FINAL_TYPE (LibfprintDemo, libfprint_demo, FP, DEMO, GtkApplication)
G_DEFINE_TYPE (LibfprintDemo, libfprint_demo, GTK_TYPE_APPLICATION)
typedef enum {
IMAGE_DISPLAY_NONE = 0,
IMAGE_DISPLAY_MINUTIAE = 1 << 0,
IMAGE_DISPLAY_BINARY = 1 << 1
} ImageDisplayFlags;
struct _LibfprintDemoWindow
{
GtkApplicationWindow parent_instance;
GtkWidget *header_bar;
GtkWidget *mode_stack;
GtkWidget *capture_button;
GtkWidget *cancel_button;
GtkWidget *capture_image;
GtkWidget *spinner;
GtkWidget *instructions;
GCancellable *cancellable;
gboolean opened;
FpDevice *dev;
FpImage *img;
ImageDisplayFlags img_flags;
};
G_DECLARE_FINAL_TYPE (LibfprintDemoWindow, libfprint_demo_window, FP, DEMO_WINDOW, GtkApplicationWindow)
G_DEFINE_TYPE (LibfprintDemoWindow, libfprint_demo_window, GTK_TYPE_APPLICATION_WINDOW)
typedef enum {
EMPTY_MODE,
NOIMAGING_MODE,
CAPTURE_MODE,
SPINNER_MODE,
ERROR_MODE,
RETRY_MODE
} LibfprintDemoMode;
static void libfprint_demo_set_mode (LibfprintDemoWindow *win,
LibfprintDemoMode mode);
static unsigned char *
img_to_rgbdata (const guint8 *imgdata,
int width,
int height)
{
int size = width * height;
guint8 *rgbdata = g_malloc (size * 3);
size_t i;
size_t rgb_offset = 0;
for (i = 0; i < size; i++)
{
guint8 pixel = imgdata[i];
rgbdata[rgb_offset++] = pixel;
rgbdata[rgb_offset++] = pixel;
rgbdata[rgb_offset++] = pixel;
}
return rgbdata;
}
static void
plot_minutiae (unsigned char *rgbdata,
int width,
int height,
GPtrArray *minutiae)
{
int i;
#define write_pixel(num) \
do \
{ \
rgbdata[((num) * 3)] = 0xff; \
rgbdata[((num) * 3) + 1] = 0; \
rgbdata[((num) * 3) + 2] = 0; \
} \
while(0)
for (i = 0; i < minutiae->len; i++)
{
struct fp_minutia *min = g_ptr_array_index (minutiae, i);
int x, y;
size_t pixel_offset;
fp_minutia_get_coords (min, &x, &y);
pixel_offset = (y * width) + x;
write_pixel (pixel_offset - 2);
write_pixel (pixel_offset - 1);
write_pixel (pixel_offset);
write_pixel (pixel_offset + 1);
write_pixel (pixel_offset + 2);
write_pixel (pixel_offset - (width * 2));
write_pixel (pixel_offset - (width * 1) - 1);
write_pixel (pixel_offset - (width * 1));
write_pixel (pixel_offset - (width * 1) + 1);
write_pixel (pixel_offset + (width * 1) - 1);
write_pixel (pixel_offset + (width * 1));
write_pixel (pixel_offset + (width * 1) + 1);
write_pixel (pixel_offset + (width * 2));
}
}
static GdkPixbuf *
img_to_pixbuf (FpImage *img,
ImageDisplayFlags flags)
{
int width;
int height;
const guint8 *data;
unsigned char *rgbdata;
width = fp_image_get_width (img);
height = fp_image_get_height (img);
if (flags & IMAGE_DISPLAY_BINARY)
data = fp_image_get_binarized (img, NULL);
else
data = fp_image_get_data (img, NULL);
if (!data)
return NULL;
rgbdata = img_to_rgbdata (data, width, height);
if (flags & IMAGE_DISPLAY_MINUTIAE)
{
GPtrArray *minutiae;
minutiae = fp_image_get_minutiae (img);
plot_minutiae (rgbdata, width, height, minutiae);
}
return gdk_pixbuf_new_from_data (rgbdata, GDK_COLORSPACE_RGB,
FALSE, 8, width, height,
width * 3, (GdkPixbufDestroyNotify) g_free,
NULL);
}
static void
update_image (LibfprintDemoWindow *win)
{
GdkPixbuf *pixbuf;
if (win->img == NULL)
{
gtk_image_clear (GTK_IMAGE (win->capture_image));
return;
}
g_debug ("Updating image, minutiae %s, binary mode %s",
win->img_flags & IMAGE_DISPLAY_MINUTIAE ? "shown" : "hidden",
win->img_flags & IMAGE_DISPLAY_BINARY ? "on" : "off");
pixbuf = img_to_pixbuf (win->img, win->img_flags);
gtk_image_set_from_pixbuf (GTK_IMAGE (win->capture_image), pixbuf);
g_object_unref (pixbuf);
}
static void
libfprint_demo_set_spinner_label (LibfprintDemoWindow *win,
const char *message)
{
char *label;
label = g_strdup_printf ("<b><span size=\"large\">%s</span></b>", message);
gtk_label_set_markup (GTK_LABEL (win->instructions), label);
g_free (label);
}
static void
libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
{
FpScanType scan_type;
const char *message;
scan_type = fp_device_get_scan_type (win->dev);
switch (scan_type)
{
case FP_SCAN_TYPE_PRESS:
message = "Place your finger on the fingerprint reader";
break;
case FP_SCAN_TYPE_SWIPE:
message = "Swipe your finger across the fingerprint reader";
break;
default:
g_assert_not_reached ();
}
libfprint_demo_set_spinner_label (win, message);
}
static void
dev_capture_start_cb (FpDevice *dev,
GAsyncResult *res,
void *user_data)
{
g_autoptr(GError) error = NULL;
LibfprintDemoWindow *win = user_data;
FpImage *image = NULL;
g_clear_object (&win->cancellable);
image = fp_device_capture_finish (dev, res, &error);
if (!image)
{
g_warning ("Error capturing data: %s", error->message);
if (error->domain == FP_DEVICE_RETRY ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
libfprint_demo_set_mode (win, RETRY_MODE);
else if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
libfprint_demo_set_mode (win, NOIMAGING_MODE);
else
libfprint_demo_set_mode (win, ERROR_MODE);
return;
}
g_clear_object (&win->img);
win->img = image;
update_image (win);
libfprint_demo_set_mode (win, CAPTURE_MODE);
}
static void
dev_start_capture (LibfprintDemoWindow *win)
{
libfprint_demo_set_capture_label (win);
fp_device_capture (win->dev, TRUE, win->cancellable, (GAsyncReadyCallback) dev_capture_start_cb, win);
}
static void
dev_open_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
{
LibfprintDemoWindow *win = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
libfprint_demo_set_mode (win, ERROR_MODE);
return;
}
dev_start_capture (win);
}
static void
activate_capture (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
LibfprintDemoWindow *win = user_data;
libfprint_demo_set_mode (win, SPINNER_MODE);
g_clear_pointer (&win->img, g_object_unref);
g_clear_object (&win->cancellable);
win->cancellable = g_cancellable_new ();
if (win->opened)
{
dev_start_capture (win);
return;
}
libfprint_demo_set_spinner_label (win, "Opening fingerprint reader");
win->opened = TRUE;
fp_device_open (win->dev, win->cancellable, (GAsyncReadyCallback) dev_open_cb, user_data);
}
static void
cancel_capture (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
LibfprintDemoWindow *win = user_data;
g_debug ("cancelling %p", win->cancellable);
if (win->cancellable)
g_cancellable_cancel (win->cancellable);
}
static void
activate_quit (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
GtkWidget *win;
GList *list, *next;
list = gtk_application_get_windows (app);
while (list)
{
win = list->data;
next = list->next;
gtk_widget_destroy (GTK_WIDGET (win));
list = next;
}
}
static void
activate_show_minutiae (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
LibfprintDemoWindow *win = user_data;
GVariant *state;
gboolean new_state;
state = g_action_get_state (G_ACTION (action));
new_state = !g_variant_get_boolean (state);
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
g_variant_unref (state);
if (new_state)
win->img_flags |= IMAGE_DISPLAY_MINUTIAE;
else
win->img_flags &= ~IMAGE_DISPLAY_MINUTIAE;
update_image (win);
}
static void
activate_show_binary (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
LibfprintDemoWindow *win = user_data;
GVariant *state;
gboolean new_state;
state = g_action_get_state (G_ACTION (action));
new_state = !g_variant_get_boolean (state);
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
g_variant_unref (state);
if (new_state)
win->img_flags |= IMAGE_DISPLAY_BINARY;
else
win->img_flags &= ~IMAGE_DISPLAY_BINARY;
update_image (win);
}
static void
change_show_minutiae_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
g_simple_action_set_state (action, state);
}
static void
change_show_binary_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
g_simple_action_set_state (action, state);
}
static GActionEntry app_entries[] = {
{ "quit", activate_quit, NULL, NULL, NULL },
};
static GActionEntry win_entries[] = {
{ "show-minutiae", activate_show_minutiae, NULL, "false", change_show_minutiae_state },
{ "show-binary", activate_show_binary, NULL, "false", change_show_binary_state },
{ "capture", activate_capture, NULL, NULL, NULL },
{ "cancel", cancel_capture, NULL, NULL, NULL }
};
static void
activate (GApplication *app)
{
LibfprintDemoWindow *window;
window = g_object_new (libfprint_demo_window_get_type (),
"application", app,
NULL);
gtk_widget_show (GTK_WIDGET (window));
}
static void
libfprint_demo_set_mode (LibfprintDemoWindow *win,
LibfprintDemoMode mode)
{
char *title;
switch (mode)
{
case EMPTY_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
gtk_widget_set_sensitive (win->capture_button, FALSE);
gtk_widget_set_sensitive (win->cancel_button, FALSE);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
break;
case NOIMAGING_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
gtk_widget_set_sensitive (win->capture_button, FALSE);
gtk_widget_set_sensitive (win->cancel_button, FALSE);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
break;
case CAPTURE_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "capture-mode");
gtk_widget_set_sensitive (win->capture_button, TRUE);
gtk_widget_set_sensitive (win->cancel_button, FALSE);
title = g_strdup_printf ("%s Test", fp_device_get_name (win->dev));
gtk_header_bar_set_title (GTK_HEADER_BAR (win->header_bar), title);
g_free (title);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
break;
case SPINNER_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
gtk_widget_set_sensitive (win->capture_button, FALSE);
gtk_widget_set_sensitive (win->cancel_button, TRUE);
gtk_spinner_start (GTK_SPINNER (win->spinner));
break;
case ERROR_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
gtk_widget_set_sensitive (win->capture_button, FALSE);
gtk_widget_set_sensitive (win->cancel_button, FALSE);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
break;
case RETRY_MODE:
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "retry-mode");
gtk_widget_set_sensitive (win->capture_button, TRUE);
gtk_widget_set_sensitive (win->cancel_button, FALSE);
gtk_spinner_stop (GTK_SPINNER (win->spinner));
break;
default:
g_assert_not_reached ();
}
}
static void
libfprint_demo_init (LibfprintDemo *app)
{
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
}
static void
libfprint_demo_class_init (LibfprintDemoClass *class)
{
GApplicationClass *app_class = G_APPLICATION_CLASS (class);
app_class->activate = activate;
}
static void
libfprint_demo_window_init (LibfprintDemoWindow *window)
{
FpContext *ctx;
GPtrArray *devices;
gtk_widget_init_template (GTK_WIDGET (window));
gtk_window_set_default_size (GTK_WINDOW (window), 700, 500);
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries, G_N_ELEMENTS (win_entries),
window);
ctx = fp_context_new ();
devices = fp_context_get_devices (ctx);
if (!devices)
{
libfprint_demo_set_mode (window, ERROR_MODE);
return;
}
/* Empty list? */
if (devices->len == 0)
{
libfprint_demo_set_mode (window, EMPTY_MODE);
return;
}
if (!fp_device_has_feature (g_ptr_array_index (devices, 0), FP_DEVICE_FEATURE_CAPTURE))
{
libfprint_demo_set_mode (window, NOIMAGING_MODE);
return;
}
window->dev = g_object_ref (g_ptr_array_index (devices, 0));
libfprint_demo_set_mode (window, CAPTURE_MODE);
}
static void
libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
gtk_widget_class_set_template_from_resource (widget_class, "/libfprint_demo/gtk-libfprint-test.ui");
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, header_bar);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, mode_stack);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, capture_button);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, cancel_button);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, capture_image);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, spinner);
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, instructions);
//FIXME setup dispose
}
int
main (int argc, char **argv)
{
GtkApplication *app;
app = GTK_APPLICATION (g_object_new (libfprint_demo_get_type (),
"application-id", "org.freedesktop.libfprint.Demo",
"flags", G_APPLICATION_FLAGS_NONE,
NULL));
return g_application_run (G_APPLICATION (app), 0, NULL);
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/libfprint_demo">
<file>gtk-libfprint-test.ui</file>
</gresource>
</gresources>

427
demo/gtk-libfprint-test.ui Normal file
View File

@@ -0,0 +1,427 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="LibfprintDemoWindow" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="default_width">500</property>
<property name="default_height">400</property>
<property name="show_menubar">False</property>
<child>
<object class="GtkStack" id="mode_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkGrid" id="spinner-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="row_spacing">12</property>
<child>
<object class="GtkSpinner" id="spinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">9</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="instructions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">9</property>
<property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;Please press finger on reader&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="name">spinner-mode</property>
<property name="title">spinner-mode</property>
</packing>
</child>
<child>
<object class="GtkAspectFrame" id="capture-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<property name="ratio">1.2999999523162842</property>
<child>
<object class="GtkImage" id="capture_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
<packing>
<property name="name">capture-mode</property>
<property name="title">capture-mode</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="retry-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="row_spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">9</property>
<property name="pixel_size">192</property>
<property name="icon_name">dialog-warning-symbolic</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">9</property>
<property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;Device reported a recoverable error. Please retry!&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="name">retry-mode</property>
<property name="title">retry-mode</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="noimaging-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="row_spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">9</property>
<property name="pixel_size">192</property>
<property name="icon_name">scanner-symbolic</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">9</property>
<property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;Fingerprint reader does not support capturing images&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Please connect a supported fingerprint reader and start the application again</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="name">noimaging-mode</property>
<property name="title">noimaging-mode</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="error-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="row_spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">9</property>
<property name="pixel_size">192</property>
<property name="icon_name">dialog-warning-symbolic</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">9</property>
<property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;An error occurred trying to access the fingerprint reader&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Please consult the debugging output before restarting the application</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="name">error-mode</property>
<property name="title">error-mode</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="empty-mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<property name="row_spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">9</property>
<property name="pixel_size">192</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">9</property>
<property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;No fingerprint readers found&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Please connect a supported fingerprint reader and start the application again</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="name">empty-mode</property>
<property name="title">empty-mode</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Fingerprint Reader Test</property>
<property name="subtitle">Capture test</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkMenuButton" id="option-menu-button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="menu-model">options-menu</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">open-menu-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="action_name">win.cancel</property>
<child>
<object class="GtkLabel" id="cancel_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Cancel</property>
<property name="use_underline">True</property>
</object>
</child>
<style>
<class name="text-button"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="capture_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="action_name">win.capture</property>
<child>
<object class="GtkLabel" id="capture_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Capture</property>
<property name="use_underline">True</property>
</object>
</child>
<style>
<class name="text-button"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</template>
<menu id="options-menu">
<section>
<item>
<attribute name="label" translatable="yes">Show Minutiae</attribute>
<attribute name="action">win.show-minutiae</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Show Binary</attribute>
<attribute name="action">win.show-binary</attribute>
</item>
</section>
</menu>
</interface>

30
demo/meson.build Normal file
View File

@@ -0,0 +1,30 @@
gtk_test_resources = gnome.compile_resources('gtk-test-resources',
'gtk-libfprint-test.gresource.xml',
source_dir : '.',
c_name : 'gtk_test')
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
datadir = join_paths(prefix, get_option('datadir'))
executable('gtk-libfprint-test',
[ 'gtk-libfprint-test.c', gtk_test_resources ],
dependencies: [
gtk_dep,
libfprint_dep,
],
c_args: '-DPACKAGE_VERSION="' + meson.project_version() + '"',
install: true,
install_dir: bindir)
appdata = 'org.freedesktop.libfprint.Demo.appdata.xml'
install_data(appdata,
install_dir: join_paths(datadir, 'metainfo'))
desktop = 'org.freedesktop.libfprint.Demo.desktop'
install_data(desktop,
install_dir: join_paths(datadir, 'applications'))
icon = 'org.freedesktop.libfprint.Demo.png'
install_data(icon,
install_dir: join_paths(datadir, 'icons'))

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.freedesktop.libfprint.Demo.desktop</id>
<name>Fingerprint Reader Demo</name>
<summary>Test fingerprint readers</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1+</project_license>
<description>
<p>
Fingerprint Reader Demo is a test application for the libfprint
fingerprint reader library. Its purpose is to test drivers, new and old,
in a sandbox, to make sure that the drivers and associated functions
work correctly.
</p>
<p>
Fingerprint Reader Demo does not modify the system, or replace integration
in desktop environments.
</p>
</description>
<url type="homepage">https://fprint.freedesktop.org</url>
<screenshots>
<screenshot type="default" width="1024" height="576">https://git.gnome.org/browse/totem/plain/data/appdata/ss-main.png</screenshot>
<screenshot width="1024" height="576">https://git.gnome.org/browse/totem/plain/data/appdata/ss-music-playlist.png</screenshot>
</screenshots>
<updatecontact>hadess@hadess.net</updatecontact>
<!-- Incorrect, but appstream-util won't validate without it -->
<translation type="gettext">libfprint</translation>
</component>

View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Name=Fingerprint Reader Demo
Comment=Test fingerprint readers
Keywords=finger;print;fingerprint;fprint;demo;driver;reader;
Exec=gtk-libfprint-test
Icon=org.freedesktop.libfprint.Demo
Terminal=false
Type=Application
Categories=GTK;GNOME;Development;System;
StartupNotify=true

View File

@@ -0,0 +1,74 @@
{
"app-id": "org.freedesktop.libfprint.Demo",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk-libfprint-test",
"finish-args": [
/* X11 + XShm access */
"--share=ipc", "--socket=fallback-x11",
/* Wayland access */
"--socket=wayland",
/* OpenGL access */
"--device=dri",
/* USB access */
"--device=all"
],
"cleanup": [ "/include", "/lib/pkgconfig/" ],
"modules": [
{
"name": "libusb",
"config-opts": [ "--disable-static" ],
"cleanup": [
"/lib/*.la",
"/lib/pkgconfig",
"/include"
],
"sources": [
{
"type": "archive",
"url": "https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26.tar.bz2",
"sha256": "12ce7a61fc9854d1d2a1ffe095f7b5fac19ddba095c259e6067a46500381b5a5"
}
],
"post-install": [
"install -Dm644 COPYING /app/share/licenses/libusb/COPYING"
]
},
{
"name": "libgusb",
"buildsystem": "meson",
"config-opts": [ "-Dtests=false", "-Dvapi=false", "-Ddocs=false" ],
"sources": [
{
"type": "archive",
"url": "https://github.com/hughsie/libgusb/releases/download/0.4.6/libgusb-0.4.6.tar.xz",
"sha256": "1b0422bdcd72183272ac42eec9398c5a0bc48a02f618fa3242c468cbbd003049"
}
]
},
{
"name": "gudev",
"buildsystem": "meson",
"config-opts": [ "-Dtests=disabled", "-Dintrospection=disabled", "-Dvapi=disabled" ],
"sources": [
{
"type": "archive",
"url": "https://download.gnome.org/sources/libgudev/238/libgudev-238.tar.xz",
"sha256": "61266ab1afc9d73dbc60a8b2af73e99d2fdff47d99544d085760e4fa667b5dd1"
}
]
},
{
"name": "libfprint",
"buildsystem": "meson",
"config-opts": [ "-Dudev_hwdb=disabled", "-Dudev_rules=disabled", "-Dgtk-examples=true", "-Ddrivers=all" ],
"sources": [
{
"type": "git",
"url": "https://gitlab.freedesktop.org/libfprint/libfprint.git"
}
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,10 +0,0 @@
EXTRA_DIST = doxygen.cfg
docs: doxygen.cfg
doxygen $^
docs-upload: docs
ln -s html api
ncftpput -f ~/.ncftp/reactivated -m -R httpdocs/fprint api/
rm -f api

113
doc/advanced-topics.xml Normal file
View File

@@ -0,0 +1,113 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="advanced-topics" xmlns:xi="http://www.w3.org/2003/XInclude">
<title>Advanced Topics</title>
<refsect2 id="compatibility">
<title>Device and print compatibility</title>
<para>
Moving off generic conceptual ideas and onto libfprint-specific
implementation details, here are some introductory notes regarding how
libfprint copes with compatibility of fingerprints.
</para>
<para>
libfprint deals with a whole variety of different fingerprint readers and
the design includes considerations of compatibility and interoperability
between multiple devices. Your application should also be prepared to
work with more than one type of fingerprint reader and should consider that
enrolled fingerprint X may not be compatible with the device the user has
plugged in today.
</para>
<para>
libfprint implements the principle that fingerprints from different devices
are not necessarily compatible. For example, different devices may see
significantly different areas of fingerprint surface, and comparing images
between the devices would be unreliable. Also, devices can stretch and
distort images in different ways.
</para>
<para>
libfprint also implements the principle that in some cases, fingerprints
<emphasis>are</emphasis> compatible between different devices. If you go and buy two
identical fingerprint readers, it seems logical that you should be able
to enroll on one and verify on another without problems.
</para>
<para>
libfprint takes a fairly simplistic approach to these issues. Internally,
fingerprint hardware is driven by individual drivers. libfprint enforces
that a fingerprint that came from a device backed by driver X is never
compared to a fingerprint that came from a device backed by driver Y.
</para>
<para>
Additionally, libfprint is designed for the situation where a single driver
may support a range of devices which differ in imaging or scanning
properties. For example, a driver may support two ranges of devices which
even though are programmed over the same interface, one device sees
substantially less of the finger flesh, therefore images from the two
device types should be incompatible despite being from the same driver. To
implement this, each driver assigns a <emphasis>device type</emphasis> to each device
that it detects based on its imaging characteristics. libfprint ensures that
two prints being compared have the same device type.
</para>
<para>
In summary, libfprint represents fingerprints in several internal structures
and each representation will offer you a way of determining the
<ulink url="#driver">driver</ulink> and <ulink url="#device-id">device ID</ulink> of the print in
question. Prints are only compatible if the driver ID <emphasis role="strong">and</emphasis> devtypes
match. libfprint does offer you some "is this print compatible?" helper
functions, so you don't have to worry about these details too much.
</para>
</refsect2>
<refsect2 id="driver">
<title>Driver</title>
<para>
Each driver is assigned a unique string identifier by the project maintainer.
</para>
<para>
The only reason you may be interested in retrieving the driver ID for a
driver is for the purpose of checking if some print data is compatible
with a device. libfprint uses the driver ID as one way of checking that
the print you are trying to verify is compatible with the device in
question - it ensures that enrollment data from one driver is never fed to
another. Note that libfprint does provide you with helper functions to
determine whether a print is compatible with a device, so under most
circumstances, you don't have to worry about driver IDs at all.
</para>
</refsect2>
<refsect2 id="device-id">
<title>Device ID</title>
<para>
Internally, the behind a device assigns a string identifier to the device
This cannot be used as a unique ID for a specific device as many devices
under the same range may share the same devtype. The device ID may even
be the same string in all cases. It is guaranteed to have a non-zero length
and be a valid file name. It defaults to "0".
</para>
<para>
The only reason you may be interested in retrieving the device ID for a
device is for the purpose of checking if some print data is compatible
with a device. libfprint uses the device ID as one way of checking that the
print you are verifying is compatible with the device in question - the
device ID must be equal. This effectively allows drivers to support more
than one type of device where the data from each one is not compatible with
the other. Note that libfprint does provide you with helper functions to
determine whether a print is compatible with a device, so under most
circumstances, you don't have to worry about devtypes at all.
</para>
</refsect2>
</chapter>

File diff suppressed because it is too large Load Diff

30
doc/getting-started.xml Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
<title>Getting Started</title>
<para>
libfprint includes several simple functional examples under the <computeroutput>examples/</computeroutput>
directory in the libfprint source distribution. Those are good starting
points.
</para>
<para>
Usually the first thing you want to do is determine which fingerprint
devices are present. This is done using the <ulink url="fp-context.html">FpContext</ulink> object.
</para>
<para>
Once you have found a device you would like to operate, you should open it.
Refer to <ulink url="fp-context.html">device operations</ulink>. This section also details enrollment,
image capture, and verification.
</para>
<para>
That should be enough to get you started, but do remember there are
documentation pages on other aspects of libfprint's API (see the modules
page).
</para>
</chapter>

106
doc/intro.xml Normal file
View File

@@ -0,0 +1,106 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="intro" xmlns:xi="http://www.w3.org/2003/XInclude">
<title>Introduction</title>
<para>
libfprint is an open source library to provide access to fingerprint
scanning devices. For more info, see the
<ulink url="https://fprint.freedesktop.org/">libfprint project homepage</ulink>.
</para>
<para>
This documentation is aimed at application developers who wish to integrate
fingerprint-related functionality into their software. libfprint has been
designed so that you only have to do this once by integrating your
software with libfprint, you'll be supporting all the fingerprint readers
that we have got our hands on. As such, the API is rather general (and
therefore hopefully easy to comprehend!), and does its best to hide the
technical details that required to operate the hardware.
</para>
<para>
This documentation is not aimed at developers wishing to develop and
contribute fingerprint device drivers to libfprint.
</para>
<para>
Feedback on this API and its associated documentation is appreciated. Was
anything unclear? Does anything seem unreasonably complicated? Is anything
missing? Let us know on the
<ulink url="https://lists.freedesktop.org/mailman/listinfo/fprint">mailing list</ulink>.
</para>
<refsect2 id="enrollment">
<title>Enrollment</title>
<para>
Before you dive into the API, it's worth introducing a couple of concepts.
</para>
<para>
The process of enrolling a finger is where you effectively scan your
finger for the purposes of teaching the system what your finger looks like.
This means that you scan your fingerprint, then the system processes it and
stores some data about your fingerprint to refer to later.
</para>
</refsect2>
<refsect2 id="verification">
<title>Verification</title>
<para>
Verification is what most people think of when they think about fingerprint
scanning. The process of verification is effectively performing a fresh
fingerprint scan, and then comparing that scan to a finger that was
previously enrolled.
</para>
<para>
As an example scenario, verification can be used to implement what people
would picture as fingerprint login (i.e. fingerprint replaces password).
For example:
</para>
<itemizedlist mark='dot'>
<listitem>
I enroll my fingerprint through some software that trusts I am who I say
I am. This is a prerequisite before I can perform fingerprint-based
login for my account.
</listitem>
<listitem>
Some time later, I want to login to my computer. I enter my username,
but instead of prompting me for a password, it asks me to scan my finger.
I scan my finger.
</listitem>
<listitem>
The system compares the finger I just scanned to the one that was
enrolled earlier. If the system decides that the fingerprints match,
I am successfully logged in. Otherwise, the system informs me that I am
not authorised to login as that user.
</listitem>
</itemizedlist>
</refsect2>
<refsect2 id="identification">
<title>Identification</title>
<para>
Identification is the process of comparing a freshly scanned fingerprint
to a <emphasis>collection</emphasis> of previously enrolled fingerprints. For example,
imagine there are 100 people in an organisation, and they all have enrolled
their fingerprints. One user walks up to a fingerprint scanner and scans
their finger. With <emphasis>no other knowledge</emphasis> of who that user might be,
the system examines their fingerprint, looks in the database, and determines
that the user is user number #61.
</para>
<para>
In other words, verification might be seen as a one-to-one fingerprint
comparison where you know the identity of the user that you wish to
authenticate, whereas identification is a one-to-many comparison where you
do not know the identity of the user that you wish to authenticate.
</para>
</refsect2>
</chapter>

View File

@@ -0,0 +1,310 @@
<SECTION>
<FILE>drivers_api</FILE>
</SECTION>
<SECTION>
<FILE>fp-context</FILE>
<TITLE>FpContext</TITLE>
FP_TYPE_CONTEXT
FpContextClass
fp_context_new
fp_context_enumerate
fp_context_get_devices
FpContext
</SECTION>
<SECTION>
<FILE>fp-device</FILE>
FP_TYPE_DEVICE
FP_DEVICE_RETRY
FP_DEVICE_ERROR
FpDeviceType
FpDeviceFeature
FpScanType
FpDeviceRetry
FpDeviceError
FpFingerStatusFlags
fp_device_retry_quark
fp_device_error_quark
FpEnrollProgress
FpMatchCb
fp_device_get_driver
fp_device_get_device_id
fp_device_get_name
fp_device_get_scan_type
fp_device_get_nr_enroll_stages
fp_device_get_finger_status
fp_device_get_features
fp_device_has_feature
fp_device_has_storage
fp_device_supports_identify
fp_device_supports_capture
fp_device_is_open
fp_device_open
fp_device_close
fp_device_enroll
fp_device_verify
fp_device_identify
fp_device_capture
fp_device_delete_print
fp_device_list_prints
fp_device_clear_storage
fp_device_suspend
fp_device_resume
fp_device_open_finish
fp_device_close_finish
fp_device_enroll_finish
fp_device_verify_finish
fp_device_identify_finish
fp_device_capture_finish
fp_device_delete_print_finish
fp_device_list_prints_finish
fp_device_clear_storage_finish
fp_device_suspend_finish
fp_device_resume_finish
fp_device_open_sync
fp_device_close_sync
fp_device_enroll_sync
fp_device_verify_sync
fp_device_identify_sync
fp_device_capture_sync
fp_device_delete_print_sync
fp_device_list_prints_sync
fp_device_clear_storage_sync
fp_device_suspend_sync
fp_device_resume_sync
FpDevice
</SECTION>
<SECTION>
<FILE>fp-image</FILE>
FP_TYPE_IMAGE
FpMinutia
fp_image_new
fp_image_get_width
fp_image_get_height
fp_image_get_ppmm
fp_image_get_minutiae
fp_image_detect_minutiae
fp_image_detect_minutiae_finish
fp_image_get_data
fp_image_get_binarized
fp_minutia_get_coords
FpImage
</SECTION>
<SECTION>
<FILE>fp-image-device</FILE>
FP_TYPE_IMAGE_DEVICE
FpImageDevice
</SECTION>
<SECTION>
<FILE>fp-print</FILE>
FP_TYPE_PRINT
FpFinger
FpPrint
fp_print_new
fp_print_get_driver
fp_print_get_device_id
fp_print_get_device_stored
fp_print_get_image
fp_print_get_finger
fp_print_get_username
fp_print_get_description
fp_print_get_enroll_date
fp_print_set_finger
fp_print_set_username
fp_print_set_description
fp_print_set_enroll_date
fp_print_compatible
fp_print_equal
fp_print_serialize
fp_print_deserialize
</SECTION>
<SECTION>
<FILE>fpi-assembling</FILE>
fpi_frame
fpi_frame_asmbl_ctx
fpi_do_movement_estimation
fpi_assemble_frames
fpi_line_asmbl_ctx
fpi_assemble_lines
</SECTION>
<SECTION>
<FILE>fpi-context</FILE>
fpi_get_driver_types
</SECTION>
<SECTION>
<FILE>fpi-device</FILE>
FpDeviceClass
FpTimeoutFunc
FpiDeviceAction
FpIdEntry
FpiDeviceUdevSubtypeFlags
fpi_device_get_usb_device
fpi_device_get_udev_data
fpi_device_get_virtual_env
fpi_device_get_current_action
fpi_device_retry_new
fpi_device_error_new
fpi_device_retry_new_msg
fpi_device_error_new_msg
fpi_device_get_driver_data
fpi_device_get_enroll_data
fpi_device_get_capture_data
fpi_device_get_verify_data
fpi_device_get_identify_data
fpi_device_get_delete_data
fpi_device_get_cancellable
fpi_device_action_is_cancelled
fpi_device_add_timeout
fpi_device_set_nr_enroll_stages
fpi_device_set_scan_type
fpi_device_update_features
fpi_device_critical_enter
fpi_device_critical_leave
fpi_device_remove
fpi_device_report_finger_status
fpi_device_report_finger_status_changes
fpi_device_action_error
fpi_device_probe_complete
fpi_device_open_complete
fpi_device_close_complete
fpi_device_enroll_complete
fpi_device_verify_complete
fpi_device_identify_complete
fpi_device_capture_complete
fpi_device_clear_storage_complete
fpi_device_delete_complete
fpi_device_list_complete
fpi_device_suspend_complete
fpi_device_resume_complete
fpi_device_enroll_progress
fpi_device_verify_report
fpi_device_identify_report
fpi_device_class_auto_initialize_features
</SECTION>
<SECTION>
<FILE>fpi-image</FILE>
FpiImageFlags
FpImage
fpi_std_sq_dev
fpi_mean_sq_diff_norm
fpi_image_resize
</SECTION>
<SECTION>
<FILE>fpi-image-device</FILE>
<TITLE>Internal FpImageDevice</TITLE>
FpiImageDeviceState
FpImageDeviceClass
fpi_image_device_session_error
fpi_image_device_open_complete
fpi_image_device_close_complete
fpi_image_device_activate_complete
fpi_image_device_deactivate_complete
fpi_image_device_report_finger_status
fpi_image_device_image_captured
fpi_image_device_retry_scan
fpi_image_device_set_bz3_threshold
</SECTION>
<SECTION>
<FILE>fpi-log</FILE>
fp_dbg
fp_info
fp_warn
fp_err
BUG_ON
BUG
</SECTION>
<SECTION>
<FILE>fpi-print</FILE>
FpiPrintType
FpiMatchResult
fpi_print_add_print
fpi_print_set_type
fpi_print_set_device_stored
fpi_print_add_from_image
fpi_print_bz3_match
fpi_print_generate_user_id
fpi_print_fill_from_user_id
</SECTION>
<SECTION>
<FILE>fpi-ssm</FILE>
FpiSsmCompletedCallback
FpiSsmHandlerCallback
fpi_ssm_new
fpi_ssm_new_full
fpi_ssm_free
fpi_ssm_start
fpi_ssm_start_subsm
fpi_ssm_next_state
fpi_ssm_next_state_delayed
fpi_ssm_jump_to_state
fpi_ssm_jump_to_state_delayed
fpi_ssm_cancel_delayed_state_change
fpi_ssm_mark_completed
fpi_ssm_mark_failed
fpi_ssm_set_data
fpi_ssm_get_data
fpi_ssm_get_device
fpi_ssm_get_error
fpi_ssm_dup_error
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_with_weak_pointer_cb
FpiSsm
</SECTION>
<SECTION>
<FILE>fpi-usb-transfer</FILE>
FPI_USB_ENDPOINT_IN
FPI_USB_ENDPOINT_OUT
FpiUsbTransferCallback
FpiTransferType
FpiUsbTransfer
fpi_usb_transfer_new
fpi_usb_transfer_ref
fpi_usb_transfer_unref
fpi_usb_transfer_set_short_error
fpi_usb_transfer_fill_bulk
fpi_usb_transfer_fill_bulk_full
fpi_usb_transfer_fill_control
fpi_usb_transfer_fill_interrupt
fpi_usb_transfer_fill_interrupt_full
fpi_usb_transfer_submit
fpi_usb_transfer_submit_sync
<SUBSECTION Standard>
FPI_TYPE_USB_TRANSFER
fpi_usb_transfer_get_type
</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>

8
doc/libfprint-2.types Normal file
View File

@@ -0,0 +1,8 @@
#include <fprint.h>
#include <fp-image-device.h>
fp_context_get_type
fp_device_get_type
fp_image_device_get_type
fp_image_get_type
fp_print_get_type

76
doc/libfprint-docs.xml Normal file
View File

@@ -0,0 +1,76 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
]>
<book id="index">
<bookinfo>
<title>libfprint Reference Manual</title>
<releaseinfo>
<para>This document is the API reference for the libfprint library.</para>
<para>
The latest version of libfprint, as well as the latest version of
this API reference, is <ulink role="online-location" url="https://fprint.freedesktop.org/libfprint-dev/">available online</ulink>.
</para>
</releaseinfo>
</bookinfo>
<part>
<title>Library Overview</title>
<xi:include href="intro.xml"/>
<xi:include href="advanced-topics.xml"/>
<xi:include href="getting-started.xml"/>
</part>
<part>
<title>Library API Documentation</title>
<xi:include href="xml/fp-context.xml"/>
<xi:include href="xml/fp-device.xml"/>
<xi:include href="xml/fp-image-device.xml"/>
<xi:include href="xml/fp-print.xml"/>
<xi:include href="xml/fp-image.xml"/>
</part>
<part>
<title>Writing Drivers</title>
<chapter id="driver-dev">
<title>Device methods for drivers</title>
<xi:include href="xml/fpi-device.xml"/>
<xi:include href="xml/fpi-image-device.xml"/>
</chapter>
<chapter id="driver-helpers">
<title>USB, SPI 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-ssm.xml"/>
<xi:include href="xml/fpi-log.xml"/>
</chapter>
<chapter id="driver-img">
<title>Image manipulation</title>
<xi:include href="xml/fpi-image.xml"/>
<xi:include href="xml/fpi-assembling.xml"/>
</chapter>
<chapter id="driver-print">
<title>Print handling</title>
<xi:include href="xml/fpi-print.xml"/>
</chapter>
<chapter id="driver-misc">
<title>Listing drivers</title>
<xi:include href="xml/fpi-context.xml"/>
</chapter>
</part>
<index id="api-index">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
<index id="deprecated-api-index" role="deprecated">
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
</book>

View File

@@ -0,0 +1,116 @@
<SECTION>
<INCLUDE>fprint.h</INCLUDE>
<FILE>context</FILE>
<TITLE>Device discovery and hotplugging</TITLE>
FP_TYPE_CONTEXT
FpContext
fp_context_new
fp_context_enumerate
fp_context_get_devices
</SECTION>
<SECTION>
<INCLUDE>fprint.h</INCLUDE>
<FILE>device</FILE>
<TITLE>Device</TITLE>
FP_TYPE_DEVICE
FpDevice
FpDeviceType
FpScanType
FpDeviceRetry
FpDeviceError
FP_DEVICE_ERROR
FP_DEVICE_RETRY
fp_device_get_driver
fp_device_get_device_id
fp_device_get_name
fp_device_get_scan_type
fp_device_open
fp_device_open_finish
fp_device_open_sync
fp_device_close
fp_device_close_finish
fp_device_close_sync
fp_device_enroll
fp_device_enroll_finish
fp_device_enroll_sync
fp_device_identify
fp_device_identify_finish
fp_device_identify_sync
fp_device_capture
fp_device_capture_finish
fp_device_capture_sync
fp_device_verify
fp_device_verify_finish
fp_device_verify_sync
_fp_device_get_cancellable
</SECTION>
<SECTION>
<INCLUDE>fprint.h</INCLUDE>
<FILE>print</FILE>
<TITLE>Fingerprint handling</TITLE>
FpPrint
fp_print_new
</SECTION>
<SECTION>
<INCLUDE>fprint.h</INCLUDE>
<FILE>image</FILE>
<TITLE>Image handling</TITLE>
FP_TYPE_IMAGE
FpImage
fp_image_new
fp_image_detect_minutiae
fp_image_detect_minutiae_finish
fp_image_device_new
fp_image_get_binarized
fp_image_get_data
fp_image_get_height
fp_image_get_minutiae
fp_image_get_ppmm
fp_image_get_width
</SECTION>
<SECTION>
<FILE>internal-image-device</FILE>
<INCLUDE>drivers_api.h</INCLUDE>
<TITLE>Base class for image devices</TITLE>
FpImageDevice
FpImageDeviceClass
FpiImageDeviceState
</SECTION>
<SECTION>
<FILE>internal-usb-transfers</FILE>
<INCLUDE>drivers_api.h</INCLUDE>
<TITLE>USB Transfers</TITLE>
FpUsbTransfer
fp_usb_transfer_fill_bulk
fp_usb_transfer_fill_bulk_full
fp_usb_transfer_fill_control
fp_usb_transfer_fill_interrupt
fp_usb_transfer_fill_interrupt_full
fp_usb_transfer_get_type
fp_usb_transfer_new
fp_usb_transfer_ref
fp_usb_transfer_set_short_error
fp_usb_transfer_submit
fp_usb_transfer_submit_sync
fp_usb_transfer_unref
FpUsbTransferCallback
FP_USB_ENDPOINT_IN
FP_USB_ENDPOINT_OUT
</SECTION>

41
doc/meson.build Normal file
View File

@@ -0,0 +1,41 @@
subdir('xml')
private_headers = [
'config.h',
'nbis-helpers.h',
'fprint.h',
# Subdirectories to ignore
'drivers',
'nbis',
]
html_images = [
]
content_files = [
'intro.xml'
]
expand_content_files = content_files
glib_prefix = dependency('glib-2.0').get_variable(pkgconfig: 'prefix')
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
gnome.gtkdoc(versioned_libname,
main_xml: 'libfprint-docs.xml',
src_dir: join_paths(meson.project_source_root(), 'libfprint'),
include_directories: include_directories('../libfprint'),
dependencies: libfprint_dep,
content_files: content_files,
expand_content_files: expand_content_files,
ignore_headers: private_headers,
gobject_typesfile: 'libfprint-2.types',
fixxref_args: [
'--html-dir=@0@'.format(docpath),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')),
],
html_assets: html_images,
install: true)

View File

@@ -0,0 +1,8 @@
<!ENTITY package "@PACKAGE@">
<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
<!ENTITY package_name "@PACKAGE_NAME@">
<!ENTITY package_string "@PACKAGE_STRING@">
<!ENTITY package_tarname "@PACKAGE_TARNAME@">
<!ENTITY package_url "@PACKAGE_URL@">
<!ENTITY package_version "@PACKAGE_VERSION@">
<!ENTITY package_api_version "@PACKAGE_API_VERSION@">

12
doc/xml/meson.build Normal file
View File

@@ -0,0 +1,12 @@
ent_conf = configuration_data()
ent_conf.set('PACKAGE', versioned_libname)
ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/libfprint/libfprint/issues')
ent_conf.set('PACKAGE_NAME', versioned_libname)
ent_conf.set('PACKAGE_STRING', versioned_libname)
ent_conf.set('PACKAGE_TARNAME', 'libfprint-' + meson.project_version())
ent_conf.set('PACKAGE_URL', 'https://fprint.freedesktop.org/')
ent_conf.set('PACKAGE_VERSION', meson.project_version())
ent_conf.set('PACKAGE_API_VERSION', '1.0')
configure_file(input: 'gtkdocentities.ent.in',
output: 'gtkdocentities.ent',
configuration: ent_conf)

View File

@@ -1,26 +0,0 @@
INCLUDES = -I$(top_srcdir)
noinst_PROGRAMS = verify_live enroll verify img_capture cpp-test
verify_live_SOURCES = verify_live.c
verify_live_LDADD = ../libfprint/libfprint.la
enroll_SOURCES = enroll.c
enroll_LDADD = ../libfprint/libfprint.la
verify_SOURCES = verify.c
verify_LDADD = ../libfprint/libfprint.la
img_capture_SOURCES = img_capture.c
img_capture_LDADD = ../libfprint/libfprint.la
cpp_test_SOURCES = cpp-test.cpp
cpp_test_LDADD = ../libfprint/libfprint.la
if BUILD_X11_EXAMPLES
noinst_PROGRAMS += img_capture_continuous
img_capture_continuous_CFLAGS = $(X_CFLAGS) $(XV_CFLAGS)
img_capture_continuous_SOURCES = img_capture_continuous.c
img_capture_continuous_LDADD = ../libfprint/libfprint.la $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS);
endif

208
examples/clear-storage.c Normal file
View File

@@ -0,0 +1,208 @@
/*
* Example storage clearing program, which deletes all the
* fingers which have been previously enrolled to disk.
* Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
* Copyright (C) 2024 Abhinav Baid <abhinavbaid@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-clear-storage"
#include <stdlib.h>
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _ClearStorageData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
int ret_value;
} ClearStorageData;
static void
clear_storage_data_free (ClearStorageData *clear_storage_data)
{
g_clear_handle_id (&clear_storage_data->sigint_handler, g_source_remove);
g_clear_object (&clear_storage_data->cancellable);
g_main_loop_unref (clear_storage_data->loop);
g_free (clear_storage_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClearStorageData, clear_storage_data_free)
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
g_autoptr(GError) error = NULL;
ClearStorageData *clear_storage_data = user_data;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (clear_storage_data->loop);
}
static void
clear_storage_quit (FpDevice *dev,
ClearStorageData *clear_storage_data)
{
if (!fp_device_is_open (dev))
{
g_main_loop_quit (clear_storage_data->loop);
return;
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
clear_storage_data);
}
static void
on_clear_storage_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
g_autoptr(GError) error = NULL;
ClearStorageData *clear_storage_data = user_data;
if (fp_device_clear_storage_finish (dev, res, &error))
{
if (!clear_saved_prints (dev, &error))
{
g_warning ("Clear saved prints from local storage failed: %s",
error->message);
clear_storage_data->ret_value = EXIT_FAILURE;
}
else
{
g_print ("Clear storage successful!\n");
clear_storage_data->ret_value = EXIT_SUCCESS;
}
clear_storage_quit (dev, clear_storage_data);
return;
}
g_warning ("Failed to clear storage: %s", error->message);
clear_storage_data->ret_value = EXIT_FAILURE;
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
{
g_autoptr(GError) clear_error = NULL;
if (clear_saved_prints (dev, &clear_error))
clear_storage_data->ret_value = EXIT_SUCCESS;
else
g_warning ("Clear saved prints from local storage failed: %s",
clear_error->message);
}
clear_storage_quit (dev, clear_storage_data);
}
static void
start_clear_storage (FpDevice *dev, ClearStorageData *clear_storage_data)
{
char buffer[20];
g_print ("Clear device storage? [Y/n]? ");
if (fgets (buffer, sizeof (buffer), stdin) &&
(buffer[0] == 'Y' || buffer[0] == 'y'))
{
fp_device_clear_storage (dev, clear_storage_data->cancellable,
(GAsyncReadyCallback) on_clear_storage_completed,
clear_storage_data);
return;
}
clear_storage_quit (dev, clear_storage_data);
}
static void
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
g_autoptr(GError) error = NULL;
ClearStorageData *clear_storage_data = user_data;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
clear_storage_quit (dev, clear_storage_data);
return;
}
g_print ("Opened device. ");
start_clear_storage (dev, clear_storage_data);
}
static gboolean
sigint_cb (void *user_data)
{
ClearStorageData *clear_storage_data = user_data;
g_cancellable_cancel (clear_storage_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(ClearStorageData) clear_storage_data = NULL;
GPtrArray *devices;
FpDevice *dev;
setenv ("G_MESSAGES_DEBUG", "all", 0);
setenv ("LIBUSB_DEBUG", "3", 0);
ctx = fp_context_new ();
devices = fp_context_get_devices (ctx);
if (!devices)
{
g_warning ("Impossible to get devices");
return EXIT_FAILURE;
}
dev = discover_device (devices);
if (!dev)
{
g_warning ("No devices detected.");
return EXIT_FAILURE;
}
clear_storage_data = g_new0 (ClearStorageData, 1);
clear_storage_data->ret_value = EXIT_FAILURE;
clear_storage_data->loop = g_main_loop_new (NULL, FALSE);
clear_storage_data->cancellable = g_cancellable_new ();
clear_storage_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
clear_storage_data,
NULL);
fp_device_open (dev, clear_storage_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
clear_storage_data);
g_main_loop_run (clear_storage_data->loop);
return clear_storage_data->ret_value;
}

View File

@@ -6,6 +6,10 @@
int main (int argc, char **argv)
{
fp_init ();
return 0;
FpContext *ctx;
ctx = fp_context_new ();
g_object_unref (ctx);
return 0;
}

View File

@@ -1,7 +1,8 @@
/*
* Example fingerprint enrollment program
* Enrolls your right index finger and saves the print to disk
* Enrolls your chosen finger and saves the print to disk
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 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
@@ -18,139 +19,254 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-enroll"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
#include "storage.h"
#include "utilities.h"
typedef struct _EnrollData
{
struct fp_dscv_dev *ddev = discovered_devs[0];
struct fp_driver *drv;
if (!ddev)
return NULL;
drv = fp_dscv_dev_get_driver(ddev);
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
return ddev;
}
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
gboolean update_fingerprint;
} EnrollData;
struct fp_print_data *enroll(struct fp_dev *dev) {
struct fp_print_data *enrolled_print = NULL;
int r;
printf("You will need to successfully scan your finger %d times to "
"complete the process.\n", fp_dev_get_nr_enroll_stages(dev));
do {
struct fp_img *img = NULL;
sleep(1);
printf("\nScan your finger now.\n");
r = fp_enroll_finger_img(dev, &enrolled_print, &img);
if (img) {
fp_img_save_to_file(img, "enrolled.pgm");
printf("Wrote scanned image to enrolled.pgm\n");
fp_img_free(img);
}
if (r < 0) {
printf("Enroll failed with error %d\n", r);
return NULL;
}
switch (r) {
case FP_ENROLL_COMPLETE:
printf("Enroll complete!\n");
break;
case FP_ENROLL_FAIL:
printf("Enroll failed, something wen't wrong :(\n");
return NULL;
case FP_ENROLL_PASS:
printf("Enroll stage passed. Yay!\n");
break;
case FP_ENROLL_RETRY:
printf("Didn't quite catch that. Please try again.\n");
break;
case FP_ENROLL_RETRY_TOO_SHORT:
printf("Your swipe was too short, please try again.\n");
break;
case FP_ENROLL_RETRY_CENTER_FINGER:
printf("Didn't catch that, please center your finger on the "
"sensor and try again.\n");
break;
case FP_ENROLL_RETRY_REMOVE_FINGER:
printf("Scan failed, please remove your finger and then try "
"again.\n");
break;
}
} while (r != FP_ENROLL_COMPLETE);
if (!enrolled_print) {
fprintf(stderr, "Enroll complete but no print?\n");
return NULL;
}
printf("Enrollment completed!\n\n");
return enrolled_print;
}
int main(void)
static void
enroll_data_free (EnrollData *enroll_data)
{
int r = 1;
struct fp_dscv_dev *ddev;
struct fp_dscv_dev **discovered_devs;
struct fp_dev *dev;
struct fp_print_data *data;
g_clear_handle_id (&enroll_data->sigint_handler, g_source_remove);
g_clear_object (&enroll_data->cancellable);
g_main_loop_unref (enroll_data->loop);
g_free (enroll_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
printf("This program will enroll your right index finger, "
"unconditionally overwriting any right-index print that was enrolled "
"previously. If you want to continue, press enter, otherwise hit "
"Ctrl+C\n");
getchar();
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
EnrollData *enroll_data = user_data;
r = fp_init();
if (r < 0) {
fprintf(stderr, "Failed to initialize libfprint\n");
exit(1);
}
fp_set_debug(3);
g_autoptr(GError) error = NULL;
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "Could not discover devices\n");
goto out;
}
fp_device_close_finish (dev, res, &error);
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "No devices detected.\n");
goto out;
}
if (error)
g_warning ("Failed closing device %s", error->message);
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "Could not open device.\n");
goto out;
}
printf("Opened device. It's now time to enroll your finger.\n\n");
data = enroll(dev);
if (!data)
goto out_close;
r = fp_print_data_save(data, RIGHT_INDEX);
if (r < 0)
fprintf(stderr, "Data save failed, code %d\n", r);
fp_print_data_free(data);
out_close:
fp_dev_close(dev);
out:
fp_exit();
return r;
g_main_loop_quit (enroll_data->loop);
}
static void
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
EnrollData *enroll_data = user_data;
g_autoptr(FpPrint) print = NULL;
g_autoptr(GError) error = NULL;
print = fp_device_enroll_finish (dev, res, &error);
if (!error)
{
enroll_data->ret_value = EXIT_SUCCESS;
if (fp_device_has_feature (dev, FP_DEVICE_FEATURE_STORAGE))
g_debug ("Device has storage, saving a print reference locally");
else
g_debug ("Device has not storage, saving print only locally");
/* 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
* containing the handle to the device print */
int r = print_data_save (print, enroll_data->finger,
enroll_data->update_fingerprint);
if (r < 0)
{
g_warning ("Data save failed, code %d", r);
enroll_data->ret_value = EXIT_FAILURE;
}
}
else
{
g_warning ("Enroll failed with error %s", error->message);
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
enroll_data);
}
static void
on_enroll_progress (FpDevice *device,
gint completed_stages,
FpPrint *print,
gpointer user_data,
GError *error)
{
if (error)
{
g_warning ("Enroll stage %d of %d failed with error %s",
completed_stages,
fp_device_get_nr_enroll_stages (device),
error->message);
return;
}
if (print && fp_print_get_image (print) &&
print_image_save (print, "enrolled.pgm"))
printf ("Wrote scanned image to enrolled.pgm\n");
printf ("Enroll stage %d of %d passed. Yay!\n", completed_stages,
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
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
EnrollData *enroll_data = user_data;
FpPrint *print_template;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
g_main_loop_quit (enroll_data->loop);
return;
}
printf ("Opened device.\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 "
"complete the process.\n\n", finger_to_string (enroll_data->finger),
fp_device_get_nr_enroll_stages (dev));
printf ("Scan your finger now.\n");
print_template = print_create_template (dev, enroll_data->finger, enroll_data->update_fingerprint);
fp_device_enroll (dev, print_template, enroll_data->cancellable,
on_enroll_progress, NULL, NULL,
(GAsyncReadyCallback) on_enroll_completed,
enroll_data);
}
static gboolean
sigint_cb (void *user_data)
{
EnrollData *enroll_data = user_data;
g_cancellable_cancel (enroll_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(EnrollData) enroll_data = NULL;
GPtrArray *devices;
FpDevice *dev;
FpFinger finger;
g_print ("This program will enroll the selected finger overwriting any print for the same"
" finger that was enrolled previously. Fingerprint updates without erasing old data"
" are possible on devices supporting that. Ctrl+C interrupts program execution.\n");
g_print ("Choose the finger to enroll:\n");
finger = finger_chooser ();
if (finger == FP_FINGER_UNKNOWN)
{
g_warning ("Unknown finger selected");
return EXIT_FAILURE;
}
setenv ("G_MESSAGES_DEBUG", "all", 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;
}
enroll_data = g_new0 (EnrollData, 1);
enroll_data->finger = finger;
enroll_data->ret_value = EXIT_FAILURE;
enroll_data->loop = g_main_loop_new (NULL, FALSE);
enroll_data->cancellable = g_cancellable_new ();
enroll_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
enroll_data,
NULL);
fp_device_open (dev, enroll_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
enroll_data);
g_main_loop_run (enroll_data->loop);
return enroll_data->ret_value;
}

321
examples/identify.c Normal file
View File

@@ -0,0 +1,321 @@
/*
* Example fingerprint verification program, which verifies the
* finger which has been previously enrolled to disk.
* Copyright (C) 2020 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
*/
#define FP_COMPONENT "example-identify"
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _IdentifyData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
int ret_value;
} IdentifyData;
static void
identify_data_free (IdentifyData *identify_data)
{
g_clear_handle_id (&identify_data->sigint_handler, g_source_remove);
g_clear_object (&identify_data->cancellable);
g_main_loop_unref (identify_data->loop);
g_free (identify_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdentifyData, identify_data_free)
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
IdentifyData *identify_data = user_data;
g_autoptr(GError) error = NULL;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (identify_data->loop);
}
static void
identify_quit (FpDevice *dev,
IdentifyData *identify_data)
{
if (!fp_device_is_open (dev))
{
g_main_loop_quit (identify_data->loop);
return;
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, identify_data);
}
static void start_identification (FpDevice *dev,
IdentifyData *identify_data);
static void
on_identify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
IdentifyData *identify_data = user_data;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) match = NULL;
g_autoptr(GError) error = NULL;
char buffer[20];
if (!fp_device_identify_finish (dev, res, &match, &print, &error))
{
g_warning ("Failed to identify print: %s", error->message);
identify_data->ret_value = EXIT_FAILURE;
if (error->domain != FP_DEVICE_RETRY)
{
identify_quit (dev, identify_data);
return;
}
}
g_print ("Identify again? [Y/n]? ");
if (fgets (buffer, sizeof (buffer), stdin) &&
(buffer[0] == 'Y' || buffer[0] == 'y' || buffer[0] == '\n'))
{
start_identification (dev, identify_data);
return;
}
identify_quit (dev, identify_data);
}
static FpPrint *
get_stored_print (FpDevice *dev, FpPrint *print)
{
g_autoptr(GPtrArray) gallery = gallery_data_load (dev);
guint index;
if (g_ptr_array_find_with_equal_func (gallery, print,
(GEqualFunc) fp_print_equal,
&index))
return g_object_ref (g_ptr_array_index (gallery, index));
return NULL;
}
static void
on_identify_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
gpointer user_data, GError *error)
{
IdentifyData *identify_data = user_data;
if (error)
{
g_warning ("Identify report: No finger matched, retry error reported: %s",
error->message);
return;
}
if (print && fp_print_get_image (print) &&
print_image_save (print, "identify.pgm"))
g_print ("Print image saved as identify.pgm\n");
if (match)
{
g_autoptr(FpPrint) matched_print = g_object_ref (match);
const GDate *date;
char date_str[128] = {};
identify_data->ret_value = EXIT_SUCCESS;
if (fp_print_get_device_stored (match))
{
FpPrint *stored_print = get_stored_print (dev, match);
if (stored_print)
matched_print = g_steal_pointer (&stored_print);
}
date = 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",
fp_print_get_enroll_date (matched_print));
else
strcpy (date_str, "<unknown>");
g_debug ("Identify report: device %s matched finger %s successfully "
"with print '%s', enrolled on date %s by user %s",
fp_device_get_name (dev),
finger_to_string (fp_print_get_finger (matched_print)),
fp_print_get_description (matched_print), date_str,
fp_print_get_username (matched_print));
g_print ("IDENTIFIED!\n");
}
else
{
g_debug ("Identification report: No finger matched");
g_print ("NOT IDENTIFIED!\n");
}
}
static void
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
{
IdentifyData *identify_data = user_data;
g_autoptr(GPtrArray) gallery = NULL;
g_autoptr(GError) error = NULL;
gallery = fp_device_list_prints_finish (dev, res, &error);
if (!error)
{
if (!gallery->len)
{
g_warning ("No prints saved on device");
identify_quit (dev, identify_data);
return;
}
g_debug ("Identifying with %u prints in gallery", gallery->len);
fp_device_identify (dev, gallery, identify_data->cancellable,
on_identify_cb, identify_data, NULL,
(GAsyncReadyCallback) on_identify_completed,
identify_data);
}
else
{
g_warning ("Loading prints failed with error %s", error->message);
identify_quit (dev, identify_data);
}
}
static void
start_identification (FpDevice *dev, IdentifyData *identify_data)
{
if (fp_device_has_feature (dev, FP_DEVICE_FEATURE_STORAGE))
{
g_print ("Creating finger template, using device storage...\n");
fp_device_list_prints (dev, NULL,
(GAsyncReadyCallback) on_list_completed,
identify_data);
}
else
{
g_autoptr(GPtrArray) gallery = gallery_data_load (dev);
if (!gallery)
{
identify_quit (dev, identify_data);
return;
}
g_print ("Gallery loaded. Time to identify!\n");
fp_device_identify (dev, gallery, identify_data->cancellable,
on_identify_cb, identify_data, NULL,
(GAsyncReadyCallback) on_identify_completed,
identify_data);
}
}
static void
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
IdentifyData *identify_data = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
identify_quit (dev, identify_data);
return;
}
g_print ("Opened device. ");
start_identification (dev, identify_data);
}
static gboolean
sigint_cb (void *user_data)
{
IdentifyData *identify_data = user_data;
g_cancellable_cancel (identify_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(IdentifyData) identify_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;
}
if (!fp_device_has_feature (dev, FP_DEVICE_FEATURE_IDENTIFY))
{
g_warning ("Device %s does not support identification.",
fp_device_get_name (dev));
return EXIT_FAILURE;
}
identify_data = g_new0 (IdentifyData, 1);
identify_data->ret_value = EXIT_FAILURE;
identify_data->loop = g_main_loop_new (NULL, FALSE);
identify_data->cancellable = g_cancellable_new ();
identify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
identify_data,
NULL);
fp_device_open (dev, identify_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
identify_data);
g_main_loop_run (identify_data->loop);
return identify_data->ret_value;
}

192
examples/img-capture.c Normal file
View File

@@ -0,0 +1,192 @@
/*
* Example fingerprint verification program, which verifies the
* finger which has been previously enrolled to disk.
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
* Copyright (C) 2020 Vasily Khoruzhick <anarsoul@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-capture"
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct CaptureData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
int ret_value;
const char *filename;
} CaptureData;
static void
capture_data_free (CaptureData *capture_data)
{
g_clear_handle_id (&capture_data->sigint_handler, g_source_remove);
g_clear_object (&capture_data->cancellable);
g_main_loop_unref (capture_data->loop);
g_free (capture_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (CaptureData, capture_data_free)
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
CaptureData *capture_data = user_data;
g_autoptr(GError) error = NULL;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (capture_data->loop);
}
static void
capture_quit (FpDevice *dev,
CaptureData *capture_data)
{
if (!fp_device_is_open (dev))
{
g_main_loop_quit (capture_data->loop);
return;
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, capture_data);
}
static void
dev_capture_cb (FpDevice *dev,
GAsyncResult *res,
void *user_data)
{
g_autoptr(GError) error = NULL;
CaptureData *capture_data = user_data;
FpImage *image = NULL;
g_clear_object (&capture_data->cancellable);
image = fp_device_capture_finish (dev, res, &error);
if (!image)
{
g_warning ("Error capturing data: %s", error->message);
capture_quit (dev, capture_data);
return;
}
save_image_to_pgm (image, capture_data->filename);
capture_quit (dev, capture_data);
}
static void
start_capture (FpDevice *dev, CaptureData *capture_data)
{
fp_device_capture (dev, TRUE, capture_data->cancellable, (GAsyncReadyCallback) dev_capture_cb, capture_data);
}
static void
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
CaptureData *capture_data = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
capture_quit (dev, capture_data);
return;
}
g_print ("Opened device. ");
start_capture (dev, capture_data);
}
static gboolean
sigint_cb (void *user_data)
{
CaptureData *capture_data = user_data;
g_cancellable_cancel (capture_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (int argc, const char *argv[])
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(CaptureData) capture_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;
}
if (!fp_device_has_feature (dev, FP_DEVICE_FEATURE_CAPTURE))
{
g_warning ("Device %s doesn't support capture",
fp_device_get_name (dev));
return EXIT_FAILURE;
}
capture_data = g_new0 (CaptureData, 1);
capture_data->ret_value = EXIT_FAILURE;
capture_data->loop = g_main_loop_new (NULL, FALSE);
capture_data->cancellable = g_cancellable_new ();
capture_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
capture_data,
NULL);
if (argc == 2)
capture_data->filename = argv[1];
else
capture_data->filename = "finger.pgm";
fp_device_open (dev, capture_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
capture_data);
g_main_loop_run (capture_data->loop);
return capture_data->ret_value;
}

View File

@@ -1,105 +0,0 @@
/*
* Example libfprint image capture program
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <libfprint/fprint.h>
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
{
struct fp_dscv_dev *ddev = discovered_devs[0];
struct fp_driver *drv;
if (!ddev)
return NULL;
drv = fp_dscv_dev_get_driver(ddev);
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
return ddev;
}
int main(void)
{
int r = 1;
struct fp_dscv_dev *ddev;
struct fp_dscv_dev **discovered_devs;
struct fp_dev *dev;
struct fp_img *img = NULL;
r = fp_init();
if (r < 0) {
fprintf(stderr, "Failed to initialize libfprint\n");
exit(1);
}
fp_set_debug(3);
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "Could not discover devices\n");
goto out;
}
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "No devices detected.\n");
goto out;
}
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "Could not open device.\n");
goto out;
}
if (!fp_dev_supports_imaging(dev)) {
fprintf(stderr, "this device does not have imaging capabilities.\n");
goto out_close;
}
printf("Opened device. It's now time to scan your finger.\n\n");
r = fp_dev_img_capture(dev, 0, &img);
if (r) {
fprintf(stderr, "image capture failed, code %d\n", r);
goto out_close;
}
r = fp_img_save_to_file(img, "finger.pgm");
if (r) {
fprintf(stderr, "img save failed, code %d\n", r);
goto out_close;
}
fp_img_standardize(img);
r = fp_img_save_to_file(img, "finger_standardized.pgm");
fp_img_free(img);
if (r) {
fprintf(stderr, "standardized img save failed, code %d\n", r);
goto out_close;
}
r = 0;
out_close:
fp_dev_close(dev);
out:
fp_exit();
return r;
}

View File

@@ -1,259 +0,0 @@
/*
* Example libfprint continuous image capture program
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libfprint/fprint.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/Xvlib.h>
#define FORMAT 0x32595559
static int adaptor = -1;
static unsigned char *framebuffer = NULL;
static Display *display = NULL;
static Window window=(Window)NULL;
static XvImage *xv_image = NULL;
static XvAdaptorInfo *info;
static GC gc;
static int connection = -1;
/* based on macro by Bart Nabbe */
#define GREY2YUV(grey, y, u, v)\
y = (9798*grey + 19235*grey + 3736*grey) / 32768;\
u = (-4784*grey - 9437*grey + 14221*grey) / 32768 + 128;\
v = (20218*grey - 16941*grey - 3277*grey) / 32768 + 128;\
y = y < 0 ? 0 : y;\
u = u < 0 ? 0 : u;\
v = v < 0 ? 0 : v;\
y = y > 255 ? 255 : y;\
u = u > 255 ? 255 : u;\
v = v > 255 ? 255 : v
static void grey2yuy2 (unsigned char *grey, unsigned char *YUV, int num) {
int i, j;
int y0, y1, u0, u1, v0, v1;
int gval;
for (i = 0, j = 0; i < num; i += 2, j += 4)
{
gval = grey[i];
GREY2YUV (gval, y0, u0 , v0);
gval = grey[i + 1];
GREY2YUV (gval, y1, u1 , v1);
YUV[j + 0] = y0;
YUV[j + 1] = (u0+u1)/2;
YUV[j + 2] = y1;
YUV[j + 3] = (v0+v1)/2;
}
}
static void display_frame(struct fp_img *img)
{
int width = fp_img_get_width(img);
int height = fp_img_get_height(img);
unsigned char *data = fp_img_get_data(img);
if (adaptor < 0)
return;
grey2yuy2(data, framebuffer, width * height);
xv_image = XvCreateImage(display, info[adaptor].base_id, FORMAT,
framebuffer, width, height);
XvPutImage(display, info[adaptor].base_id, window, gc, xv_image,
0, 0, width, height, 0, 0, width, height);
}
static void QueryXv()
{
int num_adaptors;
int num_formats;
XvImageFormatValues *formats = NULL;
int i,j;
char xv_name[5];
XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors,
&info);
for(i = 0; i < num_adaptors; i++) {
formats = XvListImageFormats(display, info[i].base_id,
&num_formats);
for(j = 0; j < num_formats; j++) {
xv_name[4] = 0;
memcpy(xv_name, &formats[j].id, 4);
if(formats[j].id == FORMAT) {
printf("using Xv format 0x%x %s %s\n",
formats[j].id, xv_name,
(formats[j].format==XvPacked)
? "packed" : "planar");
if (adaptor < 0)
adaptor = i;
}
}
}
XFree(formats);
if (adaptor < 0)
printf("No suitable Xv adaptor found\n");
}
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
{
struct fp_dscv_dev *ddev = discovered_devs[0];
struct fp_driver *drv;
if (!ddev)
return NULL;
drv = fp_dscv_dev_get_driver(ddev);
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
return ddev;
}
int main(void)
{
int r = 1;
XEvent xev;
XGCValues xgcv;
long background=0x010203;
struct fp_dscv_dev *ddev;
struct fp_dscv_dev **discovered_devs;
struct fp_dev *dev;
int img_width;
int img_height;
int standardize = 0;
r = fp_init();
if (r < 0) {
fprintf(stderr, "Failed to initialize libfprint\n");
exit(1);
}
fp_set_debug(3);
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "Could not discover devices\n");
goto out;
}
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "No devices detected.\n");
goto out;
}
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "Could not open device.\n");
goto out;
}
if (!fp_dev_supports_imaging(dev)) {
fprintf(stderr, "this device does not have imaging capabilities.\n");
goto out_close;
}
img_width = fp_dev_get_img_width(dev);
img_height = fp_dev_get_img_height(dev);
if (img_width <= 0 || img_height <= 0) {
fprintf(stderr, "this device returns images with variable dimensions,"
" this example does not support that.\n");
goto out_close;
}
framebuffer = malloc(img_width * img_height * 2);
if (!framebuffer)
goto out_close;
/* make the window */
display = XOpenDisplay(getenv("DISPLAY"));
if(display == NULL) {
fprintf(stderr,"Could not open display \"%s\"\n",
getenv("DISPLAY"));
goto out_close;
}
QueryXv();
if (adaptor < 0)
goto out_close;
window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0,
img_width, img_height, 0,
WhitePixel(display, DefaultScreen(display)), background);
XSelectInput(display, window, StructureNotifyMask | KeyPressMask);
XMapWindow(display, window);
connection = ConnectionNumber(display);
gc = XCreateGC(display, window, 0, &xgcv);
printf("Press S to toggle standardized mode, Q to quit\n");
while (1) { /* event loop */
struct fp_img *img;
r = fp_dev_img_capture(dev, 1, &img);
if (r) {
fprintf(stderr, "image capture failed, code %d\n", r);
goto out_close;
}
if (standardize)
fp_img_standardize(img);
display_frame(img);
fp_img_free(img);
XFlush(display);
while (XPending(display) > 0) {
XNextEvent(display, &xev);
if (xev.type != KeyPress)
continue;
switch (XKeycodeToKeysym(display, xev.xkey.keycode, 0)) {
case XK_q:
case XK_Q:
r = 0;
goto out_close;
break;
case XK_s:
case XK_S:
standardize = !standardize;
break;
}
} /* XPending */
}
r = 0;
out_close:
if (framebuffer)
free(framebuffer);
fp_dev_close(dev);
if ((void *) window != NULL)
XUnmapWindow(display, window);
if (display != NULL)
XFlush(display);
out:
fp_exit();
return r;
}

283
examples/manage-prints.c Normal file
View File

@@ -0,0 +1,283 @@
/*
* Example fingerprint device prints listing and deletion
* Enrolls your right index finger and saves the print to disk
* Copyright (C) 2019 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
*/
#define FP_COMPONENT "example-mange-prints"
#include <stdio.h>
#include <libfprint/fprint.h>
#include "utilities.h"
typedef struct _ListData
{
GMainLoop *loop;
int ret_value;
GList *to_delete;
gboolean any_failed;
} ListData;
static void
list_data_free (ListData *list_data)
{
g_list_free_full (list_data->to_delete, g_object_unref);
g_main_loop_unref (list_data->loop);
g_free (list_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ListData, list_data_free)
static void
on_device_closed (FpDevice *dev,
GAsyncResult *res,
gpointer user_data)
{
ListData *list_data = user_data;
g_autoptr(GError) error = NULL;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (list_data->loop);
}
typedef struct _DeleteData
{
ListData *list_data;
FpPrint *print;
} DeleteData;
static void
delete_data_free (DeleteData *delete_data)
{
g_object_unref (delete_data->print);
g_free (delete_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DeleteData, delete_data_free);
static void on_print_deleted (FpDevice *dev,
GAsyncResult *res,
gpointer user_data);
static void
delete_next_print (FpDevice *dev,
ListData *list_data)
{
FpPrint *print;
g_assert_nonnull (list_data->to_delete);
print = list_data->to_delete->data;
g_debug ("Deleting print %s", fp_print_get_description (print));
fp_device_delete_print (dev, print, NULL,
(GAsyncReadyCallback) on_print_deleted, list_data);
}
static void
on_print_deleted (FpDevice *dev,
GAsyncResult *res,
gpointer user_data)
{
ListData *list_data = user_data;
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) print = NULL;
GList *deleted_link;
fp_device_delete_print_finish (dev, res, &error);
deleted_link = list_data->to_delete;
print = g_steal_pointer (&deleted_link->data);
list_data->to_delete = g_list_delete_link (list_data->to_delete, deleted_link);
if (error)
{
g_warning ("Failed to remove print %s: %s",
fp_print_get_description (print), error->message);
list_data->any_failed = TRUE;
}
else
{
g_debug ("Deleted print %s from device", fp_print_get_description (print));
}
if (list_data->to_delete != NULL)
{
delete_next_print (dev, list_data);
}
else
{
if (!list_data->any_failed)
list_data->ret_value = EXIT_SUCCESS;
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
list_data);
}
}
static void
on_list_completed (FpDevice *dev,
GAsyncResult *res,
gpointer user_data)
{
ListData *list_data = user_data;
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(GError) error = NULL;
prints = fp_device_list_prints_finish (dev, res, &error);
if (!error)
{
guint i;
char buf[128];
g_print ("Device contains %u prints\n", prints->len);
for (i = 0; i < prints->len; ++i)
{
FpPrint * print = prints->pdata[i];
const GDate *date = fp_print_get_enroll_date (print);
g_print ("[%d] Print of %s finger for username %s", i + 1,
finger_to_string (fp_print_get_finger (print)),
fp_print_get_username (print));
if (date && g_date_valid (date))
{
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d\0", date);
g_print (", enrolled on %s", buf);
}
g_print (". Description: %s\n", fp_print_get_description (print));
}
if (prints->len)
{
gint64 idx = 0;
g_print ("Want to delete saved print? [<number>/A/n]\n> ");
if (fgets (buf, 3, stdin))
idx = g_ascii_strtoll (buf, NULL, 10);
if (idx > 0 && idx <= prints->len)
{
FpPrint *print = prints->pdata[idx - 1];
list_data->to_delete = g_list_prepend (list_data->to_delete,
g_object_ref (print));
}
else if (buf[0] == 'A')
{
for (i = 0; i < prints->len; ++i)
{
FpPrint *print = prints->pdata[i];
list_data->to_delete = g_list_prepend (list_data->to_delete,
g_object_ref (print));
}
}
else
{
if (buf[0] == 'n' || buf[0] == 'N')
list_data->ret_value = EXIT_SUCCESS;
else
g_warning ("Invalid finger selected");
}
}
if (list_data->to_delete)
delete_next_print (dev, list_data);
else
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
list_data);
}
else
{
g_warning ("Getting prints failed with error %s", error->message);
g_main_loop_quit (list_data->loop);
}
}
static void
on_device_opened (FpDevice *dev,
GAsyncResult *res,
gpointer user_data)
{
ListData *list_data = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
g_main_loop_quit (list_data->loop);
return;
}
if (!fp_device_has_feature (dev, FP_DEVICE_FEATURE_STORAGE))
{
g_warning ("Device %s doesn't support storage", fp_device_get_name (dev));
g_main_loop_quit (list_data->loop);
return;
}
fp_device_list_prints (dev, NULL,
(GAsyncReadyCallback) on_list_completed, list_data);
}
int
main (void)
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(ListData) list_data = NULL;
GPtrArray *devices;
FpDevice *dev;
g_print ("This program will report the prints saved in device\n");
setenv ("G_MESSAGES_DEBUG", "all", 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;
}
list_data = g_new0 (ListData, 1);
list_data->ret_value = EXIT_FAILURE;
list_data->loop = g_main_loop_new (NULL, FALSE);
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened, list_data);
g_main_loop_run (list_data->loop);
return list_data->ret_value;
}

29
examples/meson.build Normal file
View File

@@ -0,0 +1,29 @@
examples = [
'enroll',
'identify',
'img-capture',
'manage-prints',
'verify',
'clear-storage',
]
foreach example: examples
executable(example,
[ example + '.c', 'storage.c', 'utilities.c' ],
dependencies: [
libfprint_dep,
glib_dep,
],
)
endforeach
executable('cpp-test',
'cpp-test.cpp',
dependencies: libfprint_dep,
)
if installed_tests
install_subdir('prints',
install_dir: installed_tests_testdir)
endif

3
examples/prints/README Normal file
View File

@@ -0,0 +1,3 @@
These are example images from NIST and are in the public domain.
The PNG files have been generated by using the greyscale data as a mask.

BIN
examples/prints/arch.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
examples/prints/arch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
examples/prints/whorl.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
examples/prints/whorl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

111
examples/sendvirtimg.py Executable file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env python3
# This script can be used together with the virtual_imgdev to simulate an
# image based fingerprint reader.
#
# To use, set the FP_VIRTUAL_IMAGE environment variable for both the
# libfprint using program (e.g. fprintd) and this script.
#
# Usually this would work by adding it into the systemd unit file. The
# best way of doing so is to create
# /etc/systemd/system/fprintd.service.d/fprintd-test.conf
#
# [Service]
# RuntimeDirectory=fprint
# Environment=FP_VIRTUAL_IMAGE=/run/fprint/virtimg_sock
# Environment=G_MESSAGES_DEBUG=all
# ReadWritePaths=$RUNTIME_DIR
#
# After that run:
#
# systemctl daemon-reload
# systemctl restart fprintd.service
#
# You may also need to disable selinux.
#
# Then run this script with e.g.
# FP_VIRTUAL_IMAGE=/run/fprint/virtimg_sock ./sendvirtimg.py prints/whorl.png
import cairo
import sys
import os
import socket
import struct
if len(sys.argv) != 2:
sys.stderr.write('You need to pass a PNG with an alpha channel!\n')
sys.exit(1)
# Just copied from the C file, we could also use the introspection data for
# this. Also, most of them do *not* make any sense.
commands = {
'retry' : struct.pack('ii', -1, 0),
'retry-too-short' : struct.pack('ii', -1, 1),
'retry-center-finger' : struct.pack('ii', -1, 2),
'retry-remove-finger' : struct.pack('ii', -1, 3),
'error' : struct.pack('ii', -2, 0),
'error-not-supported' : struct.pack('ii', -2, 1),
'error-not-open' : struct.pack('ii', -2, 2),
'error-already-open' : struct.pack('ii', -2, 3),
'error-busy' : struct.pack('ii', -2, 4),
'error-proto' : struct.pack('ii', -2, 5),
'error-data-invalid' : struct.pack('ii', -2, 6),
'error-data-not-found' : struct.pack('ii', -2, 7),
'error-data-full' : struct.pack('ii', -2, 8),
}
if sys.argv[1] in commands:
command = commands[sys.argv[1]]
else:
png = cairo.ImageSurface.create_from_png(sys.argv[1])
# Cairo wants 4 byte aligned rows, so just add a few pixel if necessary
w = png.get_width()
h = png.get_height()
w = (w + 3) // 4 * 4
h = (h + 3) // 4 * 4
img = cairo.ImageSurface(cairo.Format.A8, w, h)
cr = cairo.Context(img)
cr.set_source_rgba(1, 1, 1, 1)
cr.paint()
cr.set_source_rgba(0, 0, 0, 0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.set_source_surface(png)
cr.paint()
mem = img.get_data()
mem = mem.tobytes()
assert len(mem) == img.get_width() * img.get_height()
command = struct.pack('ii', img.get_width(), img.get_height())
command += mem
def write_dbg_img():
dbg_img_rgb = cairo.ImageSurface(cairo.Format.RGB24, img.get_width(), img.get_height())
dbg_cr = cairo.Context(dbg_img_rgb)
dbg_cr.set_source_rgb(0, 0, 0)
dbg_cr.paint()
dbg_cr.set_source_rgb(1, 1, 1)
dbg_cr.mask_surface(img, 0, 0)
dbg_img_rgb.write_to_png('/tmp/test.png')
#write_dbg_img()
# Send image through socket
sockaddr = os.environ['FP_VIRTUAL_IMAGE']
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(sockaddr)
sock.sendall(command)

354
examples/storage.c Normal file
View File

@@ -0,0 +1,354 @@
/*
* Trivial storage driver for example programs
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2019-2020 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
*/
#define FP_COMPONENT "example-storage"
#include <libfprint/fprint.h>
#include <libfprint/fpi-compat.h>
#include "storage.h"
#include <errno.h>
#include <glib/gstdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define STORAGE_FILE "test-storage.variant"
static char *
get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
{
const char *driver;
const char *dev_id;
if (print)
{
driver = fp_print_get_driver (print);
dev_id = fp_print_get_device_id (print);
}
else
{
driver = fp_device_get_driver (dev);
dev_id = fp_device_get_device_id (dev);
}
return g_strdup_printf ("%s/%s/%x",
driver,
dev_id,
finger);
}
static char *
get_print_prefix_for_device (FpDevice *dev)
{
const char *driver;
const char *dev_id;
driver = fp_device_get_driver (dev);
dev_id = fp_device_get_device_id (dev);
return g_strdup_printf ("%s/%s/", driver, dev_id);
}
static GVariantDict *
load_data (void)
{
GVariantDict *res;
GVariant *var;
gchar *contents = NULL;
gsize length = 0;
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL))
{
g_warning ("Error loading storage, assuming it is empty");
return g_variant_dict_new (NULL);
}
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT,
contents,
length,
FALSE,
g_free,
contents);
res = g_variant_dict_new (var);
g_variant_unref (var);
return res;
}
static int
save_data (GVariant *data)
{
const gchar *contents = NULL;
gsize length;
length = g_variant_get_size (data);
contents = (gchar *) g_variant_get_data (data);
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL))
{
g_warning ("Error saving storage,!");
return -1;
}
g_variant_ref_sink (data);
g_variant_unref (data);
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
print_data_save (FpPrint *print, FpFinger finger, gboolean update_fingerprint)
{
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
g_autoptr(GError) error = NULL;
g_autoptr(GVariantDict) dict = NULL;
g_autofree guchar *data = NULL;
GVariant *val;
gsize size;
int res;
dict = load_data ();
fp_print_serialize (print, &data, &size, &error);
if (error)
{
g_warning ("Error serializing data: %s", error->message);
return -1;
}
val = g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), data, size, 1);
g_variant_dict_insert_value (dict, descr, val);
res = save_data (g_variant_dict_end (dict));
return res;
}
FpPrint *
print_data_load (FpDevice *dev, FpFinger finger)
{
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
g_autoptr(GVariant) val = NULL;
g_autoptr(GVariantDict) dict = NULL;
dict = load_data ();
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
if (val)
return load_print_from_data (val);
return NULL;
}
GPtrArray *
gallery_data_load (FpDevice *dev)
{
g_autoptr(GVariantDict) dict = NULL;
g_autoptr(GVariant) dict_variant = NULL;
g_autofree char *dev_prefix = NULL;
GPtrArray *gallery;
GVariantIter iter;
GVariant *value;
gchar *key;
gallery = g_ptr_array_new_with_free_func (g_object_unref);
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))
{
FpPrint *print;
const guchar *stored_data;
g_autoptr(GError) error = NULL;
gsize stored_len;
if (!g_str_has_prefix (key, dev_prefix))
continue;
stored_data = (const guchar *) g_variant_get_fixed_array (value, &stored_len, 1);
print = fp_print_deserialize (stored_data, stored_len, &error);
if (error)
{
g_warning ("Error deserializing data: %s", error->message);
continue;
}
g_ptr_array_add (gallery, print);
}
return gallery;
}
gboolean
clear_saved_prints (FpDevice *dev,
GError **error)
{
g_autoptr(GVariantDict) dict = NULL;
g_autoptr(GVariantDict) updated_dict = NULL;
g_autoptr(GVariant) dict_variant = NULL;
g_autofree char *dev_prefix = NULL;
GPtrArray *print_keys;
GVariantIter iter;
GVariant *value;
gchar *key;
print_keys = g_ptr_array_new_with_free_func (g_free);
dict = load_data ();
dict_variant = g_variant_dict_end (dict);
dev_prefix = get_print_prefix_for_device (dev);
g_variant_iter_init (&iter, dict_variant);
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
{
if (!g_str_has_prefix (key, dev_prefix))
continue;
g_ptr_array_add (print_keys, g_strdup (key));
}
if (!print_keys->len)
return TRUE;
updated_dict = load_data ();
for (guint i = 0; i < print_keys->len; ++i)
{
key = g_ptr_array_index (print_keys, i);
if (!g_variant_dict_remove (updated_dict, key))
{
g_warning ("Print '%s' key not found!", key);
continue;
}
g_debug ("Dropping print '%s' from gallery", key);
}
save_data (g_variant_dict_end (updated_dict));
return TRUE;
}
FpPrint *
print_create_template (FpDevice *dev, FpFinger finger, gboolean load_existing)
{
g_autoptr(GVariantDict) dict = NULL;
g_autoptr(GDateTime) datetime = 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;
gint year, month, day;
if (load_existing)
{
dict = load_data ();
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 ();
g_date_time_get_ymd (datetime, &year, &month, &day);
date = g_date_new_dmy (day, month, year);
fp_print_set_enroll_date (template, date);
return template;
}
gboolean
save_image_to_pgm (FpImage *img, const char *path)
{
FILE *fd = fopen (path, "w");
size_t write_size;
const guchar *data = fp_image_get_data (img, &write_size);
int r;
if (!fd)
{
g_warning ("could not open '%s' for writing: %d", path, errno);
return FALSE;
}
r = fprintf (fd, "P5 %d %d 255\n",
fp_image_get_width (img), fp_image_get_height (img));
if (r < 0)
{
fclose (fd);
g_critical ("pgm header write failed, error %d", r);
return FALSE;
}
r = fwrite (data, 1, write_size, fd);
if (r < write_size)
{
fclose (fd);
g_critical ("short write (%d)", r);
return FALSE;
}
fclose (fd);
g_debug ("written to '%s'", path);
return TRUE;
}
gboolean
print_image_save (FpPrint *print, const char *path)
{
FpImage *img = NULL;
g_return_val_if_fail (FP_IS_PRINT (print), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
img = fp_print_get_image (print);
if (img)
return save_image_to_pgm (img, path);
return FALSE;
}

40
examples/storage.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* Trivial storage driver for example programs
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.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 <glib.h>
#include <libfprint/fprint.h>
int print_data_save (FpPrint *print,
FpFinger finger,
gboolean update_fingerprint);
FpPrint * print_data_load (FpDevice *dev,
FpFinger finger);
GPtrArray * gallery_data_load (FpDevice *dev);
gboolean clear_saved_prints (FpDevice *dev,
GError **error);
FpPrint * print_create_template (FpDevice *dev,
FpFinger finger,
const gboolean load_existing);
gboolean print_image_save (FpPrint *print,
const char *path);
gboolean save_image_to_pgm (FpImage *img,
const char *path);

128
examples/utilities.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* Utilities for example programs
*
* Copyright (C) 2019 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
*/
#define FP_COMPONENT "example-utilities"
#include <libfprint/fprint.h>
#include <stdio.h>
#include "utilities.h"
FpDevice *
discover_device (GPtrArray * devices)
{
FpDevice *dev;
int i;
if (!devices->len)
return NULL;
if (devices->len == 1)
{
i = 0;
}
else
{
g_print ("Multiple devices found, choose one\n");
for (i = 0; i < devices->len; ++i)
{
dev = g_ptr_array_index (devices, i);
g_print ("[%d] %s (%s) - driver %s\n", i,
fp_device_get_device_id (dev), fp_device_get_name (dev),
fp_device_get_driver (dev));
}
g_print ("> ");
if (!scanf ("%d%*c", &i))
return NULL;
if (i < 0 || i >= devices->len)
return NULL;
}
dev = g_ptr_array_index (devices, i);
g_print ("Selected device %s (%s) claimed by %s driver\n",
fp_device_get_device_id (dev), fp_device_get_name (dev),
fp_device_get_driver (dev));
return dev;
}
const char *
finger_to_string (FpFinger finger)
{
switch (finger)
{
case FP_FINGER_LEFT_THUMB:
return "left thumb";
case FP_FINGER_LEFT_INDEX:
return "left index";
case FP_FINGER_LEFT_MIDDLE:
return "left middle";
case FP_FINGER_LEFT_RING:
return "left ring";
case FP_FINGER_LEFT_LITTLE:
return "left little";
case FP_FINGER_RIGHT_THUMB:
return "right thumb";
case FP_FINGER_RIGHT_INDEX:
return "right index";
case FP_FINGER_RIGHT_MIDDLE:
return "right middle";
case FP_FINGER_RIGHT_RING:
return "right ring";
case FP_FINGER_RIGHT_LITTLE:
return "right little";
case FP_FINGER_UNKNOWN:
default:
return "unknown";
}
}
FpFinger
finger_chooser (void)
{
int i = FP_FINGER_UNKNOWN;
for (i = FP_FINGER_FIRST; i <= FP_FINGER_LAST; ++i)
g_print (" [%d] %s\n", (i - FP_FINGER_FIRST), finger_to_string (i));
g_print ("> ");
if (!scanf ("%d%*c", &i))
return FP_FINGER_UNKNOWN;
i += FP_FINGER_FIRST;
if (i < FP_FINGER_FIRST || i > FP_FINGER_LAST)
return FP_FINGER_UNKNOWN;
return i;
}

25
examples/utilities.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* Trivial storage driver for example programs
*
* Copyright (C) 2019 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
*/
#pragma once
FpDevice * discover_device (GPtrArray *devices);
FpFinger finger_chooser (void);
const char * finger_to_string (FpFinger finger);

View File

@@ -1,7 +1,8 @@
/*
* Example fingerprint verification program, which verifies the right index
* Example fingerprint verification program, which verifies the
* finger which has been previously enrolled to disk.
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 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
@@ -18,128 +19,344 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-verify"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
#include "storage.h"
#include "utilities.h"
typedef struct _VerifyData
{
struct fp_dscv_dev *ddev = discovered_devs[0];
struct fp_driver *drv;
if (!ddev)
return NULL;
drv = fp_dscv_dev_get_driver(ddev);
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
return ddev;
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
} VerifyData;
static void
verify_data_free (VerifyData *verify_data)
{
g_clear_handle_id (&verify_data->sigint_handler, g_source_remove);
g_clear_object (&verify_data->cancellable);
g_main_loop_unref (verify_data->loop);
g_free (verify_data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyData, verify_data_free)
static void
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
VerifyData *verify_data = user_data;
g_autoptr(GError) error = NULL;
fp_device_close_finish (dev, res, &error);
if (error)
g_warning ("Failed closing device %s", error->message);
g_main_loop_quit (verify_data->loop);
}
int verify(struct fp_dev *dev, struct fp_print_data *data)
static void
verify_quit (FpDevice *dev,
VerifyData *verify_data)
{
int r;
if (!fp_device_is_open (dev))
{
g_main_loop_quit (verify_data->loop);
return;
}
do {
struct fp_img *img = NULL;
sleep(1);
printf("\nScan your finger now.\n");
r = fp_verify_finger_img(dev, data, &img);
if (img) {
fp_img_save_to_file(img, "verify.pgm");
printf("Wrote scanned image to verify.pgm\n");
fp_img_free(img);
}
if (r < 0) {
printf("verification failed with error %d :(\n", r);
return r;
}
switch (r) {
case FP_VERIFY_NO_MATCH:
printf("NO MATCH!\n");
return 0;
case FP_VERIFY_MATCH:
printf("MATCH!\n");
return 0;
case FP_VERIFY_RETRY:
printf("Scan didn't quite work. Please try again.\n");
break;
case FP_VERIFY_RETRY_TOO_SHORT:
printf("Swipe was too short, please try again.\n");
break;
case FP_VERIFY_RETRY_CENTER_FINGER:
printf("Please center your finger on the sensor and try again.\n");
break;
case FP_VERIFY_RETRY_REMOVE_FINGER:
printf("Please remove finger from the sensor and try again.\n");
break;
}
} while (1);
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, verify_data);
}
int main(void)
static void start_verification (FpDevice *dev,
VerifyData *verify_data);
static void
on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
{
int r = 1;
struct fp_dscv_dev *ddev;
struct fp_dscv_dev **discovered_devs;
struct fp_dev *dev;
struct fp_print_data *data;
VerifyData *verify_data = user_data;
r = fp_init();
if (r < 0) {
fprintf(stderr, "Failed to initialize libfprint\n");
exit(1);
}
fp_set_debug(3);
g_autoptr(FpPrint) print = NULL;
g_autoptr(GError) error = NULL;
char buffer[20];
gboolean match;
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "Could not discover devices\n");
goto out;
}
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
{
g_warning ("Failed to verify print: %s", error->message);
verify_data->ret_value = EXIT_FAILURE;
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "No devices detected.\n");
goto out;
}
if (error->domain != FP_DEVICE_RETRY)
{
verify_quit (dev, verify_data);
return;
}
}
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "Could not open device.\n");
goto out;
}
g_print ("Verify again? [Y/n]? ");
if (fgets (buffer, sizeof (buffer), stdin) &&
(buffer[0] == 'Y' || buffer[0] == 'y' || buffer[0] == '\n'))
{
start_verification (dev, verify_data);
return;
}
printf("Opened device. Loading previously enrolled right index finger "
"data...\n");
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
if (r != 0) {
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
fprintf(stderr, "Did you remember to enroll your right index finger "
"first?\n");
goto out_close;
}
printf("Print loaded. Time to verify!\n");
do {
char buffer[20];
verify(dev, data);
printf("Verify again? [Y/n]? ");
fgets(buffer, sizeof(buffer), stdin);
if (buffer[0] != '\n' && buffer[0] != 'y' && buffer[0] != 'Y')
break;
} while (1);
fp_print_data_free(data);
out_close:
fp_dev_close(dev);
out:
fp_exit();
return r;
verify_quit (dev, verify_data);
}
static void
on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
gpointer user_data, GError *error)
{
VerifyData *verify_data = user_data;
if (error)
{
g_warning ("Match report: Finger not matched, retry error reported: %s",
error->message);
return;
}
if (print && fp_print_get_image (print) &&
print_image_save (print, "verify.pgm"))
g_print ("Print image saved as verify.pgm\n");
if (match)
{
const GDate *date = fp_print_get_enroll_date (match);
char date_str[128] = "<unknown>";
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",
fp_print_get_enroll_date (match));
g_debug ("Match report: device %s matched finger %s successifully "
"with print %s, enrolled on date %s by user %s",
fp_device_get_name (dev),
finger_to_string (fp_print_get_finger (match)),
fp_print_get_description (match), date_str,
fp_print_get_username (match));
g_print ("MATCH!\n");
}
else
{
g_debug ("Match report: Finger not matched");
g_print ("NO MATCH!\n");
}
}
static FpPrint *
get_stored_print (FpDevice *dev, VerifyData *verify_data)
{
FpPrint *verify_print;
g_print ("Loading previously enrolled %s finger data...\n",
finger_to_string (verify_data->finger));
verify_print = print_data_load (dev, verify_data->finger);
if (!verify_print)
{
g_warning ("Failed to load fingerprint data");
g_warning ("Did you remember to enroll your %s finger first?",
finger_to_string (verify_data->finger));
}
return verify_print;
}
static void
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
{
VerifyData *verify_data = user_data;
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(GError) error = NULL;
prints = fp_device_list_prints_finish (dev, res, &error);
if (!error)
{
FpPrint *verify_print = NULL;
g_autoptr(FpPrint) stored_print = NULL;
guint i;
if (!prints->len)
{
g_warning ("No prints saved on device");
verify_quit (dev, verify_data);
return;
}
stored_print = get_stored_print (dev, verify_data);
for (i = 0; i < prints->len; ++i)
{
FpPrint *print = prints->pdata[i];
if (stored_print && fp_print_equal (stored_print, print))
/* If the private print data matches, let's use the stored print
* as it contains more metadata to show */
print = stored_print;
if (fp_print_get_finger (print) == verify_data->finger &&
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
{
const GDate *verify_print_date = NULL;
const GDate *print_date = fp_print_get_enroll_date (print);
if (verify_print)
verify_print_date = fp_print_get_enroll_date (verify_print);
if (!verify_print || !print_date || !verify_print_date ||
g_date_compare (print_date, verify_print_date) >= 0)
verify_print = print;
}
}
if (!verify_print)
{
verify_quit (dev, verify_data);
return;
}
g_debug ("Comparing print with %s",
fp_print_get_description (verify_print));
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable,
on_match_cb, verify_data, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
}
else
{
g_warning ("Loading prints failed with error %s", error->message);
verify_quit (dev, verify_data);
}
}
static void
start_verification (FpDevice *dev, VerifyData *verify_data)
{
if (verify_data->finger == FP_FINGER_UNKNOWN)
{
g_print ("Choose the finger to verify:\n");
verify_data->finger = finger_chooser ();
}
if (verify_data->finger == FP_FINGER_UNKNOWN)
{
g_warning ("Unknown finger selected");
verify_data->ret_value = EXIT_FAILURE;
verify_quit (dev, verify_data);
return;
}
if (fp_device_has_feature (dev, FP_DEVICE_FEATURE_STORAGE))
{
g_print ("Creating finger template, using device storage...\n");
fp_device_list_prints (dev, NULL,
(GAsyncReadyCallback) on_list_completed,
verify_data);
}
else
{
g_autoptr(FpPrint) verify_print = get_stored_print (dev, verify_data);
if (!verify_print)
{
verify_quit (dev, verify_data);
return;
}
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable,
on_match_cb, verify_data, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
}
}
static void
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
{
VerifyData *verify_data = user_data;
g_autoptr(GError) error = NULL;
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
verify_quit (dev, verify_data);
return;
}
g_print ("Opened device. ");
start_verification (dev, verify_data);
}
static gboolean
sigint_cb (void *user_data)
{
VerifyData *verify_data = user_data;
g_cancellable_cancel (verify_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
g_autoptr(FpContext) ctx = NULL;
g_autoptr(VerifyData) verify_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;
}
verify_data = g_new0 (VerifyData, 1);
verify_data->ret_value = EXIT_FAILURE;
verify_data->loop = g_main_loop_new (NULL, FALSE);
verify_data->cancellable = g_cancellable_new ();
verify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
verify_data,
NULL);
fp_device_open (dev, verify_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
verify_data);
g_main_loop_run (verify_data->loop);
return verify_data->ret_value;
}

View File

@@ -1,187 +0,0 @@
/*
* Example fingerprint verification program
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libfprint/fprint.h>
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
{
struct fp_dscv_dev *ddev = discovered_devs[0];
struct fp_driver *drv;
if (!ddev)
return NULL;
drv = fp_dscv_dev_get_driver(ddev);
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
return ddev;
}
struct fp_print_data *enroll(struct fp_dev *dev) {
struct fp_print_data *enrolled_print = NULL;
int r;
printf("You will need to successfully scan your finger %d times to "
"complete the process.\n", fp_dev_get_nr_enroll_stages(dev));
do {
sleep(1);
printf("\nScan your finger now.\n");
r = fp_enroll_finger(dev, &enrolled_print);
if (r < 0) {
printf("Enroll failed with error %d\n", r);
return NULL;
}
switch (r) {
case FP_ENROLL_COMPLETE:
printf("Enroll complete!\n");
break;
case FP_ENROLL_FAIL:
printf("Enroll failed, something wen't wrong :(\n");
return NULL;
case FP_ENROLL_PASS:
printf("Enroll stage passed. Yay!\n");
break;
case FP_ENROLL_RETRY:
printf("Didn't quite catch that. Please try again.\n");
break;
case FP_ENROLL_RETRY_TOO_SHORT:
printf("Your swipe was too short, please try again.\n");
break;
case FP_ENROLL_RETRY_CENTER_FINGER:
printf("Didn't catch that, please center your finger on the "
"sensor and try again.\n");
break;
case FP_ENROLL_RETRY_REMOVE_FINGER:
printf("Scan failed, please remove your finger and then try "
"again.\n");
break;
}
} while (r != FP_ENROLL_COMPLETE);
if (!enrolled_print) {
fprintf(stderr, "Enroll complete but no print?\n");
return NULL;
}
printf("Enrollment completed!\n\n");
return enrolled_print;
}
int verify(struct fp_dev *dev, struct fp_print_data *data)
{
int r;
do {
sleep(1);
printf("\nScan your finger now.\n");
r = fp_verify_finger(dev, data);
if (r < 0) {
printf("verification failed with error %d :(\n", r);
return r;
}
switch (r) {
case FP_VERIFY_NO_MATCH:
printf("NO MATCH!\n");
return 0;
case FP_VERIFY_MATCH:
printf("MATCH!\n");
return 0;
case FP_VERIFY_RETRY:
printf("Scan didn't quite work. Please try again.\n");
break;
case FP_VERIFY_RETRY_TOO_SHORT:
printf("Swipe was too short, please try again.\n");
break;
case FP_VERIFY_RETRY_CENTER_FINGER:
printf("Please center your finger on the sensor and try again.\n");
break;
case FP_VERIFY_RETRY_REMOVE_FINGER:
printf("Please remove finger from the sensor and try again.\n");
break;
}
} while (1);
}
int main(void)
{
int r = 1;
struct fp_dscv_dev *ddev;
struct fp_dscv_dev **discovered_devs;
struct fp_dev *dev;
struct fp_print_data *data;
r = fp_init();
if (r < 0) {
fprintf(stderr, "Failed to initialize libfprint\n");
exit(1);
}
fp_set_debug(3);
discovered_devs = fp_discover_devs();
if (!discovered_devs) {
fprintf(stderr, "Could not discover devices\n");
goto out;
}
ddev = discover_device(discovered_devs);
if (!ddev) {
fprintf(stderr, "No devices detected.\n");
goto out;
}
dev = fp_dev_open(ddev);
fp_dscv_devs_free(discovered_devs);
if (!dev) {
fprintf(stderr, "Could not open device.\n");
goto out;
}
printf("Opened device. It's now time to enroll your finger.\n\n");
data = enroll(dev);
if (!data)
goto out_close;
printf("Normally we'd save that print to disk, and recall it at some "
"point later when we want to authenticate the user who just "
"enrolled. In the interests of demonstration, we'll authenticate "
"that user immediately.\n");
do {
char buffer[20];
verify(dev, data);
printf("Verify again? [Y/n]? ");
fgets(buffer, sizeof(buffer), stdin);
if (buffer[0] != '\n' && buffer[0] != 'y' && buffer[0] != 'Y')
break;
} while (1);
fp_print_data_free(data);
out_close:
fp_dev_close(dev);
out:
fp_exit();
return r;
}

1
gcovr.cfg Normal file
View File

@@ -0,0 +1 @@
gcov-ignore-parse-errors = suspicious_hits.warn

View File

@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libfprint
Description: Generic C API for fingerprint reader access
Version: @VERSION@
Libs: -L${libdir} -lfprint
Cflags: -I${includedir}/libfprint

View File

@@ -1,161 +0,0 @@
lib_LTLIBRARIES = libfprint.la
noinst_PROGRAMS = fprint-list-udev-rules
MOSTLYCLEANFILES = $(udev_rules_DATA)
UPEKE2_SRC = drivers/upeke2.c
UPEKTS_SRC = drivers/upekts.c
UPEKTC_SRC = drivers/upektc.c
UPEKSONLY_SRC = drivers/upeksonly.c
URU4000_SRC = drivers/uru4000.c
AES1610_SRC = drivers/aes1610.c
AES2501_SRC = drivers/aes2501.c drivers/aes2501.h
AES4000_SRC = drivers/aes4000.c
FDU2000_SRC = drivers/fdu2000.c
VCOM5S_SRC = drivers/vcom5s.c
VFS101_SRC = drivers/vfs101.c
EXTRA_DIST = \
$(UPEKE2_SRC) \
$(UPEKTS_SRC) \
$(UPEKTC_SRC) \
$(UPEKSONLY_SRC) \
$(URU4000_SRC) \
$(AES1610_SRC) \
$(AES2501_SRC) \
$(AES4000_SRC) \
$(FDU2000_SRC) \
$(VCOM5S_SRC) \
$(VFS101_SRC) \
aeslib.c aeslib.h \
imagemagick.c \
gdkpixbuf.c
DRIVER_SRC =
OTHER_SRC =
NBIS_SRC = \
nbis/include/bozorth.h \
nbis/include/bz_array.h \
nbis/include/defs.h \
nbis/include/lfs.h \
nbis/include/log.h \
nbis/include/morph.h \
nbis/include/sunrast.h \
nbis/bozorth3/bozorth3.c \
nbis/bozorth3/bz_alloc.c \
nbis/bozorth3/bz_drvrs.c \
nbis/bozorth3/bz_gbls.c \
nbis/bozorth3/bz_io.c \
nbis/bozorth3/bz_sort.c \
nbis/mindtct/binar.c \
nbis/mindtct/block.c \
nbis/mindtct/contour.c \
nbis/mindtct/detect.c \
nbis/mindtct/dft.c \
nbis/mindtct/free.c \
nbis/mindtct/globals.c \
nbis/mindtct/imgutil.c \
nbis/mindtct/init.c \
nbis/mindtct/line.c \
nbis/mindtct/log.c \
nbis/mindtct/loop.c \
nbis/mindtct/maps.c \
nbis/mindtct/matchpat.c \
nbis/mindtct/minutia.c \
nbis/mindtct/morph.c \
nbis/mindtct/quality.c \
nbis/mindtct/remove.c \
nbis/mindtct/ridges.c \
nbis/mindtct/shape.c \
nbis/mindtct/sort.c \
nbis/mindtct/util.c
libfprint_la_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS)
libfprint_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@
libfprint_la_LIBADD = -lm $(LIBUSB_LIBS) $(GLIB_LIBS) $(CRYPTO_LIBS)
fprint_list_udev_rules_SOURCES = fprint-list-udev-rules.c
fprint_list_udev_rules_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(IMAGEMAGICK_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS)
fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la
udev_rules_DATA = 60-fprint-autosuspend.rules
udev_rulesdir = $(sysconfdir)/udev/rules.d/
$(udev_rules_DATA): fprint-list-udev-rules
$(builddir)/fprint-list-udev-rules > $@
if ENABLE_UPEKE2
DRIVER_SRC += $(UPEKE2_SRC)
endif
if ENABLE_UPEKTS
DRIVER_SRC += $(UPEKTS_SRC)
endif
if ENABLE_UPEKSONLY
DRIVER_SRC += $(UPEKSONLY_SRC)
endif
#if ENABLE_UPEKTC
#DRIVER_SRC += $(UPEKTC_SRC)
#endif
if ENABLE_URU4000
DRIVER_SRC += $(URU4000_SRC)
endif
if ENABLE_VCOM5S
DRIVER_SRC += $(VCOM5S_SRC)
endif
#if ENABLE_FDU2000
#DRIVER_SRC += $(FDU2000_SRC)
#endif
if ENABLE_AES1610
DRIVER_SRC += $(AES1610_SRC)
endif
if ENABLE_AES2501
DRIVER_SRC += $(AES2501_SRC)
endif
if ENABLE_AES4000
DRIVER_SRC += $(AES4000_SRC)
endif
if ENABLE_VFS101
DRIVER_SRC += $(VFS101_SRC)
endif
if REQUIRE_IMAGEMAGICK
OTHER_SRC += imagemagick.c
libfprint_la_CFLAGS += $(IMAGING_CFLAGS)
libfprint_la_LIBADD += $(IMAGING_LIBS)
endif
if REQUIRE_GDKPIXBUF
OTHER_SRC += gdkpixbuf.c
libfprint_la_CFLAGS += $(IMAGING_CFLAGS)
libfprint_la_LIBADD += $(IMAGING_LIBS)
endif
if REQUIRE_AESLIB
OTHER_SRC += aeslib.c aeslib.h
endif
libfprint_la_SOURCES = \
fp_internal.h \
async.c \
core.c \
data.c \
drv.c \
img.c \
imgdev.c \
poll.c \
sync.c \
$(DRIVER_SRC) \
$(OTHER_SRC) \
$(NBIS_SRC)
pkginclude_HEADERS = fprint.h

View File

@@ -1,173 +0,0 @@
/*
* Shared functions between libfprint Authentec drivers
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "aeslib"
#include <errno.h>
#include <libusb.h>
#include <glib.h>
#include "fp_internal.h"
#include "aeslib.h"
#define MAX_REGWRITES_PER_REQUEST 16
#define BULK_TIMEOUT 4000
#define EP_IN (1 | LIBUSB_ENDPOINT_IN)
#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
struct write_regv_data {
struct fp_img_dev *imgdev;
unsigned int num_regs;
const struct aes_regwrite *regs;
unsigned int offset;
aes_write_regv_cb callback;
void *user_data;
};
static void continue_write_regv(struct write_regv_data *wdata);
/* libusb bulk callback for regv write completion transfer. continues the
* transaction */
static void write_regv_trf_complete(struct libusb_transfer *transfer)
{
struct write_regv_data *wdata = transfer->user_data;
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
wdata->callback(wdata->imgdev, -EIO, wdata->user_data);
else if (transfer->length != transfer->actual_length)
wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data);
else
continue_write_regv(wdata);
g_free(transfer->buffer);
libusb_free_transfer(transfer);
}
/* write from wdata->offset to upper_bound (inclusive) of wdata->regs */
static int do_write_regv(struct write_regv_data *wdata, int upper_bound)
{
unsigned int offset = wdata->offset;
unsigned int num = upper_bound - offset + 1;
size_t alloc_size = num * 2;
unsigned char *data = g_malloc(alloc_size);
unsigned int i;
size_t data_offset = 0;
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
int r;
if (!transfer) {
g_free(data);
return -ENOMEM;
}
for (i = offset; i < offset + num; i++) {
const struct aes_regwrite *regwrite = &wdata->regs[i];
data[data_offset++] = regwrite->reg;
data[data_offset++] = regwrite->value;
}
libusb_fill_bulk_transfer(transfer, wdata->imgdev->udev, EP_OUT, data,
alloc_size, write_regv_trf_complete, wdata, BULK_TIMEOUT);
r = libusb_submit_transfer(transfer);
if (r < 0) {
g_free(data);
libusb_free_transfer(transfer);
}
return r;
}
/* write the next batch of registers to be written, or if there are no more,
* indicate completion to the caller */
static void continue_write_regv(struct write_regv_data *wdata)
{
unsigned int offset = wdata->offset;
unsigned int regs_remaining;
unsigned int limit;
unsigned int upper_bound;
int i;
int r;
/* skip all zeros and ensure there is still work to do */
while (TRUE) {
if (offset >= wdata->num_regs) {
fp_dbg("all registers written");
wdata->callback(wdata->imgdev, 0, wdata->user_data);
return;
}
if (wdata->regs[offset].reg)
break;
offset++;
}
wdata->offset = offset;
regs_remaining = wdata->num_regs - offset;
limit = MIN(regs_remaining, MAX_REGWRITES_PER_REQUEST);
upper_bound = offset + limit - 1;
/* determine if we can write the entire of the regs at once, or if there
* is a zero dividing things up */
for (i = offset; i <= upper_bound; i++)
if (!wdata->regs[i].reg) {
upper_bound = i - 1;
break;
}
r = do_write_regv(wdata, upper_bound);
if (r < 0) {
wdata->callback(wdata->imgdev, r, wdata->user_data);
return;
}
wdata->offset = upper_bound + 1;
}
/* write a load of registers to the device, combining multiple writes in a
* single URB up to a limit. insert writes to non-existent register 0 to force
* specific groups of writes to be separated by different URBs. */
void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
unsigned int num_regs, aes_write_regv_cb callback, void *user_data)
{
struct write_regv_data *wdata = g_malloc(sizeof(*wdata));
fp_dbg("write %d regs", num_regs);
wdata->imgdev = dev;
wdata->num_regs = num_regs;
wdata->regs = regs;
wdata->offset = 0;
wdata->callback = callback;
wdata->user_data = user_data;
continue_write_regv(wdata);
}
void aes_assemble_image(unsigned char *input, size_t width, size_t height,
unsigned char *output)
{
size_t row, column;
for (column = 0; column < width; column++) {
for (row = 0; row < height; row += 2) {
output[width * row + column] = (*input & 0x07) * 36;
output[width * (row + 1) + column] = ((*input & 0x70) >> 4) * 36;
input++;
}
}
}

View File

@@ -1,414 +0,0 @@
/*
* Asynchronous I/O functionality
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "async"
#include <config.h>
#include <errno.h>
#include <glib.h>
#include "fp_internal.h"
/* Drivers call this when device initialisation has completed */
void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
{
fp_dbg("status %d", status);
BUG_ON(dev->state != DEV_STATE_INITIALIZING);
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_INITIALIZED;
opened_devices = g_slist_prepend(opened_devices, dev);
if (dev->open_cb)
dev->open_cb(dev, status, dev->open_cb_data);
}
API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb,
void *user_data)
{
struct fp_driver *drv = ddev->drv;
struct fp_dev *dev;
libusb_device_handle *udevh;
int r;
fp_dbg("");
r = libusb_open(ddev->udev, &udevh);
if (r < 0) {
fp_err("usb_open failed, error %d", r);
return r;
}
dev = g_malloc0(sizeof(*dev));
dev->drv = drv;
dev->udev = udevh;
dev->__enroll_stage = -1;
dev->state = DEV_STATE_INITIALIZING;
dev->open_cb = cb;
dev->open_cb_data = user_data;
if (!drv->open) {
fpi_drvcb_open_complete(dev, 0);
return 0;
}
dev->state = DEV_STATE_INITIALIZING;
r = drv->open(dev, ddev->driver_data);
if (r) {
fp_err("device initialisation failed, driver=%s", drv->name);
libusb_close(udevh);
g_free(dev);
}
return r;
}
/* Drivers call this when device deinitialisation has completed */
void fpi_drvcb_close_complete(struct fp_dev *dev)
{
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
dev->state = DEV_STATE_DEINITIALIZED;
libusb_close(dev->udev);
if (dev->close_cb)
dev->close_cb(dev, dev->close_cb_data);
g_free(dev);
}
API_EXPORTED void fp_async_dev_close(struct fp_dev *dev,
fp_dev_close_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
if (g_slist_index(opened_devices, (gconstpointer) dev) == -1)
fp_err("device %p not in opened list!", dev);
opened_devices = g_slist_remove(opened_devices, (gconstpointer) dev);
dev->close_cb = callback;
dev->close_cb_data = user_data;
if (!drv->close) {
fpi_drvcb_close_complete(dev);
return;
}
dev->state = DEV_STATE_DEINITIALIZING;
drv->close(dev);
}
/* Drivers call this when enrollment has started */
void fpi_drvcb_enroll_started(struct fp_dev *dev, int status)
{
fp_dbg("status %d", status);
BUG_ON(dev->state != DEV_STATE_ENROLL_STARTING);
if (status) {
if (status > 0) {
status = -status;
fp_dbg("adjusted to %d", status);
}
dev->state = DEV_STATE_ERROR;
if (dev->enroll_stage_cb)
dev->enroll_stage_cb(dev, status, NULL, NULL,
dev->enroll_stage_cb_data);
} else {
dev->state = DEV_STATE_ENROLLING;
}
}
API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev,
fp_enroll_stage_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
int r;
if (!dev->nr_enroll_stages || !drv->enroll_start) {
fp_err("driver %s has 0 enroll stages or no enroll func",
drv->name);
return -ENOTSUP;
}
fp_dbg("starting enrollment");
dev->enroll_stage_cb = callback;
dev->enroll_stage_cb_data = user_data;
dev->state = DEV_STATE_ENROLL_STARTING;
r = drv->enroll_start(dev);
if (r < 0) {
dev->enroll_stage_cb = NULL;
fp_err("failed to start enrollment");
dev->state = DEV_STATE_ERROR;
}
return r;
}
/* Drivers call this when an enroll stage has completed */
void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
struct fp_print_data *data, struct fp_img *img)
{
BUG_ON(dev->state != DEV_STATE_ENROLLING);
fp_dbg("result %d", result);
if (!dev->enroll_stage_cb) {
fp_dbg("ignoring enroll result as no callback is subscribed");
return;
}
if (result == FP_ENROLL_COMPLETE && !data) {
fp_err("BUG: complete but no data?");
result = FP_ENROLL_FAIL;
}
dev->enroll_stage_cb(dev, result, data, img, dev->enroll_stage_cb_data);
}
/* Drivers call this when enrollment has stopped */
void fpi_drvcb_enroll_stopped(struct fp_dev *dev)
{
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_ENROLL_STOPPING);
dev->state = DEV_STATE_INITIALIZED;
if (dev->enroll_stop_cb)
dev->enroll_stop_cb(dev, dev->enroll_stop_cb_data);
}
API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
fp_enroll_stop_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
int r;
fp_dbg("");
if (!drv->enroll_start)
return -ENOTSUP;
dev->enroll_stage_cb = NULL;
dev->enroll_stop_cb = callback;
dev->enroll_stop_cb_data = user_data;
dev->state = DEV_STATE_ENROLL_STOPPING;
if (!drv->enroll_stop) {
fpi_drvcb_enroll_stopped(dev);
return 0;
}
r = drv->enroll_stop(dev);
if (r < 0) {
fp_err("failed to stop enrollment");
dev->enroll_stop_cb = NULL;
}
return r;
}
API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
struct fp_print_data *data, fp_verify_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
int r;
fp_dbg("");
if (!drv->verify_start)
return -ENOTSUP;
dev->state = DEV_STATE_VERIFY_STARTING;
dev->verify_cb = callback;
dev->verify_cb_data = user_data;
dev->verify_data = data;
r = drv->verify_start(dev);
if (r < 0) {
dev->verify_cb = NULL;
dev->state = DEV_STATE_ERROR;
fp_err("failed to start verification, error %d", r);
}
return r;
}
/* Drivers call this when verification has started */
void fpi_drvcb_verify_started(struct fp_dev *dev, int status)
{
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_VERIFY_STARTING);
if (status) {
if (status > 0) {
status = -status;
fp_dbg("adjusted to %d", status);
}
dev->state = DEV_STATE_ERROR;
if (dev->verify_cb)
dev->verify_cb(dev, status, NULL, dev->verify_cb_data);
} else {
dev->state = DEV_STATE_VERIFYING;
}
}
/* Drivers call this to report a verify result (which might mark completion) */
void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result,
struct fp_img *img)
{
fp_dbg("result %d", result);
BUG_ON(dev->state != DEV_STATE_VERIFYING);
if (result < 0 || result == FP_VERIFY_NO_MATCH
|| result == FP_VERIFY_MATCH)
dev->state = DEV_STATE_VERIFY_DONE;
if (dev->verify_cb)
dev->verify_cb(dev, result, img, dev->verify_cb_data);
else
fp_dbg("ignoring verify result as no callback is subscribed");
}
/* Drivers call this when verification has stopped */
void fpi_drvcb_verify_stopped(struct fp_dev *dev)
{
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_VERIFY_STOPPING);
dev->state = DEV_STATE_INITIALIZED;
if (dev->verify_stop_cb)
dev->verify_stop_cb(dev, dev->verify_stop_cb_data);
}
API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
fp_verify_stop_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
gboolean iterating = (dev->state == DEV_STATE_VERIFYING);
int r;
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_ERROR
&& dev->state != DEV_STATE_VERIFYING
&& dev->state != DEV_STATE_VERIFY_DONE);
dev->verify_cb = NULL;
dev->verify_stop_cb = callback;
dev->verify_stop_cb_data = user_data;
dev->state = DEV_STATE_VERIFY_STOPPING;
if (!drv->verify_start)
return -ENOTSUP;
if (!drv->verify_stop) {
dev->state = DEV_STATE_INITIALIZED;
fpi_drvcb_verify_stopped(dev);
return 0;
}
r = drv->verify_stop(dev, iterating);
if (r < 0) {
fp_err("failed to stop verification");
dev->verify_stop_cb = NULL;
}
return r;
}
API_EXPORTED int fp_async_identify_start(struct fp_dev *dev,
struct fp_print_data **gallery, fp_identify_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
int r;
fp_dbg("");
if (!drv->identify_start)
return -ENOTSUP;
dev->state = DEV_STATE_IDENTIFY_STARTING;
dev->identify_cb = callback;
dev->identify_cb_data = user_data;
dev->identify_gallery = gallery;
r = drv->identify_start(dev);
if (r < 0) {
fp_err("identify_start failed with error %d", r);
dev->identify_cb = NULL;
dev->state = DEV_STATE_ERROR;
}
return r;
}
/* Driver-lib: identification has started, expect results soon */
void fpi_drvcb_identify_started(struct fp_dev *dev, int status)
{
fp_dbg("status %d", status);
BUG_ON(dev->state != DEV_STATE_IDENTIFY_STARTING);
if (status) {
if (status > 0) {
status = -status;
fp_dbg("adjusted to %d", status);
}
dev->state = DEV_STATE_ERROR;
if (dev->identify_cb)
dev->identify_cb(dev, status, 0, NULL, dev->identify_cb_data);
} else {
dev->state = DEV_STATE_IDENTIFYING;
}
}
/* Drivers report an identify result (which might mark completion) */
void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
size_t match_offset, struct fp_img *img)
{
fp_dbg("result %d", result);
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
&& dev->state != DEV_STATE_ERROR);
if (result < 0 || result == FP_VERIFY_NO_MATCH
|| result == FP_VERIFY_MATCH)
dev->state = DEV_STATE_IDENTIFY_DONE;
if (dev->identify_cb)
dev->identify_cb(dev, result, match_offset, img, dev->identify_cb_data);
else
fp_dbg("ignoring verify result as no callback is subscribed");
}
API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
fp_identify_stop_cb callback, void *user_data)
{
struct fp_driver *drv = dev->drv;
gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING);
int r;
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
&& dev->state != DEV_STATE_IDENTIFY_DONE);
dev->state = DEV_STATE_IDENTIFY_STOPPING;
dev->identify_cb = NULL;
dev->identify_stop_cb = callback;
dev->identify_stop_cb_data = user_data;
if (!drv->identify_start)
return -ENOTSUP;
if (!drv->identify_stop) {
dev->state = DEV_STATE_INITIALIZED;
fpi_drvcb_identify_stopped(dev);
return 0;
}
r = drv->identify_stop(dev, iterating);
if (r < 0) {
fp_err("failed to stop identification");
dev->identify_stop_cb = NULL;
}
return r;
}
/* Drivers call this when identification has stopped */
void fpi_drvcb_identify_stopped(struct fp_dev *dev)
{
fp_dbg("");
BUG_ON(dev->state != DEV_STATE_IDENTIFY_STOPPING);
dev->state = DEV_STATE_INITIALIZED;
if (dev->identify_stop_cb)
dev->identify_stop_cb(dev, dev->identify_stop_cb_data);
}

View File

@@ -1,974 +0,0 @@
/*
* Core functions for libfprint
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <libusb.h>
#include "fp_internal.h"
static int log_level = 0;
static int log_level_fixed = 0;
libusb_context *fpi_usb_ctx = NULL;
GSList *opened_devices = NULL;
/**
* \mainpage libfprint API Reference
* libfprint is an open source library to provide access to fingerprint
* scanning devices. For more info, see the
* <a href="http://www.reactivated.net/fprint/Libfprint">libfprint project
* homepage</a>.
*
* This documentation is aimed at application developers who wish to integrate
* fingerprint-related functionality into their software. libfprint has been
* designed so that you only have to do this once - by integrating your
* software with libfprint, you'll be supporting all the fingerprint readers
* that we have got our hands on. As such, the API is rather general (and
* therefore hopefully easy to comprehend!), and does its best to hide the
* technical details that required to operate the hardware.
*
* This documentation is not aimed at developers wishing to develop and
* contribute fingerprint device drivers to libfprint.
*
* Feedback on this API and its associated documentation is appreciated. Was
* anything unclear? Does anything seem unreasonably complicated? Is anything
* missing? Let us know on the
* <a href="http://www.reactivated.net/fprint/Mailing_list">mailing list</a>.
*
* \section enrollment Enrollment
*
* Before you dive into the API, it's worth introducing a couple of concepts.
*
* The process of enrolling a finger is where you effectively scan your
* finger for the purposes of teaching the system what your finger looks like.
* This means that you scan your fingerprint, then the system processes it and
* stores some data about your fingerprint to refer to later.
*
* \section verification Verification
*
* Verification is what most people think of when they think about fingerprint
* scanning. The process of verification is effectively performing a fresh
* fingerprint scan, and then comparing that scan to a finger that was
* previously enrolled.
*
* As an example scenario, verification can be used to implement what people
* would picture as fingerprint login (i.e. fingerprint replaces password).
* For example:
* - I enroll my fingerprint through some software that trusts I am who I say
* I am. This is a prerequisite before I can perform fingerprint-based
* login for my account.
* - Some time later, I want to login to my computer. I enter my username,
* but instead of prompting me for a password, it asks me to scan my finger.
* I scan my finger.
* - The system compares the finger I just scanned to the one that was
* enrolled earlier. If the system decides that the fingerprints match,
* I am successfully logged in. Otherwise, the system informs me that I am
* not authorised to login as that user.
*
* \section identification Identification
*
* Identification is the process of comparing a freshly scanned fingerprint
* to a <em>collection</em> of previously enrolled fingerprints. For example,
* imagine there are 100 people in an organisation, and they all have enrolled
* their fingerprints. One user walks up to a fingerprint scanner and scans
* their finger. With <em>no other knowledge</em> of who that user might be,
* the system examines their fingerprint, looks in the database, and determines
* that the user is user number #61.
*
* In other words, verification might be seen as a one-to-one fingerprint
* comparison where you know the identity of the user that you wish to
* authenticate, whereas identification is a one-to-many comparison where you
* do not know the identity of the user that you wish to authenticate.
*
* \section compat_general Device and print compatibility
* Moving off generic conceptual ideas and onto libfprint-specific
* implementation details, here are some introductory notes regarding how
* libfprint copes with compatibility of fingerprints.
*
* libfprint deals with a whole variety of different fingerprint readers and
* the design includes considerations of compatibility and interoperability
* between multiple devices. Your application should also be prepared to
* work with more than one type of fingerprint reader and should consider that
* enrolled fingerprint X may not be compatible with the device the user has
* plugged in today.
*
* libfprint implements the principle that fingerprints from different devices
* are not necessarily compatible. For example, different devices may see
* significantly different areas of fingerprint surface, and comparing images
* between the devices would be unreliable. Also, devices can stretch and
* distort images in different ways.
*
* libfprint also implements the principle that in some cases, fingerprints
* <em>are</em> compatible between different devices. If you go and buy two
* identical fingerprint readers, it seems logical that you should be able
* to enroll on one and verify on another without problems.
*
* libfprint takes a fairly simplistic approach to these issues. Internally,
* fingerprint hardware is driven by individual drivers. libfprint enforces
* that a fingerprint that came from a device backed by driver X is never
* compared to a fingerprint that came from a device backed by driver Y.
*
* Additionally, libfprint is designed for the situation where a single driver
* may support a range of devices which differ in imaging or scanning
* properties. For example, a driver may support two ranges of devices which
* even though are programmed over the same interface, one device sees
* substantially less of the finger flesh, therefore images from the two
* device types should be incompatible despite being from the same driver. To
* implement this, each driver assigns a <em>device type</em> to each device
* that it detects based on its imaging characteristics. libfprint ensures that
* two prints being compared have the same device type.
*
* In summary, libfprint represents fingerprints in several internal structures
* and each representation will offer you a way of determining the
* \ref driver_id "driver ID" and \ref devtype "devtype" of the print in
* question. Prints are only compatible if the driver ID <b>and</b> devtypes
* match. libfprint does offer you some "is this print compatible?" helper
* functions, so you don't have to worry about these details too much.
*
* \section sync Synchronity/asynchronity
*
* Currently, all data acquisition operations are synchronous and can
* potentially block for extended periods of time. For example, the enroll
* function will block for an unpredictable amount of time until the user
* scans their finger.
*
* Alternative asynchronous/non-blocking functionality will be offered in
* future but has not been implemented yet.
*
* \section getting_started Getting started
*
* libfprint includes several simple functional examples under the examples/
* directory in the libfprint source distribution. Those are good starting
* points.
*
* Usually the first thing you want to do is determine which fingerprint
* devices are present. This is done through \ref dscv_dev "device discovery".
*
* Once you have found a device you would like to operate, you should open it.
* Refer to \ref dev "device operations". This section also details enrollment,
* image capture, and verification.
*
*
* That should be enough to get you started, but do remember there are
* documentation pages on other aspects of libfprint's API (see the modules
* page).
*/
/** @defgroup core Core library operations */
/**
* @defgroup dev Device operations
* In order to interact with fingerprint scanners, your software will
* interface primarily with libfprint's representation of devices, detailed
* on this page.
*
* \section enrolling Enrolling
* Enrolling is represented within libfprint as a multi-stage process. This
* slightly complicates things for application developers, but is required
* for a smooth process.
*
* Some devices require the user to scan their finger multiple times in
* order to complete the enrollment process. libfprint must return control
* to your application inbetween each scan in order for your application to
* instruct the user to swipe their finger again. Each scan is referred to
* as a stage, so a device that requires 3 scans for enrollment corresponds
* to you running 3 enrollment stages using libfprint.
*
* The fp_dev_get_nr_enroll_stages() function can be used to find out how
* many enroll stages are needed.
*
* In order to complete an enroll stage, you call an enroll function such
* as fp_enroll_finger(). The return of this function does not necessarily
* indicate that a stage has completed though, as the user may not have
* produced a good enough scan. Each stage may have to be retried several
* times.
*
* The exact semantics of the enroll functions are described in the
* fp_enroll_finger() documentation. You should pay careful attention to the
* details.
*
* \section imaging Imaging
* libfprint provides you with some ways to retrieve images of scanned
* fingers, such as the fp_dev_img_capture() function, or some enroll/verify
* function variants which provide images. You may wish to do something with
* such images in your application.
*
* However, you must be aware that not all hardware supported by libfprint
* operates like this. Most hardware does operate simply by sending
* fingerprint images to the host computer for further processing, but some
* devices do all fingerprint processing in hardware and do not present images
* to the host computer.
*
* You can use fp_dev_supports_imaging() to see if image capture is possible
* on a particular device. Your application must be able to cope with the
* fact that libfprint does support regular operations (e.g. enrolling and
* verification) on some devices which do not provide images.
*
* \section devtype Devtypes
* Internally, the \ref drv "driver" behind a device assigns a 32-bit
* <em>devtype</em> identifier to the device. This cannot be used as a unique
* ID for a specific device as many devices under the same range may share
* the same devtype. The devtype may even be 0 in all cases.
*
* The only reason you may be interested in retrieving the devtype for a
* device is for the purpose of checking if some print data is compatible
* with a device. libfprint uses the devtype as one way of checking that the
* print you are verifying is compatible with the device in question - the
* devtypes must be equal. This effectively allows drivers to support more
* than one type of device where the data from each one is not compatible with
* the other. Note that libfprint does provide you with helper functions to
* determine whether a print is compatible with a device, so under most
* circumstances, you don't have to worry about devtypes at all.
*/
/** @defgroup dscv_dev Device discovery
* These functions allow you to scan the system for supported fingerprint
* scanning hardware. This is your starting point when integrating libfprint
* into your software.
*
* When you've identified a discovered device that you would like to control,
* you can open it with fp_dev_open(). Note that discovered devices may no
* longer be available at the time when you want to open them, for example
* the user may have unplugged the device.
*/
/** @defgroup drv Driver operations
* Internally, libfprint is abstracted into various drivers to communicate
* with the different types of supported fingerprint readers. libfprint works
* hard so that you don't have to care about these internal abstractions,
* however there are some situations where you may be interested in a little
* behind-the-scenes driver info.
*
* You can obtain the driver for a device using fp_dev_get_driver(), which
* you can pass to the functions documented on this page.
*
* \section driver_id Driver IDs
* Each driver is assigned a unique ID by the project maintainer. These
* assignments are
* <a href="http://www.reactivated.net/fprint/Driver_ID_assignments">
* documented on the wiki</a> and will never change.
*
* The only reason you may be interested in retrieving the driver ID for a
* driver is for the purpose of checking if some print data is compatible
* with a device. libfprint uses the driver ID as one way of checking that
* the print you are trying to verify is compatible with the device in
* question - it ensures that enrollment data from one driver is never fed to
* another. Note that libfprint does provide you with helper functions to
* determine whether a print is compatible with a device, so under most
* circumstances, you don't have to worry about driver IDs at all.
*/
static GSList *registered_drivers = NULL;
void fpi_log(enum fpi_log_level level, const char *component,
const char *function, const char *format, ...)
{
va_list args;
FILE *stream = stdout;
const char *prefix;
#ifndef ENABLE_DEBUG_LOGGING
if (!log_level)
return;
if (level == LOG_LEVEL_WARNING && log_level < 2)
return;
if (level == LOG_LEVEL_INFO && log_level < 3)
return;
#endif
switch (level) {
case LOG_LEVEL_INFO:
prefix = "info";
break;
case LOG_LEVEL_WARNING:
stream = stderr;
prefix = "warning";
break;
case LOG_LEVEL_ERROR:
stream = stderr;
prefix = "error";
break;
case LOG_LEVEL_DEBUG:
stream = stderr;
prefix = "debug";
break;
default:
stream = stderr;
prefix = "unknown";
break;
}
fprintf(stream, "%s:%s [%s] ", component ? component : "fp", prefix,
function);
va_start (args, format);
vfprintf(stream, format, args);
va_end (args);
fprintf(stream, "\n");
}
static void register_driver(struct fp_driver *drv)
{
if (drv->id == 0) {
fp_err("not registering driver %s: driver ID is 0", drv->name);
return;
}
registered_drivers = g_slist_prepend(registered_drivers, (gpointer) drv);
fp_dbg("registered driver %s", drv->name);
}
static struct fp_driver * const primitive_drivers[] = {
#ifdef ENABLE_UPEKTS
&upekts_driver,
#endif
#ifdef ENABLE_UPEKE2
&upeke2_driver,
#endif
};
static struct fp_img_driver * const img_drivers[] = {
#ifdef ENABLE_AES4000
&aes4000_driver,
#endif
#ifdef ENABLE_AES2501
&aes2501_driver,
#endif
#ifdef ENABLE_URU4000
&uru4000_driver,
#endif
#ifdef ENABLE_VCOM5S
&vcom5s_driver,
#endif
#ifdef ENABLE_UPEKSONLY
&upeksonly_driver,
#endif
#ifdef ENABLE_AES1610
&aes1610_driver,
#endif
#ifdef ENABLE_VFS101
&vfs101_driver,
#endif
/*#ifdef ENABLE_UPEKTC
&upektc_driver,
#endif
#ifdef ENABLE_FDU2000
&fdu2000_driver,
#endif
*/
};
static void register_drivers(void)
{
unsigned int i;
for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
register_driver(primitive_drivers[i]);
for (i = 0; i < G_N_ELEMENTS(img_drivers); i++) {
struct fp_img_driver *imgdriver = img_drivers[i];
fpi_img_driver_setup(imgdriver);
register_driver(&imgdriver->driver);
}
}
API_EXPORTED struct fp_driver **fprint_get_drivers (void)
{
GPtrArray *array;
unsigned int i;
array = g_ptr_array_new ();
for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
g_ptr_array_add (array, primitive_drivers[i]);
for (i = 0; i < G_N_ELEMENTS(img_drivers); i++)
g_ptr_array_add (array, &(img_drivers[i]->driver));
/* Add a null item terminating the array */
g_ptr_array_add (array, NULL);
return (struct fp_driver **) g_ptr_array_free (array, FALSE);
}
static struct fp_driver *find_supporting_driver(libusb_device *udev,
const struct usb_id **usb_id, uint32_t *devtype)
{
int ret;
GSList *elem = registered_drivers;
struct libusb_device_descriptor dsc;
const struct usb_id *best_usb_id;
struct fp_driver *best_drv;
uint32_t best_devtype;
int drv_score = 0;
ret = libusb_get_device_descriptor(udev, &dsc);
if (ret < 0) {
fp_err("Failed to get device descriptor");
return NULL;
}
best_drv = NULL;
best_devtype = 0;
do {
struct fp_driver *drv = elem->data;
uint32_t type = 0;
const struct usb_id *id;
for (id = drv->id_table; id->vendor; id++) {
if (dsc.idVendor == id->vendor && dsc.idProduct == id->product) {
if (drv->discover) {
int r = drv->discover(&dsc, &type);
if (r < 0)
fp_err("%s discover failed, code %d", drv->name, r);
if (r <= 0)
continue;
/* Has a discover function, and matched our device */
drv_score = 100;
} else {
/* Already got a driver as good */
if (drv_score >= 50)
continue;
drv_score = 50;
}
fp_dbg("driver %s supports USB device %04x:%04x",
drv->name, id->vendor, id->product);
best_usb_id = id;
best_drv = drv;
best_devtype = type;
/* We found the best possible driver */
if (drv_score == 100)
break;
}
}
} while ((elem = g_slist_next(elem)));
if (best_drv != NULL) {
fp_dbg("selected driver %s supports USB device %04x:%04x",
best_drv->name, dsc.idVendor, dsc.idProduct);
*devtype = best_devtype;
*usb_id = best_usb_id;
}
return best_drv;
}
static struct fp_dscv_dev *discover_dev(libusb_device *udev)
{
const struct usb_id *usb_id;
struct fp_driver *drv;
struct fp_dscv_dev *ddev;
uint32_t devtype;
drv = find_supporting_driver(udev, &usb_id, &devtype);
if (!drv)
return NULL;
ddev = g_malloc0(sizeof(*ddev));
ddev->drv = drv;
ddev->udev = udev;
ddev->driver_data = usb_id->driver_data;
ddev->devtype = devtype;
return ddev;
}
/** \ingroup dscv_dev
* Scans the system and returns a list of discovered devices. This is your
* entry point into finding a fingerprint reader to operate.
* \returns a NULL-terminated list of discovered devices. Must be freed with
* fp_dscv_devs_free() after use.
*/
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
{
GSList *tmplist = NULL;
struct fp_dscv_dev **list;
libusb_device *udev;
libusb_device **devs;
int dscv_count = 0;
int r;
int i = 0;
if (registered_drivers == NULL)
return NULL;
r = libusb_get_device_list(fpi_usb_ctx, &devs);
if (r < 0) {
fp_err("couldn't enumerate USB devices, error %d", r);
return NULL;
}
/* Check each device against each driver, temporarily storing successfully
* discovered devices in a GSList.
*
* Quite inefficient but excusable as we'll only be dealing with small
* sets of drivers against small sets of USB devices */
while ((udev = devs[i++]) != NULL) {
struct fp_dscv_dev *ddev = discover_dev(udev);
if (!ddev)
continue;
tmplist = g_slist_prepend(tmplist, (gpointer) ddev);
dscv_count++;
}
/* Convert our temporary GSList into a standard NULL-terminated pointer
* array. */
list = g_malloc(sizeof(*list) * (dscv_count + 1));
if (dscv_count > 0) {
GSList *elem = tmplist;
i = 0;
do {
list[i++] = elem->data;
} while ((elem = g_slist_next(elem)));
}
list[dscv_count] = NULL; /* NULL-terminate */
g_slist_free(tmplist);
return list;
}
/** \ingroup dscv_dev
* Free a list of discovered devices. This function destroys the list and all
* discovered devices that it included, so make sure you have opened your
* discovered device <b>before</b> freeing the list.
* \param devs the list of discovered devices. If NULL, function simply
* returns.
*/
API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
{
int i;
if (!devs)
return;
for (i = 0; devs[i]; i++)
g_free(devs[i]);
g_free(devs);
}
/** \ingroup dscv_dev
* Gets the \ref drv "driver" for a discovered device.
* \param dev the discovered device
* \returns the driver backing the device
*/
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
{
return dev->drv;
}
/** \ingroup dscv_dev
* Gets the \ref devtype "devtype" for a discovered device.
* \param dev the discovered device
* \returns the devtype of the device
*/
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
{
return dev->devtype;
}
enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv)
{
switch (drv->type) {
case DRIVER_PRIMITIVE:
return PRINT_DATA_RAW;
case DRIVER_IMAGING:
return PRINT_DATA_NBIS_MINUTIAE;
default:
fp_err("unrecognised drv type %d", drv->type);
return PRINT_DATA_RAW;
}
}
/** \ingroup dscv_dev
* Determines if a specific \ref print_data "stored print" appears to be
* compatible with a discovered device.
* \param dev the discovered device
* \param data the print for compatibility checking
* \returns 1 if the print is compatible with the device, 0 otherwise
*/
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
struct fp_print_data *data)
{
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
data->type);
}
/** \ingroup dscv_dev
* Determines if a specific \ref dscv_print "discovered print" appears to be
* compatible with a discovered device.
* \param dev the discovered device
* \param data the discovered print for compatibility checking
* \returns 1 if the print is compatible with the device, 0 otherwise
*/
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
struct fp_dscv_print *data)
{
return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
data->driver_id, data->devtype, 0);
}
/** \ingroup dscv_dev
* Searches a list of discovered devices for a device that appears to be
* compatible with a \ref print_data "stored print".
* \param devs a list of discovered devices
* \param data the print under inspection
* \returns the first discovered device that appears to support the print, or
* NULL if no apparently compatible devices could be found
*/
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs,
struct fp_print_data *data)
{
struct fp_dscv_dev *ddev;
int i;
for (i = 0; (ddev = devs[i]); i++)
if (fp_dscv_dev_supports_print_data(ddev, data))
return ddev;
return NULL;
}
/** \ingroup dscv_dev
* Searches a list of discovered devices for a device that appears to be
* compatible with a \ref dscv_print "discovered print".
* \param devs a list of discovered devices
* \param print the print under inspection
* \returns the first discovered device that appears to support the print, or
* NULL if no apparently compatible devices could be found
*/
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs,
struct fp_dscv_print *print)
{
struct fp_dscv_dev *ddev;
int i;
for (i = 0; (ddev = devs[i]); i++)
if (fp_dscv_dev_supports_dscv_print(ddev, print))
return ddev;
return NULL;
}
/** \ingroup dev
* Get the \ref drv "driver" for a fingerprint device.
* \param dev the device
* \returns the driver controlling the device
*/
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
{
return dev->drv;
}
/** \ingroup dev
* Gets the number of \ref enrolling "enroll stages" required to enroll a
* fingerprint with the device.
* \param dev the device
* \returns the number of enroll stages
*/
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
{
return dev->nr_enroll_stages;
}
/** \ingroup dev
* Gets the \ref devtype "devtype" for a device.
* \param dev the device
* \returns the devtype
*/
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
{
return dev->devtype;
}
/** \ingroup dev
* Determines if a stored print is compatible with a certain device.
* \param dev the device
* \param data the stored print
* \returns 1 if the print is compatible with the device, 0 if not
*/
API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
struct fp_print_data *data)
{
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
data->type);
}
/** \ingroup dev
* Determines if a \ref dscv_print "discovered print" appears to be compatible
* with a certain device.
* \param dev the device
* \param data the discovered print
* \returns 1 if the print is compatible with the device, 0 if not
*/
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
struct fp_dscv_print *data)
{
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
0, data->driver_id, data->devtype, 0);
}
/** \ingroup drv
* Retrieves the name of the driver. For example: "upekts"
* \param drv the driver
* \returns the driver name. Must not be modified or freed.
*/
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
{
return drv->name;
}
/** \ingroup drv
* Retrieves a descriptive name of the driver. For example: "UPEK TouchStrip"
* \param drv the driver
* \returns the descriptive name. Must not be modified or freed.
*/
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
{
return drv->full_name;
}
/** \ingroup drv
* Retrieves the driver ID code for a driver.
* \param drv the driver
* \returns the driver ID
*/
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
{
return drv->id;
}
/** \ingroup drv
* Retrieves the scan type for the devices associated with the driver.
* \param drv the driver
* \returns the scan type
*/
API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv)
{
return drv->scan_type;
}
static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev)
{
if (dev->drv->type != DRIVER_IMAGING)
return NULL;
return dev->priv;
}
/** \ingroup dev
* Determines if a device has imaging capabilities. If a device has imaging
* capabilities you are able to perform imaging operations such as retrieving
* scan images using fp_dev_img_capture(). However, not all devices are
* imaging devices - some do all processing in hardware. This function will
* indicate which class a device in question falls into.
* \param dev the fingerprint device
* \returns 1 if the device is an imaging device, 0 if the device does not
* provide images to the host computer
*/
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
{
return dev->drv->type == DRIVER_IMAGING;
}
/** \ingroup dev
* Determines if a device is capable of \ref identification "identification"
* through fp_identify_finger() and similar. Not all devices support this
* functionality.
* \param dev the fingerprint device
* \returns 1 if the device is capable of identification, 0 otherwise.
*/
API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
{
return dev->drv->identify_start != NULL;
}
/** \ingroup dev
* Captures an \ref img "image" from a device. The returned image is the raw
* image provided by the device, you may wish to \ref img_std "standardize" it.
*
* If set, the <tt>unconditional</tt> flag indicates that the device should
* capture an image unconditionally, regardless of whether a finger is there
* or not. If unset, this function will block until a finger is detected on
* the sensor.
*
* \param dev the device
* \param unconditional whether to unconditionally capture an image, or to only capture when a finger is detected
* \param image a location to return the captured image. Must be freed with
* fp_img_free() after use.
* \return 0 on success, non-zero on error. -ENOTSUP indicates that either the
* unconditional flag was set but the device does not support this, or that the
* device does not support imaging.
* \sa fp_dev_supports_imaging()
*/
API_EXPORTED int fp_dev_img_capture(struct fp_dev *dev, int unconditional,
struct fp_img **image)
{
struct fp_img_dev *imgdev = dev_to_img_dev(dev);
if (!imgdev) {
fp_dbg("image capture on non-imaging device");
return -ENOTSUP;
}
//return fpi_imgdev_capture(imgdev, unconditional, image);
/* FIXME reimplement async */
return -ENOTSUP;
}
/** \ingroup dev
* Gets the expected width of images that will be captured from the device.
* This function will return -1 for devices that are not
* \ref imaging "imaging devices". If the width of images from this device
* can vary, 0 will be returned.
* \param dev the device
* \returns the expected image width, or 0 for variable, or -1 for non-imaging
* devices.
*/
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
{
struct fp_img_dev *imgdev = dev_to_img_dev(dev);
if (!imgdev) {
fp_dbg("get image width for non-imaging device");
return -1;
}
return fpi_imgdev_get_img_width(imgdev);
}
/** \ingroup dev
* Gets the expected height of images that will be captured from the device.
* This function will return -1 for devices that are not
* \ref imaging "imaging devices". If the height of images from this device
* can vary, 0 will be returned.
* \param dev the device
* \returns the expected image height, or 0 for variable, or -1 for non-imaging
* devices.
*/
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
{
struct fp_img_dev *imgdev = dev_to_img_dev(dev);
if (!imgdev) {
fp_dbg("get image height for non-imaging device");
return -1;
}
return fpi_imgdev_get_img_height(imgdev);
}
/** \ingroup core
* Set message verbosity.
* - Level 0: no messages ever printed by the library (default)
* - Level 1: error messages are printed to stderr
* - Level 2: warning and error messages are printed to stderr
* - Level 3: informational messages are printed to stdout, warning and error
* messages are printed to stderr
*
* The default level is 0, which means no messages are ever printed. If you
* choose to increase the message verbosity level, ensure that your
* application does not close the stdout/stderr file descriptors.
*
* You are advised to set level 3. libfprint is conservative with its message
* logging and most of the time, will only log messages that explain error
* conditions and other oddities. This will help you debug your software.
*
* If the LIBFPRINT_DEBUG environment variable was set when libfprint was
* initialized, this function does nothing: the message verbosity is fixed
* to the value in the environment variable.
*
* If libfprint was compiled without any message logging, this function does
* nothing: you'll never get any messages.
*
* If libfprint was compiled with verbose debug message logging, this function
* does nothing: you'll always get messages from all levels.
*
* \param ctx the context to operate on, or NULL for the default context
* \param level debug level to set
*/
API_EXPORTED void fp_set_debug(int level)
{
if (log_level_fixed)
return;
log_level = level;
libusb_set_debug(fpi_usb_ctx, level);
}
/** \ingroup core
* Initialise libfprint. This function must be called before you attempt to
* use the library in any way.
* \return 0 on success, non-zero on error.
*/
API_EXPORTED int fp_init(void)
{
char *dbg = getenv("LIBFPRINT_DEBUG");
int r;
fp_dbg("");
r = libusb_init(&fpi_usb_ctx);
if (r < 0)
return r;
if (dbg) {
log_level = atoi(dbg);
if (log_level) {
log_level_fixed = 1;
libusb_set_debug(fpi_usb_ctx, log_level);
}
}
register_drivers();
fpi_poll_init();
return 0;
}
/** \ingroup core
* Deinitialise libfprint. This function should be called during your program
* exit sequence. You must not use any libfprint functions after calling this
* function, unless you call fp_init() again.
*/
API_EXPORTED void fp_exit(void)
{
fp_dbg("");
if (opened_devices) {
GSList *copy = g_slist_copy(opened_devices);
GSList *elem = copy;
fp_dbg("naughty app left devices open on exit!");
do
fp_dev_close((struct fp_dev *) elem->data);
while ((elem = g_slist_next(elem)));
g_slist_free(copy);
g_slist_free(opened_devices);
opened_devices = NULL;
}
fpi_data_exit();
fpi_poll_exit();
g_slist_free(registered_drivers);
registered_drivers = NULL;
libusb_exit(fpi_usb_ctx);
}

View File

@@ -1,685 +0,0 @@
/*
* Fingerprint data handling and storage
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* 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 <config.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gstdio.h>
#include "fp_internal.h"
#define DIR_PERMS 0700
/** @defgroup print_data Stored prints
* Stored prints are represented by a structure named <tt>fp_print_data</tt>.
* Stored prints are originally obtained from an enrollment function such as
* fp_enroll_finger().
*
* This page documents the various operations you can do with a stored print.
* Note that by default, "stored prints" are not actually stored anywhere
* except in RAM. For the simple scenarios, libfprint provides a simple API
* for you to save and load the stored prints referring to a single user in
* their home directory. For more advanced users, libfprint provides APIs for
* you to convert print data to a byte string, and to reconstruct stored prints
* from such data at a later point. You are welcome to store these byte strings
* in any fashion that suits you.
*/
static char *base_store = NULL;
static void storage_setup(void)
{
const char *homedir;
homedir = g_getenv("HOME");
if (!homedir)
homedir = g_get_home_dir();
if (!homedir)
return;
base_store = g_build_filename(homedir, ".fprint/prints", NULL);
g_mkdir_with_parents(base_store, DIR_PERMS);
/* FIXME handle failure */
}
void fpi_data_exit(void)
{
g_free(base_store);
}
#define FP_FINGER_IS_VALID(finger) \
((finger) >= LEFT_THUMB && (finger) <= RIGHT_LITTLE)
/* for debug messages only */
#ifdef ENABLE_DEBUG_LOGGING
static const char *finger_num_to_str(enum fp_finger finger)
{
const char *names[] = {
[LEFT_THUMB] = "left thumb",
[LEFT_INDEX] = "left index",
[LEFT_MIDDLE] = "left middle",
[LEFT_RING] = "left ring",
[LEFT_LITTLE] = "left little",
[RIGHT_THUMB] = "right thumb",
[RIGHT_INDEX] = "right index",
[RIGHT_MIDDLE] = "right middle",
[RIGHT_RING] = "right ring",
[RIGHT_LITTLE] = "right little",
};
if (!FP_FINGER_IS_VALID(finger))
return "UNKNOWN";
return names[finger];
}
#endif
static struct fp_print_data *print_data_new(uint16_t driver_id,
uint32_t devtype, enum fp_print_data_type type, size_t length)
{
struct fp_print_data *data = g_malloc(sizeof(*data) + length);
fp_dbg("length=%zd driver=%02x devtype=%04x", length, driver_id, devtype);
memset(data, 0, sizeof(*data));
data->driver_id = driver_id;
data->devtype = devtype;
data->type = type;
data->length = length;
return data;
}
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
{
return print_data_new(dev->drv->id, dev->devtype,
fpi_driver_get_data_type(dev->drv), length);
}
/** \ingroup print_data
* Convert a stored print into a unified representation inside a data buffer.
* You can then store this data buffer in any way that suits you, and load
* it back at some later time using fp_print_data_from_data().
* \param data the stored print
* \param ret output location for the data buffer. Must be freed with free()
* after use.
* \returns the size of the freshly allocated buffer, or 0 on error.
*/
API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
unsigned char **ret)
{
struct fpi_print_data_fp1 *buf;
size_t buflen;
fp_dbg("");
buflen = sizeof(*buf) + data->length;
buf = malloc(buflen);
if (!buf)
return 0;
*ret = (unsigned char *) buf;
buf->prefix[0] = 'F';
buf->prefix[1] = 'P';
buf->prefix[2] = '1';
buf->driver_id = GUINT16_TO_LE(data->driver_id);
buf->devtype = GUINT32_TO_LE(data->devtype);
buf->data_type = data->type;
memcpy(buf->data, data->data, data->length);
return buflen;
}
/** \ingroup print_data
* Load a stored print from a data buffer. The contents of said buffer must
* be the untouched contents of a buffer previously supplied to you by the
* fp_print_data_get_data() function.
* \param buf the data buffer
* \param buflen the length of the buffer
* \returns the stored print represented by the data, or NULL on error. Must
* be freed with fp_print_data_free() after use.
*/
API_EXPORTED struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
size_t buflen)
{
struct fpi_print_data_fp1 *raw = (struct fpi_print_data_fp1 *) buf;
size_t print_data_len;
struct fp_print_data *data;
fp_dbg("buffer size %zd", buflen);
if (buflen < sizeof(*raw))
return NULL;
if (strncmp(raw->prefix, "FP1", 3) != 0) {
fp_dbg("bad header prefix");
return NULL;
}
print_data_len = buflen - sizeof(*raw);
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
GUINT32_FROM_LE(raw->devtype), raw->data_type, print_data_len);
memcpy(data->data, raw->data, print_data_len);
return data;
}
static char *get_path_to_storedir(uint16_t driver_id, uint32_t devtype)
{
char idstr[5];
char devtypestr[9];
g_snprintf(idstr, sizeof(idstr), "%04x", driver_id);
g_snprintf(devtypestr, sizeof(devtypestr), "%08x", devtype);
return g_build_filename(base_store, idstr, devtypestr, NULL);
}
static char *__get_path_to_print(uint16_t driver_id, uint32_t devtype,
enum fp_finger finger)
{
char *dirpath;
char *path;
char fingername[2];
g_snprintf(fingername, 2, "%x", finger);
dirpath = get_path_to_storedir(driver_id, devtype);
path = g_build_filename(dirpath, fingername, NULL);
g_free(dirpath);
return path;
}
static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger)
{
return __get_path_to_print(dev->drv->id, dev->devtype, finger);
}
/** \ingroup print_data
* Saves a stored print to disk, assigned to a specific finger. Even though
* you are limited to storing only the 10 human fingers, this is a
* per-device-type limit. For example, you can store the users right index
* finger from a DigitalPersona scanner, and you can also save the right index
* finger from a UPEK scanner. When you later come to load the print, the right
* one will be automatically selected.
*
* This function will unconditionally overwrite a fingerprint previously
* saved for the same finger and device type. The print is saved in a hidden
* directory beneath the current user's home directory.
* \param data the stored print to save to disk
* \param finger the finger that this print corresponds to
* \returns 0 on success, non-zero on error.
*/
API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
enum fp_finger finger)
{
GError *err = NULL;
char *path;
char *dirpath;
unsigned char *buf;
size_t len;
int r;
if (!base_store)
storage_setup();
fp_dbg("save %s print from driver %04x", finger_num_to_str(finger),
data->driver_id);
len = fp_print_data_get_data(data, &buf);
if (!len)
return -ENOMEM;
path = __get_path_to_print(data->driver_id, data->devtype, finger);
dirpath = g_path_get_dirname(path);
r = g_mkdir_with_parents(dirpath, DIR_PERMS);
if (r < 0) {
fp_err("couldn't create storage directory");
g_free(path);
g_free(dirpath);
return r;
}
fp_dbg("saving to %s", path);
g_file_set_contents(path, buf, len, &err);
free(buf);
g_free(dirpath);
g_free(path);
if (err) {
r = err->code;
fp_err("save failed: %s", err->message);
g_error_free(err);
/* FIXME interpret error codes */
return r;
}
return 0;
}
gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
enum fp_print_data_type type2)
{
if (driver_id1 != driver_id2) {
fp_dbg("driver ID mismatch: %02x vs %02x", driver_id1, driver_id2);
return FALSE;
}
if (devtype1 != devtype2) {
fp_dbg("devtype mismatch: %04x vs %04x", devtype1, devtype2);
return FALSE;
}
if (type1 != type2) {
fp_dbg("type mismatch: %d vs %d", type1, type2);
return FALSE;
}
return TRUE;
}
static int load_from_file(char *path, struct fp_print_data **data)
{
gsize length;
gchar *contents;
GError *err = NULL;
struct fp_print_data *fdata;
fp_dbg("from %s", path);
g_file_get_contents(path, &contents, &length, &err);
if (err) {
int r = err->code;
fp_err("%s load failed: %s", path, err->message);
g_error_free(err);
/* FIXME interpret more error codes */
if (r == G_FILE_ERROR_NOENT)
return -ENOENT;
else
return r;
}
fdata = fp_print_data_from_data(contents, length);
g_free(contents);
if (!fdata)
return -EIO;
*data = fdata;
return 0;
}
/** \ingroup print_data
* Loads a previously stored print from disk. The print must have been saved
* earlier using the fp_print_data_save() function.
*
* A return code of -ENOENT indicates that the fingerprint requested could not
* be found. Other error codes (both positive and negative) are possible for
* obscure error conditions (e.g. corruption).
*
* \param dev the device you are loading the print for
* \param finger the finger of the file you are loading
* \param data output location to put the corresponding stored print. Must be
* freed with fp_print_data_free() after use.
* \returns 0 on success, non-zero on error
*/
API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
enum fp_finger finger, struct fp_print_data **data)
{
gchar *path;
struct fp_print_data *fdata;
int r;
if (!base_store)
storage_setup();
path = get_path_to_print(dev, finger);
r = load_from_file(path, &fdata);
g_free(path);
if (r)
return r;
if (!fp_dev_supports_print_data(dev, fdata)) {
fp_err("print data is not compatible!");
fp_print_data_free(fdata);
return -EINVAL;
}
*data = fdata;
return 0;
}
/** \ingroup print_data
* Removes a stored print from disk previously saved with fp_print_data_save().
* \param dev the device that the print belongs to
* \param finger the finger of the file you are deleting
* \returns 0 on success, negative on error
*/
API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
enum fp_finger finger)
{
int r;
gchar *path = get_path_to_print(dev, finger);
fp_dbg("remove finger %d at %s", finger, path);
r = g_unlink(path);
g_free(path);
if (r < 0)
fp_dbg("unlink failed with error %d", r);
/* FIXME: cleanup empty directory */
return r;
}
/** \ingroup print_data
* Attempts to load a stored print based on a \ref dscv_print
* "discovered print" record.
*
* A return code of -ENOENT indicates that the file referred to by the
* discovered print could not be found. Other error codes (both positive and
* negative) are possible for obscure error conditions (e.g. corruption).
*
* \param print the discovered print
* \param data output location to point to the corresponding stored print. Must
* be freed with fp_print_data_free() after use.
* \returns 0 on success, non-zero on error.
*/
API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
struct fp_print_data **data)
{
return load_from_file(print->path, data);
}
/** \ingroup print_data
* Frees a stored print. Must be called when you are finished using the print.
* \param data the stored print to destroy. If NULL, function simply returns.
*/
API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
{
g_free(data);
}
/** \ingroup print_data
* Gets the \ref driver_id "driver ID" for a stored print. The driver ID
* indicates which driver the print originally came from. The print is
* only usable with a device controlled by that driver.
* \param data the stored print
* \returns the driver ID of the driver compatible with the print
*/
API_EXPORTED uint16_t fp_print_data_get_driver_id(struct fp_print_data *data)
{
return data->driver_id;
}
/** \ingroup print_data
* Gets the \ref devtype "devtype" for a stored print. The devtype represents
* which type of device under the parent driver is compatible with the print.
* \param data the stored print
* \returns the devtype of the device range compatible with the print
*/
API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
{
return data->devtype;
}
/** @defgroup dscv_print Print discovery
* The \ref print_data "stored print" documentation detailed a simple API
* for storing per-device prints for a single user, namely
* fp_print_data_save(). It also detailed a load function,
* fp_print_data_load(), but usage of this function is limited to scenarios
* where you know which device you would like to use, and you know which
* finger you are looking to verify.
*
* In other cases, it would be more useful to be able to enumerate all
* previously saved prints, potentially even before device discovery. These
* functions are designed to offer this functionality to you.
*
* Discovered prints are stored in a <tt>dscv_print</tt> structure, and you
* can use functions documented below to access some information about these
* prints. You can determine if a discovered print appears to be compatible
* with a device using functions such as fp_dscv_dev_supports_dscv_print() and
* fp_dev_supports_dscv_print().
*
* When you are ready to use the print, you can load it into memory in the form
* of a stored print by using the fp_print_data_from_dscv_print() function.
*
* You may have noticed the use of the word "appears" in the above paragraphs.
* libfprint performs print discovery simply by examining the file and
* directory structure of libfprint's private data store. It does not examine
* the actual prints themselves. Just because a print has been discovered
* and appears to be compatible with a certain device does not necessarily mean
* that it is usable; when you come to load or use it, under unusual
* circumstances it may turn out that the print is corrupt or not for the
* device that it appeared to be. Also, it is possible that the print may have
* been deleted by the time you come to load it.
*/
static GSList *scan_dev_store_dir(char *devpath, uint16_t driver_id,
uint32_t devtype, GSList *list)
{
GError *err = NULL;
const gchar *ent;
struct fp_dscv_print *print;
GDir *dir = g_dir_open(devpath, 0, &err);
if (!dir) {
fp_err("opendir %s failed: %s", devpath, err->message);
g_error_free(err);
return list;
}
while ((ent = g_dir_read_name(dir))) {
/* ent is an 1 hex character fp_finger code */
guint64 val;
enum fp_finger finger;
gchar *endptr;
if (*ent == 0 || strlen(ent) != 1)
continue;
val = g_ascii_strtoull(ent, &endptr, 16);
if (endptr == ent || !FP_FINGER_IS_VALID(val)) {
fp_dbg("skipping print file %s", ent);
continue;
}
finger = (enum fp_finger) val;
print = g_malloc(sizeof(*print));
print->driver_id = driver_id;
print->devtype = devtype;
print->path = g_build_filename(devpath, ent, NULL);
print->finger = finger;
list = g_slist_prepend(list, print);
}
g_dir_close(dir);
return list;
}
static GSList *scan_driver_store_dir(char *drvpath, uint16_t driver_id,
GSList *list)
{
GError *err = NULL;
const gchar *ent;
GDir *dir = g_dir_open(drvpath, 0, &err);
if (!dir) {
fp_err("opendir %s failed: %s", drvpath, err->message);
g_error_free(err);
return list;
}
while ((ent = g_dir_read_name(dir))) {
/* ent is an 8 hex character devtype */
guint64 val;
uint32_t devtype;
gchar *endptr;
gchar *path;
if (*ent == 0 || strlen(ent) != 8)
continue;
val = g_ascii_strtoull(ent, &endptr, 16);
if (endptr == ent) {
fp_dbg("skipping devtype %s", ent);
continue;
}
devtype = (uint32_t) val;
path = g_build_filename(drvpath, ent, NULL);
list = scan_dev_store_dir(path, driver_id, devtype, list);
g_free(path);
}
g_dir_close(dir);
return list;
}
/** \ingroup dscv_print
* Scans the users home directory and returns a list of prints that were
* previously saved using fp_print_data_save().
* \returns a NULL-terminated list of discovered prints, must be freed with
* fp_dscv_prints_free() after use.
*/
API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
{
GDir *dir;
const gchar *ent;
GError *err = NULL;
GSList *tmplist = NULL;
GSList *elem;
unsigned int tmplist_len;
struct fp_dscv_print **list;
unsigned int i;
if (!base_store)
storage_setup();
dir = g_dir_open(base_store, 0, &err);
if (!dir) {
fp_err("opendir %s failed: %s", base_store, err->message);
g_error_free(err);
return NULL;
}
while ((ent = g_dir_read_name(dir))) {
/* ent is a 4 hex digit driver_id */
gchar *endptr;
gchar *path;
guint64 val;
uint16_t driver_id;
if (*ent == 0 || strlen(ent) != 4)
continue;
val = g_ascii_strtoull(ent, &endptr, 16);
if (endptr == ent) {
fp_dbg("skipping drv id %s", ent);
continue;
}
driver_id = (uint16_t) val;
path = g_build_filename(base_store, ent, NULL);
tmplist = scan_driver_store_dir(path, driver_id, tmplist);
g_free(path);
}
g_dir_close(dir);
tmplist_len = g_slist_length(tmplist);
list = g_malloc(sizeof(*list) * (tmplist_len + 1));
elem = tmplist;
for (i = 0; i < tmplist_len; i++, elem = g_slist_next(elem))
list[i] = elem->data;
list[tmplist_len] = NULL; /* NULL-terminate */
g_slist_free(tmplist);
return list;
}
/** \ingroup dscv_print
* Frees a list of discovered prints. This function also frees the discovered
* prints themselves, so make sure you do not use any discovered prints
* after calling this function.
* \param prints the list of discovered prints. If NULL, function simply
* returns.
*/
API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints)
{
int i;
struct fp_dscv_print *print;
if (!prints)
return;
for (i = 0; (print = prints[i]); i++) {
if (print)
g_free(print->path);
g_free(print);
}
g_free(prints);
}
/** \ingroup dscv_print
* Gets the \ref driver_id "driver ID" for a discovered print. The driver ID
* indicates which driver the print originally came from. The print is only
* usable with a device controlled by that driver.
* \param print the discovered print
* \returns the driver ID of the driver compatible with the print
*/
API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print)
{
return print->driver_id;
}
/** \ingroup dscv_print
* Gets the \ref devtype "devtype" for a discovered print. The devtype
* represents which type of device under the parent driver is compatible
* with the print.
* \param print the discovered print
* \returns the devtype of the device range compatible with the print
*/
API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print)
{
return print->devtype;
}
/** \ingroup dscv_print
* Gets the finger code for a discovered print.
* \param print discovered print
* \returns a finger code from #fp_finger
*/
API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print)
{
return print->finger;
}
/** \ingroup dscv_print
* Removes a discovered print from disk. After successful return of this
* function, functions such as fp_dscv_print_get_finger() will continue to
* operate as before, however calling fp_print_data_from_dscv_print() will
* fail for obvious reasons.
* \param print the discovered print to remove from disk
* \returns 0 on success, negative on error
*/
API_EXPORTED int fp_dscv_print_delete(struct fp_dscv_print *print)
{
int r;
fp_dbg("remove at %s", print->path);
r = g_unlink(print->path);
if (r < 0)
fp_dbg("unlink failed with error %d", r);
/* FIXME: cleanup empty directory */
return r;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
/*
* AuthenTec AES1660 driver for libfprint
* Copyright (C) 2012 Vasily Khoruzhick
*
* 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 "aes1660"
#include "drivers_api.h"
#include "aeslib.h"
#include "aesx660.h"
#include "aes1660.h"
#define FRAME_WIDTH 128
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
struct _FpiDeviceAes1660
{
FpiDeviceAesX660 parent;
};
G_DECLARE_FINAL_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI,
DEVICE_AES1660, FpiDeviceAesX660);
G_DEFINE_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI_TYPE_DEVICE_AES_X660);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
.frame_height = AESX660_FRAME_HEIGHT,
.image_width = IMAGE_WIDTH,
.get_pixel = aes_get_pixel,
};
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x1660, },
{ .vid = 0x08ff, .pid = 0x1680, },
{ .vid = 0x08ff, .pid = 0x1681, },
{ .vid = 0x08ff, .pid = 0x1682, },
{ .vid = 0x08ff, .pid = 0x1683, },
{ .vid = 0x08ff, .pid = 0x1684, },
{ .vid = 0x08ff, .pid = 0x1685, },
{ .vid = 0x08ff, .pid = 0x1686, },
{ .vid = 0x08ff, .pid = 0x1687, },
{ .vid = 0x08ff, .pid = 0x1688, },
{ .vid = 0x08ff, .pid = 0x1689, },
{ .vid = 0x08ff, .pid = 0x168a, },
{ .vid = 0x08ff, .pid = 0x168b, },
{ .vid = 0x08ff, .pid = 0x168c, },
{ .vid = 0x08ff, .pid = 0x168d, },
{ .vid = 0x08ff, .pid = 0x168e, },
{ .vid = 0x08ff, .pid = 0x168f, },
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
static void
fpi_device_aes1660_init (FpiDeviceAes1660 *self)
{
}
static void
fpi_device_aes1660_class_init (FpiDeviceAes1660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
dev_class->id = "aes1660";
dev_class->full_name = "AuthenTec AES1660";
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->id_table = id_table;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->bz3_threshold = 20;
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
img_class->img_height = -1;
aes_class->init_seqs[0] = aes1660_init_1;
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes1660_init_1);
aes_class->init_seqs[1] = aes1660_init_2;
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes1660_init_2);
aes_class->start_imaging_cmd = (unsigned char *) aes1660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof (aes1660_start_imaging_cmd);
aes_class->assembling_ctx = &assembling_ctx;
}

1989
libfprint/drivers/aes1660.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,152 +19,155 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __AES2501_H
#define __AES2501_H
#pragma once
enum aes2501_regs {
AES2501_REG_CTRL1 = 0x80,
AES2501_REG_CTRL2 = 0x81,
AES2501_REG_EXCITCTRL = 0x82, /* excitation control */
AES2501_REG_DETCTRL = 0x83, /* detect control */
AES2501_REG_COLSCAN = 0x88, /* column scan rate register */
AES2501_REG_MEASDRV = 0x89, /* measure drive */
AES2501_REG_MEASFREQ = 0x8a, /* measure frequency */
AES2501_REG_DEMODPHASE1 = 0x8d,
AES2501_REG_DEMODPHASE2 = 0x8c,
AES2501_REG_CHANGAIN = 0x8e, /* channel gain */
AES2501_REG_ADREFHI = 0x91, /* A/D reference high */
AES2501_REG_ADREFLO = 0x92, /* A/D reference low */
AES2501_REG_STRTROW = 0x93, /* start row */
AES2501_REG_ENDROW = 0x94, /* end row */
AES2501_REG_STRTCOL = 0x95, /* start column */
AES2501_REG_ENDCOL = 0x96, /* end column */
AES2501_REG_DATFMT = 0x97, /* data format */
AES2501_REG_IMAGCTRL = 0x98, /* image data */
AES2501_REG_STAT = 0x9a,
AES2501_REG_CHWORD1 = 0x9b, /* challenge word 1 */
AES2501_REG_CHWORD2 = 0x9c,
AES2501_REG_CHWORD3 = 0x9d,
AES2501_REG_CHWORD4 = 0x9e,
AES2501_REG_CHWORD5 = 0x9f,
AES2501_REG_TREG1 = 0xa1, /* test register 1 */
AES2501_REG_AUTOCALOFFSET = 0xa8,
AES2501_REG_TREGC = 0xac,
AES2501_REG_TREGD = 0xad,
AES2501_REG_LPONT = 0xb4, /* low power oscillator on time */
AES2501_REG_CTRL1 = 0x80,
AES2501_REG_CTRL2 = 0x81,
AES2501_REG_EXCITCTRL = 0x82, /* excitation control */
AES2501_REG_DETCTRL = 0x83, /* detect control */
AES2501_REG_COLSCAN = 0x88, /* column scan rate register */
AES2501_REG_MEASDRV = 0x89, /* measure drive */
AES2501_REG_MEASFREQ = 0x8a, /* measure frequency */
AES2501_REG_DEMODPHASE1 = 0x8d,
AES2501_REG_DEMODPHASE2 = 0x8c,
AES2501_REG_CHANGAIN = 0x8e, /* channel gain */
AES2501_REG_ADREFHI = 0x91, /* A/D reference high */
AES2501_REG_ADREFLO = 0x92, /* A/D reference low */
AES2501_REG_STRTROW = 0x93, /* start row */
AES2501_REG_ENDROW = 0x94, /* end row */
AES2501_REG_STRTCOL = 0x95, /* start column */
AES2501_REG_ENDCOL = 0x96, /* end column */
AES2501_REG_DATFMT = 0x97, /* data format */
AES2501_REG_IMAGCTRL = 0x98, /* image data */
AES2501_REG_STAT = 0x9a,
AES2501_REG_CHWORD1 = 0x9b, /* challenge word 1 */
AES2501_REG_CHWORD2 = 0x9c,
AES2501_REG_CHWORD3 = 0x9d,
AES2501_REG_CHWORD4 = 0x9e,
AES2501_REG_CHWORD5 = 0x9f,
AES2501_REG_TREG1 = 0xa1, /* test register 1 */
AES2501_REG_AUTOCALOFFSET = 0xa8,
AES2501_REG_TREGC = 0xac,
AES2501_REG_TREGD = 0xad,
AES2501_REG_LPONT = 0xb4, /* low power oscillator on time */
};
#define FIRST_AES2501_REG AES2501_REG_CTRL1
#define LAST_AES2501_REG AES2501_REG_CHWORD5
#define FIRST_AES2501_REG AES2501_REG_CTRL1
#define LAST_AES2501_REG AES2501_REG_CHWORD5
#define AES2501_CTRL1_MASTER_RESET (1<<0)
#define AES2501_CTRL1_SCAN_RESET (1<<1) /* stop + restart scan sequencer */
#define AES2501_CTRL1_MASTER_RESET (1 << 0)
#define AES2501_CTRL1_SCAN_RESET (1 << 1) /* stop + restart scan sequencer */
/* 1 = continuously updated, 0 = updated prior to starting a scan */
#define AES2501_CTRL1_REG_UPDATE (1<<2)
#define AES2501_CTRL1_REG_UPDATE (1 << 2)
/* 1 = continuous scans, 0 = single scans */
#define AES2501_CTRL2_CONTINUOUS 0x01
#define AES2501_CTRL2_READ_REGS 0x02 /* dump registers */
#define AES2501_CTRL2_SET_ONE_SHOT 0x04
#define AES2501_CTRL2_CLR_ONE_SHOT 0x08
#define AES2501_CTRL2_READ_ID 0x10
#define AES2501_CTRL2_CONTINUOUS 0x01
#define AES2501_CTRL2_READ_REGS 0x02 /* dump registers */
#define AES2501_CTRL2_SET_ONE_SHOT 0x04
#define AES2501_CTRL2_CLR_ONE_SHOT 0x08
#define AES2501_CTRL2_READ_ID 0x10
enum aes2501_detection_rate {
/* rate of detection cycles: */
AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* continuously */
AES2501_DETCTRL_DRATE_16_MS = 0x01, /* every 16.62ms */
AES2501_DETCTRL_DRATE_31_MS = 0x02, /* every 31.24ms */
AES2501_DETCTRL_DRATE_62_MS = 0x03, /* every 62.50ms */
AES2501_DETCTRL_DRATE_125_MS = 0x04, /* every 125.0ms */
AES2501_DETCTRL_DRATE_250_MS = 0x05, /* every 250.0ms */
AES2501_DETCTRL_DRATE_500_MS = 0x06, /* every 500.0ms */
AES2501_DETCTRL_DRATE_1_S = 0x07, /* every 1s */
/* rate of detection cycles: */
AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* continuously */
AES2501_DETCTRL_DRATE_16_MS = 0x01, /* every 16.62ms */
AES2501_DETCTRL_DRATE_31_MS = 0x02, /* every 31.24ms */
AES2501_DETCTRL_DRATE_62_MS = 0x03, /* every 62.50ms */
AES2501_DETCTRL_DRATE_125_MS = 0x04, /* every 125.0ms */
AES2501_DETCTRL_DRATE_250_MS = 0x05, /* every 250.0ms */
AES2501_DETCTRL_DRATE_500_MS = 0x06, /* every 500.0ms */
AES2501_DETCTRL_DRATE_1_S = 0x07, /* every 1s */
};
enum aes2501_settling_delay {
AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25ms */
AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5ms */
AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125ms */
AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250ms */
AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25ms */
AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5ms */
AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125ms */
AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250ms */
};
enum aes2501_col_scan_rate {
AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32us */
AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64us */
AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128us */
AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256us */
AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512us */
AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024us */
AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048us */
AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32us */
AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64us */
AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128us */
AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256us */
AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512us */
AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024us */
AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048us */
};
enum aes2501_mesure_drive {
AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */
AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */
AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */
AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */
AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */
AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */
AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */
AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */
};
/* Select (1=square | 0=sine) wave drive during measure */
#define AES2501_MEASDRV_SQUARE 0x20
/* 0 = use mesure drive setting, 1 = when sine wave is selected */
#define AES2501_MEASDRV_MEASURE_SQUARE 0x10
#define AES2501_MEASDRV_SQUARE 0x20
/* 0 = use measure drive setting, 1 = when sine wave is selected */
#define AES2501_MEASDRV_MEASURE_SQUARE 0x10
enum aes2501_measure_freq {
AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */
AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */
AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */
AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */
AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */
AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */
AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */
AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */
AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */
AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */
};
#define DEMODPHASE_NONE 0x00
#define DEMODPHASE_180_00 0x40 /* 180 degrees */
#define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */
#define DEMODPHASE_NONE 0x00
#define DEMODPHASE_180_00 0x40 /* 180 degrees */
#define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */
#define AES2501_REG_DEMODPHASE1 0x8d
#define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */
#define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */
#define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */
#define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */
enum aes2501_sensor_gain1 {
AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */
AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */
AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */
AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */
AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */
AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */
AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */
AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */
};
enum aes2501_sensor_gain2 {
AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */
AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */
AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */
AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */
AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */
AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */
AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */
AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */
};
#define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */
#define AES2501_DATFMT_LOW_RES 0x20
#define AES2501_DATFMT_BIN_IMG 0x10
#define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */
#define AES2501_DATFMT_LOW_RES 0x20
#define AES2501_DATFMT_BIN_IMG 0x10
/* don't send image or authentication messages when imaging */
#define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01
#define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01
/* send histogram when imaging */
#define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02
#define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02
/* send histogram at end of each row rather than each scan */
#define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04
#define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04
/* send full image array rather than 64x64 center */
#define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08
#define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08
/* return registers before data (rather than after) */
#define AES2501_IMAGCTRL_REG_FIRST 0x10
#define AES2501_IMAGCTRL_REG_FIRST 0x10
/* return test registers with register dump */
#define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20
#define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20
#define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */
#define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */
/* Enable the reading of the register in TREGD */
#define AES2501_TREGC_ENABLE 0x01
#define AES2501_TREGC_ENABLE 0x01
#define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */
#define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */
#define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */
#define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */
#endif /* __AES2501_H */
#define AES2501_ADREFHI_MIN_VALUE 0x28
#define AES2501_ADREFHI_MAX_VALUE 0x58
#define AES2501_SUM_HIGH_THRESH 1000
#define AES2501_SUM_LOW_THRESH 700

582
libfprint/drivers/aes2550.c Normal file
View File

@@ -0,0 +1,582 @@
/*
* AuthenTec AES2550/AES2810 driver for libfprint
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2007 Cyrille Bagard
* Copyright (C) 2007-2012 Vasily Khoruzhick
*
* Based on AES2501 driver
*
* 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 "aes2550"
#include "drivers_api.h"
#include "aes2550.h"
#include "aeslib.h"
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
#define BULK_TIMEOUT 4000
/*
* The AES2550 is an imaging device using a swipe-type sensor. It samples
* the finger at preprogrammed intervals, sending a 192x16 frame to the
* computer.
* Unless the user is scanning their finger unreasonably fast, the frames
* *will* overlap. The implementation below detects this overlap and produces
* a contiguous image as the end result.
* The fact that the user determines the length of the swipe (and hence the
* number of useful frames) and also the fact that overlap varies means that
* images returned from this driver vary in height.
*/
#define FRAME_WIDTH 192
#define FRAME_HEIGHT 8
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
struct _FpiDeviceAes2550
{
FpImageDevice parent;
GSList *strips;
size_t strips_len;
gboolean deactivating;
int heartbeat_cnt;
};
G_DECLARE_FINAL_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
FpImageDevice);
G_DEFINE_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
.frame_height = FRAME_HEIGHT,
.image_width = IMAGE_WIDTH,
.get_pixel = aes_get_pixel,
};
/****** FINGER PRESENCE DETECTION ******/
static unsigned char finger_det_reqs[] = {
0x80, AES2550_REG80_MASTER_RESET,
0x95, (8 << AES2550_REG95_COL_SCANNED_OFS) | (1 << AES2550_REG95_EPIX_AVG_OFS),
0xad, 0x00,
0xbd, (0 << AES2550_REGBD_LPO_IN_15_8_OFS),
0xbe, (0 << AES2550_REGBE_LPO_IN_7_0_OFS),
0xcf, AES2550_REGCF_INTERFERENCE_CHK_EN,
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
AES2550_CMD_RUN_FD,
};
static void start_finger_detection (FpImageDevice *dev);
static void
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
unsigned char *data = transfer->buffer;
if (error)
{
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
return;
}
fp_dbg ("transfer completed, len: %.4x, data: %.2x %.2x",
(gint) transfer->actual_length, (int) data[0], (int) data[1]);
/* Check if we got 2 bytes, reg address 0x83 and its value */
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT))
{
/* finger present, start capturing */
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
else
{
/* no finger, poll for a new histogram */
start_finger_detection (dev);
}
}
static void
finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
gpointer user_data, GError *error)
{
FpiUsbTransfer *transfer;
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
transfer = fpi_usb_transfer_new (device);
/* 2 bytes of result */
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
}
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
FpiUsbTransfer *transfer;
G_DEBUG_HERE ();
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, finger_det_reqs,
sizeof (finger_det_reqs), NULL);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_reqs_cb, NULL);
}
/****** CAPTURE ******/
static unsigned char capture_reqs[] = {
0x80, AES2550_REG80_MASTER_RESET,
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_HGC_ENABLE),
0x85, AES2550_REG85_FLUSH_PER_FRAME,
0x8f, AES2550_REG8F_AUTH_DISABLE | AES2550_REG8F_EHISTO_DISABLE,
0xbf, AES2550_REGBF_RSR_DIR_UPDOWN_MOTION | AES2550_REGBF_RSR_LEVEL_SUPER_RSR,
0xcf, (3 << AES2550_REGCF_INTERFERENCE_AVG_OFFS) | AES2550_REGCF_INTERFERENCE_AVG_EN,
0xdc, (1 << AES2550_REGDC_BP_NUM_REF_SWEEP_OFS),
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x03, /* Heart beat cmd, 3 * 16 cycles without sending image */
AES2550_CMD_GET_ENROLL_IMG,
};
static unsigned char capture_set_idle_reqs[] = {
0x80, AES2550_REG80_MASTER_RESET,
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
AES2550_CMD_SET_IDLE_MODE,
};
enum capture_states {
CAPTURE_WRITE_REQS,
CAPTURE_READ_DATA,
CAPTURE_SET_IDLE,
CAPTURE_NUM_STATES,
};
/* Returns number of processed bytes */
static gboolean
process_strip_data (FpiSsm *ssm, FpImageDevice *dev,
unsigned char *data)
{
unsigned char *stripdata;
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
struct fpi_frame *stripe;
int len;
if (data[0] != AES2550_EDATA_MAGIC)
{
fp_dbg ("Bogus magic: %.2x", (int) (data[0]));
return FALSE;
}
len = data[1] * 256 + data[2];
if (len != (AES2550_STRIP_SIZE - 3))
fp_dbg ("Bogus frame len: %.4x", len);
stripe = g_malloc0 (FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bits per pixel */
stripe->delta_x = (int8_t) data[6];
stripe->delta_y = -(int8_t) data[7];
stripdata = stripe->data;
memcpy (stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
self->strips = g_slist_prepend (self->strips, stripe);
self->strips_len++;
fp_dbg ("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
return TRUE;
}
static void
capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer user_data,
GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
if (!error && self->strips_len)
{
FpImage *img;
self->strips = g_slist_reverse (self->strips);
img = fpi_assemble_frames (&assembling_ctx, self->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
/* marking machine complete will re-trigger finger detection loop */
fpi_ssm_mark_completed (transfer->ssm);
}
else
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
}
static void
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
unsigned char *data = transfer->buffer;
if (error)
{
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fp_dbg ("request completed, len: %.4x", (gint) transfer->actual_length);
if (transfer->actual_length >= 2)
fp_dbg ("data: %.2x %.2x", (int) data[0], (int) data[1]);
switch (transfer->actual_length)
{
case AES2550_STRIP_SIZE:
if (!process_strip_data (transfer->ssm, dev, data))
{
fp_dbg ("Processing strip data failed");
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
return;
}
self->heartbeat_cnt = 0;
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
break;
case AES2550_HEARTBEAT_SIZE:
if (data[0] == AES2550_HEARTBEAT_MAGIC)
{
/* No data for a long time => finger was removed or there's no movement */
self->heartbeat_cnt++;
if (self->heartbeat_cnt == 3)
{
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
* assemble image and submit it to the library */
fp_dbg ("Got 3 heartbeats => finger removed");
fpi_ssm_next_state (transfer->ssm);
}
else
{
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_READ_DATA);
}
}
break;
default:
fp_dbg ("Short frame %d, skip",
(gint) transfer->actual_length);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
break;
}
}
static void
capture_run_state (FpiSsm *ssm, FpDevice *dev)
{
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_WRITE_REQS:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, capture_reqs,
sizeof (capture_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
break;
case CAPTURE_READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_data_cb, NULL);
}
break;
case CAPTURE_SET_IDLE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
capture_set_idle_reqs,
sizeof (capture_set_idle_reqs),
NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_set_idle_reqs_cb, NULL);
}
break;
}
;
}
static void
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (_dev);
FpImageDevice *dev = FP_IMAGE_DEVICE (self);
fp_dbg ("Capture completed");
if (self->deactivating)
{
complete_deactivation (dev);
g_clear_pointer (&error, g_error_free);
}
else if (error)
{
fpi_image_device_session_error (dev, error);
}
else
{
start_finger_detection (dev);
}
}
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
FpiSsm *ssm;
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
self->heartbeat_cnt = 0;
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state, CAPTURE_NUM_STATES);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
static unsigned char init_reqs[] = {
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_FORCE_FINGER_PRESENT),
0x85, AES2550_REG85_FLUSH_PER_FRAME,
0xa8, AES2550_REGA8_DIG_BIT_EN,
0x81, AES2550_REG81_NSHOT,
};
static unsigned char calibrate_reqs[] = {
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
AES2550_CMD_CALIBRATE,
AES2550_CMD_READ_CALIBRATION_DATA,
};
enum activate_states {
WRITE_INIT,
READ_DATA,
CALIBRATE,
READ_CALIB_TABLE,
ACTIVATE_NUM_STATES,
};
/* TODO: use calibration table, datasheet is rather terse on that
* need more info for implementation */
static void
calibrate_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
fpi_ssm_usb_transfer_cb (transfer, device, user_data, error);
}
static void
activate_run_state (FpiSsm *ssm, FpDevice *dev)
{
switch (fpi_ssm_get_cur_state (ssm))
{
case WRITE_INIT:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, init_reqs,
sizeof (init_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
break;
case READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
break;
case CALIBRATE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
calibrate_reqs,
sizeof (calibrate_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
break;
case READ_CALIB_TABLE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
calibrate_read_data_cb, NULL);
}
break;
}
}
static void
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
fpi_image_device_activate_complete (dev, error);
if (!error)
start_finger_detection (dev);
}
static void
dev_activate (FpImageDevice *dev)
{
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
self->deactivating = TRUE;
}
static void
complete_deactivation (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
G_DEBUG_HERE ();
self->deactivating = FALSE;
g_slist_free (self->strips);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_deactivate_complete (dev, NULL);
}
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
/* TODO check that device has endpoints we're using */
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
fpi_image_device_open_complete (dev, error);
}
static void
dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x2550, },/* AES2550 */
{ .vid = 0x08ff, .pid = 0x2810, },/* AES2810 */
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
static void
fpi_device_aes2550_init (FpiDeviceAes2550 *self)
{
}
static void
fpi_device_aes2550_class_init (FpiDeviceAes2550Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
dev_class->id = "aes2550";
dev_class->full_name = "AuthenTec AES2550/AES2810";
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->id_table = id_table;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->img_open = dev_init;
img_class->img_close = dev_deinit;
img_class->activate = dev_activate;
img_class->deactivate = dev_deactivate;
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
img_class->img_height = -1;
}

111
libfprint/drivers/aes2550.h Normal file
View File

@@ -0,0 +1,111 @@
/*
* AuthenTec AES2550/AES2810 driver for libfprint
* Copyright (C) 2012 Vasily Khoruzhick
*
* 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
/* Registers bits */
#define AES2550_REG80_MASTER_RESET (1 << 0)
#define AES2550_REG80_FORCE_FINGER_PRESENT (1 << 1)
#define AES2550_REG80_LPO_START (1 << 2)
#define AES2550_REG80_HGC_ENABLE (1 << 3)
#define AES2550_REG80_SENSOR_MODE_OFS (4)
#define AES2550_REG80_AUTO_RESTART_FD (1 << 6)
#define AES2550_REG80_EXT_REG_ENABLE (1 << 7)
#define AES2550_REG81_CONT_SCAN (1 << 0)
#define AES2550_REG81_READ_REG (1 << 1)
#define AES2550_REG81_NSHOT (1 << 2)
#define AES2550_REG81_RUN_FD (1 << 3)
#define AES2550_REG81_READ_ID (1 << 4)
#define AES2550_REG81_RUN_CAL (1 << 5)
#define AES2550_REG81_RUN_TIMER (1 << 6)
#define AES2550_REG81_RUN_BIST (1 << 7)
#define AES2550_REG83_FINGER_PRESENT (1 << 7)
#define AES2550_REG85_FLUSH_PER_FRAME (1 << 7)
#define AES2550_REG8F_EDATA_DISABLE (1 << 1)
#define AES2550_REG8F_AUTH_DISABLE (1 << 2)
#define AES2550_REG8F_EHISTO_DISABLE (1 << 3)
#define AES2550_REG8F_HISTO64 (1 << 4)
#define AES2550_REG8F_SINGLE_REG_ENABLE (1 << 6)
#define AES2550_REG95_COL_SCANNED_OFS (0)
#define AES2550_REG95_EPIX_AVG_OFS (4)
#define AES2550_REGA8_DIG_BIT_DATA_OFS (0)
#define AES2550_REGA8_DIG_BIT_EN (1 << 4)
#define AES2550_REGA8_FIXED_BIT_DATA (1 << 5)
#define AES2550_REGA8_INVERT_BIT_DATA (1 << 6)
#define AES2550_REGAD_LPFD_AVG_OFS (0)
#define AES2550_REGAD_DETECT_FGROFF (1 << 4)
#define AES2550_REGAD_ADVRANGE_2V (1 << 6)
#define AES2550_REGB1_ATE_CONT_IMAGE (1 << 1)
#define AES2550_REGB1_ANALOG_RESET (1 << 2)
#define AES2550_REGB1_ANALOG_PD (1 << 3)
#define AES2550_REGB1_TEST_EMBD_WORD (1 << 4)
#define AES2550_REGB1_ORIG_EMBD_WORD (1 << 5)
#define AES2550_REGB1_RESET_UHSM (1 << 6)
#define AES2550_REGB1_RESET_SENSOR (1 << 7)
#define AES2550_REGBD_LPO_IN_15_8_OFS (0)
#define AES2550_REGBE_LPO_IN_7_0_OFS (0)
#define AES2550_REGBF_RSR_LEVEL_DISABLED (0 << 0)
#define AES2550_REGBF_RSR_LEVEL_LEADING_RSR (1 << 0)
#define AES2550_REGBF_RSR_LEVEL_SIMPLE_RSR (2 << 0)
#define AES2550_REGBF_RSR_LEVEL_SUPER_RSR (3 << 0)
#define AES2550_REGBF_RSR_DIR_DOWN_MOTION (0 << 2)
#define AES2550_REGBF_RSR_DIR_UP_MOTION (1 << 2)
#define AES2550_REGBF_RSR_DIR_UPDOWN_MOTION (2 << 2)
#define AES2550_REGBF_NOISE_FLOOR_MODE (1 << 4)
#define AES2550_REGBF_QUADRATURE_MODE (1 << 5)
#define AES2550_REGCF_INTERFERENCE_CHK_EN (1 << 0)
#define AES2550_REGCF_INTERFERENCE_AVG_EN (1 << 1)
#define AES2550_REGCF_INTERFERENCE_AVG_OFFS (4)
#define AES2550_REGDC_BP_NUM_REF_SWEEP_OFS (0)
#define AES2550_REGDC_DEBUG_CTRL2_OFS (3)
#define AES2550_REGDD_DEBUG_CTRL1_OFS (0)
/* Commands */
enum aes2550_cmds {
AES2550_CMD_SET_IDLE_MODE = 0x00,
AES2550_CMD_RUN_FD = 0x01,
AES2550_CMD_GET_ENROLL_IMG = 0x02,
AES2550_CMD_CALIBRATE = 0x06,
AES2550_CMD_READ_CALIBRATION_DATA = 0x10,
AES2550_CMD_HEARTBEAT = 0x70,
};
/* Messages */
#define AES2550_STRIP_SIZE (0x31e + 3)
#define AES2550_HEARTBEAT_SIZE (4 + 3)
#define AES2550_EDATA_MAGIC 0xe0
#define AES2550_HEARTBEAT_MAGIC 0xdb
#define AES2550_EP_IN_BUF_SIZE 8192

View File

@@ -0,0 +1,97 @@
/*
* AuthenTec AES2660 driver for libfprint
* Copyright (C) 2012 Vasily Khoruzhick
*
* 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 "aes2660"
#include "drivers_api.h"
#include "aeslib.h"
#include "aesx660.h"
#include "aes2660.h"
#define FRAME_WIDTH 192
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
struct _FpiDeviceAes2660
{
FpiDeviceAesX660 parent;
};
G_DECLARE_FINAL_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI,
DEVICE_AES2660, FpiDeviceAesX660);
G_DEFINE_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI_TYPE_DEVICE_AES_X660);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
.frame_height = AESX660_FRAME_HEIGHT,
.image_width = IMAGE_WIDTH,
.get_pixel = aes_get_pixel,
};
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x2660, },
{ .vid = 0x08ff, .pid = 0x2680, },
{ .vid = 0x08ff, .pid = 0x2681, },
{ .vid = 0x08ff, .pid = 0x2682, },
{ .vid = 0x08ff, .pid = 0x2683, },
{ .vid = 0x08ff, .pid = 0x2684, },
{ .vid = 0x08ff, .pid = 0x2685, },
{ .vid = 0x08ff, .pid = 0x2686, },
{ .vid = 0x08ff, .pid = 0x2687, },
{ .vid = 0x08ff, .pid = 0x2688, },
{ .vid = 0x08ff, .pid = 0x2689, },
{ .vid = 0x08ff, .pid = 0x268a, },
{ .vid = 0x08ff, .pid = 0x268b, },
{ .vid = 0x08ff, .pid = 0x268c, },
{ .vid = 0x08ff, .pid = 0x268d, },
{ .vid = 0x08ff, .pid = 0x268e, },
{ .vid = 0x08ff, .pid = 0x268f, },
{ .vid = 0x08ff, .pid = 0x2691, },
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
static void
fpi_device_aes2660_init (FpiDeviceAes2660 *self)
{
}
static void
fpi_device_aes2660_class_init (FpiDeviceAes2660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
dev_class->id = "aes2660";
dev_class->full_name = "AuthenTec AES2660";
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->id_table = id_table;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->bz3_threshold = 20;
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
img_class->img_height = -1;
aes_class->init_seqs[0] = aes2660_init_1;
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes2660_init_1);
aes_class->init_seqs[1] = aes2660_init_2;
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes2660_init_2);
aes_class->start_imaging_cmd = (unsigned char *) aes2660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof (aes2660_start_imaging_cmd);
aes_class->assembling_ctx = &assembling_ctx;
}

1963
libfprint/drivers/aes2660.h Normal file

File diff suppressed because it is too large Load Diff

162
libfprint/drivers/aes3500.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* AuthenTec AES3500 driver for libfprint
*
* AES3500 is a press-typed sensor, which captures image in 128x128
* pixels.
*
* Thanks Rafael Toledo for the Windows driver and the help.
*
* This work is derived from Daniel Drake's AES4000 driver.
*
* Copyright (C) 2011-2013 Juvenn Woo <machese@gmail.com>
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "aes3500"
#include "aes3k.h"
#define DATA_BUFLEN 0x2089
/* image size = FRAME_WIDTH x FRAME_WIDTH */
#define FRAME_WIDTH 128
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
#define ENLARGE_FACTOR 2
static struct aes_regwrite init_reqs[] = {
/* master reset */
{ 0x80, 0x01 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0x80, 0x00 },
{ 0, 0 },
/* scan reset */
{ 0x80, 0x02 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
/* disable register buffering */
{ 0x80, 0x04 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0, 0 },
/* windows driver reads registers now (81 02) */
{ 0x80, 0x00 },
{ 0x81, 0x00 },
/* set excitation bias current: 2mhz drive ring frequency,
* 4V drive ring voltage, 16.5mA excitation bias */
{ 0x82, 0x04 },
/* continuously sample drive ring for finger detection,
* 62.50ms debounce delay */
{ 0x83, 0x13 },
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
{ 0x85, 0x3d }, /* set calibration capacitance */
{ 0x86, 0x03 }, /* detect drive voltage */
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
{ 0x88, 0x02 }, /* set column scan period */
{ 0x89, 0x02 }, /* set measure drive */
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
{ 0x8b, 0x33 }, /* set matrix pattern */
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
{ 0x8e, 0x23 }, /* set sensor gain */
{ 0x8f, 0x07 }, /* set image parameters */
{ 0x90, 0x00 }, /* carrier offset null */
{ 0x91, 0x1c }, /* set A/D reference high */
{ 0x92, 0x08 }, /* set A/D reference low */
{ 0x93, 0x00 }, /* set start row to 0 */
{ 0x94, 0x07 }, /* set end row */
{ 0x95, 0x00 }, /* set start column to 0 */
{ 0x96, 0x1f }, /* set end column */
{ 0x97, 0x04 }, /* data format and thresholds */
{ 0x98, 0x28 }, /* image data control */
{ 0x99, 0x00 }, /* disable general purpose outputs */
{ 0x9a, 0x0b }, /* set initial scan state */
{ 0x9b, 0x00 }, /* clear challenge word bits */
{ 0x9c, 0x00 }, /* clear challenge word bits */
{ 0x9d, 0x09 }, /* set some challenge word bits */
{ 0x9e, 0x53 }, /* clear challenge word bits */
{ 0x9f, 0x6b }, /* set some challenge word bits */
{ 0, 0 },
};
static struct aes_regwrite capture_reqs[] = {
{ 0x80, 0x00 },
{ 0x81, 0x00 },
{ 0, 0 },
{ 0x81, 0x04 },
{ 0, 0 },
{ 0x81, 0x00 },
};
struct _FpiDeviceAes3500
{
FpiDeviceAes3k parent;
};
G_DECLARE_FINAL_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI,
DEVICE_AES3500, FpiDeviceAes3k);
G_DEFINE_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI_TYPE_DEVICE_AES3K);
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x5731 },
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
static void
fpi_device_aes3500_init (FpiDeviceAes3500 *self)
{
}
static void
fpi_device_aes3500_class_init (FpiDeviceAes3500Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
dev_class->id = "aes3500";
dev_class->full_name = "AuthenTec AES3500";
dev_class->id_table = id_table;
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
aes_class->data_buflen = DATA_BUFLEN;
aes_class->frame_width = FRAME_WIDTH;
aes_class->frame_size = FRAME_SIZE;
aes_class->frame_number = FRAME_NUMBER;
aes_class->enlarge_factor = ENLARGE_FACTOR;
aes_class->init_reqs = init_reqs;
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
aes_class->capture_reqs = capture_reqs;
aes_class->capture_reqs_len = G_N_ELEMENTS (capture_reqs);
}

272
libfprint/drivers/aes3k.c Normal file
View File

@@ -0,0 +1,272 @@
/*
* AuthenTec AES3500/AES4000 common routines
*
* The AES3500 and AES4000 sensors are press-typed, and could capture
* fingerprint images in 128x128 and 96x96 pixels respectively. They
* share a same communication interface: a number of frames are
* transferred and captured, from which a final image could be
* assembled. Each frame has fixed height of 16 pixels.
*
* As the imaging area is a bit small, only a part of finger could be
* captured, the detected minutiae are not so many that the NBIS
* matching works not so good. The verification rate is very low at the
* moment.
*
* This work is derived from Daniel Drake's AES4000 driver.
*
* Copyright (C) 2013 Juvenn Woo <machese@gmail.com>
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "aes3k"
#include "drivers_api.h"
#include "aeslib.h"
#include "aes3k.h"
typedef struct
{
/* This is used both as a flag that we are in a capture operation
* and for cancellation.
*/
GCancellable *img_capture_cancel;
} FpiDeviceAes3kPrivate;
#define CTRL_TIMEOUT 1000
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
static void do_capture (FpImageDevice *dev);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAes3k, fpi_device_aes3k, FP_TYPE_IMAGE_DEVICE);
static void
aes3k_assemble_image (unsigned char *input, size_t width, size_t height,
unsigned char *output)
{
size_t row, column;
for (column = 0; column < width; column++)
{
for (row = 0; row < height; row += 2)
{
output[width * row + column] = (*input & 0x0f) * 17;
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
input++;
}
}
}
static void
img_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (device);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
unsigned char *ptr = transfer->buffer;
FpImage *tmp;
FpImage *img;
int i;
/* Image capture operation is finished (error/completed) */
g_clear_object (&priv->img_capture_cancel);
if (error)
{
if (g_error_matches (error,
G_IO_ERROR,
G_IO_ERROR_CANCELLED))
{
/* Cancellation implies we are deactivating. */
g_error_free (error);
fpi_image_device_deactivate_complete (dev, NULL);
return;
}
fpi_image_device_session_error (dev, error);
return;
}
fpi_image_device_report_finger_status (dev, TRUE);
tmp = fp_image_new (cls->frame_width, cls->frame_width);
tmp->width = cls->frame_width;
tmp->height = cls->frame_width;
tmp->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
for (i = 0; i < cls->frame_number; i++)
{
fp_dbg ("frame header byte %02x", *ptr);
ptr++;
aes3k_assemble_image (ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
ptr += cls->frame_size;
}
/* FIXME: this is an ugly hack to make the image big enough for NBIS
* to process reliably */
img = fpi_image_resize (tmp, cls->enlarge_factor, cls->enlarge_factor);
g_object_unref (tmp);
fpi_image_device_image_captured (dev, img);
/* FIXME: rather than assuming finger has gone, we should poll regs until
* it really has. */
fpi_image_device_report_finger_status (dev, FALSE);
/* Note: The transfer is re-started when we switch to the AWAIT_FINGER_ON state. */
}
static void
do_capture (FpImageDevice *dev)
{
g_autoptr(FpiUsbTransfer) img_trf = NULL;
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (img_trf, EP_IN, cls->data_buflen);
img_trf->short_is_error = TRUE;
fpi_usb_transfer_submit (g_steal_pointer (&img_trf), 0,
priv->img_capture_cancel,
img_cb, NULL);
}
static void
capture_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
if (result)
{
g_clear_object (&priv->img_capture_cancel);
fpi_image_device_session_error (dev, result);
return;
}
/* FIXME: we never cancel a pending capture. So we are likely leaving the
* hardware in a bad state should we abort the capture operation and the
* user does not touch the device.
* But, we don't know how we might cancel, so just leave it as is. */
do_capture (dev);
}
static void
do_capture_start (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
aes_write_regv (dev, cls->capture_reqs, cls->capture_reqs_len, capture_reqs_cb, NULL);
}
static void
init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
{
fpi_image_device_activate_complete (dev, result);
}
static void
aes3k_dev_activate (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
}
static void
aes3k_dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
/* If a capture is running, then deactivation finishes from the cancellation handler */
if (priv->img_capture_cancel)
g_cancellable_cancel (priv->img_capture_cancel);
else
fpi_image_device_deactivate_complete (dev, NULL);
}
static void
aes3k_dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
{
g_assert (!priv->img_capture_cancel);
priv->img_capture_cancel = g_cancellable_new ();
do_capture_start (dev);
}
}
static void
fpi_device_aes3k_init (FpiDeviceAes3k *self)
{
}
static void
aes3k_dev_init (FpImageDevice *dev)
{
GError *error = NULL;
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
{
fpi_image_device_open_complete (dev, error);
return;
}
fpi_image_device_open_complete (dev, NULL);
}
static void
aes3k_dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete (dev, error);
}
static void
fpi_device_aes3k_class_init (FpiDeviceAes3kClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
img_class->img_open = aes3k_dev_init;
img_class->img_close = aes3k_dev_deinit;
img_class->activate = aes3k_dev_activate;
img_class->change_state = aes3k_dev_change_state;
img_class->deactivate = aes3k_dev_deactivate;
/* Extremely low due to low image quality. */
img_class->bz3_threshold = 9;
/* Everything else is set by the subclasses. */
}

62
libfprint/drivers/aes3k.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* AuthenTec AES3500/AES4000 common routines
*
* The AES3500 and AES4000 sensors are press-typed, and could capture
* fingerprint images in 128x128 and 96x96 pixels respectively. They
* share a same communication interface: a number of frames are
* transferred and captured, from which a final image could be
* assembled. Each frame has fixed height of 16 pixels.
*
* As the imaging area is a bit small, only a part of finger could be
* captured, the detected minutiae are not so many that the NBIS
* matching works not so good. The verification rate is very low at the
* moment.
*
* This work is derived from Daniel Drake's AES4000 driver.
*
* Copyright (C) 2013 Juvenn Woo <machese@gmail.com>
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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-image-device.h"
#include "aeslib.h"
#define AES3K_FRAME_HEIGHT 16
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAes3k, fpi_device_aes3k, FPI,
DEVICE_AES3K, FpImageDevice)
#define FPI_TYPE_DEVICE_AES3K (fpi_device_aes3k_get_type ())
struct _FpiDeviceAes3kClass
{
FpImageDeviceClass parent;
gsize frame_width; /* image size = frame_width x frame_width */
gsize frame_size; /* 4 bits/pixel: frame_width x AES3K_FRAME_HEIGHT / 2 */
gsize frame_number; /* number of frames */
gsize enlarge_factor;
gsize data_buflen; /* buffer length of usb bulk transfer */
struct aes_regwrite *init_reqs; /* initial values sent to device */
gsize init_reqs_len;
struct aes_regwrite *capture_reqs; /* capture values sent to device */
gsize capture_reqs_len;
};

View File

@@ -1,5 +1,12 @@
/*
* AuthenTec AES4000 driver for libfprint
*
* AES4000 is a press-typed sensor, which captures image in 96x96
* pixels.
*
* This work is derived from Daniel Drake's AES4000 driver.
*
* Copyright (C) 2013 Juvenn Woo <machese@gmail.com>
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* This library is free software; you can redistribute it and/or
@@ -19,252 +26,134 @@
#define FP_COMPONENT "aes4000"
#include <errno.h>
#include "aes3k.h"
#include <glib.h>
#include <libusb.h>
#define DATA_BUFLEN 0x1259
#include <aeslib.h>
#include <fp_internal.h>
#define CTRL_TIMEOUT 1000
#define EP_IN (1 | LIBUSB_ENDPOINT_IN)
#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
#define DATA_BUFLEN 0x1259
#define NR_SUBARRAYS 6
#define SUBARRAY_LEN 768
#define IMG_HEIGHT 96
#define IMG_WIDTH 96
/* image size = FRAME_WIDTH x FRAME_WIDTH */
#define FRAME_WIDTH 96
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
#define ENLARGE_FACTOR 3
struct aes4k_dev {
struct libusb_transfer *img_trf;
static struct aes_regwrite init_reqs[] = {
/* master reset */
{ 0x80, 0x01 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0x80, 0x00 },
{ 0, 0 },
/* scan reset */
{ 0x80, 0x02 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
/* disable register buffering */
{ 0x80, 0x04 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0, 0 },
/* windows driver reads registers now (81 02) */
{ 0x80, 0x00 },
{ 0x81, 0x00 },
/* set excitation bias current: 2mhz drive ring frequency,
* 4V drive ring voltage, 16.5mA excitation bias */
{ 0x82, 0x04 },
/* continuously sample drive ring for finger detection,
* 62.50ms debounce delay */
{ 0x83, 0x13 },
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
{ 0x85, 0x3d }, /* set calibration capacitance */
{ 0x86, 0x03 }, /* detect drive voltage */
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
{ 0x88, 0x02 }, /* set column scan period */
{ 0x89, 0x02 }, /* set measure drive */
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
{ 0x8b, 0x33 }, /* set matrix pattern */
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
{ 0x8e, 0x23 }, /* set sensor gain */
{ 0x8f, 0x07 }, /* set image parameters */
{ 0x90, 0x00 }, /* carrier offset null */
{ 0x91, 0x1c }, /* set A/D reference high */
{ 0x92, 0x08 }, /* set A/D reference low */
{ 0x93, 0x00 }, /* set start row to 0 */
{ 0x94, 0x05 }, /* set end row to 5 */
{ 0x95, 0x00 }, /* set start column to 0 */
{ 0x96, 0x18 }, /* set end column to 24*4=96 */
{ 0x97, 0x04 }, /* data format and thresholds */
{ 0x98, 0x28 }, /* image data control */
{ 0x99, 0x00 }, /* disable general purpose outputs */
{ 0x9a, 0x0b }, /* set initial scan state */
{ 0x9b, 0x00 }, /* clear challenge word bits */
{ 0x9c, 0x00 }, /* clear challenge word bits */
{ 0x9d, 0x09 }, /* set some challenge word bits */
{ 0x9e, 0x53 }, /* clear challenge word bits */
{ 0x9f, 0x6b }, /* set some challenge word bits */
{ 0, 0 },
};
static const struct aes_regwrite init_reqs[] = {
/* master reset */
{ 0x80, 0x01 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0x80, 0x00 },
{ 0, 0 },
/* scan reset */
{ 0x80, 0x02 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
/* disable register buffering */
{ 0x80, 0x04 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0, 0 },
/* windows driver reads registers now (81 02) */
{ 0x80, 0x00 },
{ 0x81, 0x00 },
/* set excitation bias current: 2mhz drive ring frequency,
* 4V drive ring voltage, 16.5mA excitation bias */
{ 0x82, 0x04 },
/* continuously sample drive ring for finger detection,
* 62.50ms debounce delay */
{ 0x83, 0x13 },
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
{ 0x85, 0x3d }, /* set calibration capacitance */
{ 0x86, 0x03 }, /* detect drive voltage */
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
{ 0x88, 0x02 }, /* set column scan period */
{ 0x89, 0x02 }, /* set measure drive */
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
{ 0x8b, 0x33 }, /* set matrix pattern */
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
{ 0x8e, 0x23 }, /* set sensor gain */
{ 0x8f, 0x07 }, /* set image parameters */
{ 0x90, 0x00 }, /* carrier offset null */
{ 0x91, 0x1c }, /* set A/D reference high */
{ 0x92, 0x08 }, /* set A/D reference low */
{ 0x93, 0x00 }, /* set start row to 0 */
{ 0x94, 0x05 }, /* set end row to 5 */
{ 0x95, 0x00 }, /* set start column to 0 */
{ 0x96, 0x18 }, /* set end column to 24*4=96 */
{ 0x97, 0x04 }, /* data format and thresholds */
{ 0x98, 0x28 }, /* image data control */
{ 0x99, 0x00 }, /* disable general purpose outputs */
{ 0x9a, 0x0b }, /* set initial scan state */
{ 0x9b, 0x00 }, /* clear challenge word bits */
{ 0x9c, 0x00 }, /* clear challenge word bits */
{ 0x9d, 0x09 }, /* set some challenge word bits */
{ 0x9e, 0x53 }, /* clear challenge word bits */
{ 0x9f, 0x6b }, /* set some challenge word bits */
{ 0, 0 },
{ 0x80, 0x00 },
{ 0x81, 0x00 },
{ 0, 0 },
{ 0x81, 0x04 },
{ 0, 0 },
{ 0x81, 0x00 },
static struct aes_regwrite capture_reqs[] = {
{ 0x80, 0x00 },
{ 0x81, 0x00 },
{ 0, 0 },
{ 0x81, 0x04 },
{ 0, 0 },
{ 0x81, 0x00 },
};
static void do_capture(struct fp_img_dev *dev);
static void img_cb(struct libusb_transfer *transfer)
struct _FpiDeviceAes4000
{
struct fp_img_dev *dev = transfer->user_data;
struct aes4k_dev *aesdev = dev->priv;
unsigned char *ptr = transfer->buffer;
struct fp_img *tmp;
struct fp_img *img;
int i;
FpiDeviceAes3k parent;
};
G_DECLARE_FINAL_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI,
DEVICE_AES4000, FpiDeviceAes3k);
G_DEFINE_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
goto err;
} else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
fpi_imgdev_session_error(dev, -EIO);
goto err;
} else if (transfer->length != transfer->actual_length) {
fpi_imgdev_session_error(dev, -EPROTO);
goto err;
}
fpi_imgdev_report_finger_status(dev, TRUE);
tmp = fpi_img_new(IMG_WIDTH * IMG_HEIGHT);
tmp->width = IMG_WIDTH;
tmp->height = IMG_HEIGHT;
tmp->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED;
for (i = 0; i < NR_SUBARRAYS; i++) {
fp_dbg("subarray header byte %02x", *ptr);
ptr++;
aes_assemble_image(ptr, 96, 16, tmp->data + (i * 96 * 16));
ptr += SUBARRAY_LEN;
}
/* FIXME: this is an ugly hack to make the image big enough for NBIS
* to process reliably */
img = fpi_im_resize(tmp, ENLARGE_FACTOR);
fp_img_free(tmp);
fpi_imgdev_image_captured(dev, img);
/* FIXME: rather than assuming finger has gone, we should poll regs until
* it really has, then restart the capture */
fpi_imgdev_report_finger_status(dev, FALSE);
do_capture(dev);
err:
g_free(transfer->buffer);
aesdev->img_trf = NULL;
libusb_free_transfer(transfer);
}
static void do_capture(struct fp_img_dev *dev)
{
struct aes4k_dev *aesdev = dev->priv;
unsigned char *data;
int r;
aesdev->img_trf = libusb_alloc_transfer(0);
if (!aesdev->img_trf) {
fpi_imgdev_session_error(dev, -EIO);
return;
}
data = g_malloc(DATA_BUFLEN);
libusb_fill_bulk_transfer(aesdev->img_trf, dev->udev, EP_IN, data,
DATA_BUFLEN, img_cb, dev, 0);
r = libusb_submit_transfer(aesdev->img_trf);
if (r < 0) {
g_free(data);
libusb_free_transfer(aesdev->img_trf);
aesdev->img_trf = NULL;
fpi_imgdev_session_error(dev, r);
}
}
static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data)
{
fpi_imgdev_activate_complete(dev, result);
if (result == 0)
do_capture(dev);
}
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
{
aes_write_regv(dev, init_reqs, G_N_ELEMENTS(init_reqs), init_reqs_cb, NULL);
return 0;
}
static void dev_deactivate(struct fp_img_dev *dev)
{
struct aes4k_dev *aesdev = dev->priv;
/* FIXME: should wait for cancellation to complete before returning
* from deactivation, otherwise app may legally exit before we've
* cleaned up */
if (aesdev->img_trf)
libusb_cancel_transfer(aesdev->img_trf);
fpi_imgdev_deactivate_complete(dev);
}
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
{
int r;
r = libusb_claim_interface(dev->udev, 0);
if (r < 0)
fp_err("could not claim interface 0");
dev->priv = g_malloc0(sizeof(struct aes4k_dev));
if (r == 0)
fpi_imgdev_open_complete(dev, 0);
return r;
}
static void dev_deinit(struct fp_img_dev *dev)
{
g_free(dev->priv);
libusb_release_interface(dev->udev, 0);
fpi_imgdev_close_complete(dev);
}
static const struct usb_id id_table[] = {
{ .vendor = 0x08ff, .product = 0x5501 },
{ 0, 0, 0, },
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x5501 },
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
struct fp_img_driver aes4000_driver = {
.driver = {
.id = 3,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES4000",
.id_table = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,
.img_height = IMG_HEIGHT * ENLARGE_FACTOR,
.img_width = IMG_WIDTH * ENLARGE_FACTOR,
static void
fpi_device_aes4000_init (FpiDeviceAes4000 *self)
{
}
/* temporarily lowered until image quality improves */
.bz3_threshold = 9,
static void
fpi_device_aes4000_class_init (FpiDeviceAes4000Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
.open = dev_init,
.close = dev_deinit,
.activate = dev_activate,
.deactivate = dev_deactivate,
};
dev_class->id = "aes4000";
dev_class->full_name = "AuthenTec AES4000";
dev_class->id_table = id_table;
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
aes_class->data_buflen = DATA_BUFLEN;
aes_class->frame_width = FRAME_WIDTH;
aes_class->frame_size = FRAME_SIZE;
aes_class->frame_number = FRAME_NUMBER;
aes_class->enlarge_factor = ENLARGE_FACTOR;
aes_class->init_reqs = init_reqs;
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
aes_class->capture_reqs = capture_reqs;
aes_class->capture_reqs_len = G_N_ELEMENTS (capture_reqs);
}

169
libfprint/drivers/aeslib.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* Shared functions between libfprint Authentec drivers
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "aeslib"
#include "drivers_api.h"
#include <errno.h>
#include <string.h>
#include "aeslib.h"
#define MAX_REGWRITES_PER_REQUEST 16
#define BULK_TIMEOUT 4000
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
struct write_regv_data
{
unsigned int num_regs;
const struct aes_regwrite *regs;
unsigned int offset;
aes_write_regv_cb callback;
void *user_data;
};
static void continue_write_regv (FpImageDevice *dev,
struct write_regv_data *wdata);
/* libusb bulk callback for regv write completion transfer. continues the
* transaction */
static void
write_regv_trf_complete (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
struct write_regv_data *wdata = user_data;
if (error)
{
wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
g_free (wdata);
}
else
{
continue_write_regv (FP_IMAGE_DEVICE (device), wdata);
}
}
/* write from wdata->offset to upper_bound (inclusive) of wdata->regs */
static void
do_write_regv (FpImageDevice *dev, struct write_regv_data *wdata, int upper_bound)
{
unsigned int offset = wdata->offset;
unsigned int num = upper_bound - offset + 1;
size_t alloc_size = num * 2;
unsigned int i;
size_t data_offset = 0;
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (transfer, EP_OUT, alloc_size);
for (i = offset; i < offset + num; i++)
{
const struct aes_regwrite *regwrite = &wdata->regs[i];
transfer->buffer[data_offset++] = regwrite->reg;
transfer->buffer[data_offset++] = regwrite->value;
}
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
write_regv_trf_complete, wdata);
}
/* write the next batch of registers to be written, or if there are no more,
* indicate completion to the caller */
static void
continue_write_regv (FpImageDevice *dev, struct write_regv_data *wdata)
{
unsigned int offset = wdata->offset;
unsigned int regs_remaining;
unsigned int limit;
unsigned int upper_bound;
int i;
/* skip all zeros and ensure there is still work to do */
while (TRUE)
{
if (offset >= wdata->num_regs)
{
fp_dbg ("all registers written");
wdata->callback (dev, 0, wdata->user_data);
g_free (wdata);
return;
}
if (wdata->regs[offset].reg)
break;
offset++;
}
wdata->offset = offset;
regs_remaining = wdata->num_regs - offset;
limit = MIN (regs_remaining, MAX_REGWRITES_PER_REQUEST);
upper_bound = offset + limit - 1;
/* determine if we can write the entire of the regs at once, or if there
* is a zero dividing things up */
for (i = offset; i <= upper_bound; i++)
if (!wdata->regs[i].reg)
{
upper_bound = i - 1;
break;
}
do_write_regv (dev, wdata, upper_bound);
wdata->offset = upper_bound + 1;
}
/* write a load of registers to the device, combining multiple writes in a
* single URB up to a limit. insert writes to non-existent register 0 to force
* specific groups of writes to be separated by different URBs. */
void
aes_write_regv (FpImageDevice *dev, const struct aes_regwrite *regs,
unsigned int num_regs, aes_write_regv_cb callback,
void *user_data)
{
struct write_regv_data *wdata;
fp_dbg ("write %d regs", num_regs);
wdata = g_malloc (sizeof (*wdata));
wdata->num_regs = num_regs;
wdata->regs = regs;
wdata->offset = 0;
wdata->callback = callback;
wdata->user_data = user_data;
continue_write_regv (dev, wdata);
}
unsigned char
aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame,
unsigned int x,
unsigned int y)
{
unsigned char ret;
ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)];
ret = y % 2 ? ret >> 4 : ret & 0xf;
ret *= 17;
return ret;
}

View File

@@ -0,0 +1,46 @@
/*
* Shared functions between libfprint Authentec drivers
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* 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 <fprint.h>
struct aes_regwrite
{
unsigned char reg;
unsigned char value;
};
struct fpi_frame;
struct fpi_frame_asmbl_ctx;
typedef void (*aes_write_regv_cb)(FpImageDevice *dev,
GError *error,
void *user_data);
void aes_write_regv (FpImageDevice *dev,
const struct aes_regwrite *regs,
unsigned int num_regs,
aes_write_regv_cb callback,
void *user_data);
unsigned char aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame,
unsigned int x,
unsigned int y);

751
libfprint/drivers/aesx660.c Normal file
View File

@@ -0,0 +1,751 @@
/*
* AuthenTec AES1660/AES2660 common routines
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2007 Cyrille Bagard
* Copyright (C) 2007-2008,2012 Vasily Khoruzhick
*
* Based on AES2550 driver
*
* 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 "aesX660"
#include "drivers_api.h"
#include "aeslib.h"
#include "aesx660.h"
typedef struct
{
GByteArray *stripe_packet;
GSList *strips;
size_t strips_len;
gboolean deactivating;
struct aesX660_cmd *init_seq;
size_t init_seq_len;
unsigned int init_cmd_idx;
unsigned int init_seq_idx;
} FpiDeviceAesX660Private;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAesX660, fpi_device_aes_x660, FP_TYPE_IMAGE_DEVICE);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
#define BULK_TIMEOUT 4000
#define FRAME_HEIGHT AESX660_FRAME_HEIGHT
#define ID_LEN 8
#define INIT_LEN 4
#define CALIBRATE_DATA_LEN 4
#define FINGER_DET_DATA_LEN 4
FP_GNUC_ACCESS (read_only, 3, 4)
static void
aesX660_send_cmd_timeout (FpiSsm *ssm,
FpDevice *_dev,
const unsigned char *cmd,
size_t cmd_len,
FpiUsbTransferCallback callback,
int timeout)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, (unsigned char *) cmd,
cmd_len, NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, timeout, NULL, callback, NULL);
}
FP_GNUC_ACCESS (read_only, 3, 4)
static void
aesX660_send_cmd (FpiSsm *ssm,
FpDevice *dev,
const unsigned char *cmd,
size_t cmd_len,
FpiUsbTransferCallback callback)
{
return aesX660_send_cmd_timeout (ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
}
static void
aesX660_read_response (FpiSsm *ssm,
FpDevice *_dev,
gboolean short_is_error,
gboolean cancellable,
size_t buf_len,
FpiUsbTransferCallback callback)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
GCancellable *cancel = NULL;
if (cancellable)
cancel = fpi_device_get_cancellable (_dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, buf_len);
transfer->ssm = ssm;
transfer->short_is_error = short_is_error;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, cancel, callback, NULL);
}
static void
aesX660_read_calibrate_data_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer user_data, GError *error)
{
unsigned char *data = transfer->buffer;
if (error)
{
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* Calibrate response was read correctly? */
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE)
{
fp_dbg ("Bogus calibrate response: %.2x", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus calibrate "
"response: %.2x",
data[0]));
return;
}
fpi_ssm_next_state (transfer->ssm);
}
/****** FINGER PRESENCE DETECTION ******/
enum finger_det_states {
FINGER_DET_SEND_LED_CMD,
FINGER_DET_SEND_FD_CMD,
FINGER_DET_READ_FD_DATA,
FINGER_DET_SET_IDLE,
FINGER_DET_NUM_STATES,
};
static void
finger_det_read_fd_data_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer user_data,
GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
unsigned char *data = transfer->buffer;
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
fpi_ssm_next_state (transfer->ssm);
return;
}
if (error)
{
fp_dbg ("Failed to read FD data");
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE)
{
fp_dbg ("Bogus FD response: %.2x", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus FD response %.2x",
data[0]));
return;
}
if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || priv->deactivating)
{
/* Finger present or we're deactivating... */
fpi_ssm_next_state (transfer->ssm);
}
else
{
fp_dbg ("Wait for finger returned %.2x as result",
data[AESX660_FINGER_PRESENT_OFFSET]);
fpi_ssm_jump_to_state (transfer->ssm, FINGER_DET_SEND_FD_CMD);
}
}
static void
finger_det_set_idle_cmd_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer user_data,
GError *error)
{
if (!error)
fpi_ssm_mark_completed (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
finger_det_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
fp_dbg ("Finger detection completed");
fpi_image_device_report_finger_status (dev, TRUE);
if (priv->deactivating)
{
complete_deactivation (dev);
if (error)
g_error_free (error);
}
else if (error)
{
fpi_image_device_session_error (dev, error);
}
else
{
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
}
static void
finger_det_run_state (FpiSsm *ssm, FpDevice *dev)
{
switch (fpi_ssm_get_cur_state (ssm))
{
case FINGER_DET_SEND_LED_CMD:
aesX660_send_cmd (ssm, dev, led_blink_cmd, sizeof (led_blink_cmd),
fpi_ssm_usb_transfer_cb);
break;
case FINGER_DET_SEND_FD_CMD:
aesX660_send_cmd_timeout (ssm, dev, wait_for_finger_cmd, sizeof (wait_for_finger_cmd),
fpi_ssm_usb_transfer_cb, 0);
break;
case FINGER_DET_READ_FD_DATA:
aesX660_read_response (ssm, dev, TRUE, TRUE, FINGER_DET_DATA_LEN, finger_det_read_fd_data_cb);
break;
case FINGER_DET_SET_IDLE:
aesX660_send_cmd (ssm, dev, set_idle_cmd, sizeof (set_idle_cmd),
finger_det_set_idle_cmd_cb);
break;
}
}
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiSsm *ssm;
if (priv->deactivating)
{
complete_deactivation (dev);
return;
}
ssm = fpi_ssm_new (FP_DEVICE (dev), finger_det_run_state,
FINGER_DET_NUM_STATES);
fpi_ssm_start (ssm, finger_det_sm_complete);
}
/****** CAPTURE ******/
enum capture_states {
CAPTURE_SEND_LED_CMD,
CAPTURE_SEND_CAPTURE_CMD,
CAPTURE_READ_STRIPE_DATA,
CAPTURE_SET_IDLE,
CAPTURE_NUM_STATES,
};
/* Returns number of processed bytes */
static int
process_stripe_data (FpiSsm *ssm, FpiDeviceAesX660 *self,
unsigned char *data, gsize length)
{
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
struct fpi_frame *stripe;
unsigned char *stripdata;
if (length < AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2)
{
fp_warn ("Received stripe data is too short, got %zi expected %i bytes!",
length,
AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
return 0;
}
stripe = g_malloc (cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bpp */
stripdata = stripe->data;
fp_dbg ("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
data[AESX660_LAST_FRAME_OFFSET]);
stripe->delta_x = (int8_t) data[AESX660_FRAME_DELTA_X_OFFSET];
stripe->delta_y = -(int8_t) data[AESX660_FRAME_DELTA_Y_OFFSET];
fp_dbg ("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK)
{
memcpy (stripdata, data + AESX660_IMAGE_OFFSET, cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
priv->strips = g_slist_prepend (priv->strips, stripe);
priv->strips_len++;
return data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT;
}
g_free (stripe);
return 0;
}
static void
capture_set_idle_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
if (!error)
{
FpImage *img;
priv->strips = g_slist_reverse (priv->strips);
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
img->flags |= FPI_IMAGE_PARTIAL;
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
g_slist_free (priv->strips);
priv->strips = NULL;
priv->strips_len = 0;
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
fpi_ssm_mark_completed (transfer->ssm);
}
else
{
fpi_ssm_mark_failed (transfer->ssm, error);
}
}
static void
capture_read_stripe_data_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer user_data,
GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
unsigned char *data = transfer->buffer;
int finger_missing = 0;
size_t actual_length = transfer->actual_length;
if (error)
{
g_byte_array_set_size (priv->stripe_packet, 0);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fp_dbg ("Got %" G_GSIZE_FORMAT " bytes of data", actual_length);
while (actual_length)
{
gssize payload_length;
gssize still_needed_len;
gssize copy_len;
still_needed_len = MAX (0, AESX660_HEADER_SIZE - (gssize) priv->stripe_packet->len);
copy_len = MIN (actual_length, still_needed_len);
g_byte_array_append (priv->stripe_packet, data, copy_len);
data += copy_len;
actual_length -= copy_len;
/* Do we have a full header? */
if (priv->stripe_packet->len < AESX660_HEADER_SIZE)
break;
payload_length = priv->stripe_packet->data[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
(priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8);
fp_dbg ("Got frame, type %.2x payload of size %.4lx",
priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET],
(long) payload_length);
still_needed_len = MAX (0, AESX660_HEADER_SIZE + payload_length - (gssize) priv->stripe_packet->len);
copy_len = MIN (actual_length, still_needed_len);
g_byte_array_append (priv->stripe_packet, data, copy_len);
data += copy_len;
actual_length -= copy_len;
/* Do we have a full packet including the payload? */
if (priv->stripe_packet->len < payload_length + AESX660_HEADER_SIZE)
break;
finger_missing |= process_stripe_data (transfer->ssm,
self,
priv->stripe_packet->data,
priv->stripe_packet->len);
g_byte_array_set_size (priv->stripe_packet, 0);
}
fp_dbg ("finger %s", finger_missing ? "missing" : "present");
if (finger_missing)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_STRIPE_DATA);
}
static void
capture_run_state (FpiSsm *ssm, FpDevice *_dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_SEND_LED_CMD:
aesX660_send_cmd (ssm, _dev, led_solid_cmd, sizeof (led_solid_cmd),
fpi_ssm_usb_transfer_cb);
break;
case CAPTURE_SEND_CAPTURE_CMD:
g_byte_array_set_size (priv->stripe_packet, 0);
aesX660_send_cmd (ssm, _dev, cls->start_imaging_cmd,
cls->start_imaging_cmd_len,
fpi_ssm_usb_transfer_cb);
break;
case CAPTURE_READ_STRIPE_DATA:
aesX660_read_response (ssm, _dev, FALSE, FALSE, AESX660_BULK_TRANSFER_SIZE,
capture_read_stripe_data_cb);
break;
case CAPTURE_SET_IDLE:
fp_dbg ("Got %" G_GSIZE_FORMAT " frames", priv->strips_len);
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
capture_set_idle_cmd_cb);
break;
}
}
static void
capture_sm_complete (FpiSsm *ssm, FpDevice *device, GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
fp_dbg ("Capture completed");
if (priv->deactivating)
{
complete_deactivation (FP_IMAGE_DEVICE (device));
if (error)
g_error_free (error);
}
else if (error)
{
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
}
else
{
start_finger_detection (FP_IMAGE_DEVICE (device));
}
}
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiSsm *ssm;
if (priv->deactivating)
{
complete_deactivation (dev);
return;
}
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state, CAPTURE_NUM_STATES);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
enum activate_states {
ACTIVATE_SET_IDLE,
ACTIVATE_SEND_READ_ID_CMD,
ACTIVATE_READ_ID,
ACTIVATE_SEND_CALIBRATE_CMD,
ACTIVATE_READ_CALIBRATE_DATA,
ACTIVATE_SEND_INIT_CMD,
ACTIVATE_READ_INIT_RESPONSE,
ACTIVATE_NUM_STATES,
};
static void
activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
unsigned char *data = transfer->buffer;
if (error)
{
fp_dbg ("read_id cmd failed");
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* ID was read correctly */
if (data[0] == 0x07)
{
fp_dbg ("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x",
data[4], data[3], data[5], data[6], data[7]);
}
else
{
fp_dbg ("Bogus read ID response: %.2x", data[AESX660_RESPONSE_TYPE_OFFSET]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read ID response %.2x",
data[AESX660_RESPONSE_TYPE_OFFSET]));
return;
}
switch (priv->init_seq_idx)
{
case 0:
priv->init_seq = cls->init_seqs[0];
priv->init_seq_len = cls->init_seqs_len[0];
priv->init_seq_idx = 1;
priv->init_cmd_idx = 0;
/* Do calibration only after 1st init sequence */
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
break;
case 1:
priv->init_seq = cls->init_seqs[1];
priv->init_seq_len = cls->init_seqs_len[1];
priv->init_seq_idx = 2;
priv->init_cmd_idx = 0;
fpi_ssm_next_state (transfer->ssm);
break;
default:
fp_dbg ("Failed to init device! init status: %.2x", data[7]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Failed to init device %.2x",
data[7]));
break;
}
}
static void
activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
unsigned char *data = transfer->buffer;
fp_dbg ("read_init_cb");
if (error)
{
fp_dbg ("read_init transfer status: %s, actual_len: %d", error->message,
(gint) transfer->actual_length);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* ID was read correctly */
if (data[0] != 0x42 || data[3] != 0x01)
{
fp_dbg ("Bogus read init response: %.2x %.2x", data[0],
data[3]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read init response: "
"%.2x %.2x", data[0], data[3]));
return;
}
priv->init_cmd_idx++;
if (priv->init_cmd_idx == priv->init_seq_len)
{
if (priv->init_seq_idx < 2)
fpi_ssm_jump_to_state (transfer->ssm,
ACTIVATE_SEND_READ_ID_CMD);
else
fpi_ssm_mark_completed (transfer->ssm);
return;
}
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
}
static void
activate_run_state (FpiSsm *ssm, FpDevice *_dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
switch (fpi_ssm_get_cur_state (ssm))
{
case ACTIVATE_SET_IDLE:
priv->init_seq_idx = 0;
fp_dbg ("Activate: set idle");
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_SEND_READ_ID_CMD:
fp_dbg ("Activate: read ID");
aesX660_send_cmd (ssm, _dev, read_id_cmd, sizeof (read_id_cmd),
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_ID:
aesX660_read_response (ssm, _dev, TRUE, FALSE, ID_LEN, activate_read_id_cb);
break;
case ACTIVATE_SEND_INIT_CMD:
fp_dbg ("Activate: send init seq #%d cmd #%d",
priv->init_seq_idx,
priv->init_cmd_idx);
aesX660_send_cmd (ssm, _dev,
priv->init_seq[priv->init_cmd_idx].cmd,
priv->init_seq[priv->init_cmd_idx].len,
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_INIT_RESPONSE:
fp_dbg ("Activate: read init response");
aesX660_read_response (ssm, _dev, TRUE, FALSE, INIT_LEN, activate_read_init_cb);
break;
case ACTIVATE_SEND_CALIBRATE_CMD:
aesX660_send_cmd (ssm, _dev, calibrate_cmd, sizeof (calibrate_cmd),
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_CALIBRATE_DATA:
aesX660_read_response (ssm, _dev, TRUE, FALSE, CALIBRATE_DATA_LEN, aesX660_read_calibrate_data_cb);
break;
}
}
static void
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (_dev), error);
if (!error)
start_finger_detection (FP_IMAGE_DEVICE (_dev));
}
static void
aesX660_dev_activate (FpImageDevice *dev)
{
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void
aesX660_dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
priv->deactivating = TRUE;
}
static void
aesX660_dev_init (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
GError *error = NULL;
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
priv->stripe_packet = g_byte_array_new ();
fpi_image_device_open_complete (dev, error);
}
static void
aesX660_dev_deinit (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
GError *error = NULL;
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
g_clear_pointer (&priv->stripe_packet, g_byte_array_unref);
fpi_image_device_close_complete (dev, error);
}
static void
complete_deactivation (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
G_DEBUG_HERE ();
priv->deactivating = FALSE;
g_slist_free (priv->strips);
priv->strips = NULL;
priv->strips_len = 0;
fpi_image_device_deactivate_complete (dev, NULL);
}
static void
fpi_device_aes_x660_init (FpiDeviceAesX660 *self)
{
}
static void
fpi_device_aes_x660_class_init (FpiDeviceAesX660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->img_open = aesX660_dev_init;
img_class->img_close = aesX660_dev_deinit;
img_class->activate = aesX660_dev_activate;
img_class->deactivate = aesX660_dev_deactivate;
/* Everything else is set by the subclasses. */
}

111
libfprint/drivers/aesx660.h Normal file
View File

@@ -0,0 +1,111 @@
/*
* AuthenTec AES1660/AES2660 common definitions
* Copyright (c) 2012 Vasily Khoruzhick <anarsoul@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
*/
#pragma once
#define AESX660_HEADER_SIZE 3
#define AESX660_RESPONSE_TYPE_OFFSET 0x00
#define AESX660_RESPONSE_SIZE_LSB_OFFSET 0x01
#define AESX660_RESPONSE_SIZE_MSB_OFFSET 0x02
#define AESX660_CALIBRATE_RESPONSE 0x06
#define AESX660_FINGER_DET_RESPONSE 0x40
#define AESX660_FINGER_PRESENT_OFFSET 0x03
#define AESX660_FINGER_PRESENT 0x01
#define AESX660_IMAGE_OK_OFFSET 0x03
#define AESX660_IMAGE_OK 0x0d
#define AESX660_LAST_FRAME_OFFSET 0x04
#define AESX660_LAST_FRAME_BIT 0x01
#define AESX660_FRAME_DELTA_X_OFFSET 16
#define AESX660_FRAME_DELTA_Y_OFFSET 17
#define AESX660_IMAGE_OFFSET 43
#define AESX660_BULK_TRANSFER_SIZE 4096
#define AESX660_FRAME_HEIGHT 8
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAesX660, fpi_device_aes_x660, FPI,
DEVICE_AES_X660, FpImageDevice)
#define FPI_TYPE_DEVICE_AES_X660 (fpi_device_aes_x660_get_type ())
struct _FpiDeviceAesX660Class
{
FpImageDeviceClass parent;
struct aesX660_cmd *init_seqs[2];
gsize init_seqs_len[2];
guint8 *start_imaging_cmd;
gsize start_imaging_cmd_len;
struct fpi_frame_asmbl_ctx *assembling_ctx;
};
struct aesX660_cmd
{
const guint8 *cmd;
gsize len;
};
/* 0x77 cmd seems to control LED, this sequence
* makes LED blink
*/
static const guint8 led_blink_cmd[] = {
0x77, 0x18, 0x00,
0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3,
0x01, 0x00, 0x7f
};
/* This sequence makes LED light solid
*/
static const guint8 led_solid_cmd[] = {
0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f
};
static const guint8 wait_for_finger_cmd[] = {
0x20,
0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32
};
/* 0x40 cmd response
*
static const guint8 pkt1371[] = {
0x40, 0x01, 0x00, 0x01
};
*/
static const guint8 set_idle_cmd[] = {
0x0d, /* Reset or "set idle"? */
};
static const guint8 read_id_cmd[] = {
0x44, 0x02, 0x00, 0x08, 0x00, /* Max transfer size is 8 */
0x07, /* Read ID? */
};
static const guint8 calibrate_cmd[] = {
0x44, 0x02, 0x00, 0x04, 0x00,
0x06,
};

1425
libfprint/drivers/egis0570.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,592 @@
/*
* Egis Technology Inc. (aka. LighTuning) 0570 driver for libfprint
* Copyright (C) 2021 Maxim Kolesnikov <kolesnikov@svyazcom.ru>
* Copyright (C) 2021 Saeed/Ali Rk <saeed.ali.rahimi@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
*/
#include "drivers_api.h"
#ifndef __EGIS0570_H
#define __EGIS0570_H 1
/*
* Device data
*/
#define EGIS0570_CONF 1
#define EGIS0570_INTF 0
/*
* Device endpoints
*/
#define EGIS0570_EPOUT 0x04 /* ( 4 | FPI_USB_ENDPOINT_OUT ) */
#define EGIS0570_EPIN 0x83 /* ( 3 | FPI_USB_ENDPOINT_IN ) */
/*
* Initialization packets (7 bytes each)
*
* First 4 bytes are equivalent to string "EGIS", which must be just a company identificator
* Other 3 bytes are not recognized yet and may be not important, as they are always the same
* Answers for each packet contain 7 bytes again
* First 4 bytes are reversed "EGIS", which is "SIGE", which is company ID again
* Other 3 bytes are not recognized yet
* But there is a pattern.
* Sending last packet makes sensor return image
*/
#define EGIS0570_TIMEOUT 10000
#define EGIS0570_PKTSIZE 7
#define EGIS0570_INIT_TOTAL (sizeof ((init_pkts)) / sizeof ((init_pkts[0])))
// static unsigned char init_pkts[][EGIS0570_PKTSIZE] =
// {
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x09 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x09 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x03 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x03 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x01 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x01 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x01 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x01 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3e },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0b },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x03 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80 },
// { 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80 },
// { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f },
// { 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */
// };
static unsigned char init_pkts[][EGIS0570_PKTSIZE] =
{
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x09 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x09 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x03 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x03 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x01 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x01 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x01 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x01 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x25, 0x00 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x53, 0x00 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3e },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0b },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x03 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80 },
{ 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80 },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f },
{ 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */
};
/* There is another Packet !
* That just Work the same !!
* And the Size is different !!!
*/
/*
#define EGIS0570_INIT_TOTAL2 (sizeof((init_pkts2)) / sizeof((init_pkts2[0])))
static unsigned char init_pkts2[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x07},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x07},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x02},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x02},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x25, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x53, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3b},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f},
{0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe}
};
*/
/*
* After sending initial packets device returns image data (32512 bytes)
* To ask device to send image data again, host needs to send four additional packets
* Further work is to repeatedly send four repeat packets and read image data
*/
#define EGIS0570_INPSIZE 32512
/* 5 image with captured in different time of size 114 * 57 = 6498
* 5 * 6498 = 32490 plus 22 extra unrecognized char size data
* Two continuous image in this 5 images may have time delay of less than 20ms
*/
#define EGIS0570_IMGSIZE 6498
#define EGIS0570_IMGWIDTH 114
#define EGIS0570_IMGHEIGHT 57
/* size of middle area that is used from each frame */
#define EGIS0570_RFMGHEIGHT 17
/* rows to ignore from top and bottom of the image*/
#define EGIS0570_RFMDIS (EGIS0570_IMGHEIGHT - EGIS0570_RFMGHEIGHT) / 2
#define EGIS0570_IMGCOUNT 5
/*
* Image repeat request
* First 4 bytes are the same as in initialization packets
* Have no idea what the other 3 bytes mean
*/
#define EGIS0570_REPEAT_TOTAL (sizeof ((repeat_pkts)) / sizeof ((repeat_pkts[0])))
static unsigned char repeat_pkts[][EGIS0570_PKTSIZE] =
{
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f },
{ 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x0f },
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f },
{ 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */
};
/*
* This sensor is small so I decided to reduce bz3_threshold from
* 40 to 10 to have more success to fail ratio
* Bozorth3 Algorithm seems not fine at the end
* foreget about security :))
*/
#define EGIS0570_BZ3_THRESHOLD 25 /* and even less What a joke */
#define EGIS0570_MIN_MEAN 20
#define EGIS0570_MARGIN 3
#define EGIS0570_RESIZE 2
#endif
// Calibration
enum driver_version {
PACKET_CALIBRATION,
PACKET_VERSION_1,
NONE,
};
#define PRESISTENT_DATA_LENGTH 9
#define EGIS0570_CAL_IMG_TOT 22 //124
#define EGIS0570_CAL_INPSIZE 6528
#define EGIS0570_CAL_BS_ELM 7
#define IMG_COL_IGNORE 23
#define TARGET_UPPER 80
#define TARGET_LOWER 70
// #define SIDE_DIFF (-10)
#define SIDE_DIFF (+5)
/* static pkts */
static guint8 EGIS0570_CAL_CONFIGURATION_MODE_PKT[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x1f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x05, 0x08},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0xff}
};
static guint8 EGIS0570_CAL_PKT_ZERO_RANGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x10},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x04, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x05, 0x08},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x06, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x07, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x08, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0a, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0b, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0c, 0xff},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0x00}
};
static guint8 EGIS0570_CAL_CAPTURING_AREA[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71}
};
static guint8 EGIS0570_CAL_SENSOR_AND_EMITTER[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x15},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x08}
};
static guint8 EGIS0570_CAL_WHITE_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x3f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x00}
};
static guint8 EGIS0570_CAL_BLACK_WHITE_GET_IMAGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x20},
{0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0x33}
};
static guint8 EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x00}
};
static guint8 EGIS0570_CAL_BLACK_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x03},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0xff},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0xff}
};
static guint8 EGIS0570_CAL_BLACK_WHITE_CLEAR[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00}
};
static guint8 EGIS0570_CAL_MIDDLE_BLACK_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x7f},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x7f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f}
};
static guint8 EGIS0570_CAL_GET_IMAGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0x33}
};
static guint8 EGIS0570_CAL_AFTER_IMAGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f}
};
static guint8 EGIS0570_CAL_REPEAT[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x0f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f}
};
static guint8 EGIS0570_CAL_BORDER_WHITE_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3f},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x3f},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f}
};
static guint8 EGIS0570_CAL_FIRST_BS_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00},
};
static guint8 EGIS0570_CAL_BEFORE_GET_IMAGE[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f}
};
static guint8 EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x1c},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x1c},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x31},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x40}
};
static guint8 EGIS0570_CAL_NO_IMAGE_SETTING_0[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x05},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x08, 0x1c}
};
static guint8 EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0b, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0c, 0xff},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0xff},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x1d},
{0x45, 0x47, 0x49, 0x53, 0x01, 0x04, 0x00}
};
static guint8 EGIS0570_CAL_NO_IMAGE_PRE_FIRST[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00}
};
static guint8 EGIS0570_CAL_NO_IMAGE_REQUEST[][EGIS0570_PKTSIZE] =
{
{0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00},
{0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00}
};
#define EGIS0570_CAL_STATIC_LIST_SIZEOF (sizeof ((EGIS0570_CAL_STATIC_LIST)) / sizeof ((EGIS0570_CAL_STATIC_LIST[0])))
static guint8 * EGIS0570_CAL_STATIC_LIST[] = {
*EGIS0570_CAL_CONFIGURATION_MODE_PKT,
*EGIS0570_CAL_PKT_ZERO_RANGE,
*EGIS0570_CAL_CAPTURING_AREA,
*EGIS0570_CAL_SENSOR_AND_EMITTER,
*EGIS0570_CAL_WHITE_SETTING,
*EGIS0570_CAL_BLACK_WHITE_GET_IMAGE,
*EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE,
*EGIS0570_CAL_BLACK_SETTING,
*EGIS0570_CAL_BLACK_WHITE_CLEAR,
*EGIS0570_CAL_MIDDLE_BLACK_SETTING,
*EGIS0570_CAL_GET_IMAGE,
*EGIS0570_CAL_AFTER_IMAGE,
*EGIS0570_CAL_REPEAT,
*EGIS0570_CAL_BORDER_WHITE_SETTING,
*EGIS0570_CAL_FIRST_BS_SETTING,
*EGIS0570_CAL_BEFORE_GET_IMAGE,
*EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA,
*EGIS0570_CAL_NO_IMAGE_SETTING_0,
*EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING,
*EGIS0570_CAL_NO_IMAGE_PRE_FIRST,
*EGIS0570_CAL_NO_IMAGE_REQUEST,
};
#define EGIS0570_HELPER_PKT_SIZEOF(x) (sizeof (x) / sizeof (x[0]))
static guint8 EGIS0570_CAL_STATIC_LIST_SIZE[] = {
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_CONFIGURATION_MODE_PKT),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_PKT_ZERO_RANGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_CAPTURING_AREA),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_SENSOR_AND_EMITTER),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_WHITE_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_GET_IMAGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_CLEAR),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_MIDDLE_BLACK_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_GET_IMAGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_AFTER_IMAGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_REPEAT),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BORDER_WHITE_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_FIRST_BS_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BEFORE_GET_IMAGE),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_SETTING_0),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_PRE_FIRST),
EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_REQUEST),
};
/* Calibration logic */
enum cal_proc_en {
CAL_CONF_PKT,
CAL_PKT_ZERO_RNG,
CAL_CAPT_AREA,
CAL_SENS_AND_EMIT,
CAL_RNG_20_58,
CAL_RNG_60_D0,
CAL_WHITE_SET,
CAL_BLACK_WHITE_GET_IMG,
CAL_BLACK_WHITE_AFTER_IMAGE,
CAL_BLACK_SET,
CAL_CHECK_BLACK_WHITE,
CAL_5_ROWS_ZEROS,
CAL_BLACK_WHITE_CLEAR,
CAL_RNG_60_D1,
CAL_MID_BLACK_SET,
CAL_GET_IMG,
CAL_AFTER_IMG,
CAL_GET_9,
CAL_BORDER_WHITE_SET,
CAL_FIRST_BS_SET,
CAL_BS_CHK_SET,
CAL_PKT_02,
CAL_BEFORE_IMG,
CAL_BS_JUMP,
CAL_BS_END,
CAL_PKT_15_0,
CAL_PKT_16_3C,
CAL_CHK_NEW_CONF,
CAL_GET_21,
CAL_NO_IMG_CAP_AREA,
CAL_NO_IMG_SET_0,
CAL_NO_IMG_03_1C,
CAL_NO_CHK_03_80,
CAL_NO_SET_03_80,
CAL_NO_IMG_14_BS_SET,
CAL_NO_IMG_14_BS_CHK_SET,
CAL_NO_IMG_PRE_FIRST,
CAL_NO_IMG_GET_8,
CAL_NO_IMG_14_BS_JUMP,
CAL_NO_IMG_14_BS_END,
CAL_NO_IMG_16_BS_SET,
CAL_NO_IMG_16_BS_CHK_SET_15,
CAL_NO_IMG_16_BS_SET_16,
CAL_NO_IMG_16_BS_JUMP,
CAL_NO_IMG_16_BS_END,
CAL_END,
};
#define EGIS0570_CAL_PROC_SIZEOF (sizeof ((calibration_procedure)) / sizeof ((calibration_procedure[0])))
static guint8 calibration_procedure[] = {
// conf
CAL_CONF_PKT,
// sensor check
CAL_PKT_ZERO_RNG,
CAL_CAPT_AREA,
CAL_SENS_AND_EMIT,
CAL_RNG_20_58,
CAL_RNG_60_D0,
CAL_WHITE_SET,
CAL_BLACK_WHITE_GET_IMG,
CAL_BLACK_WHITE_AFTER_IMAGE,
CAL_BLACK_SET,
CAL_BLACK_WHITE_GET_IMG,
CAL_BLACK_WHITE_AFTER_IMAGE,
CAL_CHECK_BLACK_WHITE,
// not binary 16
CAL_CAPT_AREA,
CAL_5_ROWS_ZEROS,
CAL_BLACK_WHITE_CLEAR,
CAL_RNG_20_58,
CAL_RNG_60_D1,
CAL_MID_BLACK_SET,
CAL_GET_IMG,
CAL_AFTER_IMG,
CAL_GET_9,
CAL_BORDER_WHITE_SET,
CAL_GET_IMG,
CAL_AFTER_IMG,
CAL_GET_9,
// binary
CAL_FIRST_BS_SET,
CAL_BS_CHK_SET, // 0
CAL_PKT_02, // 1
CAL_BEFORE_IMG, // 2
CAL_GET_IMG, // 3
CAL_AFTER_IMG, // 4
CAL_GET_9, // 5
CAL_BS_JUMP, // 6
CAL_BS_END, // 7
// check pictures.
CAL_PKT_15_0,
CAL_PKT_16_3C,
CAL_CHK_NEW_CONF,
CAL_PKT_02,
CAL_BEFORE_IMG,
CAL_GET_IMG,
CAL_AFTER_IMG,
CAL_GET_21,
// no image 14
CAL_NO_IMG_CAP_AREA,
CAL_NO_IMG_SET_0,
CAL_NO_IMG_03_1C,
CAL_NO_CHK_03_80,
CAL_NO_SET_03_80,
CAL_NO_IMG_14_BS_SET,
CAL_NO_IMG_14_BS_CHK_SET, // 0
CAL_NO_IMG_PRE_FIRST, // 1
CAL_NO_IMG_GET_8, // 2
CAL_NO_IMG_14_BS_JUMP, // 3
CAL_NO_IMG_14_BS_END, // 4
// no image 16
CAL_NO_IMG_16_BS_SET,
CAL_NO_IMG_16_BS_CHK_SET_15, // 0
CAL_NO_IMG_16_BS_SET_16, // 1
CAL_NO_IMG_PRE_FIRST, // 2
CAL_NO_IMG_GET_8, // 3
CAL_NO_IMG_16_BS_JUMP, // 4
CAL_NO_IMG_16_BS_END, // 5
// end
CAL_CONF_PKT,
CAL_CONF_PKT,
CAL_END,
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,223 @@
/*
* 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;

1010
libfprint/drivers/elan.c Normal file

File diff suppressed because it is too large Load Diff

235
libfprint/drivers/elan.h Normal file
View File

@@ -0,0 +1,235 @@
/*
* Elan driver for libfprint
*
* Copyright (C) 2017 Igor Filatov <ia.filatov@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
*/
#pragma once
#include <glib.h>
#define ELAN_VEND_ID 0x04f3
/* a default device type */
#define ELAN_ALL_DEV 0
/* devices with quirks */
#define ELAN_0907 (1 << 0)
#define ELAN_0C03 (1 << 1)
#define ELAN_0C42 (1 << 2)
/* devices which don't require frame rotation before assembling */
#define ELAN_NOT_ROTATED ELAN_0C03
/* min FW version that supports calibration */
#define ELAN_MIN_CALIBRATION_FW 0x0138
/* max difference between background image mean and calibration mean
* (the response value of get_calib_mean_cmd)*/
#define ELAN_CALIBRATION_MAX_DELTA 500
/* times to retry reading calibration status during one session
* generally prevents calibration from looping indefinitely */
#define ELAN_CALIBRATION_ATTEMPTS 10
/* min and max frames in a capture */
#define ELAN_MIN_FRAMES 7
#define ELAN_MAX_FRAMES 30
/* crop frames to this height to improve stitching */
#define ELAN_MAX_FRAME_HEIGHT 50
/* number of frames to drop at the end of capture because frames captured
* while the finger is being lifted can be bad */
#define ELAN_SKIP_LAST_FRAMES 2
#define ELAN_CMD_LEN 0x2
#define ELAN_EP_CMD_OUT (0x1 | FPI_USB_ENDPOINT_OUT)
#define ELAN_EP_CMD_IN (0x3 | FPI_USB_ENDPOINT_IN)
#define ELAN_EP_IMG_IN (0x2 | FPI_USB_ENDPOINT_IN)
/* used as response length to tell the driver to skip reading response */
#define ELAN_CMD_SKIP_READ 0
/* usual command timeout and timeout for when we need to check if the finger is
* still on the device */
#define ELAN_CMD_TIMEOUT 10000
#define ELAN_FINGER_TIMEOUT 200
G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
FpImageDevice);
struct elan_cmd
{
unsigned char cmd[ELAN_CMD_LEN];
int response_len;
int response_in;
unsigned short devices;
gboolean never_cancel;
};
static const struct elan_cmd get_sensor_dim_cmd = {
.cmd = {0x00, 0x0c},
.response_len = 0x4,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
static const struct elan_cmd get_fw_ver_cmd = {
.cmd = {0x40, 0x19},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
/* unknown, returns 0x0 0x1 on 0907 */
static const struct elan_cmd activate_cmd_1 = {
.cmd = {0x40, 0x2a},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_0907,
};
static const struct elan_cmd get_image_cmd = {
.cmd = {0x00, 0x09},
/* raw frame sizes are calculated from image dimensions reported by the
* device */
.response_len = -1,
.response_in = ELAN_EP_IMG_IN,
.devices = ELAN_ALL_DEV,
};
static const struct elan_cmd read_sensor_status_cmd = {
.cmd = {0x40, 0x13},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
static const struct elan_cmd get_calib_status_cmd = {
.cmd = {0x40, 0x23},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
static const struct elan_cmd get_calib_mean_cmd = {
.cmd = {0x40, 0x24},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
static const struct elan_cmd led_on_cmd = {
.cmd = {0x40, 0x31},
.response_len = ELAN_CMD_SKIP_READ,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
/* wait for finger
* subsequent read will not complete until finger is placed on the reader */
static const struct elan_cmd pre_scan_cmd = {
.cmd = {0x40, 0x3f},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
};
/* led off, stop waiting for finger */
static const struct elan_cmd stop_cmd = {
.cmd = {0x00, 0x0b},
.response_len = ELAN_CMD_SKIP_READ,
.response_in = ELAN_EP_CMD_IN,
.devices = ELAN_ALL_DEV,
.never_cancel = TRUE,
};
static const FpIdEntry elan_id_table[] = {
{.vid = ELAN_VEND_ID, .pid = 0x0903, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0907, .driver_data = ELAN_0907},
{.vid = ELAN_VEND_ID, .pid = 0x0c01, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c02, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c03, .driver_data = ELAN_0C03},
{.vid = ELAN_VEND_ID, .pid = 0x0c04, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c05, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c06, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c07, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c08, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c09, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0a, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0b, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0c, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0e, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c0f, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c10, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c11, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c12, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c13, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c14, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c15, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c16, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c17, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c18, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c19, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1a, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1b, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1c, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1e, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c1f, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c20, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c21, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c22, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c23, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c24, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c25, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c26, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c27, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c28, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c29, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2a, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2b, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2c, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2e, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c2f, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c30, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c31, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .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 = 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 = 0x0c4f, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c6e, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c58, .driver_data = ELAN_ALL_DEV},
{.vid = 0, .pid = 0, .driver_data = 0},
};
static void elan_cmd_done (FpiSsm *ssm);
static void elan_cmd_read (FpiSsm *ssm,
FpDevice *dev);
static void elan_calibrate (FpiDeviceElan *self);
static void elan_capture (FpiDeviceElan *self);
static void dev_change_state (FpImageDevice *dev,
FpiImageDeviceState state);

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More