From fd2875aa3ea340a554b36d6abfb4764c29c5655a Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 6 Jun 2020 23:04:26 -0700 Subject: [PATCH 01/27] examples: add img-capture example This one can be useful in scripts, e.g. for building fingerprint dataset. --- examples/img-capture.c | 185 +++++++++++++++++++++++++++++++++++++++++ examples/meson.build | 2 +- examples/storage.c | 2 +- examples/storage.h | 2 + 4 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 examples/img-capture.c diff --git a/examples/img-capture.c b/examples/img-capture.c new file mode 100644 index 00000000..780c5d72 --- /dev/null +++ b/examples/img-capture.c @@ -0,0 +1,185 @@ +/* + * Example fingerprint verification program, which verifies the + * finger which has been previously enrolled to disk. + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2019 Marco Trevisan + * Copyright (C) 2020 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 "example-capture" + +#include +#include +#include + +#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\n", 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; + } + + 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; +} diff --git a/examples/meson.build b/examples/meson.build index 90a1178c..a0ea9ec5 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,5 +1,5 @@ -examples = [ 'enroll', 'verify', 'manage-prints' ] +examples = [ 'enroll', 'verify', 'manage-prints', 'img-capture' ] foreach example: examples executable(example, [ example + '.c', 'storage.c', 'utilities.c' ], diff --git a/examples/storage.c b/examples/storage.c index ebffb33f..4cccea21 100644 --- a/examples/storage.c +++ b/examples/storage.c @@ -180,7 +180,7 @@ print_create_template (FpDevice *dev, FpFinger finger) } -static gboolean +gboolean save_image_to_pgm (FpImage *img, const char *path) { FILE *fd = fopen (path, "w"); diff --git a/examples/storage.h b/examples/storage.h index 6c6c2206..0cc82696 100644 --- a/examples/storage.h +++ b/examples/storage.h @@ -28,3 +28,5 @@ FpPrint * print_create_template (FpDevice *dev, FpFinger finger); gboolean print_image_save (FpPrint *print, const char *path); +gboolean save_image_to_pgm (FpImage *img, + const char *path); From b6f965c1d9734b023904cedb8c266d4085ee310c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 29 Apr 2020 20:16:02 +0200 Subject: [PATCH 02/27] fpi-device: Use the current action string instead of value --- libfprint/fpi-device.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index 7c1c851c..0cc5ef41 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -593,7 +593,11 @@ fpi_device_action_error (FpDevice *device, if (error != NULL) { - g_debug ("Device reported generic error during action; action was: %i", priv->current_action); + g_autofree char *action_str = NULL; + + action_str = g_enum_to_string (FPI_TYPE_DEVICE_ACTION, priv->current_action); + g_debug ("Device reported generic error (%s) during action; action was: %s", + error->message, action_str); } else { @@ -682,10 +686,13 @@ fp_device_task_return_in_idle_cb (gpointer user_data) { FpDeviceTaskReturnData *data = user_data; FpDevicePrivate *priv = fp_device_get_instance_private (data->device); + g_autofree char *action_str = NULL; g_autoptr(GTask) task = NULL; - g_debug ("Completing action %d in idle!", priv->current_action); + + action_str = g_enum_to_string (FPI_TYPE_DEVICE_ACTION, priv->current_action); + g_debug ("Completing action %s in idle!", action_str); task = g_steal_pointer (&priv->current_task); priv->current_action = FPI_DEVICE_ACTION_NONE; From 7f7d099ba0f0880ea2ccd8c117ab3feb1a272816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 16 Jun 2020 22:43:18 +0200 Subject: [PATCH 03/27] fpi-device: Don't double check for cancellable value g_cancellable_is_cancelled already handles properly null values --- libfprint/fpi-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index 0cc5ef41..4f900551 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -391,7 +391,7 @@ fpi_device_action_is_cancelled (FpDevice *device) cancellable = g_task_get_cancellable (priv->current_task); - return cancellable ? g_cancellable_is_cancelled (cancellable) : FALSE; + return g_cancellable_is_cancelled (cancellable); } /** From cbf1dcca29b97f718be6889c465bddf8a2c364fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 16 Jun 2020 22:48:51 +0200 Subject: [PATCH 04/27] fpi-image-device: Improve debugging messages --- libfprint/fpi-image-device.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libfprint/fpi-image-device.c b/libfprint/fpi-image-device.c index 11399a1f..8fc1b92d 100644 --- a/libfprint/fpi-image-device.c +++ b/libfprint/fpi-image-device.c @@ -94,6 +94,8 @@ static void fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state) { FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self); + g_autofree char *prev_state_str = NULL; + g_autofree char *state_str = NULL; /* Cannot change to inactive using this function. */ g_assert (state != FPI_IMAGE_DEVICE_STATE_INACTIVE); @@ -102,7 +104,10 @@ fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state) * next operation. */ g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove); - fp_dbg ("Image device internal state change from %d to %d\n", priv->state, state); + prev_state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, priv->state); + state_str = g_enum_to_string (FPI_TYPE_IMAGE_DEVICE_STATE, state); + fp_dbg ("Image device internal state change from %s to %s\n", + prev_state_str, state_str); priv->state = state; g_object_notify (G_OBJECT (self), "fpi-image-device-state"); @@ -121,6 +126,7 @@ fp_image_device_enroll_maybe_await_finger_on (FpImageDevice *self) } else { + fp_dbg ("Awaiting finger on"); priv->enroll_await_on_pending = TRUE; } } From c6b8430c7264321059c1a3dfdba5223c8973f563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 16 Jun 2020 22:49:18 +0200 Subject: [PATCH 05/27] fpi-print: Improve debug on print score --- libfprint/fpi-print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fpi-print.c b/libfprint/fpi-print.c index 617e7b41..16877b8b 100644 --- a/libfprint/fpi-print.c +++ b/libfprint/fpi-print.c @@ -240,7 +240,7 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr gint score; gstruct = g_ptr_array_index (template->prints, i); score = bozorth_to_gallery (probe_len, pstruct, gstruct); - fp_dbg ("score %d", score); + fp_dbg ("score %d/%d", score, bz3_threshold); if (score >= bz3_threshold) return FPI_MATCH_SUCCESS; From e4d292b595fc0909a7f11b3e4e54736b1a943407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 16 Jun 2020 22:49:38 +0200 Subject: [PATCH 06/27] fp-image-device: Properly include fp-device.h --- libfprint/fp-image-device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fp-image-device.h b/libfprint/fp-image-device.h index 1eda8fbc..e23148b4 100644 --- a/libfprint/fp-image-device.h +++ b/libfprint/fp-image-device.h @@ -19,7 +19,7 @@ #pragma once -#include +#include "fp-device.h" G_BEGIN_DECLS From ed26976ac51e423d900c2b409a3c5ec81800666b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 16 Jun 2020 22:50:41 +0200 Subject: [PATCH 07/27] fpi-usb-transfer: Use the same values of libusb for transfer types --- libfprint/fpi-usb-transfer.c | 1 + libfprint/fpi-usb-transfer.h | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libfprint/fpi-usb-transfer.c b/libfprint/fpi-usb-transfer.c index 74b5b1ce..37033c85 100644 --- a/libfprint/fpi-usb-transfer.c +++ b/libfprint/fpi-usb-transfer.c @@ -105,6 +105,7 @@ fpi_usb_transfer_new (FpDevice * device) self = g_slice_new0 (FpiUsbTransfer); self->ref_count = 1; + self->type = FP_TRANSFER_NONE; self->device = device; diff --git a/libfprint/fpi-usb-transfer.h b/libfprint/fpi-usb-transfer.h index 40fd70cb..dc7fdb6d 100644 --- a/libfprint/fpi-usb-transfer.h +++ b/libfprint/fpi-usb-transfer.h @@ -47,10 +47,10 @@ typedef void (*FpiUsbTransferCallback)(FpiUsbTransfer *transfer, * Type of the transfer. */ typedef enum { - FP_TRANSFER_NONE = 0, - FP_TRANSFER_BULK, - FP_TRANSFER_CONTROL, - FP_TRANSFER_INTERRUPT, + FP_TRANSFER_NONE = -1, + FP_TRANSFER_CONTROL = 0, + FP_TRANSFER_BULK = 2, + FP_TRANSFER_INTERRUPT = 3, } FpiTransferType; /** From 1f96077e36cf7400dae85d24267ccc70424009b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 17 Jun 2020 14:00:19 +0200 Subject: [PATCH 08/27] 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 --- examples/enroll.c | 2 +- examples/verify.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/enroll.c b/examples/enroll.c index ce6f755d..17c231f9 100644 --- a/examples/enroll.c +++ b/examples/enroll.c @@ -112,7 +112,7 @@ on_enroll_progress (FpDevice *device, return; } - if (fp_device_supports_capture (device) && + if (print && fp_print_get_image (print) && print_image_save (print, "enrolled.pgm")) printf ("Wrote scanned image to enrolled.pgm\n"); diff --git a/examples/verify.c b/examples/verify.c index 23bfe8c0..3b4c74d8 100644 --- a/examples/verify.c +++ b/examples/verify.c @@ -124,7 +124,7 @@ on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print, return; } - if (print && fp_device_supports_capture (dev) && + if (print && fp_print_get_image (print) && print_image_save (print, "verify.pgm")) g_print ("Print image saved as verify.pgm\n"); From a5f4ad507a23634b59e4b89f7d3e825f2967bea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 17 Jun 2020 14:12:38 +0200 Subject: [PATCH 09/27] img-capture: Exit with error if the device doesn't support capture --- examples/img-capture.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/img-capture.c b/examples/img-capture.c index 780c5d72..638aa7e8 100644 --- a/examples/img-capture.c +++ b/examples/img-capture.c @@ -162,6 +162,13 @@ main (int argc, const char *argv[]) return EXIT_FAILURE; } + if (!fp_device_supports_capture (dev)) + { + 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); From 37b19674f1183604fecb561405ebc1b89ac2b787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 17 Jun 2020 14:14:35 +0200 Subject: [PATCH 10/27] verify: Use fast matching callback also for non-storage devices --- examples/verify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/verify.c b/examples/verify.c index 3b4c74d8..b47e1dbd 100644 --- a/examples/verify.c +++ b/examples/verify.c @@ -256,7 +256,7 @@ start_verification (FpDevice *dev, VerifyData *verify_data) g_print ("Print loaded. Time to verify!\n"); fp_device_verify (dev, verify_print, verify_data->cancellable, - NULL, NULL, NULL, + on_match_cb, verify_data, NULL, (GAsyncReadyCallback) on_verify_completed, verify_data); } From b7e27bfdc6fdd2806659b350b91320b035f6e474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 17 Jun 2020 14:16:34 +0200 Subject: [PATCH 11/27] 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 --- demo/gtk-libfprint-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demo/gtk-libfprint-test.c b/demo/gtk-libfprint-test.c index 8026815a..9ef87685 100644 --- a/demo/gtk-libfprint-test.c +++ b/demo/gtk-libfprint-test.c @@ -241,6 +241,8 @@ dev_capture_start_cb (FpDevice *dev, 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; From 8b64312f4bfee84c8be1eb9763f7fe87ec078a1a Mon Sep 17 00:00:00 2001 From: Vincent Huang Date: Fri, 31 Jul 2020 09:47:35 +0800 Subject: [PATCH 12/27] synaptics: support sensors pid 0xe9 & 0xdf --- libfprint/drivers/synaptics/synaptics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/synaptics/synaptics.c b/libfprint/drivers/synaptics/synaptics.c index 25ae1621..9fde846e 100644 --- a/libfprint/drivers/synaptics/synaptics.c +++ b/libfprint/drivers/synaptics/synaptics.c @@ -29,7 +29,8 @@ G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE) static const FpIdEntry id_table[] = { { .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, }, - + { .vid = SYNAPTICS_VENDOR_ID, .pid = 0xE9, }, + { .vid = SYNAPTICS_VENDOR_ID, .pid = 0xDF, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; From a4f7293f3201c41dbbd04a3e4433b510871f2926 Mon Sep 17 00:00:00 2001 From: Vincent Huang Date: Fri, 21 Aug 2020 17:42:00 +0800 Subject: [PATCH 13/27] synaptics: retry get version command once when receiving non-success status --- libfprint/drivers/synaptics/synaptics.c | 63 ++++++++++++++----------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/libfprint/drivers/synaptics/synaptics.c b/libfprint/drivers/synaptics/synaptics.c index 9fde846e..9bbae99d 100644 --- a/libfprint/drivers/synaptics/synaptics.c +++ b/libfprint/drivers/synaptics/synaptics.c @@ -898,6 +898,7 @@ dev_probe (FpDevice *device) const guint8 *data; gboolean read_ok = TRUE; g_autofree gchar *serial = NULL; + gboolean retry = TRUE; G_DEBUG_HERE (); @@ -915,35 +916,43 @@ dev_probe (FpDevice *device) if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error)) goto err_close; - /* TODO: Do not do this synchronous. */ - transfer = fpi_usb_transfer_new (device); - fpi_usb_transfer_fill_bulk (transfer, USB_EP_REQUEST, SENSOR_FW_CMD_HEADER_LEN); - transfer->short_is_error = TRUE; - transfer->buffer[0] = SENSOR_CMD_GET_VERSION; - if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error)) - goto err_close; - - g_clear_pointer (&transfer, fpi_usb_transfer_unref); - transfer = fpi_usb_transfer_new (device); - fpi_usb_transfer_fill_bulk (transfer, USB_EP_REPLY, 40); - if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error)) - goto err_close; - - fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length); - - if (!fpi_byte_reader_get_uint16_le (&reader, &status)) + while(1) { - g_warning ("Transfer in response to version query was too short"); - error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); - goto err_close; - } - if (status != 0) - { - g_warning ("Device responded with error: %d", status); - error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); - goto err_close; - } + /* TODO: Do not do this synchronous. */ + transfer = fpi_usb_transfer_new (device); + fpi_usb_transfer_fill_bulk (transfer, USB_EP_REQUEST, SENSOR_FW_CMD_HEADER_LEN); + transfer->short_is_error = TRUE; + transfer->buffer[0] = SENSOR_CMD_GET_VERSION; + if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error)) + goto err_close; + g_clear_pointer (&transfer, fpi_usb_transfer_unref); + transfer = fpi_usb_transfer_new (device); + fpi_usb_transfer_fill_bulk (transfer, USB_EP_REPLY, 40); + if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error)) + goto err_close; + + fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length); + + if (!fpi_byte_reader_get_uint16_le (&reader, &status)) + { + g_warning ("Transfer in response to version query was too short"); + error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); + goto err_close; + } + if (status != 0) + { + g_warning ("Device responded with error: %d retry: %d", status, retry); + if(retry) + { + retry = FALSE; + continue; + } + error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); + goto err_close; + } + break; + } read_ok &= fpi_byte_reader_get_uint32_le (&reader, &self->mis_version.build_time); read_ok &= fpi_byte_reader_get_uint32_le (&reader, &self->mis_version.build_num); read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.version_major); From e3c009c5b3e2cae506ba451f50d494ea5fa4d2cb Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Mon, 8 Jun 2020 21:47:32 +0800 Subject: [PATCH 14/27] fp-device: add new type FpDeviceError FP_DEVICE_ERROR_DATA_DUPLICATE --- libfprint/fp-device.h | 2 ++ libfprint/fpi-device.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/libfprint/fp-device.h b/libfprint/fp-device.h index 5c435fde..0be64ec0 100644 --- a/libfprint/fp-device.h +++ b/libfprint/fp-device.h @@ -90,6 +90,7 @@ typedef enum { * @FP_DEVICE_ERROR_DATA_INVALID: The passed data is invalid * @FP_DEVICE_ERROR_DATA_NOT_FOUND: Requested print was not found on device * @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation + * @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates * * Error codes for device operations. More specific errors from other domains * such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported. @@ -104,6 +105,7 @@ typedef enum { FP_DEVICE_ERROR_DATA_INVALID, FP_DEVICE_ERROR_DATA_NOT_FOUND, FP_DEVICE_ERROR_DATA_FULL, + FP_DEVICE_ERROR_DATA_DUPLICATE, } FpDeviceError; GQuark fp_device_retry_quark (void); diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index 4f900551..e62ab197 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -135,6 +135,10 @@ fpi_device_error_new (FpDeviceError error) msg = "Print was not found on the devices storage."; break; + case FP_DEVICE_ERROR_DATA_DUPLICATE: + msg = "This finger has already enrolled, please try a different finger"; + break; + default: g_warning ("Unsupported error, returning general error instead!"); error = FP_DEVICE_ERROR_GENERAL; From eb2aaaaa203f3d27ab110ece7c78074af05b19ef Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Mon, 8 Jun 2020 22:00:29 +0800 Subject: [PATCH 15/27] drivers: add goodix moc sensor driver support --- libfprint/drivers/goodixmoc/goodix.c | 1408 ++++++++++++++++++++ libfprint/drivers/goodixmoc/goodix.h | 58 + libfprint/drivers/goodixmoc/goodix_proto.c | 422 ++++++ libfprint/drivers/goodixmoc/goodix_proto.h | 232 ++++ libfprint/meson.build | 6 + meson.build | 1 + 6 files changed, 2127 insertions(+) create mode 100644 libfprint/drivers/goodixmoc/goodix.c create mode 100644 libfprint/drivers/goodixmoc/goodix.h create mode 100644 libfprint/drivers/goodixmoc/goodix_proto.c create mode 100644 libfprint/drivers/goodixmoc/goodix_proto.h diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c new file mode 100644 index 00000000..1eed70ec --- /dev/null +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -0,0 +1,1408 @@ +/* + * Goodix Moc driver for libfprint + * Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd. + * + * 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 "goodixmoc" + +#include "drivers_api.h" + +#include "goodix_proto.h" +#include "goodix.h" + + +/* Default enroll stages number */ +#define DEFAULT_ENROLL_SAMPLES 8 +/* Usb port setting */ +#define EP_IN (3 | FPI_USB_ENDPOINT_IN) +#define EP_OUT (1 | FPI_USB_ENDPOINT_OUT) + +#define EP_IN_MAX_BUF_SIZE (2048) + +#define MAX_USER_ID_LEN (64) + +/* Command transfer timeout :ms*/ +#define CMD_TIMEOUT (1000) +#define ACK_TIMEOUT (2000) +#define DATA_TIMEOUT (5000) + + +struct _FpiDeviceGoodixMoc +{ + FpDevice parent; + FpiSsm *task_ssm; + FpiSsm *cmd_ssm; + FpiUsbTransfer *cmd_transfer; + gboolean cmd_cancelable; + pgxfp_sensor_cfg_t sensorcfg; + gint enroll_stage; + gint max_enroll_stage; + GCancellable *cancellable; + GPtrArray *list_result; + guint8 template_id[TEMPLATE_ID_SIZE]; + gboolean is_enroll_identify; + +}; + +G_DEFINE_TYPE (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FP_TYPE_DEVICE) + +typedef void (*SynCmdMsgCallback) (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error); + +typedef struct +{ + guint8 cmd; + SynCmdMsgCallback callback; +} CommandData; + +/****************************************************************************** + * + * fp_cmd_xxx Function + * + *****************************************************************************/ +static void +fp_cmd_receive_cb (FpiUsbTransfer *transfer, + FpDevice *device, + gpointer user_data, + GError *error) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + CommandData *data = user_data; + int ret = -1, ssm_state = 0; + gxfp_cmd_response_t cmd_reponse = {0, }; + pack_header header; + guint32 crc32_calc = 0; + guint16 cmd = 0; + + if (error) + { + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } + if (data == NULL) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); + return; + } + ssm_state = fpi_ssm_get_cur_state (transfer->ssm); + /* skip zero length package */ + if (transfer->actual_length == 0) + { + fpi_ssm_jump_to_state (transfer->ssm, ssm_state); + return; + } + + ret = gx_proto_parse_header (transfer->buffer, transfer->actual_length, &header); + if (ret != 0) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Corrupted message received")); + return; + } + + gx_proto_crc32_calc (transfer->buffer, PACKAGE_HEADER_SIZE + header.len, (uint8_t *) &crc32_calc); + if(crc32_calc != *(uint32_t *) (transfer->buffer + PACKAGE_HEADER_SIZE + header.len)) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Package crc check failed")); + return; + } + + cmd = MAKE_CMD_EX (header.cmd0, header.cmd1); + + ret = gx_proto_parse_body (cmd, &transfer->buffer[PACKAGE_HEADER_SIZE], header.len, &cmd_reponse); + if (ret != 0) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Corrupted message received")); + return; + } + /* ack */ + if(header.cmd0 == RESPONSE_PACKAGE_CMD) + { + if (data->cmd != cmd_reponse.parse_msg.ack_cmd) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Unexpected response, got 0x%x", + cmd_reponse.parse_msg.ack_cmd)); + + return; + } + fpi_ssm_next_state (transfer->ssm); + return; + } + /* data */ + if (data->cmd != header.cmd0) + { + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Unexpected cmd, got 0x%x", + header.cmd0)); + return; + } + if (data->callback) + data->callback (self, &cmd_reponse, NULL); + + fpi_ssm_mark_completed (transfer->ssm); +} + + +static void +fp_cmd_run_state (FpiSsm *ssm, + FpDevice *dev) +{ + FpiUsbTransfer *transfer; + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (dev); + + switch (fpi_ssm_get_cur_state (ssm)) + { + case FP_CMD_SEND: + if (self->cmd_transfer) + { + self->cmd_transfer->ssm = ssm; + fpi_usb_transfer_submit (g_steal_pointer (&self->cmd_transfer), + CMD_TIMEOUT, + NULL, + fpi_ssm_usb_transfer_cb, + NULL); + } + else + { + fpi_ssm_next_state (ssm); + } + break; + + case FP_CMD_GET_ACK: + transfer = fpi_usb_transfer_new (dev); + transfer->ssm = ssm; + fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE); + fpi_usb_transfer_submit (transfer, + ACK_TIMEOUT, + NULL, + fp_cmd_receive_cb, + fpi_ssm_get_data (ssm)); + + break; + + case FP_CMD_GET_DATA: + transfer = fpi_usb_transfer_new (dev); + transfer->ssm = ssm; + fpi_usb_transfer_fill_bulk (transfer, EP_IN, EP_IN_MAX_BUF_SIZE); + fpi_usb_transfer_submit (transfer, + self->cmd_cancelable ? 0 : DATA_TIMEOUT, + self->cmd_cancelable ? self->cancellable : NULL, + fp_cmd_receive_cb, + fpi_ssm_get_data (ssm)); + break; + } + +} + + +static void +fp_cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (dev); + CommandData *data = fpi_ssm_get_data (ssm); + + self->cmd_ssm = NULL; + /* Notify about the SSM failure from here instead. */ + if (error) + { + if (data->callback) + data->callback (self, NULL, error); + else + g_error_free (error); + } +} + +static FpiUsbTransfer * +alloc_cmd_transfer (FpDevice *dev, + guint8 cmd0, + guint8 cmd1, + const guint8 *data, + guint16 data_len) +{ + gint ret = -1; + + g_autoptr(FpiUsbTransfer) transfer = NULL; + + guint32 total_len = data_len + PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE; + + g_return_val_if_fail (data || data_len == 0, NULL); + + transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk (transfer, EP_OUT, total_len); + + ret = gx_proto_build_package (transfer->buffer, &total_len, MAKE_CMD_EX (cmd0, cmd1), data, data_len); + + g_return_val_if_fail (ret == 0, NULL); + + return g_steal_pointer (&transfer); +} + +static void +fp_cmd_ssm_done_data_free (CommandData *data) +{ + g_free (data); +} + +static void +goodix_sensor_cmd (FpiDeviceGoodixMoc *self, + guint8 cmd0, + guint8 cmd1, + gboolean bwait_data_delay, + const guint8 * payload, + gssize payload_len, + SynCmdMsgCallback callback) +{ + + g_autoptr(FpiUsbTransfer) transfer = NULL; + + CommandData *data = g_new0 (CommandData, 1); + + transfer = alloc_cmd_transfer (FP_DEVICE (self), cmd0, cmd1, payload, payload_len); + + data->cmd = cmd0; + data->callback = callback; + + self->cmd_transfer = g_steal_pointer (&transfer); + self->cmd_cancelable = bwait_data_delay; + + self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self), + fp_cmd_run_state, + FP_CMD_NUM_STATES); + + fpi_ssm_set_data (self->cmd_ssm, data, (GDestroyNotify) fp_cmd_ssm_done_data_free); + + fpi_ssm_start (self->cmd_ssm, fp_cmd_ssm_done); + + +} +/****************************************************************************** + * + * fp_verify_xxxx Function + * + *****************************************************************************/ +static void +fp_verify_capture_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (resp->result >= GX_FAILED) + { + fp_dbg ("Capture sample failed, result: 0x%x", resp->result); + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL)); + return; + } + + if (resp->capture_data_resp.img_quality == 0) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER)); + return; + } + else if (resp->capture_data_resp.img_coverage < 35) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER)); + } + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_verify_identify_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + FpDevice *device = FP_DEVICE (self); + + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (!resp->verify.match) + { + fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error); + } + else if (memcmp (&resp->verify.template.tid, &self->template_id, TEMPLATE_ID_SIZE) != 0) + { + fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error); + } + else + { + fp_info ("Verify successful! for user: %s finger: %d", + resp->verify.template.payload.data, resp->verify.template.finger_index); + fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL); + } + + fpi_ssm_mark_completed (self->task_ssm); + +} + +static void +fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + guint8 param[3] = { 0 }; + + param[0] = 0x01; + param[1] = self->sensorcfg->config[10]; + param[2] = self->sensorcfg->config[11]; + + switch (fpi_ssm_get_cur_state (ssm)) + { + case FP_VERIFY_CAPTURE: + goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT, + true, + (const guint8 *) ¶m, + G_N_ELEMENTS (param), + fp_verify_capture_cb); + break; + + case FP_VERIFY_IDENTIFY: + goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &self->template_id, + TEMPLATE_ID_SIZE, + fp_verify_identify_cb); + break; + } + +} + +static void +fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (dev); + + fp_info ("Verify complete!"); + + if (error && error->domain == FP_DEVICE_RETRY) + fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, error); + + fpi_device_verify_complete (dev, error); + + self->task_ssm = NULL; +} + + +/****************************************************************************** + * + * fp__xxxx Function + * + *****************************************************************************/ +static gboolean +encode_finger_id ( + const guint8 * tid, + guint16 tid_len, + const guint8 * uid, + guint16 uid_len, + guint8 ** fid, + guint16 * fid_len + ) +{ + guint8 * buffer = NULL; + guint16 offset = 0; + + g_return_val_if_fail (tid != NULL, FALSE); + g_return_val_if_fail (uid != NULL, FALSE); + g_return_val_if_fail (fid != NULL, FALSE); + g_return_val_if_fail (fid_len != NULL, FALSE); + + *fid_len = (guint16) (70 + uid_len); // must include fingerid length + + *fid = (guint8 *) g_malloc0 (*fid_len + 2); + + buffer = *fid; + offset = 0; + buffer[offset++] = LOBYTE (*fid_len); + buffer[offset++] = HIBYTE (*fid_len); + + buffer[offset++] = 67; + buffer[offset++] = 1; + buffer[offset++] = 1; // finger index + buffer[offset++] = 0; // + + offset += 32; + + memcpy (&buffer[offset], tid, MIN (tid_len, TEMPLATE_ID_SIZE)); + offset += 32; // offset == 68 + + buffer[offset++] = uid_len; + memcpy (&buffer[offset], uid, uid_len); + offset += (guint8) uid_len; + + buffer[offset++] = 0; + + if (offset != (*fid_len + 2)) + { + memset (buffer, 0, *fid_len); + *fid_len = 0; + + fp_err ("offset != fid_len, %d != %d", offset, *fid_len); + return FALSE; + } + *fid_len += 2; + + return TRUE; +} +/****************************************************************************** + * + * fp_enroll_xxxx Function + * + *****************************************************************************/ + +static void +fp_enroll_enum_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (resp->result != GX_SUCCESS) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "Failed to enumerate fingers, result: 0x%x", + resp->result)); + return; + } + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE); +} + +static void +fp_enroll_identify_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (resp->verify.match) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_DUPLICATE, + "Finger is too similar to another, try use a different finger")); + // maybe need fpi_device_enroll_report_message ... + return; + } + fpi_ssm_next_state (self->task_ssm); + +} + +static void +fp_enroll_init_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + memcpy (self->template_id, resp->enroll_init.tid, TEMPLATE_ID_SIZE); + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_enroll_capture_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + /* */ + if (resp->result >= GX_FAILED) + { + fp_warn ("Capture sample failed, result: 0x%x", resp->result); + fpi_device_enroll_progress (FP_DEVICE (self), + self->enroll_stage, + NULL, + fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL)); + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE); + return; + } + + if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) || + (resp->capture_data_resp.img_coverage < self->sensorcfg->config[5])) + { + fp_warn ("Capture sample poor quality(%d): %d or coverage(%d): %d", + self->sensorcfg->config[4], + resp->capture_data_resp.img_quality, + self->sensorcfg->config[5], + resp->capture_data_resp.img_coverage); + fpi_device_enroll_progress (FP_DEVICE (self), + self->enroll_stage, + NULL, + fpi_device_retry_new (FP_DEVICE_RETRY_CENTER_FINGER)); + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE); + return; + } + if (self->is_enroll_identify) + { + self->is_enroll_identify = false; + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_IDENTIFY); + } + else + { + fpi_ssm_next_state (self->task_ssm); + } + +} +static void +fp_enroll_update_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + + if (resp->enroll_update.img_preoverlay > self->sensorcfg->config[3]) + { + fp_dbg ("Sample overlapping ratio is too High(%d): %d ", + self->sensorcfg->config[3], + resp->enroll_update.img_preoverlay); + /* here should tips move finger and try again */ + fpi_device_enroll_progress (FP_DEVICE (self), + self->enroll_stage, + NULL, + fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER)); + } + else if (resp->enroll_update.rollback) + { + fpi_device_enroll_progress (FP_DEVICE (self), + self->enroll_stage, + NULL, + fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL)); + } + else + { + self->enroll_stage++; + fpi_device_enroll_progress (FP_DEVICE (self), self->enroll_stage, NULL, NULL); + } + /* if enroll complete, no need to wait finger up */ + if (self->enroll_stage >= self->max_enroll_stage) + { + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CHECK_DUPLICATE); + return; + } + + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_enroll_check_duplicate_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (resp->check_duplicate_resp.duplicate) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_DUPLICATE, + "Finger has already enrolled")); + return; + } + + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_enroll_commit_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + if (resp->result >= GX_FAILED) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Commit template failed with errcode: 0x%x", resp->result)); + return; + } + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_finger_mode_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + /* if reach max timeout(5sec) finger not up, swtich to finger up again */ + if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT) + { + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_WAIT_FINGER_UP); + return; + } + else if (resp->finger_status.status != GX_SUCCESS) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Switch finger mode failed")); + return; + } + if (self->enroll_stage < self->max_enroll_stage) + { + fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE); + return; + } + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + FpPrint *print = NULL; + GVariant *data = NULL; + GVariant *uid = NULL; + GVariant *tid = NULL; + guint finger; + guint16 user_id_len; + guint16 payload_len = 0; + g_autofree gchar *user_id = NULL; + g_autofree guint8 *payload = NULL; + guint8 dummy[3] = { 0 }; + + dummy[1] = self->sensorcfg->config[4]; + dummy[2] = self->sensorcfg->config[5]; + + switch (fpi_ssm_get_cur_state (ssm)) + { + case FP_ENROLL_ENUM: + { + goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 1, + fp_enroll_enum_cb); + } + break; + + case FP_ENROLL_IDENTIFY: + { + dummy[0] = 0x01; + dummy[1] = self->sensorcfg->config[10]; + dummy[2] = self->sensorcfg->config[11]; + goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &self->template_id, + TEMPLATE_ID_SIZE, + fp_enroll_identify_cb); + } + break; + + case FP_ENROLL_CREATE: + { + goodix_sensor_cmd (self, MOC_CMD0_ENROLL_INIT, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 1, + fp_enroll_init_cb); + } + break; + + case FP_ENROLL_CAPTURE: + goodix_sensor_cmd (self, MOC_CMD0_CAPTURE_DATA, MOC_CMD1_DEFAULT, + true, + (const guint8 *) &dummy, + 3, + fp_enroll_capture_cb); + break; + + case FP_ENROLL_UPDATE: + dummy[0] = 1; + dummy[1] = self->sensorcfg->config[2]; + dummy[2] = self->sensorcfg->config[3]; + goodix_sensor_cmd (self, MOC_CMD0_ENROLL, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 3, + fp_enroll_update_cb); + break; + + case FP_ENROLL_WAIT_FINGER_UP: + dummy[0] = 0; + goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP, + true, + (const guint8 *) &dummy, + 1, + fp_finger_mode_cb); + break; + + case FP_ENROLL_CHECK_DUPLICATE: + goodix_sensor_cmd (self, MOC_CMD0_CHECK4DUPLICATE, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 3, + fp_enroll_check_duplicate_cb); + break; + + case FP_ENROLL_COMMIT: + { + fpi_device_get_enroll_data (device, &print); + user_id = fpi_print_generate_user_id (print); + user_id_len = strlen (user_id); + user_id_len = MIN (100, user_id_len); + finger = 1; + + if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) + memset (self->template_id, 0, TEMPLATE_ID_SIZE); + uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + user_id, + user_id_len, + 1); + + tid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + self->template_id, + TEMPLATE_ID_SIZE, + 1); + + data = g_variant_new ("(y@ay@ay)", + finger, + tid, + uid); + + fpi_print_set_type (print, FPI_PRINT_RAW); + fpi_print_set_device_stored (print, TRUE); + g_object_set (print, "fpi-data", data, NULL); + g_object_set (print, "description", user_id, NULL); + + g_debug ("user_id: %s, user_id_len: %d, finger: %d", user_id, user_id_len, finger); + + if(!encode_finger_id (self->template_id, + TEMPLATE_ID_SIZE, + (guint8 *) user_id, + user_id_len, + &payload, + &payload_len)) + { + fpi_ssm_mark_failed (ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "encode_finger_id failed")); + return; + } + goodix_sensor_cmd (self, MOC_CMD0_COMMITENROLLMENT, MOC_CMD1_DEFAULT, + false, + (const guint8 *) payload, + payload_len, + fp_enroll_commit_cb); + + } + break; + } + + +} + +static void +fp_enroll_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (dev); + FpPrint *print = NULL; + + if (error) + { + fpi_device_enroll_complete (dev, NULL, error); + return; + } + fp_info ("Enrollment complete!"); + + fpi_device_get_enroll_data (FP_DEVICE (self), &print); + + fpi_device_enroll_complete (FP_DEVICE (self), g_object_ref (print), NULL); + + self->task_ssm = NULL; +} +/****************************************************************************** + * + * fp_init_xxxx Function + * + *****************************************************************************/ +static void +fp_init_version_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + char nullstring[GX_VERSION_LEN + 1] = { 0 }; + + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + + G_STATIC_ASSERT (sizeof (resp->version_info.fwtype) == 8); + G_STATIC_ASSERT (sizeof (resp->version_info.algversion) == 8); + G_STATIC_ASSERT (sizeof (resp->version_info.fwversion) == 8); + + memcpy (nullstring, resp->version_info.fwtype, sizeof (resp->version_info.fwtype)); + fp_info ("Firmware type: %s", nullstring); + memcpy (nullstring, resp->version_info.algversion, sizeof (resp->version_info.algversion)); + fp_info ("Algversion version: %s", nullstring); + memcpy (nullstring, resp->version_info.fwversion, sizeof (resp->version_info.fwversion)); + fp_info ("Firmware version: %s", nullstring); + + fpi_ssm_next_state (self->task_ssm); +} + +static void +fp_init_config_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + + fpi_ssm_next_state (self->task_ssm); +} + + +static void +fp_init_sm_run_state (FpiSsm *ssm, FpDevice *device) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + guint8 dummy = 0; + + switch (fpi_ssm_get_cur_state (ssm)) + { + case FP_INIT_VERSION: + goodix_sensor_cmd (self, MOC_CMD0_GET_VERSION, MOC_CMD1_DEFAULT, + false, + &dummy, + 1, + fp_init_version_cb); + break; + + case FP_INIT_CONFIG: + goodix_sensor_cmd (self, MOC_CMD0_UPDATE_CONFIG, MOC_CMD1_WRITE_CFG_TO_FLASH, + false, + (guint8 *) self->sensorcfg, + sizeof (gxfp_sensor_cfg_t), + fp_init_config_cb); + break; + } + + +} + +static void +fp_init_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (dev); + + if (error) + { + fpi_device_open_complete (dev, error); + return; + } + self->task_ssm = NULL; + fpi_device_open_complete (dev, NULL); +} +/****************************************************************************** + * + * fp_template_delete Function + * + *****************************************************************************/ +static gboolean +parse_print_data (GVariant *data, + guint8 *finger, + const guint8 **tid, + gsize *tid_len, + const guint8 **user_id, + gsize *user_id_len) +{ + g_autoptr(GVariant) user_id_var = NULL; + g_autoptr(GVariant) tid_var = NULL; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (finger != NULL, FALSE); + g_return_val_if_fail (tid != NULL, FALSE); + g_return_val_if_fail (tid_len != NULL, FALSE); + g_return_val_if_fail (user_id != NULL, FALSE); + g_return_val_if_fail (user_id_len != NULL, FALSE); + + *tid = NULL; + *tid_len = 0; + *user_id = NULL; + *user_id_len = 0; + + + if (!g_variant_check_format_string (data, "(y@ay@ay)", FALSE)) + return FALSE; + + g_variant_get (data, + "(y@ay@ay)", + finger, + &tid_var, + &user_id_var); + + *tid = g_variant_get_fixed_array (tid_var, tid_len, 1); + *user_id = g_variant_get_fixed_array (user_id_var, user_id_len, 1); + + if (*user_id_len == 0 || *user_id_len > 100) + return FALSE; + + if (*user_id_len <= 0 || *user_id[0] == ' ') + return FALSE; + + if(*tid_len != TEMPLATE_ID_SIZE) + return FALSE; + + return TRUE; +} + +static void +fp_template_delete_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + FpDevice *device = FP_DEVICE (self); + + if (error) + { + fpi_device_delete_complete (device, error); + return; + } + if ((resp->result >= GX_FAILED) && (resp->result != GX_ERROR_FINGER_ID_NOEXIST)) + { + fpi_device_delete_complete (FP_DEVICE (self), + fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "Failed delete enrolled users, result: 0x%x", + resp->result)); + return; + } + + fp_info ("Successfully deleted enrolled user"); + fpi_device_delete_complete (device, NULL); +} +/****************************************************************************** + * + * fp_template_list Function + * + *****************************************************************************/ +static void +fp_template_list_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + FpDevice *device = FP_DEVICE (self); + + if (error) + { + fpi_device_list_complete (FP_DEVICE (self), NULL, error); + return; + } + if (resp->result != GX_SUCCESS) + { + fp_info ("Failed to query enrolled users: %d", resp->result); + fpi_device_list_complete (FP_DEVICE (self), + NULL, + fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "Failed to query enrolled users, result: 0x%x", + resp->result)); + return; + } + + self->list_result = g_ptr_array_new_with_free_func (g_object_unref); + + if(resp->finger_list_resp.finger_num == 0) + { + fp_info ("Database is empty"); + fpi_device_list_complete (device, + g_steal_pointer (&self->list_result), + NULL); + return; + } + + for (int n = 0; n < resp->finger_list_resp.finger_num; n++) + { + GVariant *data = NULL; + GVariant *tid = NULL; + GVariant *uid = NULL; + FpPrint *print; + gchar *userid; + + userid = (gchar *) resp->finger_list_resp.finger_list[n].payload.data; + + print = fp_print_new (FP_DEVICE (self)); + + tid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + resp->finger_list_resp.finger_list[n].tid, + TEMPLATE_ID_SIZE, + 1); + + uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + resp->finger_list_resp.finger_list[n].payload.data, + resp->finger_list_resp.finger_list[n].payload.size, + 1); + + data = g_variant_new ("(y@ay@ay)", + resp->finger_list_resp.finger_list[n].finger_index, + tid, + uid); + + fpi_print_set_type (print, FPI_PRINT_RAW); + fpi_print_set_device_stored (print, TRUE); + g_object_set (print, "fpi-data", data, NULL); + g_object_set (print, "description", userid, NULL); + fpi_print_fill_from_user_id (print, userid); + g_ptr_array_add (self->list_result, g_object_ref_sink (print)); + } + + fp_info ("Query complete!"); + fpi_device_list_complete (device, + g_steal_pointer (&self->list_result), + NULL); + +} + +/****************************************************************************** + * + * Interface Function + * + *****************************************************************************/ +static void +gx_fp_probe (FpDevice *device) +{ + GUsbDevice *usb_dev; + GError *error = NULL; + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + g_autofree gchar *serial = NULL; + gint productid = 0; + + /* Claim usb interface */ + usb_dev = fpi_device_get_usb_device (device); + if (!g_usb_device_open (usb_dev, &error)) + { + fpi_device_probe_complete (device, NULL, NULL, error); + return; + } + + if (!g_usb_device_reset (usb_dev, &error)) + goto err_close; + + if (!g_usb_device_claim_interface (usb_dev, 0, 0, &error)) + goto err_close; + + if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0) + { + + serial = g_strdup ("emulated-device"); + } + else + { + serial = g_usb_device_get_string_descriptor (usb_dev, + g_usb_device_get_serial_number_index (usb_dev), + &error); + + if (serial && !g_str_has_suffix (serial, "B0")) + fp_warn ("Device with serial %s not supported", serial); + if (error) + { + g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)), + 0, 0, NULL); + goto err_close; + } + } + productid = g_usb_device_get_pid (usb_dev); + switch (productid) + { + case 0x6496: + case 0x60A2: + self->max_enroll_stage = 12; + break; + + default: + self->max_enroll_stage = DEFAULT_ENROLL_SAMPLES; + break; + } + + fpi_device_set_nr_enroll_stages (device, self->max_enroll_stage); + + g_usb_device_close (usb_dev, NULL); + fpi_device_probe_complete (device, serial, NULL, error); + return; +err_close: + + g_usb_device_close (usb_dev, NULL); + fpi_device_probe_complete (device, NULL, NULL, error); + +} + +static void +gx_fp_init (FpDevice *device) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + GError *error = NULL; + int ret = 0; + + self->cancellable = g_cancellable_new (); + + self->sensorcfg = g_new0 (gxfp_sensor_cfg_t, 1); + + ret = gx_proto_init_sensor_config (self->sensorcfg); + if (ret != 0) + { + error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "Init sensor failed"); + fpi_device_open_complete (FP_DEVICE (self), error); + return; + } + self->sensorcfg->config[6] = self->max_enroll_stage; + + if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error)) + { + fpi_device_open_complete (FP_DEVICE (self), error); + return; + } + + /* Claim usb interface */ + if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error)) + { + fpi_device_open_complete (FP_DEVICE (self), error); + return; + } + + self->task_ssm = fpi_ssm_new (device, fp_init_sm_run_state, + FP_INIT_NUM_STATES); + + fpi_ssm_start (self->task_ssm, fp_init_ssm_done); + +} + +static void +gx_fp_exit (FpDevice *device) +{ + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + GError *error = NULL; + + g_clear_object (&self->cancellable); + g_clear_pointer (&self->sensorcfg, g_free); + + /* Release usb interface */ + g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (device)), + 0, 0, &error); + + /* Notify close complete */ + fpi_device_close_complete (FP_DEVICE (self), error); +} + + +static void +gx_fp_verify (FpDevice *device) +{ + + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + FpPrint *print = NULL; + + g_autoptr(GVariant) data = NULL; + guint8 finger; + const guint8 *user_id; + gsize user_id_len = 0; + const guint8 *tid; + gsize tid_len = 0; + + fpi_device_get_verify_data (device, &print); + + g_object_get (print, "fpi-data", &data, NULL); + + if (!parse_print_data (data, &finger, &tid, &tid_len, &user_id, &user_id_len)) + { + fpi_device_verify_complete (device, + fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); + return; + } + memcpy (&self->template_id, tid, tid_len); + + self->task_ssm = fpi_ssm_new (device, fp_verify_sm_run_state, + FP_VERIFY_NUM_STATES); + + fpi_ssm_start (self->task_ssm, fp_verify_ssm_done); + +} + +static void +gx_fp_enroll (FpDevice *device) +{ + + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + + self->enroll_stage = 0; + self->is_enroll_identify = true; + + self->task_ssm = fpi_ssm_new (device, fp_enroll_sm_run_state, + FP_ENROLL_NUM_STATES); + + fpi_ssm_start (self->task_ssm, fp_enroll_ssm_done); + +} + + +static void +gx_fp_template_list (FpDevice *device) +{ + + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + guint8 dummy[1] = { 0 }; + + G_DEBUG_HERE (); + + goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 1, + fp_template_list_cb); +} + + + +static void +gx_fp_template_delete (FpDevice *device) +{ + + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + FpPrint *print = NULL; + + g_autoptr(GVariant) data = NULL; + guint8 finger; + const guint8 *user_id; + gsize user_id_len = 0; + const guint8 *tid; + gsize tid_len = 0; + gsize payload_len = 0; + g_autofree guint8 *payload = NULL; + + fpi_device_get_delete_data (device, &print); + + g_object_get (print, "fpi-data", &data, NULL); + + if (!parse_print_data (data, &finger, &tid, &tid_len, &user_id, &user_id_len)) + { + fpi_device_delete_complete (device, + fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); + return; + } + if (!encode_finger_id (tid, tid_len, user_id, user_id_len, &payload, (guint16 *) &payload_len)) + { + fpi_device_delete_complete (device, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "encode_finger_id failed")); + return; + } + + goodix_sensor_cmd (self, MOC_CMD0_DELETETEMPLATE, MOC_CMD1_DEFAULT, + false, + (const guint8 *) payload, + payload_len, + fp_template_delete_cb); + +} + +static void +fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self) +{ + +} + +static void +gx_fp_cancel (FpDevice *device) +{ + + FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); + + /* Cancel any current interrupt transfer (resulting us to go into + * response reading mode again); then create a new cancellable + * for the next transfers. */ + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + self->cancellable = g_cancellable_new (); + +} + +static const FpIdEntry id_table[] = { + { .vid = 0x27c6, .pid = 0x5840, }, + { .vid = 0x27c6, .pid = 0x6496, }, + { .vid = 0x27c6, .pid = 0x60A2, }, + { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ +}; + + +static void +fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass) +{ + FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); + + dev_class->id = "goodixmoc"; + dev_class->full_name = "Goodix MOC Fingerprint Sensor"; + dev_class->type = FP_DEVICE_TYPE_USB; + dev_class->scan_type = FP_SCAN_TYPE_PRESS; + dev_class->id_table = id_table; + dev_class->nr_enroll_stages = DEFAULT_ENROLL_SAMPLES; + + dev_class->open = gx_fp_init; + dev_class->close = gx_fp_exit; + dev_class->probe = gx_fp_probe; + dev_class->verify = gx_fp_verify; + dev_class->enroll = gx_fp_enroll; + dev_class->delete = gx_fp_template_delete; + dev_class->list = gx_fp_template_list; + dev_class->cancel = gx_fp_cancel; +} diff --git a/libfprint/drivers/goodixmoc/goodix.h b/libfprint/drivers/goodixmoc/goodix.h new file mode 100644 index 00000000..c38bf9b9 --- /dev/null +++ b/libfprint/drivers/goodixmoc/goodix.h @@ -0,0 +1,58 @@ +/* + * Goodix Moc driver for libfprint + * Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd. + * + * 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 (FpiDeviceGoodixMoc, fpi_device_goodixmoc, FPI, DEVICE_GOODIXMOC, FpDevice) + +typedef enum { + FP_CMD_SEND = 0, + FP_CMD_GET_ACK, + FP_CMD_GET_DATA, + FP_CMD_NUM_STATES, +} FpCmdState; + + +typedef enum { + FP_INIT_VERSION = 0, + FP_INIT_CONFIG, + FP_INIT_NUM_STATES, +} FpInitState; + + +typedef enum { + FP_ENROLL_ENUM = 0, + FP_ENROLL_IDENTIFY, + FP_ENROLL_CREATE, + FP_ENROLL_CAPTURE, + FP_ENROLL_UPDATE, + FP_ENROLL_WAIT_FINGER_UP, + FP_ENROLL_CHECK_DUPLICATE, + FP_ENROLL_COMMIT, + FP_ENROLL_NUM_STATES, +} FpEnrollState; + +typedef enum { + FP_VERIFY_CAPTURE = 0, + FP_VERIFY_IDENTIFY, + FP_VERIFY_NUM_STATES, +} FpVerifyState; diff --git a/libfprint/drivers/goodixmoc/goodix_proto.c b/libfprint/drivers/goodixmoc/goodix_proto.c new file mode 100644 index 00000000..3174170b --- /dev/null +++ b/libfprint/drivers/goodixmoc/goodix_proto.c @@ -0,0 +1,422 @@ +/* + * Goodix Moc driver for libfprint + * Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd. + * + * 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 +#include "goodix_proto.h" + +/* + * Crc functions + */ + +#define WIDTH (8 * sizeof (uint32_t)) +#define FINAL_XOR_VALUE 0xFFFFFFFF +#define REFLECT_DATA(X) ((uint8_t) reflect ((X), 8)) +#define REFLECT_REMAINDER(X) ((unsigned int) reflect ((X), WIDTH)) + + +uint8_t +gx_proto_crc8_calc (uint8_t *lubp_date, uint32_t lui_len) +{ + const uint8_t *data = lubp_date; + unsigned int crc = 0; + int i, j; + + for (j = lui_len; j; j--, data++) + { + crc ^= (*data << 8); + for (i = 8; i; i--) + { + if (crc & 0x8000) + crc ^= (0x1070 << 3); + crc <<= 1; + } + } + + crc >>= 8; + crc = ~crc; + return (uint8_t) crc; +} + +typedef struct +{ + uint32_t crc; +} gf_crc32_context; + +static uint32_t s_crc_table[256] = +{ 0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, + 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, + 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, + 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca, + 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, + 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, + 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, + 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, + 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, + 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, + 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, + 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, + 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, + 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, + 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, + 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, + 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; + +static uint32_t +reflect (uint32_t data, uint8_t n_bits) +{ + unsigned long reflection = 0x00000000; + uint8_t bit; + + /* + * Reflect the data about the center bit. + */ + for (bit = 0; bit < n_bits; ++bit) + { + /* + * If the LSB bit is set, set the reflection of it. + */ + if (data & 0x01) + reflection |= (1 << ((n_bits - 1) - bit)); + + data = (data >> 1); + } + + return reflection; + +} + +static void +crc32_init (gf_crc32_context *ctx) +{ + ctx->crc = 0xFFFFFFFF; +} + +static void +crc32_update (gf_crc32_context *ctx, const uint8_t *message, uint32_t n_bytes) +{ + uint8_t data; + uint32_t byte; + + /* + * Divide the message by the polynomial, a byte at a time. + */ + for (byte = 0; byte < n_bytes; ++byte) + { + data = REFLECT_DATA (message[byte]) ^ (ctx->crc >> (WIDTH - 8)); + ctx->crc = s_crc_table[data] ^ (ctx->crc << 8); + } +} + +static void +crc32_final (gf_crc32_context *ctx, uint8_t *md) +{ + ctx->crc = (REFLECT_REMAINDER (ctx->crc) ^ FINAL_XOR_VALUE); + memcpy (md, &ctx->crc, 4); +} + +uint8_t +gx_proto_crc32_calc (uint8_t *pchMsg, uint32_t wDataLen, uint8_t *pchMsgDst) +{ + gf_crc32_context context = { 0 }; + + if (!pchMsg) + return 0; + + crc32_init (&context); + + crc32_update (&context, pchMsg, wDataLen); + + crc32_final (&context, pchMsgDst); + + + return 1; +} +/* + * protocol + * + */ + +static uint8_t dump_seq = 0; + +static void +init_pack_header ( + ppack_header pheader, + uint16_t len, + uint16_t cmd, + uint8_t packagenum + ) +{ + g_assert (pheader); + + memset (pheader, 0, sizeof (*pheader)); + pheader->cmd0 = HIBYTE (cmd); + pheader->cmd1 = LOBYTE (cmd); + pheader->packagenum = packagenum; + pheader->reserved = dump_seq++; + pheader->len = len + PACKAGE_CRC_SIZE; + pheader->crc8 = gx_proto_crc8_calc ((uint8_t *) pheader, 6); + pheader->rev_crc8 = ~pheader->crc8; +} + + +int +gx_proto_build_package (uint8_t *ppackage, + uint32_t *package_len, + uint16_t cmd, + const uint8_t *payload, + uint32_t payload_size) +{ + pack_header header; + + if (!ppackage || !package_len) + return -1; + + if(*package_len < (payload_size + PACKAGE_HEADER_SIZE + PACKAGE_CRC_SIZE)) + return -1; + + init_pack_header (&header, payload_size, cmd, 0); + + memcpy (ppackage, &header, PACKAGE_HEADER_SIZE); + memcpy (ppackage + PACKAGE_HEADER_SIZE, payload, payload_size); + + gx_proto_crc32_calc (ppackage, PACKAGE_HEADER_SIZE + payload_size, ppackage + PACKAGE_HEADER_SIZE + payload_size); + + return 0; +} + + +int +gx_proto_parse_header ( + uint8_t *buffer, + uint32_t buffer_len, + pack_header *pheader) +{ + if (!buffer || !pheader) + return -1; + if (buffer_len < PACKAGE_HEADER_SIZE) + return -1; + + memcpy (pheader, buffer, sizeof (pack_header)); + + pheader->len = GUINT16_FROM_LE (*(buffer + 4)); + pheader->len -= PACKAGE_CRC_SIZE; + + return 0; +} + +static int +gx_proto_parse_fingerid ( + uint8_t * fid_buffer, + uint16_t fid_buffer_size, + ptemplate_format_t template + ) +{ + uint8_t * buffer = NULL; + uint16_t Offset = 0; + + if (!template || !fid_buffer) + return -1; + + if (fid_buffer_size < 70) + return -1; + + buffer = fid_buffer; + Offset = 0; + + if (buffer[Offset++] != 67) + return -1; + + template->type = buffer[Offset++]; + template->finger_index = buffer[Offset++]; + Offset++; + + memcpy (template->accountid, &buffer[Offset], 32); + Offset += 32; + + memcpy (template->tid, &buffer[Offset], 32); + Offset += 32; // Offset == 68 + + template->payload.size = buffer[Offset++]; + memset (template->payload.data, 0, 56); + memcpy (template->payload.data, &buffer[Offset], template->payload.size); + + return 0; +} + +int +gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint32_t buffer_len, pgxfp_cmd_response_t presp) +{ + uint32_t offset = 0; + uint8_t *fingerlist = NULL; + + if (!buffer || !presp) + return -1; + if (buffer_len < 1) + return -1; + presp->result = buffer[0]; + switch (HIBYTE (cmd)) + { + case RESPONSE_PACKAGE_CMD: + { + presp->parse_msg.ack_cmd = buffer[1]; + } + break; + + case MOC_CMD0_UPDATE_CONFIG: + case MOC_CMD0_COMMITENROLLMENT: + case MOC_CMD0_DELETETEMPLATE: + break; + + case MOC_CMD0_GET_VERSION: + memcpy (&presp->version_info, buffer + 1, sizeof (gxfp_version_info_t)); + break; + + case MOC_CMD0_CAPTURE_DATA: + if (LOBYTE (cmd) == MOC_CMD1_DEFAULT) + { + presp->capture_data_resp.img_quality = buffer[1]; + presp->capture_data_resp.img_coverage = buffer[2]; + } + break; + + case MOC_CMD0_ENROLL_INIT: + if (presp->result == GX_SUCCESS) + memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE); + break; + + case MOC_CMD0_ENROLL: + presp->enroll_update.rollback = (buffer[0] < 0x80) ? false : true; + presp->enroll_update.img_overlay = buffer[1]; + presp->enroll_update.img_preoverlay = buffer[2]; + break; + + case MOC_CMD0_CHECK4DUPLICATE: + presp->check_duplicate_resp.duplicate = (presp->result == 0) ? false : true; + if (presp->check_duplicate_resp.duplicate) + { + uint16_t tid_size = GUINT16_FROM_LE (*(buffer + 1)); + memcpy (&presp->check_duplicate_resp.template, buffer + 3, tid_size); + } + break; + + case MOC_CMD0_GETFINGERLIST: + if (presp->result != GX_SUCCESS) + break; + presp->finger_list_resp.finger_num = buffer[1]; + if (presp->finger_list_resp.finger_num > FP_MAX_FINGERNUM) + { + presp->finger_list_resp.finger_num = 0; + presp->result = GX_ERROR_NO_AVAILABLE_SPACE; + break; + } + fingerlist = buffer + 2; + for(uint8_t num = 0; num < presp->finger_list_resp.finger_num; num++) + { + uint16_t fingerid_length = GUINT16_FROM_LE (*(fingerlist + offset)); + offset += 2; + if (gx_proto_parse_fingerid (fingerlist + offset, + fingerid_length, + &presp->finger_list_resp.finger_list[num]) != 0) + { + g_error ("parse fingerlist error"); + presp->finger_list_resp.finger_num = 0; + presp->result = GX_FAILED; + break; + } + offset += fingerid_length; + } + break; + + case MOC_CMD0_IDENTIFY: + { + uint32_t score = 0; + uint8_t study = 0; + uint16_t fingerid_size = 0; + presp->verify.match = (buffer[0] == 0) ? true : false; + if (presp->verify.match) + { + offset += 1; + presp->verify.rejectdetail = GUINT16_FROM_LE (*(buffer + offset)); + offset += 2; + score = GUINT32_FROM_LE (*(buffer + offset)); + offset += 4; + study = GUINT16_FROM_LE (*(buffer + offset)); + offset += 1; + fingerid_size = GUINT16_FROM_LE (*(buffer + offset)); + offset += 2; + if (gx_proto_parse_fingerid (buffer + offset, fingerid_size, &presp->verify.template) != 0) + { + presp->result = GX_FAILED; + break; + } + g_debug ("match, score: %d, study: %d", score, study); + } + } + break; + + case MOC_CMD0_FINGER_MODE: + presp->finger_status.status = buffer[0]; + break; + + default: + break; + } + + return 0; +} + +static uint8_t sensor_config[26] = { + 0x00, 0x00, 0x64, 0x50, 0x0f, 0x41, 0x08, 0x0a, 0x18, 0x00, 0x00, 0x23, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x05, 0x05 +}; + +int +gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig) +{ + uint32_t crc32_calc = 0; + + if (!pconfig) + return -1; + memset (pconfig, 0, sizeof (*pconfig)); + + //NOTICE: Do not change any value! + memcpy (&pconfig->config, sensor_config, 26); + pconfig->reserved[0] = 1; + + gx_proto_crc32_calc ((uint8_t *) pconfig, sizeof (*pconfig) - PACKAGE_CRC_SIZE, (uint8_t *) &crc32_calc); + + memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE); + + return 0; +} \ No newline at end of file diff --git a/libfprint/drivers/goodixmoc/goodix_proto.h b/libfprint/drivers/goodixmoc/goodix_proto.h new file mode 100644 index 00000000..1611a601 --- /dev/null +++ b/libfprint/drivers/goodixmoc/goodix_proto.h @@ -0,0 +1,232 @@ +/* + * Goodix Moc driver for libfprint + * Copyright (C) 2019 Shenzhen Goodix Technology Co., Ltd. + * + * 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 +#include +#include + +#define PACKAGE_CRC_SIZE (4) +#define PACKAGE_HEADER_SIZE (8) + +#define FP_MAX_FINGERNUM (10) + +#define TEMPLATE_ID_SIZE (32) + +#define GX_VERSION_LEN (8) + +/* Type covert */ +#define MAKE_CMD_EX(cmd0, cmd1) ((uint16_t) (((cmd0) << 8) | (cmd1))) +#define LOBYTE(value) ((uint8_t) (value)) +#define HIBYTE(value) ((uint8_t) (((uint16_t) (value) >> 8) & 0xFF)) + + +/* Error code */ +#define GX_SUCCESS 0x00 +#define GX_FAILED 0x80 +#define GX_ERROR_FINGER_ID_NOEXIST 0x9C +#define GX_ERROR_TEMPLATE_INCOMPLETE 0xB8 +#define GX_ERROR_WAIT_FINGER_UP_TIMEOUT 0xC7 +#define GX_ERROR_NO_AVAILABLE_SPACE 0x8F + +/* Command Type Define */ +#define RESPONSE_PACKAGE_CMD 0xAA + +#define MOC_CMD0_ENROLL 0xA0 +#define MOC_CMD0_ENROLL_INIT 0xA1 +#define MOC_CMD0_CAPTURE_DATA 0xA2 +#define MOC_CMD0_CHECK4DUPLICATE 0xA3 +#define MOC_CMD0_COMMITENROLLMENT 0xA4 + +#define MOC_CMD0_IDENTIFY 0xA5 +#define MOC_CMD0_GETFINGERLIST 0xA6 +#define MOC_CMD0_DELETETEMPLATE 0xA7 + +#define MOC_CMD1_DEFAULT 0x00 +#define MOC_CMD1_UNTIL_DOWN 0x00 +#define MOC_CMD1_WHEN_DOWN 0x01 + +#define MOC_CMD1_DELETE_TEMPLATE 0x04 +#define MOC_CMD1_DELETE_ALL 0x01 + +#define MOC_CMD0_GET_VERSION 0xD0 + +#define MOC_CMD0_UPDATE_CONFIG 0xC0 +#define MOC_CMD1_NWRITE_CFG_TO_FLASH 0x00 +#define MOC_CMD1_WRITE_CFG_TO_FLASH 0x01 + +#define MOC_CMD0_FINGER_MODE 0xB0 +#define MOC_CMD1_GET_FINGER_MODE 0x00 +#define MOC_CMD1_SET_FINGER_DOWN 0x01 +#define MOC_CMD1_SET_FINGER_UP 0x02 +/* */ + +typedef struct _gxfp_version_info +{ + uint8_t format[2]; + uint8_t fwtype[GX_VERSION_LEN]; + uint8_t fwversion[GX_VERSION_LEN]; + uint8_t customer[GX_VERSION_LEN]; + uint8_t mcu[GX_VERSION_LEN]; + uint8_t sensor[GX_VERSION_LEN]; + uint8_t algversion[GX_VERSION_LEN]; + uint8_t interface[GX_VERSION_LEN]; + uint8_t protocol[GX_VERSION_LEN]; + uint8_t flashVersion[GX_VERSION_LEN]; + uint8_t reserved[62]; +} gxfp_version_info_t, *pgxfp_version_info_t; + + +typedef struct _gxfp_parse_msg +{ + uint8_t ack_cmd; + bool has_no_config; +} gxfp_parse_msg_t, *pgxfp_parse_msg_t; + + +typedef struct _gxfp_enroll_init +{ + uint8_t tid[TEMPLATE_ID_SIZE]; +} gxfp_enroll_init_t, *pgxfp_enroll_init_t; + +#pragma pack(push, 1) +typedef struct _template_format +{ + uint8_t type; + uint8_t finger_index; + uint8_t accountid[32]; + uint8_t tid[32]; + struct + { + uint32_t size; + uint8_t data[56]; + } payload; + uint8_t reserve[2]; +} template_format_t, *ptemplate_format_t; + +#pragma pack(pop) + + +typedef struct _gxfp_verify +{ + bool match; + uint32_t rejectdetail; + template_format_t template; +} gxfp_verify_t, *pgxfp_verify_t; + + +typedef struct _gxfp_capturedata +{ + uint8_t img_quality; + uint8_t img_coverage; +} gxfp_capturedata_t, *pgxfp_capturedata_t; + +typedef struct _gxfp_check_duplicate +{ + bool duplicate; + template_format_t template; +} gxfp_check_duplicate_t, *pgxfp_check_duplicate_t; + + +typedef struct _gxfp_enroll_update +{ + bool rollback; + uint8_t img_overlay; + uint8_t img_preoverlay; +} gxfp_enroll_update_t, *Pgxfp_enroll_update_t; + +typedef struct _gxfp_enum_fingerlist +{ + uint8_t finger_num; + template_format_t finger_list[FP_MAX_FINGERNUM]; +} gxfp_enum_fingerlist_t, *pgxfp_enum_fingerlist_t; + +typedef struct _gxfp_enroll_commit +{ + uint8_t result; +} gxfp_enroll_commit_t, *pgxfp_enroll_commit_t; + +typedef struct _fp_finger_status +{ + uint8_t status; +} fp_finger_status_t, *pfp_finger_status_t; + + +typedef struct _fp_cmd_response +{ + uint8_t result; + union + { + gxfp_parse_msg_t parse_msg; + gxfp_verify_t verify; + gxfp_enroll_init_t enroll_init; + gxfp_capturedata_t capture_data_resp; + gxfp_check_duplicate_t check_duplicate_resp; + gxfp_enroll_commit_t enroll_commit; + gxfp_enroll_update_t enroll_update; + gxfp_enum_fingerlist_t finger_list_resp; + gxfp_version_info_t version_info; + fp_finger_status_t finger_status; + }; +} gxfp_cmd_response_t, *pgxfp_cmd_response_t; + + +typedef struct _pack_header +{ + uint8_t cmd0; + uint8_t cmd1; + uint8_t packagenum; + uint8_t reserved; + uint16_t len; + uint8_t crc8; + uint8_t rev_crc8; +} pack_header, *ppack_header; + + +typedef struct _gxfp_sensor_cfg +{ + uint8_t config[26]; + uint8_t reserved[98]; + uint8_t crc_value[4]; +} gxfp_sensor_cfg_t, *pgxfp_sensor_cfg_t; +/* */ + +int gx_proto_build_package (uint8_t *ppackage, + uint32_t *package_len, + uint16_t cmd, + const uint8_t *payload, + uint32_t payload_size); + +int gx_proto_parse_header (uint8_t *buffer, + uint32_t buffer_len, + pack_header *pheader); + +int gx_proto_parse_body (uint16_t cmd, + uint8_t *buffer, + uint32_t buffer_len, + pgxfp_cmd_response_t presponse); + +int gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig); + +uint8_t gx_proto_crc8_calc (uint8_t *lubp_date, + uint32_t lui_len); + +uint8_t gx_proto_crc32_calc (uint8_t *pchMsg, + uint32_t wDataLen, + uint8_t *pchMsgDst); diff --git a/libfprint/meson.build b/libfprint/meson.build index 4715307a..96cfe9b5 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -161,6 +161,12 @@ foreach driver: drivers 'drivers/synaptics/bmkt_message.c', ] endif + if driver == 'goodixmoc' + drivers_sources += [ + 'drivers/goodixmoc/goodix.c', + 'drivers/goodixmoc/goodix_proto.c', + ] + endif endforeach if aeslib diff --git a/meson.build b/meson.build index 27dfd068..12a1503c 100644 --- a/meson.build +++ b/meson.build @@ -110,6 +110,7 @@ default_drivers = [ 'upektc', 'upeksonly', 'upekts', + 'goodixmoc', ] all_drivers = default_drivers + virtual_drivers From c85f3851919f8aa7f861b0b39fa8c12c042a114b Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Mon, 8 Jun 2020 22:17:32 +0800 Subject: [PATCH 16/27] tests: add test for goodixmoc driver --- tests/goodixmoc/custom.ioctl | 297 +++++++++++++++++++++++++++++++++++ tests/goodixmoc/custom.py | 46 ++++++ tests/goodixmoc/device | 171 ++++++++++++++++++++ tests/meson.build | 1 + 4 files changed, 515 insertions(+) create mode 100644 tests/goodixmoc/custom.ioctl create mode 100644 tests/goodixmoc/custom.py create mode 100644 tests/goodixmoc/device diff --git a/tests/goodixmoc/custom.ioctl b/tests/goodixmoc/custom.ioctl new file mode 100644 index 00000000..92d50f95 --- /dev/null +++ b/tests/goodixmoc/custom.ioctl @@ -0,0 +1,297 @@ +@DEV /dev/bus/usb/001/003 +USBDEVFS_GET_CAPABILITIES 0 FD010000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 D00000000500BA4500611A297F + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000008009D6200D00001B5A57582000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 D0000001850067980001FE415050000000000030313030303232384C454E4F564F0000474D3138384230004746333230360000312E30322E30310055534200000000005642530000000000303030303030303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051239DE6303030303033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 140 140 0 C001000184008E71000064500F410C0A1800002300000101000101010100010105050100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B737316F3EB36C6A + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000208004BB400C00101C96A6C6B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 C00100030500FB040093B3ED01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A6000002050049B600C27E4B39 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000004080036C900A60001F1AFC9FB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A60000050600609F000094D6C40E0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000030700AC53000F411A349263 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000060800E01F00A20001605AE410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A2000007070007F8005564FA6B157100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000042400F40B000000000000000000000000000000000000000000000000000000000000000095D4A28A + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000080800CC3300A500013F9036A9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A50000090500DE2103D6515435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A10000050500807F007BE269C4 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000A08001AE500A10001AE651B42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A100000B250002FD00B786B17D6A044D24C1651C2B1A76F6396D790639F58CA6D62DDDB8E179A9BD4A6C5C6C9200000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000607006C93000F41A33C2AB4 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000C0800679800A200011C98B985000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200000D0700807F0059643EDA283F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000007070055AA016450891085EC + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00000E0800B14E00A000013F11196A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000000F070004FB000000E0109A2200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200080500629D004A354747 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001008003FC000B002017532670A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200114500A15E008E0091009E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000988D37C39E006F0083007C006D00690079008800000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000907002BD4000F41D2CA1A81 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000120800E91600A20001A47AD7CB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001307000EF1004B640F46BD2D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000A0700C43B016450398D1A9E + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000140800946B00A0000121EDB70D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000015070021DE0000007BC22C5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000B0500DF200052FA3E5D + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000016080042BD00B002019E7183CF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200174500DC23008200A200AA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000F1B14CECAA0093009F009800A90087009A009100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000C0700EB14000F416BC2A256 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001808006E9100A20001D8B88A5E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001907008976005664DBD4593000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000000D0700D22D01645041EE0D0E + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001A0800B84700A00001FB312AB1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000001B07000DF2000000CA0273AA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002000E05001FE000EF2AA657 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001C0800C53A00B00201E2B3DE5A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002001D45005BA400A8009100AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C000000000000000000000000008A57E0B3AB0071008B008F009100920093009100000000000000000000000000AF00A500AD00A000B100A300AA00A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200000F070056A9000F416A9F62DF + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00001E080013EC00A2000133FB6E9B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200001F0700F40B005A625A6BF72B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000100700E11E016450A25FACED + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000200800DE2100A000011D15EAC2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002107006B94002900A6F807F200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200110500FA0500438F0629 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000022080008F700B00201A289DE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200234500966900870088008800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D0000000000000000000000000074CA825A8800700085009600940070001A001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000120700659A000F41892EC33C + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000240800758A00A20001D5DFAEE8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000250700926D00556427B73E5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001307005CA3016450A3026C64 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000260800A35C00A00001F6560E07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000027070016E90058265460564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001405003AC500FE5F9E23 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002808008F7000B00201DE4B8395000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020029450011EE007B00950097006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D000000000000000000000000007AB44F7697006E0084008A007400720078008000000000000000000000000000AE00A500AD00A000B100A200AA00A300A3009D00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000150700738C000F41F14DD4AC + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002A080059A600A200010F033354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200002B0700BE4100566455244C8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001607009C630164501A0AD4B3 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002C080024DB00A000018A945392000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000002D0700916E005F2DD3D14D7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200170500877800E690E739 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00002E0800F20D00B0020135086750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002002F45006C9300A80083008A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000000000000000000000DD3369188A006D00870082008900940074001A00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009D00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000180700E21D000F4141D04BDE + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003008007C8300A2000111FF9D33000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003107009B6400586440DB796400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000190700DB240164506BFCE486 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000320800AA5500A0000132763DDC000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003307001FE072635FE0E8A18200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001A050016E900A4EAF211 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000340800D72800B002012BF4C937000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B0020035450049B6007D00920094008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000000000000000000000520A47F394008C009A008B008400890094006D00000000000000000000000000AE00A500AD00A000B100A300AA00A200A3009D00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001B07005FA0000F41408D8B57 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000036080001FE00A20001FABC79F6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000370700E619005964B9BF1A2300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001C07001BE4016450D2F45C51 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003808002DD200A000014EB46049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003907009867725F526A136B6D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002001D050000FF0009B0C408 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003A0800FB0400B00201F128548B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002003B4500659A0084007D008B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000BAEEF1FA8B0099009C006A009A007B0089008300000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200001E07009F60000F41F9853380 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003C0800867900A20001867E2463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200003D0700619E005864307089D800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000001F0700A659016450D3A99CD8 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00003E080050AF00A00001A5F7848C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000003F0700E51A0063324BE2275A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200200500708F00DCB5EECB + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004008001BE400B00201E7BD49D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200414500857A0078006F0074009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C0000000000000000000000000079DB6FC674009200A6008C0071006C008E009400000000000000000000000000AF00A500AD00A000B100A300A900A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000021070039C6000F41C7E8B94B + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000420800CD3200A2000136F5F911000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004307002AD5005A647427533000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000220700D6290164502CAFB954 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000440800B04F00A00001B36299D7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A0000045070005FA0061447F5F4C1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B00200230500CD3200C47A97D1 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000460800669900B002010CFEAD15000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200474500F807009500860087008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C0000000000000000000000000074D7CC3787008D00A3006D007D0081009C007C00000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000240700F906000F417EE0019C + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004808004AB500A200014A37A484000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000490700AD52005764F1A7756700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000250700C03F01645054CCAEC4 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004A08009C6300A0000169BE046B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000004B070029D60041281F96933800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002605000DF20079AA0FDB + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004C0800E11E00B00201703CF080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002004D45007F80009E008E008E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000000000000000000000D393E7738E007E00AB00840096007F0092008100000000000000000000000000AF00A500AD00A000B100A300AA00A300A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A2000027070044BB000F417FBDC115 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00004E080037C800A20001A1744041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200004F0700D02F005964C7DF8EA700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000028070051AE016450E45131B6 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000500800B94600A000017742AA0C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005107000CF300624F1EC75A2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002905004AB5002B5AB4E0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005208006F9000B00201C8DE9ECE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B00200534500F10E0077007A00720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000000000000000000000C5190965720083007500930073007E006E008200000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002A0700D52A000F41CF205E67 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000054080012ED00A20001BF88EE26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000550700F50A0058641D3C23CD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002B0700EC13016450E50CF13F + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000560800C43B00A000019C014EC9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000570700718E726054F685049700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002C05008A7500968A2CEA + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000580800E81700B00201B41CC35B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005945007689008C007100780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000D98A26F0780072007A009500A10088009C008F00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200002D0700C33C000F41B74349F7 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005A08003EC100A200016554739A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200005B0700D926005964EDCD672F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A000002E07002CD30164505C0449E8 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005C080043BC00A00001E0C3135C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000005D0700F609725F58291DE42400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B002002F050037C8008E4555F0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00005E0800956A00B002015F5F279E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002005F45000BF400A30088009D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C000000000000000000000000001A1438ED9D008D00A80071007F0092006F006100000000000000000000000000AE00A400AC009F00B100A200A900A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000300700F00F000F4154F2E814 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000060080058A700A200018370B3E9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000610700BF400059646AA8553300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A00000310700C9360164507EDE474C + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006208008E7100A00001A0F91306000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A000006307003BC4006432979DA1E700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 B0020032050004FB00326A5B9D + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000640800F30C00B00201B97BE7ED000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 B002006545006D92008D008F008A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000000000000000000000394AB8458A00750083008D0092008B0071007A00000000000000000000000000AE00A500AD00A000B100A200A900A200A3009C00000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A200003307004DB2000F4155AF289D + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000066080025DA00A200016833572C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A20000670700C23D0057645CD0AEF300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A0000034070009F6016450C7D6FF9B + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000068080009F600A00001DC3B4E93000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A00000690700BC43002E00509568C700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A3000035070019E6000F41EC883513 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006A0800DF2000A30001C8D82C7D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A300006B05003BC40055C25B16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A40000366A006798640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F647900B5C8699F + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006C0800A25D00A40001A68D87BD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A400006D0500996600E41BAEE2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 13 13 0 A60000370500689700E8D1ECD8 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00006E0800748B00A6000185042752000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 128 0 A600006F6C0055AA0001640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479006EA4C362000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 A20000380700A15E010023D1112994 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000392400847B000000000000000000000000000000000000000000000000000000000000000038910386 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A700003A6A00E619640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479007557A258 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000074080051AE00A70001AC924B34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A7000075050011EE00ACFFDA28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/tests/goodixmoc/custom.py b/tests/goodixmoc/custom.py new file mode 100644 index 00000000..56dc16ca --- /dev/null +++ b/tests/goodixmoc/custom.py @@ -0,0 +1,46 @@ +#!/usr/bin/python3 + +import gi +gi.require_version('FPrint', '2.0') +from gi.repository import FPrint, GLib + +ctx = GLib.main_context_default() + +c = FPrint.Context() +c.enumerate() +devices = c.get_devices() + +d = devices[0] +del devices + +assert d.get_driver() == "goodixmoc" + +d.open_sync() + +template = FPrint.Print.new(d) + +def enroll_progress(*args): + print('enroll progress: ' + str(args)) + +# List, enroll, list, verify, delete +print("enrolling") +p = d.enroll_sync(template, None, enroll_progress, None) +print("enroll done") + +print("listing") +stored = d.list_prints_sync() +print("listing done") +assert len(stored) == 1 +assert stored[0].equal(p) +print("verifying") +verify_res, verify_print = d.verify_sync(p) +print("verify done") +assert verify_res == True + +print("deleting") +d.delete_print_sync(p) +print("delete done") +d.close_sync() + +del d +del c diff --git a/tests/goodixmoc/device b/tests/goodixmoc/device new file mode 100644 index 00000000..627c9dc0 --- /dev/null +++ b/tests/goodixmoc/device @@ -0,0 +1,171 @@ +P: /devices/pci0000:00/0000:00:14.0/usb1/1-8 +N: bus/usb/001/003=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000 +E: DEVNAME=/dev/bus/usb/001/003 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=27c6/60a2/100 +E: TYPE=239/0/0 +E: BUSNUM=001 +E: DEVNUM=003 +E: MAJOR=189 +E: MINOR=2 +E: SUBSYSTEM=usb +E: ID_VENDOR=Goodix_Technology_Co.__Ltd. +E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd. +E: ID_VENDOR_ID=27c6 +E: ID_MODEL=Goodix_USB2.0_MISC +E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC +E: ID_MODEL_ID=60a2 +E: ID_REVISION=0100 +E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UIDCBEE4D7B_XXXX_MOC_B0 +E: ID_SERIAL_SHORT=UIDCBEE4D7B_XXXX_MOC_B0 +E: ID_BUS=usb +E: ID_USB_INTERFACES=:ff0000: +E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. +E: ID_PATH=pci-0000:00:14.0-usb-0:8 +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8 +E: LIBFPRINT_DRIVER=AuthenTec AES1610 +A: authorized=1 +A: avoid_reset_quirk=0 +A: bConfigurationValue=1 +A: bDeviceClass=ef +A: bDeviceProtocol=00 +A: bDeviceSubClass=00 +A: bMaxPacketSize0=64 +A: bMaxPower=100mA +A: bNumConfigurations=1 +A: bNumInterfaces= 1 +A: bcdDevice=0100 +A: bmAttributes=a0 +A: busnum=1 +A: configuration=UIDCBEE4D7B_XXXX_MOC_B0 +H: descriptors=12010002EF000040C627A26000010102030109022000010103A0320904000002FF0000040705830240000007050102400000 +A: dev=189:2 +A: devnum=3 +A: devpath=8 +L: driver=../../../../../bus/usb/drivers/usb +A: idProduct=60a2 +A: idVendor=27c6 +A: ltm_capable=no +A: manufacturer=Goodix Technology Co., Ltd. +A: maxchild=0 +L: port=../1-0:1.0/usb1-port8 +A: power/active_duration=324448 +A: power/async=enabled +A: power/autosuspend=2 +A: power/autosuspend_delay_ms=2000 +A: power/connected_duration=5916532 +A: power/control=auto +A: power/level=auto +A: power/persist=1 +A: power/runtime_active_kids=0 +A: power/runtime_active_time=327268 +A: power/runtime_enabled=enabled +A: power/runtime_status=active +A: power/runtime_suspended_time=5588987 +A: power/runtime_usage=0 +A: power/wakeup=disabled +A: power/wakeup_abort_count= +A: power/wakeup_active= +A: power/wakeup_active_count= +A: power/wakeup_count= +A: power/wakeup_expire_count= +A: power/wakeup_last_time_ms= +A: power/wakeup_max_time_ms= +A: power/wakeup_total_time_ms= +A: product=Goodix USB2.0 MISC +A: quirks=0x0 +A: removable=fixed +A: rx_lanes=1 +A: serial=UIDCBEE4D7B_XXXX_MOC_B0 +A: speed=12 +A: tx_lanes=1 +A: urbnum=2180 +A: version= 2.00 + +P: /devices/pci0000:00/0000:00:14.0/usb1 +N: bus/usb/001/001=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C +E: DEVNAME=/dev/bus/usb/001/001 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=1d6b/2/504 +E: TYPE=9/0/1 +E: BUSNUM=001 +E: DEVNUM=001 +E: MAJOR=189 +E: MINOR=0 +E: SUBSYSTEM=usb +E: ID_VENDOR=Linux_5.4.0-29-generic_xhci-hcd +E: ID_VENDOR_ENC=Linux\x205.4.0-29-generic\x20xhci-hcd +E: ID_VENDOR_ID=1d6b +E: ID_MODEL=xHCI_Host_Controller +E: ID_MODEL_ENC=xHCI\x20Host\x20Controller +E: ID_MODEL_ID=0002 +E: ID_REVISION=0504 +E: ID_SERIAL=Linux_5.4.0-29-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_SERIAL_SHORT=0000:00:14.0 +E: ID_BUS=usb +E: ID_USB_INTERFACES=:090000: +E: ID_VENDOR_FROM_DATABASE=Linux Foundation +E: ID_MODEL_FROM_DATABASE=2.0 root hub +E: ID_PATH=pci-0000:00:14.0 +E: ID_PATH_TAG=pci-0000_00_14_0 +E: ID_FOR_SEAT=usb-pci-0000_00_14_0 +E: TAGS=:seat: +A: authorized=1 +A: authorized_default=1 +A: avoid_reset_quirk=0 +A: bConfigurationValue=1 +A: bDeviceClass=09 +A: bDeviceProtocol=01 +A: bDeviceSubClass=00 +A: bMaxPacketSize0=64 +A: bMaxPower=0mA +A: bNumConfigurations=1 +A: bNumInterfaces= 1 +A: bcdDevice=0504 +A: bmAttributes=e0 +A: busnum=1 +A: configuration= +H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C +A: dev=189:0 +A: devnum=1 +A: devpath=0 +L: driver=../../../../bus/usb/drivers/usb +A: idProduct=0002 +A: idVendor=1d6b +A: interface_authorized_default=1 +A: ltm_capable=no +A: manufacturer=Linux 5.4.0-29-generic xhci-hcd +A: maxchild=12 +A: power/active_duration=5879432 +A: power/async=enabled +A: power/autosuspend=0 +A: power/autosuspend_delay_ms=0 +A: power/connected_duration=5916912 +A: power/control=auto +A: power/level=auto +A: power/runtime_active_kids=2 +A: power/runtime_active_time=5879430 +A: power/runtime_enabled=enabled +A: power/runtime_status=active +A: power/runtime_suspended_time=37481 +A: power/runtime_usage=0 +A: power/wakeup=disabled +A: power/wakeup_abort_count= +A: power/wakeup_active= +A: power/wakeup_active_count= +A: power/wakeup_count= +A: power/wakeup_expire_count= +A: power/wakeup_last_time_ms= +A: power/wakeup_max_time_ms= +A: power/wakeup_total_time_ms= +A: product=xHCI Host Controller +A: quirks=0x0 +A: removable=unknown +A: rx_lanes=1 +A: serial=0000:00:14.0 +A: speed=480 +A: tx_lanes=1 +A: urbnum=1319 +A: version= 2.00 diff --git a/tests/meson.build b/tests/meson.build index c37c37ac..b20b1478 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -21,6 +21,7 @@ drivers_tests = [ 'synaptics', 'vfs0050', 'vfs5011', + 'goodixmoc', ] if get_option('introspection') From 596d22a4492d6712329cb4882a22859bdaef2c96 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 3 Sep 2020 09:06:37 +0200 Subject: [PATCH 17/27] 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. --- libfprint/fp-context.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libfprint/fp-context.c b/libfprint/fp-context.c index e70077fb..6971763a 100644 --- a/libfprint/fp-context.c +++ b/libfprint/fp-context.c @@ -210,7 +210,8 @@ fp_context_finalize (GObject *object) g_clear_object (&priv->cancellable); g_clear_pointer (&priv->drivers, g_array_unref); - g_object_run_dispose (G_OBJECT (priv->usb_ctx)); + if (priv->usb_ctx) + g_object_run_dispose (G_OBJECT (priv->usb_ctx)); g_clear_object (&priv->usb_ctx); G_OBJECT_CLASS (fp_context_parent_class)->finalize (object); @@ -342,7 +343,8 @@ fp_context_enumerate (FpContext *context) priv->enumerated = TRUE; /* USB devices are handled from callbacks */ - g_usb_context_enumerate (priv->usb_ctx); + if (priv->usb_ctx) + g_usb_context_enumerate (priv->usb_ctx); /* Handle Virtual devices based on environment variables */ for (i = 0; i < priv->drivers->len; i++) From 5d0481b03142fde14441af779c07c2b7074a5c78 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 3 Sep 2020 09:00:01 +0200 Subject: [PATCH 18/27] 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. --- libfprint/fp-context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fp-context.c b/libfprint/fp-context.c index 6971763a..c2b4eb25 100644 --- a/libfprint/fp-context.c +++ b/libfprint/fp-context.c @@ -290,7 +290,7 @@ fp_context_init (FpContext *self) priv->usb_ctx = g_usb_context_new (&error); if (!priv->usb_ctx) { - fp_warn ("Could not initialise USB Subsystem: %s", error->message); + g_message ("Could not initialise USB Subsystem: %s", error->message); } else { From 5b087ed8488785516f319f3cff2665d572be2add Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 2 Sep 2020 16:38:13 +0200 Subject: [PATCH 19/27] demo: Switch to use GNOME 3.36 runtime --- .gitlab-ci.yml | 2 +- demo/org.freedesktop.libfprint.Demo.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3ad55fb5..f4779c38 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -132,7 +132,7 @@ test_indent: <<: *flatpak_artifacts .flatpak_master_template: &flatpak_master - image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32 + image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36 stage: flatpak variables: MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json" diff --git a/demo/org.freedesktop.libfprint.Demo.json b/demo/org.freedesktop.libfprint.Demo.json index 7429670e..19516a42 100644 --- a/demo/org.freedesktop.libfprint.Demo.json +++ b/demo/org.freedesktop.libfprint.Demo.json @@ -1,7 +1,7 @@ { "app-id": "org.freedesktop.libfprint.Demo", "runtime": "org.gnome.Platform", - "runtime-version": "3.32", + "runtime-version": "3.36", "sdk": "org.gnome.Sdk", "command": "gtk-libfprint-test", "finish-args": [ From 30e1a68344bedcbafd822866c2930ac2c15de782 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 2 Sep 2020 16:27:53 +0200 Subject: [PATCH 20/27] ci: Build flatpak using GNOME runner and template --- .gitlab-ci.yml | 71 ++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4779c38..12249c4b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,7 @@ include: - project: 'wayland/ci-templates' ref: master file: '/templates/fedora.yml' + - remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml' variables: extends: .libfprint_common_variables @@ -108,56 +109,34 @@ test_indent: - git diff - "! git status -s | grep -q ." -.flatpak_script_template: &flatpak_script - script: - - flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH} - # Make sure to keep this in sync with the Flatpak manifest, all arguments - # are passed except the config-args because we build it ourselves - - flatpak build app meson --prefix=/app --libdir=lib ${MESON_ARGS} _build - - flatpak build app ninja -C _build install - - flatpak build app rm -rf /app/include/ /app/lib/pkgconfig/ - - flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH} - # Generate a Flatpak bundle - - flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${DBUS_ID} - -.flatpak_artifacts_template: &flatpak_artifacts - artifacts: - paths: - - ${BUNDLE} - when: always - expire_in: 30 days - -.flatpak_template: &flatpak - <<: *flatpak_script - <<: *flatpak_artifacts - -.flatpak_master_template: &flatpak_master - image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36 - stage: flatpak - variables: - MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json" - # From demo/org.freedesktop.libfprint.Demo.json - MESON_ARGS: "-Dudev_rules=false -Dx11-examples=false -Dgtk-examples=true" - FLATPAK_MODULE: "libfprint" - DBUS_ID: "org.freedesktop.libfprint.Demo" - <<: *flatpak +.flatpak-libfprint: + stage: flatpak + extends: .flatpak + image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36 + variables: + MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json" + FLATPAK_MODULE: "libfprint" + APP_ID: "org.freedesktop.libfprint.Demo" flatpak-auto master: - <<: *flatpak_master - when: always - only: + extends: .flatpak-libfprint + when: always + only: + - tags + - master + except: + variables: + - $CI_PIPELINE_SOURCE == "schedule" + +flatpak-manual: + extends: .flatpak-libfprint + when: manual + except: + refs: - tags - master - -flatpak-manual master: - <<: *flatpak_master - when: manual - except: - refs: - - tags - - master - variables: - - $CI_PIPELINE_SOURCE == "schedule" + variables: + - $CI_PIPELINE_SOURCE == "schedule" # CONTAINERS creation stage container_fedora_build: From ce6961d1653a62131efdadc5907a917b2dd016d5 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 7 Sep 2020 12:12:34 +0200 Subject: [PATCH 21/27] 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. --- libfprint/fpi-image-device.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libfprint/fpi-image-device.h b/libfprint/fpi-image-device.h index 155390de..43492d8c 100644 --- a/libfprint/fpi-image-device.h +++ b/libfprint/fpi-image-device.h @@ -72,9 +72,8 @@ typedef enum { * fpi_device_action_error() function but doing so is not recommended in most * usecases. * - * Drivers *must* also handle cancellation properly for any long running - * operation (i.e. any operation that requires capturing). It is entirely fine - * to ignore cancellation requests for short operations (e.g. open/close). + * Image drivers must expect a @deactivate call to happen at any point during + * image capture. * * This API is solely intended for drivers. It is purely internal and neither * API nor ABI stable. From d5f7f4dfaa0588bff2e899e8b91d519f2a7e1ad1 Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Fri, 11 Sep 2020 22:36:52 +0800 Subject: [PATCH 22/27] 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 --- libfprint/drivers/goodixmoc/goodix.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index 1eed70ec..dfdd2fd0 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -879,7 +879,8 @@ fp_init_version_cb (FpiDeviceGoodixMoc *self, gxfp_cmd_response_t *resp, GError *error) { - char nullstring[GX_VERSION_LEN + 1] = { 0 }; + g_autofree gchar *fw_type = NULL; + g_autofree gchar *fw_version = NULL; if (error) { @@ -888,16 +889,20 @@ fp_init_version_cb (FpiDeviceGoodixMoc *self, } G_STATIC_ASSERT (sizeof (resp->version_info.fwtype) == 8); - G_STATIC_ASSERT (sizeof (resp->version_info.algversion) == 8); G_STATIC_ASSERT (sizeof (resp->version_info.fwversion) == 8); - memcpy (nullstring, resp->version_info.fwtype, sizeof (resp->version_info.fwtype)); - fp_info ("Firmware type: %s", nullstring); - memcpy (nullstring, resp->version_info.algversion, sizeof (resp->version_info.algversion)); - fp_info ("Algversion version: %s", nullstring); - memcpy (nullstring, resp->version_info.fwversion, sizeof (resp->version_info.fwversion)); - fp_info ("Firmware version: %s", nullstring); + fw_type = g_strndup ((const char *) resp->version_info.fwtype, sizeof (resp->version_info.fwtype)); + fp_info ("Firmware type: %s", fw_type); + if (g_strcmp0 (fw_type, "APP") != 0) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED, + "Please update firmware using fwupd")); + return; + } + fw_version = g_strndup ((const char *) resp->version_info.fwversion, sizeof (resp->version_info.fwversion)); + fp_info ("Firmware version: %s", fw_version); fpi_ssm_next_state (self->task_ssm); } From f67f61c63816d67fd07b77ba37a0da0e5b1f5763 Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Fri, 11 Sep 2020 22:47:11 +0800 Subject: [PATCH 23/27] goodixmoc: Add identify function this device support verify and identify both, actually call the same interface. --- libfprint/drivers/goodixmoc/goodix.c | 120 ++++++++++++++++++--------- 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index dfdd2fd0..6a51cb88 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -72,6 +72,12 @@ typedef struct SynCmdMsgCallback callback; } CommandData; +static gboolean parse_print_data (GVariant *data, + guint8 *finger, + const guint8 **tid, + gsize *tid_len, + const guint8 **user_id, + gsize *user_id_len); /****************************************************************************** * * fp_cmd_xxx Function @@ -340,30 +346,74 @@ fp_verify_capture_cb (FpiDeviceGoodixMoc *self, } static void -fp_verify_identify_cb (FpiDeviceGoodixMoc *self, - gxfp_cmd_response_t *resp, - GError *error) +fp_verify_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) { FpDevice *device = FP_DEVICE (self); + FpPrint *print = NULL; + GPtrArray *templates = NULL; + gint cnt = 0; + gboolean find = false; if (error) { fpi_ssm_mark_failed (self->task_ssm, error); return; } - if (!resp->verify.match) + if (resp->verify.match) { - fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error); + if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY) + { + + templates = g_ptr_array_new_with_free_func (g_object_unref); + fpi_device_get_verify_data (device, &print); + g_ptr_array_add (templates, g_object_ref_sink (print)); + + } + else + { + fpi_device_get_identify_data (device, &templates); + } + for (cnt = 0; cnt < templates->len; cnt++) + { + g_autoptr(GVariant) data = NULL; + guint8 finger; + const guint8 *user_id; + gsize user_id_len = 0; + const guint8 *tid; + gsize tid_len = 0; + print = g_ptr_array_index (templates, cnt); + g_object_get (print, "fpi-data", &data, NULL); + if (!parse_print_data (data, &finger, &tid, &tid_len, &user_id, &user_id_len)) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, + "Parse print error")); + return; + } + if (memcmp (&resp->verify.template.tid, tid, TEMPLATE_ID_SIZE) == 0) + { + find = true; + break; + } + + } + if (find) + { + if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY) + fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, error); + else + fpi_device_identify_report (device, print, print, error); + } } - else if (memcmp (&resp->verify.template.tid, &self->template_id, TEMPLATE_ID_SIZE) != 0) + + if (!find) { - fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error); - } - else - { - fp_info ("Verify successful! for user: %s finger: %d", - resp->verify.template.payload.data, resp->verify.template.finger_index); - fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL); + if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_VERIFY) + fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error); + else + fpi_device_identify_report (device, NULL, NULL, error); } fpi_ssm_mark_completed (self->task_ssm); @@ -375,6 +425,7 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) { FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); guint8 param[3] = { 0 }; + guint8 nonce[TEMPLATE_ID_SIZE] = { 0 }; param[0] = 0x01; param[1] = self->sensorcfg->config[10]; @@ -393,9 +444,9 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) case FP_VERIFY_IDENTIFY: goodix_sensor_cmd (self, MOC_CMD0_IDENTIFY, MOC_CMD1_DEFAULT, false, - (const guint8 *) &self->template_id, + (const guint8 *) nonce, TEMPLATE_ID_SIZE, - fp_verify_identify_cb); + fp_verify_cb); break; } @@ -409,9 +460,18 @@ fp_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) fp_info ("Verify complete!"); if (error && error->domain == FP_DEVICE_RETRY) - fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, error); + { + if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY) + fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, error); + else + fpi_device_identify_report (dev, NULL, NULL, error); + } - fpi_device_verify_complete (dev, error); + if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY) + fpi_device_verify_complete (dev, error); + + else + fpi_device_identify_complete (dev, error); self->task_ssm = NULL; } @@ -1252,30 +1312,9 @@ gx_fp_exit (FpDevice *device) static void -gx_fp_verify (FpDevice *device) +gx_fp_verify_identify (FpDevice *device) { - FpiDeviceGoodixMoc *self = FPI_DEVICE_GOODIXMOC (device); - FpPrint *print = NULL; - - g_autoptr(GVariant) data = NULL; - guint8 finger; - const guint8 *user_id; - gsize user_id_len = 0; - const guint8 *tid; - gsize tid_len = 0; - - fpi_device_get_verify_data (device, &print); - - g_object_get (print, "fpi-data", &data, NULL); - - if (!parse_print_data (data, &finger, &tid, &tid_len, &user_id, &user_id_len)) - { - fpi_device_verify_complete (device, - fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); - return; - } - memcpy (&self->template_id, tid, tid_len); self->task_ssm = fpi_ssm_new (device, fp_verify_sm_run_state, FP_VERIFY_NUM_STATES); @@ -1405,9 +1444,10 @@ fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass) dev_class->open = gx_fp_init; dev_class->close = gx_fp_exit; dev_class->probe = gx_fp_probe; - dev_class->verify = gx_fp_verify; dev_class->enroll = gx_fp_enroll; dev_class->delete = gx_fp_template_delete; dev_class->list = gx_fp_template_list; dev_class->cancel = gx_fp_cancel; + dev_class->verify = gx_fp_verify_identify; + dev_class->identify = gx_fp_verify_identify; } From 3962372f4791c89017ca58ca13ba3d8bfac9d666 Mon Sep 17 00:00:00 2001 From: "boger.wang" Date: Sun, 13 Sep 2020 21:14:05 +0800 Subject: [PATCH 24/27] tests: add identify test for driver goodixmoc add identify ioctl file, modify custom.py add identify test --- tests/goodixmoc/custom.ioctl | 12 +++++++++++- tests/goodixmoc/custom.py | 6 +++++- 2 files changed, 16 insertions(+), 2 deletions(-) mode change 100644 => 100755 tests/goodixmoc/custom.py diff --git a/tests/goodixmoc/custom.ioctl b/tests/goodixmoc/custom.ioctl index 92d50f95..21c85316 100644 --- a/tests/goodixmoc/custom.ioctl +++ b/tests/goodixmoc/custom.ioctl @@ -290,7 +290,17 @@ USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 A50000392400847B00000000000000000000000 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2 -USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 A700003A6A00E619640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479007557A258 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 15 15 0 a200003a07007788010023107a86d3 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA0000700800FA0500A20001E14E401B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 A200007107001DE2005A635942221700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 44 44 0 a500003b240052ad0000000000000000000000000000000000000000000000000000000000000000828af704 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA00007208002CD300A5000129052BF2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 + USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 192 0 A50000739300A15E005A632900000000640043010107000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E4650312D30303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A21C0F44B08232229E7F2E5DBFA70A5CEF58A3966ED710002FF9938030303030303030302D302D30303030303030302D6E6F626F6479008B7767E4A81CC57C17A2 +USBDEVFS_REAPURBNDELAY 0 3 1 0 0 114 114 0 a700003c6a009b64640043010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4650312d30303030303030302d302d30303030303030302d6e6f626f647900473c9b29 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 64 0 AA000074080051AE00A70001AC924B34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 USBDEVFS_REAPURBNDELAY 0 3 131 0 0 2048 0 0 diff --git a/tests/goodixmoc/custom.py b/tests/goodixmoc/custom.py old mode 100644 new mode 100755 index 56dc16ca..6cc3b702 --- a/tests/goodixmoc/custom.py +++ b/tests/goodixmoc/custom.py @@ -22,7 +22,7 @@ template = FPrint.Print.new(d) def enroll_progress(*args): print('enroll progress: ' + str(args)) -# List, enroll, list, verify, delete +# List, enroll, list, verify, identify, delete print("enrolling") p = d.enroll_sync(template, None, enroll_progress, None) print("enroll done") @@ -36,6 +36,10 @@ print("verifying") verify_res, verify_print = d.verify_sync(p) print("verify done") assert verify_res == True +print("identifying") +identify_match, identify_print = d.identify_sync(stored) +print("identify done") +assert identify_match.equal(identify_print) print("deleting") d.delete_print_sync(p) From bcce8876e2931b55874b8df01f32570f9d18fcfb Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 7 Sep 2020 12:13:39 +0200 Subject: [PATCH 25/27] 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 --- libfprint/drivers/aes3k.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index da3b6a39..db0d3701 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -42,8 +42,7 @@ typedef struct { - FpiUsbTransfer *img_trf; - gboolean deactivating; + GCancellable *img_trf_cancel; } FpiDeviceAes3kPrivate; #define CTRL_TIMEOUT 1000 @@ -77,25 +76,21 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device, { 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; - priv->img_trf = NULL; - if (error) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - /* Deactivation was completed. */ + /* Cancellation implies we are deactivating. */ g_error_free (error); - if (priv->deactivating) - fpi_image_device_deactivate_complete (dev, NULL); + fpi_image_device_deactivate_complete (dev, NULL); return; } @@ -126,21 +121,23 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device, * it really has, then restart the capture */ fpi_image_device_report_finger_status (dev, FALSE); + /* Note: We always restart the transfer, it may already be cancelled though. */ do_capture (dev); } 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); - priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev)); - fpi_usb_transfer_fill_bulk (priv->img_trf, EP_IN, cls->data_buflen); - priv->img_trf->short_is_error = TRUE; - fpi_usb_transfer_submit (priv->img_trf, 0, - fpi_device_get_cancellable (FP_DEVICE (dev)), + 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_trf_cancel, img_cb, NULL); } @@ -159,7 +156,8 @@ aes3k_dev_activate (FpImageDevice *dev) FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self); FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self); - priv->deactivating = FALSE; + g_assert (!priv->img_trf_cancel); + priv->img_trf_cancel = g_cancellable_new (); aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL); } @@ -169,10 +167,8 @@ aes3k_dev_deactivate (FpImageDevice *dev) FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev); FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self); - priv->deactivating = TRUE; - if (priv->img_trf) - return; - fpi_image_device_deactivate_complete (dev, NULL); + /* Deactivation always finishes from the cancellation handler */ + g_cancellable_cancel (priv->img_trf_cancel); } static void From 9efe25b91c2d8632cf9a8cb2480ed5fb6c614503 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 14 Sep 2020 13:47:10 +0200 Subject: [PATCH 26/27] ci: Disable flatpak building for forks Also move to use a single rules set for flatpak rather than only/except rules. --- .gitlab-ci.yml | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 12249c4b..3f0925b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -109,7 +109,7 @@ test_indent: - git diff - "! git status -s | grep -q ." -.flatpak-libfprint: +flatpak: stage: flatpak extends: .flatpak image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.36 @@ -117,26 +117,20 @@ test_indent: MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json" FLATPAK_MODULE: "libfprint" APP_ID: "org.freedesktop.libfprint.Demo" - -flatpak-auto master: - extends: .flatpak-libfprint - when: always - only: - - tags - - master - except: - variables: - - $CI_PIPELINE_SOURCE == "schedule" - -flatpak-manual: - extends: .flatpak-libfprint - when: manual - except: - refs: - - tags - - master - variables: - - $CI_PIPELINE_SOURCE == "schedule" + rules: + - if: '$CI_PROJECT_PATH != "libfprint/libfprint"' + when: never + - if: '$CI_PIPELINE_SOURCE == "schedule"' + when: never + - if: '$CI_COMMIT_BRANCH == "master"' + when: always + - if: '$CI_COMMIT_TAG' + 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 # CONTAINERS creation stage container_fedora_build: From 174aa2c0917be87014849e4b72341f825f3de327 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 8 Sep 2020 14:04:11 +0200 Subject: [PATCH 27/27] Release 1.90.3 --- NEWS | 19 +++++++++++++++++++ meson.build | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e7568d63..b01e023b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,25 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +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 diff --git a/meson.build b/meson.build index 12a1503c..daa5ed2a 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('libfprint', [ 'c', 'cpp' ], - version: '1.90.2', + version: '1.90.3', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized',