mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-06-11 18:38:07 +00:00
debian/patches: Properly handle aes3k devices, resubmitting commands
This also needs proper commands cancellation LP: #1897613
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user