egis_etu905: Decouple SSM and command data from device

While most of commands should run separated, others such as cancellation
can run concurrently so we cannot share command data in the device
structure, but it has to be rather per command.

Move it there
This commit is contained in:
Marco Trevisan (Treviño)
2026-07-24 10:54:02 +00:00
committed by Marco Trevisan
parent ffdb0a84b8
commit f3d17a24f9
+24 -32
View File
@@ -31,8 +31,6 @@ struct _FpiDeviceEgisEtu905
{ {
FpDevice parent; FpDevice parent;
FpiSsm *task_ssm; FpiSsm *task_ssm;
FpiSsm *cmd_ssm;
FpiUsbTransfer *cmd_transfer;
GPtrArray *enrolled_ids; GPtrArray *enrolled_ids;
gint max_enroll_stages; gint max_enroll_stages;
}; };
@@ -53,6 +51,7 @@ typedef void (*SynCmdMsgCallback) (FpDevice *device,
typedef struct egis_etu905_command_data typedef struct egis_etu905_command_data
{ {
SynCmdMsgCallback callback; SynCmdMsgCallback callback;
FpiUsbTransfer *cmd_transfer;
guchar *buffer_in; guchar *buffer_in;
gsize length_in; gsize length_in;
} CommandData; } CommandData;
@@ -60,6 +59,7 @@ typedef struct egis_etu905_command_data
static void static void
egis_etu905_command_data_free (CommandData *data) egis_etu905_command_data_free (CommandData *data)
{ {
g_clear_pointer (&data->cmd_transfer, fpi_usb_transfer_unref);
g_free (data->buffer_in); g_free (data->buffer_in);
g_free (data); g_free (data);
} }
@@ -248,15 +248,16 @@ egis_etu905_cmd_run_state (FpiSsm *ssm,
FpDevice *device) FpDevice *device)
{ {
g_autoptr(FpiUsbTransfer) transfer = NULL; g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device); CommandData *data = fpi_ssm_get_data (ssm);
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
case CMD_SEND: case CMD_SEND:
if (self->cmd_transfer) if (data->cmd_transfer)
{ {
self->cmd_transfer->ssm = ssm; transfer = g_steal_pointer (&data->cmd_transfer);
fpi_usb_transfer_submit (g_steal_pointer (&self->cmd_transfer), transfer->ssm = ssm;
fpi_usb_transfer_submit (g_steal_pointer (&transfer),
EGIS_ETU905_USB_SEND_TIMEOUT, EGIS_ETU905_USB_SEND_TIMEOUT,
fpi_device_get_cancellable (device), fpi_device_get_cancellable (device),
fpi_ssm_usb_transfer_cb, fpi_ssm_usb_transfer_cb,
@@ -291,15 +292,8 @@ egis_etu905_cmd_ssm_done (FpiSsm *ssm,
GError *error) GError *error)
{ {
g_autoptr(GError) local_error = error; g_autoptr(GError) local_error = error;
FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device);
CommandData *data = fpi_ssm_get_data (ssm); CommandData *data = fpi_ssm_get_data (ssm);
g_assert (self->cmd_ssm == ssm);
g_assert (!self->cmd_transfer || self->cmd_transfer->ssm == ssm);
self->cmd_ssm = NULL;
self->cmd_transfer = NULL;
if (data && data->callback) if (data && data->callback)
{ {
data->callback (device, data->callback (device,
@@ -338,8 +332,8 @@ egis_etu905_exec_cmd (FpDevice *device,
{ {
g_auto(FpiByteWriter) writer = {0}; g_auto(FpiByteWriter) writer = {0};
g_autoptr(FpiUsbTransfer) transfer = NULL; g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device);
g_autofree CommandData *data = NULL; g_autofree CommandData *data = NULL;
FpiSsm *ssm = NULL;
gsize buffer_out_length = 0; gsize buffer_out_length = 0;
gboolean written = TRUE; gboolean written = TRUE;
guint16 check_value; guint16 check_value;
@@ -382,27 +376,17 @@ egis_etu905_exec_cmd (FpDevice *device,
if (cmd_destroy) if (cmd_destroy)
g_clear_pointer (&cmd, cmd_destroy); g_clear_pointer (&cmd, cmd_destroy);
g_assert (self->cmd_ssm == NULL); /* The command runs on its own dedicated SSM, carrying all its state (the
self->cmd_ssm = fpi_ssm_new (device, * outgoing transfer and the response buffer) via the SSM data. Nothing is
egis_etu905_cmd_run_state, * shared on the device instance, so commands issued from different contexts
CMD_STATES); * (e.g. an in-progress operation and a cancellation) cannot collide. */
data = g_new0 (CommandData, 1); data = g_new0 (CommandData, 1);
data->callback = callback; data->callback = callback;
fpi_ssm_set_data (self->cmd_ssm, g_steal_pointer (&data),
(GDestroyNotify) egis_etu905_command_data_free);
if (!written) if (written)
{ {
fpi_ssm_start (self->cmd_ssm, egis_etu905_cmd_ssm_done);
fpi_ssm_mark_failed (self->cmd_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
return;
}
transfer = fpi_usb_transfer_new (device); transfer = fpi_usb_transfer_new (device);
fpi_usb_transfer_set_short_error (transfer, TRUE); fpi_usb_transfer_set_short_error (transfer, TRUE);
transfer->ssm = self->cmd_ssm;
fpi_usb_transfer_fill_bulk_full (transfer, fpi_usb_transfer_fill_bulk_full (transfer,
EGIS_ETU905_EP_CMD_OUT, EGIS_ETU905_EP_CMD_OUT,
@@ -410,9 +394,17 @@ egis_etu905_exec_cmd (FpDevice *device,
buffer_out_length, buffer_out_length,
g_free); g_free);
g_assert (self->cmd_transfer == NULL); data->cmd_transfer = g_steal_pointer (&transfer);
self->cmd_transfer = g_steal_pointer (&transfer); }
fpi_ssm_start (self->cmd_ssm, egis_etu905_cmd_ssm_done);
ssm = fpi_ssm_new (device, egis_etu905_cmd_run_state, CMD_STATES);
fpi_ssm_set_data (ssm, g_steal_pointer (&data),
(GDestroyNotify) egis_etu905_command_data_free);
fpi_ssm_start (ssm, egis_etu905_cmd_ssm_done);
if (!written)
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
} }
static void static void