egis_etu905: support template update after identify/verify

Add IDENTIFY_SEND_CANCEL_RESULT state to send cancel command
after identify/verify completes, triggering firmware template update.
Implement cancel() callback for enroll and identify/verify cancellation.
Updated umockdev test data to cover the new flow.
This commit is contained in:
Jason Huang
2026-07-25 21:21:50 +00:00
committed by Marco Trevisan
parent 84a33b7d59
commit c45781cf17
5 changed files with 127 additions and 39 deletions
+54
View File
@@ -70,6 +70,11 @@ 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_finger_on_sensor_cb (FpiUsbTransfer *transfer,
FpDevice *device,
@@ -1277,6 +1282,24 @@ egis_etu905_identify_check_cb (FpDevice *device,
fpi_ssm_next_state (self->task_ssm);
}
static void
egis_etu905_identify_send_cancel_result_cb (FpDevice *device,
guchar *buffer_in,
gsize length_in,
GError *error)
{
FpiDeviceEgisEtu905 *self = FPI_DEVICE_EGIS_ETU905 (device);
if (error)
{
fpi_ssm_mark_failed (self->task_ssm, error);
return;
}
/* Advance to complete state */
fpi_ssm_next_state (self->task_ssm);
}
static void
egis_etu905_identify_run_state (FpiSsm *ssm,
FpDevice *device)
@@ -1328,6 +1351,13 @@ egis_etu905_identify_run_state (FpiSsm *ssm,
egis_etu905_identify_check_cb);
break;
case IDENTIFY_SEND_CANCEL_RESULT:
egis_etu905_exec_cmd (device,
cmd_identify_cancel_result,
G_N_ELEMENTS (cmd_identify_cancel_result),
egis_etu905_identify_send_cancel_result_cb);
break;
case IDENTIFY_COMPLETE_SENSOR_RESET:
egis_etu905_exec_cmd (device, cmd_sensor_reset, G_N_ELEMENTS (cmd_sensor_reset),
egis_etu905_task_ssm_next_state_cb);
@@ -1599,6 +1629,29 @@ egis_etu905_close (FpDevice *device)
fpi_device_close_complete (device, g_steal_pointer (&error));
}
static void
egis_etu905_cancel (FpDevice *device)
{
FpiDeviceAction action = fpi_device_get_current_action (device);
fp_dbg ("Cancelling action %d", action);
if (action == FPI_DEVICE_ACTION_ENROLL)
{
egis_etu905_exec_cmd (device,
cmd_enroll_discard,
G_N_ELEMENTS (cmd_enroll_discard),
NULL);
}
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
{
egis_etu905_exec_cmd (device,
cmd_identify_cancel,
G_N_ELEMENTS (cmd_identify_cancel),
NULL);
}
}
static void
fpi_device_egis_etu905_init (FpiDeviceEgisEtu905 *self)
{
@@ -1622,6 +1675,7 @@ 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;
+6
View File
@@ -82,6 +82,8 @@ static const guchar rsp_identify_match_suffix[] = {0x90, 0x00};
static const guchar rsp_identify_notmatch_suffix[] = {0x90, 0x04};
static const guchar cmd_enroll_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x01, 0x00, 0x00, 0x00, 0x20};
static const guchar cmd_enroll_discard[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x04, 0x00, 0x00, 0x00, 0x20};
static const guchar cmd_sensor_start_capture[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x16, 0x02, 0x01};
@@ -97,6 +99,9 @@ static const guchar rsp_read_dirty_prefix[] = {0x00, 0x00, 0x00, 0x02, 0x64};
static const guchar cmd_commit_starting[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x16, 0x05, 0x00, 0x00, 0x00, 0x20};
static const guchar cmd_identify_cancel[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x01, 0x00};
static const guchar cmd_identify_cancel_result[] = {0x00, 0x00, 0x00, 0x04, 0x50, 0x04, 0x02, 0x00};
/* prefixes/suffixes and other things for dynamically created command payloads */
#define EGIS_ETU905_CHECK_BYTES_LENGTH 2
@@ -136,6 +141,7 @@ typedef enum {
IDENTIFY_WAIT_FINGER,
IDENTIFY_SENSOR_CHECK,
IDENTIFY_CHECK,
IDENTIFY_SEND_CANCEL_RESULT,
IDENTIFY_COMPLETE_SENSOR_RESET,
IDENTIFY_COMPLETE,
IDENTIFY_STATES,
Binary file not shown.
+29 -1
View File
@@ -5,7 +5,7 @@ import sys
import gi
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib
from gi.repository import FPrint, GLib, Gio
# Exit with error on any exception, included those happening in async callbacks
sys.excepthook = lambda *args: (traceback.print_exception(*args), sys.exit(1))
@@ -64,6 +64,34 @@ prints2 = len(stored)
print(f"--- LIST DONE: Found {prints2} prints after enroll---")
assert (prints2 - prints1) == 1
# Cancel test - start async identify and cancel it
print("--- TESTING CANCELLATION ---")
deserialized_prints = []
for sp in stored:
deserialized_prints.append(FPrint.Print.deserialize(sp.serialize()))
cancellable = Gio.Cancellable()
identify_cancelled = False
cancel_result = None
def identify_cancelled_cb(dev, res):
global identify_cancelled, cancel_result
identify_cancelled = True
try:
result = dev.identify_finish(res)
cancel_result = result
except Exception as e:
cancel_result = e
print(f"Identify cancelled with error: {e}")
d.identify(deserialized_prints, cancellable=cancellable, callback=identify_cancelled_cb)
cancellable.cancel()
while not identify_cancelled:
ctx.iteration(True)
print(f"--- CANCELLATION TEST DONE, result: {cancel_result} ---")
del deserialized_prints
# Verify
print("--- VERIFYING ---")
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
+38 -38
View File
@@ -1,8 +1,8 @@
P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3/3-3
N: bus/usb/003/002=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001
N: bus/usb/003/005=12010002FF0000407A1CAE0545530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001
E: BUSNUM=003
E: DEVNAME=/dev/bus/usb/003/002
E: DEVNUM=002
E: DEVNAME=/dev/bus/usb/003/005
E: DEVNUM=005
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
@@ -12,14 +12,14 @@ E: ID_MODEL_ID=05ae
E: ID_PATH=pci-0000:05:00.4-usb-0:3
E: ID_PATH_TAG=pci-0000_05_00_4-usb-0_3
E: ID_PATH_WITH_USB_REVISION=pci-0000:05:00.4-usbv2-0:3
E: ID_REVISION=5342
E: ID_REVISION=5345
E: ID_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357
E: ID_SERIAL_SHORT=0A8606PNA357
E: ID_USB_INTERFACES=:ffffff:
E: ID_USB_MODEL=ETU905Axx-E
E: ID_USB_MODEL_ENC=ETU905Axx-E
E: ID_USB_MODEL_ID=05ae
E: ID_USB_REVISION=5342
E: ID_USB_REVISION=5345
E: ID_USB_SERIAL=EGIS_ETU905Axx-E_0A8606PNA357
E: ID_USB_SERIAL_SHORT=0A8606PNA357
E: ID_USB_VENDOR=EGIS
@@ -30,8 +30,8 @@ E: ID_VENDOR_ENC=EGIS
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
E: ID_VENDOR_ID=1c7a
E: MAJOR=189
E: MINOR=257
E: PRODUCT=1c7a/5ae/5342
E: MINOR=260
E: PRODUCT=1c7a/5ae/5345
E: SUBSYSTEM=usb
E: TYPE=255/0/0
A: authorized=1\n
@@ -44,13 +44,13 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=100mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=5342\n
A: bcdDevice=5345\n
A: bmAttributes=a0\n
A: busnum=3\n
A: configuration=
H: descriptors=12010002FF0000407A1CAE0542530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001
A: dev=189:257\n
A: devnum=2\n
H: descriptors=12010002FF0000407A1CAE0545530102030109022700010100A0320904000003FFFFFF00070581024000000705020240000007058303400001
A: dev=189:260\n
A: devnum=5\n
A: devpath=3\n
L: driver=../../../../../../bus/usb/drivers/usb
L: firmware_node=../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/device:1b/device:1c/device:1f
@@ -65,16 +65,16 @@ A: physical_location/lid=no\n
A: physical_location/panel=top\n
A: physical_location/vertical_position=upper\n
L: port=../3-0:1.0/usb3-port3
A: power/active_duration=93136758\n
A: power/active_duration=3828402\n
A: power/async=enabled\n
A: power/autosuspend=2\n
A: power/autosuspend_delay_ms=2000\n
A: power/connected_duration=93139621\n
A: power/connected_duration=3828402\n
A: power/control=on\n
A: power/level=on\n
A: power/persist=1\n
A: power/runtime_active_kids=0\n
A: power/runtime_active_time=93138826\n
A: power/runtime_active_time=3828158\n
A: power/runtime_enabled=forbidden\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
@@ -95,11 +95,11 @@ A: rx_lanes=1\n
A: serial=0A8606PNA357\n
A: speed=12\n
A: tx_lanes=1\n
A: urbnum=5855\n
A: urbnum=1021\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3
N: bus/usb/003/001=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C
N: bus/usb/003/001=12010002090001406B1D020017060302010109021900010100E0000904000001090000000705810304000C
E: BUSNUM=003
E: CURRENT_TAGS=:seat:
E: DEVNAME=/dev/bus/usb/003/001
@@ -115,26 +115,26 @@ E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_MODEL_ID=0002
E: ID_PATH=pci-0000:05:00.4
E: ID_PATH_TAG=pci-0000_05_00_4
E: ID_REVISION=0614
E: ID_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4
E: ID_REVISION=0617
E: ID_SERIAL=Linux_6.17.0-35-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4
E: ID_SERIAL_SHORT=0000:05:00.4
E: ID_USB_INTERFACES=:090000:
E: ID_USB_MODEL=xHCI_Host_Controller
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_USB_MODEL_ID=0002
E: ID_USB_REVISION=0614
E: ID_USB_SERIAL=Linux_6.14.0-37-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4
E: ID_USB_REVISION=0617
E: ID_USB_SERIAL=Linux_6.17.0-35-generic_xhci-hcd_xHCI_Host_Controller_0000:05:00.4
E: ID_USB_SERIAL_SHORT=0000:05:00.4
E: ID_USB_VENDOR=Linux_6.14.0-37-generic_xhci-hcd
E: ID_USB_VENDOR_ENC=Linux\x206.14.0-37-generic\x20xhci-hcd
E: ID_USB_VENDOR=Linux_6.17.0-35-generic_xhci-hcd
E: ID_USB_VENDOR_ENC=Linux\x206.17.0-35-generic\x20xhci-hcd
E: ID_USB_VENDOR_ID=1d6b
E: ID_VENDOR=Linux_6.14.0-37-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x206.14.0-37-generic\x20xhci-hcd
E: ID_VENDOR=Linux_6.17.0-35-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x206.17.0-35-generic\x20xhci-hcd
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_VENDOR_ID=1d6b
E: MAJOR=189
E: MINOR=256
E: PRODUCT=1d6b/2/614
E: PRODUCT=1d6b/2/617
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=9/0/1
@@ -149,11 +149,11 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0614\n
A: bcdDevice=0617\n
A: bmAttributes=e0\n
A: busnum=3\n
A: configuration=
H: descriptors=12010002090001406B1D020014060302010109021900010100E0000904000001090000000705810304000C
H: descriptors=12010002090001406B1D020017060302010109021900010100E0000904000001090000000705810304000C
A: dev=189:256\n
A: devnum=1\n
A: devpath=0\n
@@ -163,20 +163,20 @@ A: idProduct=0002\n
A: idVendor=1d6b\n
A: interface_authorized_default=1\n
A: ltm_capable=no\n
A: manufacturer=Linux 6.14.0-37-generic xhci-hcd\n
A: manufacturer=Linux 6.17.0-35-generic xhci-hcd\n
A: maxchild=4\n
A: power/active_duration=93137993\n
A: power/active_duration=40424267\n
A: power/async=enabled\n
A: power/autosuspend=0\n
A: power/autosuspend_delay_ms=0\n
A: power/connected_duration=93139758\n
A: power/connected_duration=40424455\n
A: power/control=auto\n
A: power/level=auto\n
A: power/runtime_active_kids=1\n
A: power/runtime_active_time=93139206\n
A: power/runtime_active_time=40424257\n
A: power/runtime_enabled=enabled\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
A: power/runtime_suspended_time=50\n
A: power/runtime_usage=0\n
A: power/wakeup=disabled\n
A: power/wakeup_abort_count=\n
@@ -194,7 +194,7 @@ A: rx_lanes=1\n
A: serial=0000:05:00.4\n
A: speed=480\n
A: tx_lanes=1\n
A: urbnum=989\n
A: urbnum=421\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4
@@ -233,7 +233,7 @@ A: driver_override=(null)\n
A: enable=1\n
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/device:1b
L: iommu=../../0000:00:00.2/iommu/ivhd0
L: iommu_group=../../../../kernel/iommu_groups/20
L: iommu_group=../../../../kernel/iommu_groups/19
A: irq=44\n
A: link/l0s_aspm=0\n
A: link/l1_aspm=0\n
@@ -252,11 +252,11 @@ A: msi_irqs/50=msix\n
A: msi_irqs/51=msix\n
A: msi_irqs/52=msix\n
A: numa_node=-1\n
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 4 5 2112 5\nxHCI ring segments 23 23 4096 23\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 256 port bw ctx arrays 0 0 256 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 4 5 2112 5\nxHCI ring segments 23 23 4096 23\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
A: power/async=enabled\n
A: power/control=on\n
A: power/runtime_active_kids=1\n
A: power/runtime_active_time=93139523\n
A: power/runtime_active_time=40424587\n
A: power/runtime_enabled=forbidden\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
@@ -308,7 +308,7 @@ A: driver_override=(null)\n
A: enable=2\n
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c
L: iommu=../0000:00:00.2/iommu/ivhd0
L: iommu_group=../../../kernel/iommu_groups/8
L: iommu_group=../../../kernel/iommu_groups/7
A: irq=33\n
A: local_cpulist=0-11\n
A: local_cpus=fff\n
@@ -322,7 +322,7 @@ A: power/async=enabled\n
A: power/autosuspend_delay_ms=100\n
A: power/control=auto\n
A: power/runtime_active_kids=5\n
A: power/runtime_active_time=93139537\n
A: power/runtime_active_time=40424606\n
A: power/runtime_enabled=enabled\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n