diff --git a/libfprint/drivers/egismoc/egismoc.c b/libfprint/drivers/egismoc/egismoc.c index ab0a19a..516dec1 100644 --- a/libfprint/drivers/egismoc/egismoc.c +++ b/libfprint/drivers/egismoc/egismoc.c @@ -60,6 +60,7 @@ static const FpIdEntry egismoc_id_table[] = { { .vid = 0x1c7a, .pid = 0x0586, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 }, { .vid = 0x1c7a, .pid = 0x0587, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE1 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 }, { .vid = 0x1c7a, .pid = 0x05a1, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 }, + { .vid = 0x1c7a, .pid = 0x05aa, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_15 | EGISMOC_DRIVER_NEEDS_INIT_SDCP | EGISMOC_DRIVER_SKIP_CONTROL_INIT }, { .vid = 0x1c7a, .pid = 0x05a5, .driver_data = EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 | EGISMOC_DRIVER_MAX_ENROLL_STAGES_15 }, { .vid = 0, .pid = 0, .driver_data = 0 } }; @@ -493,6 +494,24 @@ egismoc_get_enrolled_prints (FpDevice *device) * device connection which can then be used to generate enrollment IDs and * verify identities as per SDCP. */ +static void +egismoc_sdcp_init_cb (FpDevice *device, + guchar *buffer_in, + gsize length_in, + GError *error) +{ + fp_dbg ("SDCP Init callback"); + FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device); + + if (error) + { + fpi_ssm_mark_failed (self->task_ssm, error); + return; + } + + fpi_ssm_next_state (self->task_ssm); +} + static void egismoc_sdcp_connect_cb (FpDevice *device, guchar *buffer_in, @@ -1309,6 +1328,18 @@ egismoc_enroll_run_state (FpiSsm *ssm, switch (fpi_ssm_get_cur_state (ssm)) { + case ENROLL_SDCP_INIT: + if (fpi_device_get_driver_data (device) & EGISMOC_DRIVER_NEEDS_INIT_SDCP) + { + egismoc_exec_cmd (device, cmd_sdcp_init, cmd_sdcp_init_len, + NULL, egismoc_sdcp_init_cb); + } + else + { + fpi_ssm_next_state (ssm); + } + break; + case ENROLL_SDCP_CONNECT: if (fpi_sdcp_device_is_connected (sdcp_dev)) { @@ -1592,6 +1623,18 @@ egismoc_identify_run_state (FpiSsm *ssm, switch (fpi_ssm_get_cur_state (ssm)) { + case IDENTIFY_SDCP_INIT: + if (fpi_device_get_driver_data (device) & EGISMOC_DRIVER_NEEDS_INIT_SDCP) + { + egismoc_exec_cmd (device, cmd_sdcp_init, cmd_sdcp_init_len, + NULL, egismoc_sdcp_init_cb); + } + else + { + fpi_ssm_next_state (ssm); + } + break; + case IDENTIFY_SDCP_CONNECT: if (fpi_sdcp_device_is_connected (sdcp_dev)) { @@ -1753,6 +1796,14 @@ egismoc_dev_init_handler (FpiSsm *ssm, { g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); + /* Skip USB control init for devices that don't support it (e.g. 0x05aa) */ + if ((fpi_device_get_driver_data (device) & EGISMOC_DRIVER_SKIP_CONTROL_INIT) && + fpi_ssm_get_cur_state (ssm) < DEV_GET_FW_VERSION) + { + fpi_ssm_next_state (ssm); + return; + } + switch (fpi_ssm_get_cur_state (ssm)) { case DEV_INIT_CONTROL1: diff --git a/libfprint/drivers/egismoc/egismoc.h b/libfprint/drivers/egismoc/egismoc.h index f9cba5d..382d2ed 100644 --- a/libfprint/drivers/egismoc/egismoc.h +++ b/libfprint/drivers/egismoc/egismoc.h @@ -38,6 +38,8 @@ G_DECLARE_FINAL_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FPI, DEVICE_EGISMOC, #define EGISMOC_DRIVER_CHECK_PREFIX_TYPE2 (1 << 1) #define EGISMOC_DRIVER_MAX_ENROLL_STAGES_20 (1 << 2) #define EGISMOC_DRIVER_MAX_ENROLL_STAGES_15 (1 << 3) +#define EGISMOC_DRIVER_NEEDS_INIT_SDCP (1 << 4) +#define EGISMOC_DRIVER_SKIP_CONTROL_INIT (1 << 5) #define EGISMOC_EP_CMD_OUT (0x02 | FPI_USB_ENDPOINT_OUT) #define EGISMOC_EP_CMD_IN (0x81 | FPI_USB_ENDPOINT_IN) @@ -144,6 +146,8 @@ static gsize rsp_commit_success_suffix_len = sizeof (rsp_commit_success_suffix) static guchar cmd_sdcp_connect_prefix[] = {0x00, 0x00, 0x00, 0x6b, 0x50, 0x57, 0x01, 0x00, 0x00, 0x00, 0x62, 0x20}; static gsize cmd_sdcp_connect_prefix_len = sizeof (cmd_sdcp_connect_prefix) / sizeof (cmd_sdcp_connect_prefix[0]); +static guchar cmd_sdcp_init[] = {0x00, 0x00, 0x00, 0x07, 0x50, 0x19, 0x04, 0x00, 0x00, 0x01, 0x40}; +static gsize cmd_sdcp_init_len = sizeof (cmd_sdcp_init) / sizeof (cmd_sdcp_init[0]); static guchar cmd_sdcp_connect_suffix[] = {0x00, 0x00}; static gsize cmd_sdcp_connect_suffix_len = sizeof (cmd_sdcp_connect_suffix) / sizeof (cmd_sdcp_connect_suffix[0]); static guchar rsp_sdcp_connect_success_suffix[] = {0x90, 0x00}; @@ -192,6 +196,7 @@ typedef enum { } WaitFingerStates; typedef enum { + IDENTIFY_SDCP_INIT, IDENTIFY_SDCP_CONNECT, IDENTIFY_GET_ENROLLED_IDS, IDENTIFY_CHECK_ENROLLED_NUM, @@ -206,6 +211,7 @@ typedef enum { } IdentifyStates; typedef enum { + ENROLL_SDCP_INIT, ENROLL_SDCP_CONNECT, ENROLL_GET_ENROLLED_IDS, ENROLL_CHECK_ENROLLED_NUM,