mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-06-11 10:34:18 +00:00
32767f4e16
This also needs proper commands cancellation LP: #1897613
232 lines
8.0 KiB
Diff
232 lines
8.0 KiB
Diff
From: Benjamin Berg <bberg@redhat.com>
|
|
Date: Thu, 1 Oct 2020 18:38:07 +0200
|
|
Subject: aes3k: Re-send some commands for each capture
|
|
|
|
The driver seems to have relied on the device to be fully
|
|
deactivated and activated again for each capture. This is not the case
|
|
during enroll, and as such in can cause issues.
|
|
|
|
Try fixing this by splitting out the last few commands send to the
|
|
device and assuming that this starts the capture.
|
|
|
|
Fixes: #306
|
|
|
|
Origin: https://gitlab.freedesktop.org/libfprint/libfprint/-/commit/81e0f4dfe
|
|
|
|
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libfprint/+bug/1897613
|
|
---
|
|
libfprint/drivers/aes3500.c | 4 +++
|
|
libfprint/drivers/aes3k.c | 75 ++++++++++++++++++++++++++++++++++-----------
|
|
libfprint/drivers/aes3k.h | 2 ++
|
|
libfprint/drivers/aes4000.c | 4 +++
|
|
4 files changed, 67 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c
|
|
index 3b4860b..58a9be1 100644
|
|
--- a/libfprint/drivers/aes3500.c
|
|
+++ b/libfprint/drivers/aes3500.c
|
|
@@ -106,7 +106,9 @@ static struct aes_regwrite init_reqs[] = {
|
|
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
|
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
|
{ 0, 0 },
|
|
+};
|
|
|
|
+static struct aes_regwrite capture_reqs[] = {
|
|
{ 0x80, 0x00 },
|
|
{ 0x81, 0x00 },
|
|
{ 0, 0 },
|
|
@@ -155,4 +157,6 @@ fpi_device_aes3500_class_init (FpiDeviceAes3500Class *klass)
|
|
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
|
aes_class->init_reqs = init_reqs;
|
|
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
|
|
+ aes_class->capture_reqs = capture_reqs;
|
|
+ aes_class->capture_reqs_len = G_N_ELEMENTS (capture_reqs);
|
|
}
|
|
diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c
|
|
index be3645e..bab6815 100644
|
|
--- a/libfprint/drivers/aes3k.c
|
|
+++ b/libfprint/drivers/aes3k.c
|
|
@@ -42,7 +42,10 @@
|
|
|
|
typedef struct
|
|
{
|
|
- GCancellable *img_trf_cancel;
|
|
+ /* This is used both as a flag that we are in a capture operation
|
|
+ * and for cancellation.
|
|
+ */
|
|
+ GCancellable *img_capture_cancel;
|
|
} FpiDeviceAes3kPrivate;
|
|
|
|
#define CTRL_TIMEOUT 1000
|
|
@@ -83,6 +86,9 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|
FpImage *img;
|
|
int i;
|
|
|
|
+ /* Image capture operation is finished (error/completed) */
|
|
+ g_clear_object (&priv->img_capture_cancel);
|
|
+
|
|
if (error)
|
|
{
|
|
if (g_error_matches (error,
|
|
@@ -91,13 +97,11 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|
{
|
|
/* Cancellation implies we are deactivating. */
|
|
g_error_free (error);
|
|
- g_clear_object (&priv->img_trf_cancel);
|
|
fpi_image_device_deactivate_complete (dev, NULL);
|
|
return;
|
|
}
|
|
|
|
fpi_image_device_session_error (dev, error);
|
|
- g_clear_object (&priv->img_trf_cancel);
|
|
return;
|
|
}
|
|
|
|
@@ -122,11 +126,10 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
|
fpi_image_device_image_captured (dev, img);
|
|
|
|
/* FIXME: rather than assuming finger has gone, we should poll regs until
|
|
- * it really has, then restart the capture */
|
|
+ * it really has. */
|
|
fpi_image_device_report_finger_status (dev, FALSE);
|
|
|
|
- /* Note: We always restart the transfer, it may already be cancelled though. */
|
|
- do_capture (dev);
|
|
+ /* Note: The transfer is re-started when we switch to the AWAIT_FINGER_ON state. */
|
|
}
|
|
|
|
static void
|
|
@@ -141,31 +144,51 @@ do_capture (FpImageDevice *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,
|
|
+ priv->img_capture_cancel,
|
|
img_cb, NULL);
|
|
}
|
|
|
|
static void
|
|
-init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
|
|
+capture_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
|
|
{
|
|
- FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (FPI_DEVICE_AES3K (dev));
|
|
+ FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
|
+ FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
|
|
|
- fpi_image_device_activate_complete (dev, result);
|
|
- if (!result)
|
|
+ if (result)
|
|
{
|
|
- priv->img_trf_cancel = g_cancellable_new ();
|
|
- do_capture (dev);
|
|
+ g_clear_object (&priv->img_capture_cancel);
|
|
+ fpi_image_device_session_error (dev, result);
|
|
+ return;
|
|
}
|
|
+
|
|
+ /* FIXME: we never cancel a pending capture. So we are likely leaving the
|
|
+ * hardware in a bad state should we abort the capture operation and the
|
|
+ * user does not touch the device.
|
|
+ * But, we don't know how we might cancel, so just leave it as is. */
|
|
+ do_capture (dev);
|
|
+}
|
|
+
|
|
+static void
|
|
+do_capture_start (FpImageDevice *dev)
|
|
+{
|
|
+ FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
|
+ FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
|
+
|
|
+ aes_write_regv (dev, cls->capture_reqs, cls->capture_reqs_len, capture_reqs_cb, NULL);
|
|
+}
|
|
+
|
|
+static void
|
|
+init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
|
|
+{
|
|
+ fpi_image_device_activate_complete (dev, result);
|
|
}
|
|
|
|
static void
|
|
aes3k_dev_activate (FpImageDevice *dev)
|
|
{
|
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
|
- FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
|
|
|
- g_assert (!priv->img_trf_cancel);
|
|
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
|
|
}
|
|
|
|
@@ -175,13 +198,28 @@ aes3k_dev_deactivate (FpImageDevice *dev)
|
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
|
|
|
- /* Deactivation finishes from the cancellation handler */
|
|
- if (priv->img_trf_cancel)
|
|
- g_cancellable_cancel (priv->img_trf_cancel);
|
|
+ /* If a capture is running, then deactivation finishes from the cancellation handler */
|
|
+ if (priv->img_capture_cancel)
|
|
+ g_cancellable_cancel (priv->img_capture_cancel);
|
|
else
|
|
fpi_image_device_deactivate_complete (dev, NULL);
|
|
}
|
|
|
|
+static void
|
|
+aes3k_dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
|
|
+{
|
|
+ FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
|
+ FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
|
+
|
|
+ if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
|
|
+ {
|
|
+ g_assert (!priv->img_capture_cancel);
|
|
+ priv->img_capture_cancel = g_cancellable_new ();
|
|
+
|
|
+ do_capture_start (dev);
|
|
+ }
|
|
+}
|
|
+
|
|
static void
|
|
fpi_device_aes3k_init (FpiDeviceAes3k *self)
|
|
{
|
|
@@ -224,6 +262,7 @@ fpi_device_aes3k_class_init (FpiDeviceAes3kClass *klass)
|
|
img_class->img_open = aes3k_dev_init;
|
|
img_class->img_close = aes3k_dev_deinit;
|
|
img_class->activate = aes3k_dev_activate;
|
|
+ img_class->change_state = aes3k_dev_change_state;
|
|
img_class->deactivate = aes3k_dev_deactivate;
|
|
|
|
/* Extremely low due to low image quality. */
|
|
diff --git a/libfprint/drivers/aes3k.h b/libfprint/drivers/aes3k.h
|
|
index 539f4e1..ae19bf1 100644
|
|
--- a/libfprint/drivers/aes3k.h
|
|
+++ b/libfprint/drivers/aes3k.h
|
|
@@ -57,4 +57,6 @@ struct _FpiDeviceAes3kClass
|
|
gsize data_buflen; /* buffer length of usb bulk transfer */
|
|
struct aes_regwrite *init_reqs; /* initial values sent to device */
|
|
gsize init_reqs_len;
|
|
+ struct aes_regwrite *capture_reqs; /* capture values sent to device */
|
|
+ gsize capture_reqs_len;
|
|
};
|
|
diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c
|
|
index 0a801f6..e5770b9 100644
|
|
--- a/libfprint/drivers/aes4000.c
|
|
+++ b/libfprint/drivers/aes4000.c
|
|
@@ -103,7 +103,9 @@ static struct aes_regwrite init_reqs[] = {
|
|
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
|
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
|
{ 0, 0 },
|
|
+};
|
|
|
|
+static struct aes_regwrite capture_reqs[] = {
|
|
{ 0x80, 0x00 },
|
|
{ 0x81, 0x00 },
|
|
{ 0, 0 },
|
|
@@ -152,4 +154,6 @@ fpi_device_aes4000_class_init (FpiDeviceAes4000Class *klass)
|
|
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
|
aes_class->init_reqs = init_reqs;
|
|
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
|
|
+ aes_class->capture_reqs = capture_reqs;
|
|
+ aes_class->capture_reqs_len = G_N_ELEMENTS (capture_reqs);
|
|
}
|