From b8154bf466ca26cd5e1ed2166bcf5680fdea02fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 26 Jun 2026 16:07:02 +0200 Subject: [PATCH] egis_etu905: Handle cancel as part of the device SSM return Cancelling an operation does allow the driver to do perform async ops at the moment, but rather we are supposed to just send the the cancel commands while another action may running. So we should handle this as part of the SSM final stage, if cancellation happened. --- libfprint/drivers/egismoc/egis_etu905.c | 67 ++++++++++++++++++++---- tests/egis_etu905/custom.pcapng | Bin 34732 -> 35152 bytes 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c index 1cd06b73..649360a6 100644 --- a/libfprint/drivers/egismoc/egis_etu905.c +++ b/libfprint/drivers/egismoc/egis_etu905.c @@ -72,10 +72,13 @@ typedef struct egis_etu905_enroll_print int stage; } EnrollPrint; -static void egis_etu905_identify_send_cancel_result_cb (FpDevice *device, - guchar *buffer_in, - gsize length_in, - GError *error); +static void egis_etu905_exec_cmd_full (FpDevice *device, + const guchar *cmd, + gsize cmd_length, + SynCmdMsgCallback callback, + GCancellable *cancellable); + +static void egis_etu905_cancel (FpDevice *device); static void egis_etu905_finger_on_sensor_cb (FpiUsbTransfer *transfer, @@ -164,11 +167,30 @@ egis_etu905_validate_response_suffix (const guchar *buffer_in, return result; } +static gboolean +egis_etu905_maybe_cancel (FpDevice *device, + GError *error) +{ + FpiDeviceAction action = fpi_device_get_current_action (device); + + if (!fpi_device_action_is_cancelled (device) && + !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return FALSE; + + if (action != FPI_DEVICE_ACTION_ENROLL && + action != FPI_DEVICE_ACTION_IDENTIFY) + return FALSE; + + egis_etu905_cancel (device); + return TRUE; +} + static void egis_etu905_task_ssm_done (FpiSsm *ssm, FpDevice *device, GError *error) { + g_autoptr(GError) task_error = g_steal_pointer (&error); FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); fp_dbg ("Task SSM done"); @@ -179,8 +201,14 @@ egis_etu905_task_ssm_done (FpiSsm *ssm, g_clear_pointer (&self->enrolled_ids, g_ptr_array_unref); - if (error) - fpi_device_action_error (device, error); + /* On cancellation we need to send the device-side cancel command before + * reporting the error, as the idle ->cancel vfunc may not be called due + * to the operation already being completed by the cancellable abort. */ + if (egis_etu905_maybe_cancel (device, task_error)) + return; + + if (task_error) + fpi_device_action_error (device, g_steal_pointer (&task_error)); } static void @@ -1643,6 +1671,24 @@ egis_etu905_close (FpDevice *device) fpi_device_close_complete (device, g_steal_pointer (&error)); } +static void +egis_etu905_cancel_cb (FpDevice *device, + guchar *buffer_in, + gsize length_in, + GError *error) +{ + if (error) + { + g_warning ("Cancel command failed: %s", error->message); + g_clear_error (&error); + } + + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Operation was cancelled"); + + fpi_device_action_error (device, g_steal_pointer (&error)); +} + static void egis_etu905_cancel (FpDevice *device) { @@ -1661,7 +1707,7 @@ egis_etu905_cancel (FpDevice *device) egis_etu905_exec_cmd_full (device, cmd_enroll_discard, G_N_ELEMENTS (cmd_enroll_discard), - NULL, + egis_etu905_cancel_cb, NULL); } else if (action == FPI_DEVICE_ACTION_IDENTIFY) @@ -1669,9 +1715,13 @@ egis_etu905_cancel (FpDevice *device) egis_etu905_exec_cmd_full (device, cmd_identify_cancel, G_N_ELEMENTS (cmd_identify_cancel), - NULL, + egis_etu905_cancel_cb, NULL); } + else + { + g_warning ("Cancel called for unsupported action %d", action); + } } static void @@ -1697,7 +1747,6 @@ fpi_device_egis_etu905_class_init (FpiDeviceEgisEtu905Class *klass) dev_class->probe = egis_etu905_probe; dev_class->open = egis_etu905_open; dev_class->close = egis_etu905_close; - dev_class->cancel = egis_etu905_cancel; dev_class->identify = egis_etu905_identify; dev_class->enroll = egis_etu905_enroll; dev_class->delete = egis_etu905_delete; diff --git a/tests/egis_etu905/custom.pcapng b/tests/egis_etu905/custom.pcapng index 19541d59a6c6010f5a56e2009589fb2305681ec3..730a7ad4126db4d9ab82bb7ae46455c704523bc2 100644 GIT binary patch delta 45 zcmZ3}&vaoD(*}Wz$!o-TCQB5Ba4N(wFfgzLurN+8R2JXdQ>4N;xgeEivrNVWc>qp} B4d?&> delta 18 acmcaGiD^wg(*}Wz$qrmRn-648kOu%rHU~Zc