From 7893c2cb36fedee295bb15caaf28bc2fa0cc08ef Mon Sep 17 00:00:00 2001 From: FIM43-Redeye <14264359+FIM43-Redeye@users.noreply.github.com> Date: Wed, 18 Feb 2026 17:14:43 -0500 Subject: [PATCH] goodixmoc: Wait for finger removal before completing verify The goodixmoc driver's verify state machine was missing a WAIT_FINGER_UP state between IDENTIFY and PWR_BTN_SHIELD_OFF. After the sensor reported a match/no-match result, the driver immediately completed the verify operation without waiting for the finger to be lifted from the sensor. This caused problems when fprintd retried verification after a no-match: the finger was still on the sensor, so the same (wrong) finger was scanned again instantly. On fast match-on-chip readers, all retry attempts could be exhausted in under a second, giving the user no time to reposition their finger. Add GOODIX_VERIFY_WAIT_FINGER_UP to the verify state machine, mirroring the existing GOODIX_ENROLL_WAIT_FINGER_UP in the enroll flow. The new state sends MOC_CMD0_FINGER_MODE / MOC_CMD1_SET_FINGER_UP to the sensor and waits for the finger to be removed before advancing to PWR_BTN_SHIELD_OFF. The callback handles the same cases as the enroll equivalent: - Timeout (5s): retry the finger-up wait - Protocol error: fail the SSM - Success: clear FINGER_STATUS_PRESENT and advance Link: https://gitlab.freedesktop.org/libfprint/fprintd/-/issues/209 --- libfprint/drivers/goodixmoc/goodix.c | 40 ++++++++++++++++++++++++++++ libfprint/drivers/goodixmoc/goodix.h | 1 + 2 files changed, 41 insertions(+) diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index 976675b4..27302193 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -480,6 +480,35 @@ fp_verify_cb (FpiDeviceGoodixMoc *self, } +static void +fp_verify_finger_mode_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) +{ + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + /* if reach max timeout(5sec) finger not up, try again */ + if (resp->finger_status.status == GX_ERROR_WAIT_FINGER_UP_TIMEOUT) + { + fpi_ssm_jump_to_state (self->task_ssm, GOODIX_VERIFY_WAIT_FINGER_UP); + return; + } + else if (resp->finger_status.status != GX_SUCCESS) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Switch finger mode failed")); + return; + } + fpi_device_report_finger_status_changes (FP_DEVICE (self), + FP_FINGER_STATUS_NONE, + FP_FINGER_STATUS_PRESENT); + fpi_ssm_next_state (self->task_ssm); +} + static void fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) { @@ -520,6 +549,17 @@ fp_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) fp_verify_cb); break; + case GOODIX_VERIFY_WAIT_FINGER_UP: + { + guint8 dummy = 0; + goodix_sensor_cmd (self, MOC_CMD0_FINGER_MODE, MOC_CMD1_SET_FINGER_UP, + true, + &dummy, + 1, + fp_verify_finger_mode_cb); + } + break; + case GOODIX_VERIFY_PWR_BTN_SHIELD_OFF: goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_OFF, false, diff --git a/libfprint/drivers/goodixmoc/goodix.h b/libfprint/drivers/goodixmoc/goodix.h index 1a04d0f4..ba7fce27 100644 --- a/libfprint/drivers/goodixmoc/goodix.h +++ b/libfprint/drivers/goodixmoc/goodix.h @@ -58,6 +58,7 @@ typedef enum { GOODIX_VERIFY_PWR_BTN_SHIELD_ON = 0, GOODIX_VERIFY_CAPTURE, GOODIX_VERIFY_IDENTIFY, + GOODIX_VERIFY_WAIT_FINGER_UP, GOODIX_VERIFY_PWR_BTN_SHIELD_OFF, GOODIX_VERIFY_NUM_STATES, } GoodixVerifyState;