egismoc: Indentation and syntax fixes

This commit is contained in:
Marco Trevisan (Treviño)
2024-02-19 15:31:11 +01:00
parent 7476faba68
commit b0f0322726
2 changed files with 202 additions and 127 deletions

View File

@@ -35,6 +35,18 @@
#include "egismoc.h" #include "egismoc.h"
struct _FpiDeviceEgisMoc
{
FpDevice parent;
FpiSsm *task_ssm;
FpiSsm *cmd_ssm;
FpiUsbTransfer *cmd_transfer;
GCancellable *interrupt_cancellable;
int enrolled_num;
GPtrArray *enrolled_ids;
};
G_DEFINE_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FP_TYPE_DEVICE); G_DEFINE_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FP_TYPE_DEVICE);
static const FpIdEntry egismoc_id_table[] = { static const FpIdEntry egismoc_id_table[] = {
@@ -84,9 +96,11 @@ egismoc_wait_finger_on_sensor (FpiSsm *ssm,
g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device); g_autoptr(FpiUsbTransfer) transfer = fpi_usb_transfer_new (device);
fpi_usb_transfer_fill_interrupt (transfer, EGISMOC_EP_CMD_INTERRUPT_IN, EGISMOC_USB_INTERRUPT_IN_RECV_LENGTH); fpi_usb_transfer_fill_interrupt (transfer, EGISMOC_EP_CMD_INTERRUPT_IN,
EGISMOC_USB_INTERRUPT_IN_RECV_LENGTH);
transfer->ssm = ssm; transfer->ssm = ssm;
transfer->short_is_error = FALSE; /* Interrupt on this device always returns 1 byte short; this is expected */ /* Interrupt on this device always returns 1 byte short; this is expected */
transfer->short_is_error = FALSE;
fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED); fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED);
@@ -103,7 +117,9 @@ egismoc_validate_response_prefix (const guchar *buffer_in,
const guchar *valid_prefix, const guchar *valid_prefix,
const gsize valid_prefix_len) const gsize valid_prefix_len)
{ {
const gboolean result = memcmp (buffer_in + (egismoc_read_prefix_len + EGISMOC_CHECK_BYTES_LENGTH), const gboolean result = memcmp (buffer_in +
(egismoc_read_prefix_len +
EGISMOC_CHECK_BYTES_LENGTH),
valid_prefix, valid_prefix,
valid_prefix_len) == 0; valid_prefix_len) == 0;
@@ -166,9 +182,10 @@ egismoc_cmd_receive_cb (FpiUsbTransfer *transfer,
gpointer userdata, gpointer userdata,
GError *error) GError *error)
{ {
fp_dbg ("Command receive callback");
CommandData *data = userdata; CommandData *data = userdata;
fp_dbg ("Command receive callback");
if (error) if (error)
{ {
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
@@ -206,17 +223,17 @@ egismoc_cmd_run_state (FpiSsm *ssm,
NULL, NULL,
fpi_ssm_usb_transfer_cb, fpi_ssm_usb_transfer_cb,
NULL); NULL);
break;
} }
else
{ fpi_ssm_next_state (ssm);
fpi_ssm_next_state (ssm);
}
break; break;
case CMD_GET: case CMD_GET:
transfer = fpi_usb_transfer_new (device); transfer = fpi_usb_transfer_new (device);
transfer->ssm = ssm; transfer->ssm = ssm;
fpi_usb_transfer_fill_bulk (transfer, EGISMOC_EP_CMD_IN, EGISMOC_USB_IN_RECV_LENGTH); fpi_usb_transfer_fill_bulk (transfer, EGISMOC_EP_CMD_IN,
EGISMOC_USB_IN_RECV_LENGTH);
fpi_usb_transfer_submit (g_steal_pointer (&transfer), fpi_usb_transfer_submit (g_steal_pointer (&transfer),
EGISMOC_USB_RECV_TIMEOUT, EGISMOC_USB_RECV_TIMEOUT,
NULL, NULL,
@@ -253,9 +270,9 @@ typedef union egismoc_check_bytes
} EgisMocCheckBytes; } EgisMocCheckBytes;
/* /*
Derive the 2 "check bytes" for write payloads * Derive the 2 "check bytes" for write payloads
32-bit big-endian sum of all 16-bit words (including check bytes) MOD 0xFFFF should be 0, otherwise * 32-bit big-endian sum of all 16-bit words (including check bytes) MOD 0xFFFF
the device will reject the payload * should be 0, otherwise the device will reject the payload
*/ */
static EgisMocCheckBytes static EgisMocCheckBytes
egismoc_get_check_bytes (const guchar *value, egismoc_get_check_bytes (const guchar *value,
@@ -279,7 +296,7 @@ egismoc_get_check_bytes (const guchar *value,
sum_shorts += value_bigendian_shorts[i]; sum_shorts += value_bigendian_shorts[i];
/* /*
derive the "first possible occurence" of check bytes as: derive the "first possible occurrence" of check bytes as:
`0xFFFF - (sum_of_32bit_words % 0xFFFF) `0xFFFF - (sum_of_32bit_words % 0xFFFF)
*/ */
check_bytes.check_short = 0xffff - (sum_shorts % 0xffff); check_bytes.check_short = 0xffff - (sum_shorts % 0xffff);
@@ -310,10 +327,12 @@ egismoc_exec_cmd (FpDevice *device,
transfer->short_is_error = TRUE; transfer->short_is_error = TRUE;
/* /*
buffer_out should be a fully composed command (with prefix, check bytes, etc) which looks like this * buffer_out should be a fully composed command (with prefix, check bytes, etc)
E G I S 00 00 00 01 {cb1} {cb2} {payload} * which looks like this:
where cb1 and cb2 are some check bytes generated by the egismoc_get_check_bytes method * E G I S 00 00 00 01 {cb1} {cb2} {payload}
and payload is what is passed via the cmd parameter * where cb1 and cb2 are some check bytes generated by the
* egismoc_get_check_bytes() method and payload is what is passed via the cmd
* parameter
*/ */
buffer_out_length = egismoc_write_prefix_len buffer_out_length = egismoc_write_prefix_len
+ EGISMOC_CHECK_BYTES_LENGTH + EGISMOC_CHECK_BYTES_LENGTH
@@ -323,18 +342,22 @@ egismoc_exec_cmd (FpDevice *device,
/* Prefix */ /* Prefix */
memcpy (buffer_out, egismoc_write_prefix, egismoc_write_prefix_len); memcpy (buffer_out, egismoc_write_prefix, egismoc_write_prefix_len);
/* Check Bytes - leave them as 00 for now then later generate and copy over the real ones */ /* Check Bytes - leave them as 00 for now then later generate and copy over
* the real ones */
/* Command Payload */ /* Command Payload */
memcpy (buffer_out + egismoc_write_prefix_len + EGISMOC_CHECK_BYTES_LENGTH, cmd, cmd_length); memcpy (buffer_out + egismoc_write_prefix_len + EGISMOC_CHECK_BYTES_LENGTH,
cmd, cmd_length);
/* destroy cmd if requested */ /* destroy cmd if requested */
if (cmd_destroy) if (cmd_destroy)
cmd_destroy (cmd); cmd_destroy (cmd);
/* Now fetch and set the "real" check bytes based on the currently assembled payload */ /* Now fetch and set the "real" check bytes based on the currently
* assembled payload */
check_bytes = egismoc_get_check_bytes (buffer_out, buffer_out_length); check_bytes = egismoc_get_check_bytes (buffer_out, buffer_out_length);
memcpy (buffer_out + egismoc_write_prefix_len, check_bytes.check_bytes, EGISMOC_CHECK_BYTES_LENGTH); memcpy (buffer_out + egismoc_write_prefix_len, check_bytes.check_bytes,
EGISMOC_CHECK_BYTES_LENGTH);
fpi_usb_transfer_fill_bulk_full (transfer, fpi_usb_transfer_fill_bulk_full (transfer,
EGISMOC_EP_CMD_OUT, EGISMOC_EP_CMD_OUT,
@@ -423,9 +446,9 @@ egismoc_list_fill_enrolled_ids_cb (FpDevice *device,
self->enrolled_num = 0; self->enrolled_num = 0;
/* /*
Each fingerprint ID will be returned in this response as a 32 byte array * Each fingerprint ID will be returned in this response as a 32 byte array
The other stuff in the payload is 16 bytes long, so if there is at least 1 print * The other stuff in the payload is 16 bytes long, so if there is at least 1
then the length should be at least 16+32=48 bytes long * print then the length should be at least 16+32=48 bytes long
*/ */
for (int pos = EGISMOC_LIST_RESPONSE_PREFIX_SIZE; for (int pos = EGISMOC_LIST_RESPONSE_PREFIX_SIZE;
pos < length_in - EGISMOC_LIST_RESPONSE_SUFFIX_SIZE; pos < length_in - EGISMOC_LIST_RESPONSE_SUFFIX_SIZE;
@@ -433,11 +456,13 @@ egismoc_list_fill_enrolled_ids_cb (FpDevice *device,
{ {
g_autofree guchar *print_id = g_malloc0 (EGISMOC_FINGERPRINT_DATA_SIZE); g_autofree guchar *print_id = g_malloc0 (EGISMOC_FINGERPRINT_DATA_SIZE);
memcpy (print_id, buffer_in + pos, EGISMOC_FINGERPRINT_DATA_SIZE); memcpy (print_id, buffer_in + pos, EGISMOC_FINGERPRINT_DATA_SIZE);
fp_dbg ("Device fingerprint %0d: %.*s%c", self->enrolled_num, EGISMOC_FINGERPRINT_DATA_SIZE, print_id, '\0'); fp_dbg ("Device fingerprint %0d: %.*s", self->enrolled_num,
EGISMOC_FINGERPRINT_DATA_SIZE, print_id);
g_ptr_array_add (self->enrolled_ids, g_steal_pointer (&print_id)); g_ptr_array_add (self->enrolled_ids, g_steal_pointer (&print_id));
} }
fp_info ("Number of currently enrolled fingerprints on the device is %d", self->enrolled_num); fp_info ("Number of currently enrolled fingerprints on the device is %d",
self->enrolled_num);
if (self->task_ssm) if (self->task_ssm)
fpi_ssm_next_state (self->task_ssm); fpi_ssm_next_state (self->task_ssm);
@@ -452,7 +477,8 @@ egismoc_list_run_state (FpiSsm *ssm,
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
case LIST_GET_ENROLLED_IDS: case LIST_GET_ENROLLED_IDS:
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL, egismoc_list_fill_enrolled_ids_cb); egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL,
egismoc_list_fill_enrolled_ids_cb);
break; break;
case LIST_RETURN_ENROLLED_PRINTS: case LIST_RETURN_ENROLLED_PRINTS:
@@ -482,30 +508,35 @@ egismoc_get_delete_cmd (FpDevice *device,
{ {
fp_dbg ("Get delete command"); fp_dbg ("Get delete command");
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device); FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
g_autofree const gchar *print_description = NULL;
g_autoptr(GVariant) print_data = NULL; g_autoptr(GVariant) print_data = NULL;
g_autoptr(GVariant) print_data_id_var = NULL; g_autoptr(GVariant) print_data_id_var = NULL;
const guchar *print_data_id = NULL; const guchar *print_data_id = NULL;
gsize print_data_id_len = 0; gsize print_data_id_len = 0;
g_autofree gchar *print_description = NULL;
g_autofree guchar *enrolled_print_id = NULL; g_autofree guchar *enrolled_print_id = NULL;
guchar *result = NULL; g_autofree guchar *result = NULL;
gsize pos = 0; gsize pos = 0;
/* /*
The final command body should contain: * The final command body should contain:
1) hard-coded 00 00 * 1) hard-coded 00 00
2) 2-byte size indiciator, 20*Number deleted identifiers plus 7 in form of: num_to_delete * 0x20 + 0x07 * 2) 2-byte size indiciator, 20*Number deleted identifiers plus 7 in form of:
Since max prints can be higher than 7 then this goes up to 2 bytes (e9 + 9 = 109) * num_to_delete * 0x20 + 0x07
3) Hard-coded prefix (cmd_delete_prefix) * Since max prints can be higher than 7 then this goes up to 2 bytes
4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 7 (num_to_delete * 0x20) * (e9 + 9 = 109)
5) All of the currently registered prints to delete in their 32-byte device identifiers (enrolled_list) * 3) Hard-coded prefix (cmd_delete_prefix)
* 4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 7
* (num_to_delete * 0x20)
* 5) All of the currently registered prints to delete in their 32-byte device
* identifiers (enrolled_list)
*/ */
const int num_to_delete = (!delete_print) ? self->enrolled_num : 1; const int num_to_delete = (!delete_print) ? self->enrolled_num : 1;
const gsize body_length = sizeof (guchar) * EGISMOC_FINGERPRINT_DATA_SIZE * num_to_delete; const gsize body_length = sizeof (guchar) * EGISMOC_FINGERPRINT_DATA_SIZE *
num_to_delete;
/* total_length is the 6 various bytes plus prefix and body payload */ /* total_length is the 6 various bytes plus prefix and body payload */
const gsize total_length = (sizeof (guchar) * 6) + cmd_delete_prefix_len + body_length; const gsize total_length = (sizeof (guchar) * 6) + cmd_delete_prefix_len +
body_length;
/* pre-fill entire payload with 00s */ /* pre-fill entire payload with 00s */
result = g_malloc0 (total_length); result = g_malloc0 (total_length);
@@ -514,8 +545,10 @@ egismoc_get_delete_cmd (FpDevice *device,
pos = 2; pos = 2;
/* Size Counter bytes */ /* Size Counter bytes */
/* "easiest" way to handle 2-bytes size for counter is to hard-code logic for when we go to the 2nd byte */ /* "easiest" way to handle 2-bytes size for counter is to hard-code logic for
/* note this will not work in case any model ever supports more than 14 prints (assumed max is 10) */ * when we go to the 2nd byte
* note this will not work in case any model ever supports more than 14 prints
* (assumed max is 10) */
if (num_to_delete > 7) if (num_to_delete > 7)
{ {
memset (result + pos, 0x01, sizeof (guchar)); memset (result + pos, 0x01, sizeof (guchar));
@@ -560,15 +593,18 @@ egismoc_get_delete_cmd (FpDevice *device,
if (!g_variant_check_format_string (print_data, "(@ay)", FALSE)) if (!g_variant_check_format_string (print_data, "(@ay)", FALSE))
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return NULL; return NULL;
} }
g_variant_get (print_data, "(@ay)", &print_data_id_var); g_variant_get (print_data, "(@ay)", &print_data_id_var);
print_data_id = g_variant_get_fixed_array (print_data_id_var, &print_data_id_len, sizeof (guchar)); print_data_id = g_variant_get_fixed_array (print_data_id_var,
&print_data_id_len, sizeof (guchar));
if (!g_str_has_prefix (print_description, "FP")) if (!g_str_has_prefix (print_description, "FP"))
fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.", print_description); fp_dbg ("Fingerprint '%s' was not created by libfprint; deleting anyway.",
print_description);
fp_info ("Delete fingerprint %s (%s)", print_description, print_data_id); fp_info ("Delete fingerprint %s (%s)", print_description, print_data_id);
@@ -623,14 +659,16 @@ egismoc_delete_cb (FpDevice *device,
} }
else else
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, fpi_ssm_mark_failed (self->task_ssm,
"Unsupported delete action.")); fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Unsupported delete action."));
} }
} }
else else
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, fpi_ssm_mark_failed (self->task_ssm,
"Delete print was not successfull")); fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Delete print was not successful"));
} }
} }
@@ -644,17 +682,22 @@ egismoc_delete_run_state (FpiSsm *ssm,
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
case DELETE_GET_ENROLLED_IDS: case DELETE_GET_ENROLLED_IDS:
/* get enrolled_ids and enrolled_num from device for use building delete payload below */ /* get enrolled_ids and enrolled_num from device for use building
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL, egismoc_list_fill_enrolled_ids_cb); * delete payload below
*/
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL,
egismoc_list_fill_enrolled_ids_cb);
break; break;
case DELETE_DELETE: case DELETE_DELETE:
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE) if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_DELETE)
payload = egismoc_get_delete_cmd (device, fpi_ssm_get_data (ssm), &payload_length); payload = egismoc_get_delete_cmd (device, fpi_ssm_get_data (ssm),
&payload_length);
else else
payload = egismoc_get_delete_cmd (device, NULL, &payload_length); payload = egismoc_get_delete_cmd (device, NULL, &payload_length);
egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length, g_free, egismoc_delete_cb); egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length,
g_free, egismoc_delete_cb);
break; break;
} }
} }
@@ -725,7 +768,8 @@ egismoc_enroll_status_report (FpDevice *device,
fpi_ssm_mark_failed (self->task_ssm, error); fpi_ssm_mark_failed (self->task_ssm, error);
else else
fpi_ssm_mark_failed (self->task_ssm, fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "Unknown error")); fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Unknown error"));
} }
} }
@@ -755,7 +799,8 @@ egismoc_read_capture_cb (FpDevice *device,
rsp_read_success_suffix, rsp_read_success_suffix,
rsp_read_success_suffix_len)) rsp_read_success_suffix_len))
{ {
egismoc_enroll_status_report (device, enroll_print, ENROLL_STATUS_PARTIAL_OK, NULL); egismoc_enroll_status_report (device, enroll_print,
ENROLL_STATUS_PARTIAL_OK, NULL);
} }
else else
{ {
@@ -778,11 +823,13 @@ egismoc_read_capture_cb (FpDevice *device,
rsp_read_dirty_prefix, rsp_read_dirty_prefix,
rsp_read_dirty_prefix_len)) rsp_read_dirty_prefix_len))
error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER,
"Your device is having trouble recognizing you. Make sure your sensor is clean."); "Your device is having trouble recognizing you. "
"Make sure your sensor is clean.");
else else
error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER, error = fpi_device_retry_new_msg (FP_DEVICE_RETRY_REMOVE_FINGER,
"Unknown failure trying to read your finger. Please try again."); "Unknown failure trying to read your finger. "
"Please try again.");
egismoc_enroll_status_report (device, enroll_print, ENROLL_STATUS_RETRY, error); egismoc_enroll_status_report (device, enroll_print, ENROLL_STATUS_RETRY, error);
} }
@@ -820,8 +867,9 @@ egismoc_enroll_check_cb (FpDevice *device,
} }
/* /*
Builds the full "check" payload which includes identifiers for all fingerprints which currently * Builds the full "check" payload which includes identifiers for all
should exist on the storage. This payload is used during both enrollment and verify actions. * fingerprints which currently should exist on the storage. This payload is
* used during both enrollment and verify actions.
*/ */
static guchar * static guchar *
egismoc_get_check_cmd (FpDevice *device, egismoc_get_check_cmd (FpDevice *device,
@@ -829,29 +877,36 @@ egismoc_get_check_cmd (FpDevice *device,
{ {
fp_dbg ("Get check command"); fp_dbg ("Get check command");
FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device); FpiDeviceEgisMoc *self = FPI_DEVICE_EGISMOC (device);
guchar *device_print_id = NULL; g_autofree guchar *result = NULL;
guchar *result = NULL;
gsize pos = 0; gsize pos = 0;
/* /*
The final command body should contain: * The final command body should contain:
1) hard-coded 00 00 * 1) hard-coded 00 00
2) 2-byte size indiciator, 20*Number enrolled identifiers plus 9 in form of: (enrolled_num + 1) * 0x20 + 0x09 * 2) 2-byte size indiciator, 20*Number enrolled identifiers plus 9 in form of:
Since max prints can be higher than 7 then this goes up to 2 bytes (e9 + 9 = 109) * (enrolled_num + 1) * 0x20 + 0x09
3) Hard-coded prefix (cmd_check_prefix) * Since max prints can be higher than 7 then this goes up to 2 bytes
4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 9 ((enrolled_num + 1) * 0x20) * (e9 + 9 = 109)
5) Hard-coded 32 * 0x00 bytes * 3) Hard-coded prefix (cmd_check_prefix)
6) All of the currently registered prints in their 32-byte device identifiers (enrolled_list) * 4) 2-byte size indiciator, 20*Number of enrolled identifiers without plus 9
7) Hard-coded suffix (cmd_check_suffix) * ((enrolled_num + 1) * 0x20)
* 5) Hard-coded 32 * 0x00 bytes
* 6) All of the currently registered prints in their 32-byte device identifiers
* (enrolled_list)
* 7) Hard-coded suffix (cmd_check_suffix)
*/ */
const gsize body_length = sizeof (guchar) * self->enrolled_num * EGISMOC_FINGERPRINT_DATA_SIZE; const gsize body_length = sizeof (guchar) * self->enrolled_num *
EGISMOC_FINGERPRINT_DATA_SIZE;
/* prefix length can depend on the type */ /* prefix length can depend on the type */
const gsize check_prefix_length = (fpi_device_get_driver_data (device) & EGISMOC_DRIVER_CHECK_PREFIX_TYPE2) ? const gsize check_prefix_length = (fpi_device_get_driver_data (device) &
cmd_check_prefix_type2_len : cmd_check_prefix_type1_len; EGISMOC_DRIVER_CHECK_PREFIX_TYPE2) ?
cmd_check_prefix_type2_len :
cmd_check_prefix_type1_len;
/* total_length is the 6 various bytes plus all other prefixes/suffixes and the body payload */ /* total_length is the 6 various bytes plus all other prefixes/suffixes and
* the body payload */
const gsize total_length = (sizeof (guchar) * 6) const gsize total_length = (sizeof (guchar) * 6)
+ check_prefix_length + check_prefix_length
+ EGISMOC_CMD_CHECK_SEPARATOR_LENGTH + EGISMOC_CMD_CHECK_SEPARATOR_LENGTH
@@ -865,20 +920,24 @@ egismoc_get_check_cmd (FpDevice *device,
pos = 2; pos = 2;
/* Size Counter bytes */ /* Size Counter bytes */
/* "easiest" way to handle 2-bytes size for counter is to hard-code logic for when we go to the 2nd byte */ /* "easiest" way to handle 2-bytes size for counter is to hard-code logic for
/* note this will not work in case any model ever supports more than 14 prints (assumed max is 10) */ * when we go to the 2nd byte
* note this will not work in case any model ever supports more than 14 prints
* (assumed max is 10) */
if (self->enrolled_num > 6) if (self->enrolled_num > 6)
{ {
memset (result + pos, 0x01, sizeof (guchar)); memset (result + pos, 0x01, sizeof (guchar));
pos += sizeof (guchar); pos += sizeof (guchar);
memset (result + pos, ((self->enrolled_num - 7) * 0x20) + 0x09, sizeof (guchar)); memset (result + pos, ((self->enrolled_num - 7) * 0x20) + 0x09,
sizeof (guchar));
pos += sizeof (guchar); pos += sizeof (guchar);
} }
else else
{ {
/* first byte is 0x00, just skip it */ /* first byte is 0x00, just skip it */
pos += sizeof (guchar); pos += sizeof (guchar);
memset (result + pos, ((self->enrolled_num + 1) * 0x20) + 0x09, sizeof (guchar)); memset (result + pos, ((self->enrolled_num + 1) * 0x20) + 0x09,
sizeof (guchar));
pos += sizeof (guchar); pos += sizeof (guchar);
} }
@@ -918,7 +977,7 @@ egismoc_get_check_cmd (FpDevice *device,
for (int i = 0; i < self->enrolled_num; i++) for (int i = 0; i < self->enrolled_num; i++)
{ {
device_print_id = g_ptr_array_index (self->enrolled_ids, i); gchar *device_print_id = g_ptr_array_index (self->enrolled_ids, i);
memcpy (result + pos + (print_id_length * i), device_print_id, print_id_length); memcpy (result + pos + (print_id_length * i), device_print_id, print_id_length);
} }
pos += body_length; pos += body_length;
@@ -948,7 +1007,8 @@ egismoc_enroll_run_state (FpiSsm *ssm,
{ {
case ENROLL_GET_ENROLLED_IDS: case ENROLL_GET_ENROLLED_IDS:
/* get enrolled_ids and enrolled_num from device for use in check stages below */ /* get enrolled_ids and enrolled_num from device for use in check stages below */
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL, egismoc_list_fill_enrolled_ids_cb); egismoc_exec_cmd (device, cmd_list, cmd_list_len,
NULL, egismoc_list_fill_enrolled_ids_cb);
break; break;
case ENROLL_CHECK_ENROLLED_NUM: case ENROLL_CHECK_ENROLLED_NUM:
@@ -962,11 +1022,13 @@ egismoc_enroll_run_state (FpiSsm *ssm,
break; break;
case ENROLL_SENSOR_RESET: case ENROLL_SENSOR_RESET:
egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_SENSOR_ENROLL: case ENROLL_SENSOR_ENROLL:
egismoc_exec_cmd (device, cmd_sensor_enroll, cmd_sensor_enroll_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_enroll, cmd_sensor_enroll_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_WAIT_FINGER: case ENROLL_WAIT_FINGER:
@@ -974,24 +1036,29 @@ egismoc_enroll_run_state (FpiSsm *ssm,
break; break;
case ENROLL_SENSOR_CHECK: case ENROLL_SENSOR_CHECK:
egismoc_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_CHECK: case ENROLL_CHECK:
payload = egismoc_get_check_cmd (device, &payload_length); payload = egismoc_get_check_cmd (device, &payload_length);
egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length, g_free, egismoc_enroll_check_cb); egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length,
g_free, egismoc_enroll_check_cb);
break; break;
case ENROLL_START: case ENROLL_START:
egismoc_exec_cmd (device, cmd_enroll_starting, cmd_enroll_starting_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_enroll_starting, cmd_enroll_starting_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_CAPTURE_SENSOR_RESET: case ENROLL_CAPTURE_SENSOR_RESET:
egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_CAPTURE_SENSOR_START_CAPTURE: case ENROLL_CAPTURE_SENSOR_START_CAPTURE:
egismoc_exec_cmd (device, cmd_sensor_start_capture, cmd_sensor_start_capture_len, NULL, egismoc_exec_cmd (device, cmd_sensor_start_capture, cmd_sensor_start_capture_len,
NULL,
egismoc_task_ssm_next_state_cb); egismoc_task_ssm_next_state_cb);
break; break;
@@ -1000,11 +1067,13 @@ egismoc_enroll_run_state (FpiSsm *ssm,
break; break;
case ENROLL_CAPTURE_READ_RESPONSE: case ENROLL_CAPTURE_READ_RESPONSE:
egismoc_exec_cmd (device, cmd_read_capture, cmd_read_capture_len, NULL, egismoc_read_capture_cb); egismoc_exec_cmd (device, cmd_read_capture, cmd_read_capture_len,
NULL, egismoc_read_capture_cb);
break; break;
case ENROLL_COMMIT_START: case ENROLL_COMMIT_START:
egismoc_exec_cmd (device, cmd_commit_starting, cmd_commit_starting_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_commit_starting, cmd_commit_starting_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_COMMIT: case ENROLL_COMMIT:
@@ -1019,13 +1088,16 @@ egismoc_enroll_run_state (FpiSsm *ssm,
payload_length = cmd_new_print_prefix_len + EGISMOC_FINGERPRINT_DATA_SIZE; payload_length = cmd_new_print_prefix_len + EGISMOC_FINGERPRINT_DATA_SIZE;
payload = g_malloc0 (payload_length); payload = g_malloc0 (payload_length);
memcpy (payload, cmd_new_print_prefix, cmd_new_print_prefix_len); memcpy (payload, cmd_new_print_prefix, cmd_new_print_prefix_len);
memcpy (payload + cmd_new_print_prefix_len, device_print_id, EGISMOC_FINGERPRINT_DATA_SIZE); memcpy (payload + cmd_new_print_prefix_len, device_print_id,
EGISMOC_FINGERPRINT_DATA_SIZE);
egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length, g_free, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length,
g_free, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_COMMIT_SENSOR_RESET: case ENROLL_COMMIT_SENSOR_RESET:
egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case ENROLL_COMPLETE: case ENROLL_COMPLETE:
@@ -1085,7 +1157,9 @@ egismoc_identify_check_cb (FpDevice *device,
buffer_in + EGISMOC_IDENTIFY_RESPONSE_PRINT_ID_OFFSET, buffer_in + EGISMOC_IDENTIFY_RESPONSE_PRINT_ID_OFFSET,
EGISMOC_FINGERPRINT_DATA_SIZE); EGISMOC_FINGERPRINT_DATA_SIZE);
/* Create a new print from this device_print_id and then see if it matches the one indicated */ /* Create a new print from this device_print_id and then see if it matches
* the one indicated
*/
print = fp_print_new (device); print = fp_print_new (device);
egismoc_set_print_data (print, device_print_id, NULL); egismoc_set_print_data (print, device_print_id, NULL);
@@ -1093,7 +1167,8 @@ egismoc_identify_check_cb (FpDevice *device,
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
"Failed to build a print from device response.")); "Failed to build a print from "
"device response."));
return; return;
} }
@@ -1148,8 +1223,9 @@ egismoc_identify_check_cb (FpDevice *device,
} }
else else
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, fpi_ssm_mark_failed (self->task_ssm,
"Unrecognized response from device.")); fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Unrecognized response from device."));
} }
} }
@@ -1165,7 +1241,8 @@ egismoc_identify_run_state (FpiSsm *ssm,
{ {
case IDENTIFY_GET_ENROLLED_IDS: case IDENTIFY_GET_ENROLLED_IDS:
/* get enrolled_ids and enrolled_num from device for use in check stages below */ /* get enrolled_ids and enrolled_num from device for use in check stages below */
egismoc_exec_cmd (device, cmd_list, cmd_list_len, NULL, egismoc_list_fill_enrolled_ids_cb); egismoc_exec_cmd (device, cmd_list, cmd_list_len,
NULL, egismoc_list_fill_enrolled_ids_cb);
break; break;
case IDENTIFY_CHECK_ENROLLED_NUM: case IDENTIFY_CHECK_ENROLLED_NUM:
@@ -1179,11 +1256,13 @@ egismoc_identify_run_state (FpiSsm *ssm,
break; break;
case IDENTIFY_SENSOR_RESET: case IDENTIFY_SENSOR_RESET:
egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case IDENTIFY_SENSOR_IDENTIFY: case IDENTIFY_SENSOR_IDENTIFY:
egismoc_exec_cmd (device, cmd_sensor_identify, cmd_sensor_identify_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_identify, cmd_sensor_identify_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case IDENTIFY_WAIT_FINGER: case IDENTIFY_WAIT_FINGER:
@@ -1191,26 +1270,30 @@ egismoc_identify_run_state (FpiSsm *ssm,
break; break;
case IDENTIFY_SENSOR_CHECK: case IDENTIFY_SENSOR_CHECK:
egismoc_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_check, cmd_sensor_check_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
case IDENTIFY_CHECK: case IDENTIFY_CHECK:
payload = egismoc_get_check_cmd (device, &payload_length); payload = egismoc_get_check_cmd (device, &payload_length);
egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length, g_free, egismoc_identify_check_cb); egismoc_exec_cmd (device, g_steal_pointer (&payload), payload_length,
g_free, egismoc_identify_check_cb);
break; break;
case IDENTIFY_COMPLETE_SENSOR_RESET: case IDENTIFY_COMPLETE_SENSOR_RESET:
egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len, NULL, egismoc_task_ssm_next_state_cb); egismoc_exec_cmd (device, cmd_sensor_reset, cmd_sensor_reset_len,
NULL, egismoc_task_ssm_next_state_cb);
break; break;
/* /*
In Windows, the driver seems at this point to then immediately take another read from the sensor; * In Windows, the driver seems at this point to then immediately take
this is suspected to be an on-chip "verify". However, because the user's finger is still on the * another read from the sensor; this is suspected to be an on-chip
sensor from the identify, then it seems to always return positive. We will consider this extra * "verify". However, because the user's finger is still on the sensor from
step unnecessary and just skip it in this driver. This driver will instead handle matching of the * the identify, then it seems to always return positive. We will consider
FpPrint from the gallery in the "verify" case of the callback egismoc_identify_check_cb. * this extra step unnecessary and just skip it in this driver. This driver
* will instead handle matching of the FpPrint from the gallery in the
* "verify" case of the callback egismoc_identify_check_cb.
*/ */
case IDENTIFY_COMPLETE: case IDENTIFY_COMPLETE:
if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY) if (fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY)
fpi_device_identify_complete (device, NULL); fpi_device_identify_complete (device, NULL);
@@ -1258,14 +1341,16 @@ egismoc_fw_version_cb (FpDevice *device,
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Device firmware response was not valid.")); "Device firmware response "
"was not valid."));
return; return;
} }
/* /*
FW Version is 12 bytes: a carriage return (0x0d) plus the version string itself. * FW Version is 12 bytes: a carriage return (0x0d) plus the version string
Always skip [the read prefix] + [2 * check bytes] + [3 * 0x00] that come with every payload * itself. Always skip [the read prefix] + [2 * check bytes] + [3 * 0x00] that
Then we will also skip the carriage return and take all but the last 2 bytes as the FW Version * come with every payload Then we will also skip the carriage return and take
* all but the last 2 bytes as the FW Version
*/ */
prefix_length = egismoc_read_prefix_len + 2 + 3 + 1; prefix_length = egismoc_read_prefix_len + 2 + 3 + 1;
fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len; fw_version_length = length_in - prefix_length - rsp_fw_version_suffix_len;
@@ -1346,7 +1431,8 @@ egismoc_dev_init_handler (FpiSsm *ssm,
break; break;
case DEV_GET_FW_VERSION: case DEV_GET_FW_VERSION:
egismoc_exec_cmd (device, cmd_fw_version, cmd_fw_version_len, NULL, egismoc_fw_version_cb); egismoc_exec_cmd (device, cmd_fw_version, cmd_fw_version_len,
NULL, egismoc_fw_version_cb);
break; break;
} }
@@ -1406,7 +1492,8 @@ egismoc_close (FpDevice *device)
egismoc_cancel (device); egismoc_cancel (device);
g_clear_object (&self->interrupt_cancellable); g_clear_object (&self->interrupt_cancellable);
g_usb_device_release_interface (fpi_device_get_usb_device (device), 0, 0, &error); g_usb_device_release_interface (fpi_device_get_usb_device (device),
0, 0, &error);
fpi_device_close_complete (device, error); fpi_device_close_complete (device, error);
} }
@@ -1428,7 +1515,8 @@ fpi_device_egismoc_class_init (FpiDeviceEgisMocClass *klass)
dev_class->scan_type = FP_SCAN_TYPE_PRESS; dev_class->scan_type = FP_SCAN_TYPE_PRESS;
dev_class->id_table = egismoc_id_table; dev_class->id_table = egismoc_id_table;
dev_class->nr_enroll_stages = EGISMOC_ENROLL_TIMES; dev_class->nr_enroll_stages = EGISMOC_ENROLL_TIMES;
dev_class->temp_hot_seconds = 0; /* device should be "always off" unless being used */ /* device should be "always off" unless being used */
dev_class->temp_hot_seconds = 0;
dev_class->open = egismoc_open; dev_class->open = egismoc_open;
dev_class->cancel = egismoc_cancel; dev_class->cancel = egismoc_cancel;

View File

@@ -55,19 +55,6 @@ G_DECLARE_FINAL_TYPE (FpiDeviceEgisMoc, fpi_device_egismoc, FPI, DEVICE_EGISMOC,
#define EGISMOC_LIST_RESPONSE_PREFIX_SIZE 14 #define EGISMOC_LIST_RESPONSE_PREFIX_SIZE 14
#define EGISMOC_LIST_RESPONSE_SUFFIX_SIZE 2 #define EGISMOC_LIST_RESPONSE_SUFFIX_SIZE 2
struct _FpiDeviceEgisMoc
{
FpDevice parent;
FpiSsm *task_ssm;
FpiSsm *cmd_ssm;
FpiUsbTransfer *cmd_transfer;
GCancellable *interrupt_cancellable;
int enrolled_num;
GPtrArray *enrolled_ids;
};
/* standard prefixes for all read/writes */ /* standard prefixes for all read/writes */
static guchar egismoc_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01}; static guchar egismoc_write_prefix[] = {'E', 'G', 'I', 'S', 0x00, 0x00, 0x00, 0x01};