fpcmoc: Use fpi-byte-{reader,writer} to parse/build the device data

In this way we have not endianness limitations
This commit is contained in:
Marco Trevisan (Treviño)
2026-07-01 17:49:34 +02:00
parent c039ab4754
commit 050476e1ba
+345 -195
View File
@@ -18,6 +18,7 @@
#include "drivers_api.h" #include "drivers_api.h"
#include "fpc.h" #include "fpc.h"
#include "fpi-byte-writer.h"
#define FP_COMPONENT "fpcmoc" #define FP_COMPONENT "fpcmoc"
#define MAX_ENROLL_SAMPLES (25) #define MAX_ENROLL_SAMPLES (25)
@@ -59,6 +60,7 @@ typedef struct
guint16 index; guint16 index;
guint8 *data; guint8 *data;
gsize data_len; gsize data_len;
gsize resp_len;
SynCmdMsgCallback callback; SynCmdMsgCallback callback;
} CommandData; } CommandData;
@@ -106,34 +108,6 @@ fpc_suspend_resume_cb (FpiUsbTransfer *transfer,
} }
} }
static void
fpc_evt_data_from_le (fpc_cmd_response_t *evt)
{
evt->evt_hdr.cmdid = GUINT32_FROM_LE (evt->evt_hdr.cmdid);
evt->evt_hdr.length = GUINT32_FROM_LE (evt->evt_hdr.length);
evt->evt_hdr.status = GUINT32_FROM_LE (evt->evt_hdr.status);
if (evt->evt_hdr.cmdid == FPC_EVT_INIT_RESULT)
{
evt->evt_inited.sensor = GUINT16_FROM_LE (evt->evt_inited.sensor);
evt->evt_inited.hw_id = GUINT16_FROM_LE (evt->evt_inited.hw_id);
evt->evt_inited.img_w = GUINT16_FROM_LE (evt->evt_inited.img_w);
evt->evt_inited.img_h = GUINT16_FROM_LE (evt->evt_inited.img_h);
evt->evt_inited.fw_capabilities = GUINT16_FROM_LE (evt->evt_inited.fw_capabilities);
}
else if (evt->evt_hdr.cmdid == FPC_EVT_FID_DATA)
{
evt->evt_enum_fids.status = GINT32_FROM_LE (evt->evt_enum_fids.status);
evt->evt_enum_fids.num_ids = GUINT32_FROM_LE (evt->evt_enum_fids.num_ids);
for (guint32 i = 0; i < evt->evt_enum_fids.num_ids && i < FPC_TEMPLATES_MAX; i++)
{
evt->evt_enum_fids.fid_data[i].identity_type = GUINT32_FROM_LE (evt->evt_enum_fids.fid_data[i].identity_type);
evt->evt_enum_fids.fid_data[i].identity_size = GUINT32_FROM_LE (evt->evt_enum_fids.fid_data[i].identity_size);
}
}
}
static void static void
fpc_cmd_receive_cb (FpiUsbTransfer *transfer, fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
FpDevice *device, FpDevice *device,
@@ -190,7 +164,6 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
if (ssm_state == FPC_CMD_GET_DATA) if (ssm_state == FPC_CMD_GET_DATA)
{ {
fpc_cmd_response_t evt_data = {0};
fp_dbg ("%s recv evt data length: %ld", G_STRFUNC, transfer->actual_length); fp_dbg ("%s recv evt data length: %ld", G_STRFUNC, transfer->actual_length);
if (transfer->actual_length == 0) if (transfer->actual_length == 0)
{ {
@@ -200,11 +173,10 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
return; return;
} }
memcpy (&evt_data, transfer->buffer, transfer->actual_length); data->resp_len = transfer->actual_length;
fpc_evt_data_from_le (&evt_data);
if (data->callback) if (data->callback)
data->callback (self, (guint8 *) &evt_data, NULL); data->callback (self, transfer->buffer, NULL);
fpi_ssm_mark_completed (transfer->ssm); fpi_ssm_mark_completed (transfer->ssm);
return; return;
@@ -220,6 +192,8 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer,
return; return;
} }
data->resp_len = transfer->actual_length;
if (data->callback) if (data->callback)
data->callback (self, transfer->buffer, NULL); data->callback (self, transfer->buffer, NULL);
@@ -447,7 +421,10 @@ fpc_evt_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
pfpc_cmd_response_t presp = NULL; FpiByteReader reader;
guint32 cmdid;
guint32 evt_length;
guint32 evt_status;
if (!check_data (data, &error)) if (!check_data (data, &error))
{ {
@@ -456,36 +433,82 @@ fpc_evt_cb (FpiDeviceFpcMoc *self,
return; return;
} }
presp = (pfpc_cmd_response_t) data; fpi_byte_reader_init (&reader, data, EP_IN_MAX_BUF_SIZE);
switch (presp->evt_hdr.cmdid) if (!fpi_byte_reader_get_uint32_le (&reader, &cmdid) ||
!fpi_byte_reader_get_uint32_le (&reader, &evt_length))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (!fpi_byte_reader_get_uint32_le (&reader, &evt_status))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
switch (cmdid)
{ {
case FPC_EVT_FID_DATA: case FPC_EVT_FID_DATA:
{
gint enum_status;
guint32 num_ids;
if (!fpi_byte_reader_get_int32_le (&reader, &enum_status) ||
!fpi_byte_reader_get_uint32_le (&reader, &num_ids))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
fp_dbg ("%s Enum Fids: status = %d, NumFids = %d", G_STRFUNC, fp_dbg ("%s Enum Fids: status = %d, NumFids = %d", G_STRFUNC,
presp->evt_enum_fids.status, presp->evt_enum_fids.num_ids); enum_status, num_ids);
if (presp->evt_enum_fids.status || (presp->evt_enum_fids.num_ids > FPC_TEMPLATES_MAX)) if (enum_status || (num_ids > FPC_TEMPLATES_MAX))
{ {
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,
"Get Fids failed")); "Get Fids failed"));
return; return;
} }
}
break; break;
case FPC_EVT_INIT_RESULT: case FPC_EVT_INIT_RESULT:
fp_dbg ("%s INIT: status=%d, Sensor = %d, HWID = 0x%04X, WxH = %d x %d", G_STRFUNC, {
presp->evt_inited.hdr.status, presp->evt_inited.sensor, guint16 sensor;
presp->evt_inited.hw_id, presp->evt_inited.img_w, presp->evt_inited.img_h); guint16 hw_id;
guint16 img_w;
guint16 img_h;
const guint8 *fw_version;
fp_dbg ("%s INIT: FW version: %s", G_STRFUNC, (gchar *) presp->evt_inited.fw_version); if (!fpi_byte_reader_get_uint16_le (&reader, &sensor) ||
!fpi_byte_reader_get_uint16_le (&reader, &hw_id) ||
!fpi_byte_reader_get_uint16_le (&reader, &img_w) ||
!fpi_byte_reader_get_uint16_le (&reader, &img_h) ||
!fpi_byte_reader_get_data (&reader, MAX_FW_VERSION_STR_LEN, &fw_version))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
fp_dbg ("%s INIT: status=%d, Sensor = %d, HWID = 0x%04X, WxH = %d x %d", G_STRFUNC,
evt_status, sensor, hw_id, img_w, img_h);
fp_dbg ("%s INIT: FW version: %s", G_STRFUNC, (const gchar *) fw_version);
}
break; break;
case FPC_EVT_FINGER_DWN: case FPC_EVT_FINGER_DWN:
fp_dbg ("%s Got finger down event (%d)", G_STRFUNC, presp->evt_hdr.status); fp_dbg ("%s Got finger down event (%d)", G_STRFUNC, evt_status);
fpi_device_report_finger_status_changes (FP_DEVICE (self), fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_PRESENT, FP_FINGER_STATUS_PRESENT,
FP_FINGER_STATUS_NONE); FP_FINGER_STATUS_NONE);
if (presp->evt_hdr.status != 0) if (evt_status != 0)
{ {
/* Redo the current task state if capture failed */ /* Redo the current task state if capture failed */
fpi_ssm_jump_to_state (self->task_ssm, fpi_ssm_get_cur_state (self->task_ssm)); fpi_ssm_jump_to_state (self->task_ssm, fpi_ssm_get_cur_state (self->task_ssm));
@@ -503,7 +526,7 @@ fpc_evt_cb (FpiDeviceFpcMoc *self,
default: default:
fpi_ssm_mark_failed (self->task_ssm, fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Unknown Evt (0x%x)!", presp->evt_hdr.cmdid)); "Unknown Evt (0x%x)!", cmdid));
return; return;
} }
@@ -633,7 +656,10 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self,
{ {
g_autoptr(GPtrArray) list_result = NULL; g_autoptr(GPtrArray) list_result = NULL;
FpDevice *device = FP_DEVICE (self); FpDevice *device = FP_DEVICE (self);
pfpc_cmd_response_t presp = NULL; FpiByteReader reader;
guint32 cmdid;
guint32 evt_length;
guint32 evt_status;
if (error) if (error)
{ {
@@ -650,18 +676,42 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self,
return; return;
} }
presp = (pfpc_cmd_response_t) data; fpi_byte_reader_init (&reader, data, EP_IN_MAX_BUF_SIZE);
if (presp->evt_hdr.cmdid != FPC_EVT_FID_DATA)
if (!fpi_byte_reader_get_uint32_le (&reader, &cmdid) ||
!fpi_byte_reader_get_uint32_le (&reader, &evt_length) ||
!fpi_byte_reader_get_uint32_le (&reader, &evt_status))
{
fpi_device_list_complete (FP_DEVICE (self),
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (cmdid != FPC_EVT_FID_DATA)
{ {
fpi_device_list_complete (FP_DEVICE (self), fpi_device_list_complete (FP_DEVICE (self),
NULL, NULL,
fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID,
"Recv evt is incorrect: 0x%x", "Recv evt is incorrect: 0x%x",
presp->evt_hdr.cmdid)); cmdid));
return; return;
} }
if (presp->evt_enum_fids.num_ids > FPC_TEMPLATES_MAX) {
gint enum_status;
guint32 num_ids;
if (!fpi_byte_reader_get_int32_le (&reader, &enum_status) ||
!fpi_byte_reader_get_uint32_le (&reader, &num_ids))
{
fpi_device_list_complete (FP_DEVICE (self),
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (num_ids > FPC_TEMPLATES_MAX)
{ {
fpi_device_list_complete (FP_DEVICE (self), fpi_device_list_complete (FP_DEVICE (self),
NULL, NULL,
@@ -672,7 +722,7 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self,
list_result = g_ptr_array_new_with_free_func (g_object_unref); list_result = g_ptr_array_new_with_free_func (g_object_unref);
if (presp->evt_enum_fids.num_ids == 0) if (num_ids == 0)
{ {
fp_info ("Database is empty"); fp_info ("Database is empty");
fpi_device_list_complete (device, fpi_device_list_complete (device,
@@ -681,23 +731,50 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self,
return; return;
} }
for (int n = 0; n < presp->evt_enum_fids.num_ids; n++) for (guint32 n = 0; n < num_ids; n++)
{ {
FpPrint *print = NULL; FpPrint *print = NULL;
fpc_fid_data_t *fid_data = &presp->evt_enum_fids.fid_data[n]; fpc_fid_data_t fid_data = {0};
guint8 subfactor;
guint32 identity_type;
guint32 identity_size;
if ((fid_data->subfactor != FPC_SUBTYPE_RESERVED) && if (!fpi_byte_reader_get_uint8 (&reader, &subfactor) ||
(fid_data->identity_type != FPC_IDENTITY_TYPE_RESERVED)) !fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
!fpi_byte_reader_get_uint32_le (&reader, &identity_size))
{
fpi_device_list_complete (FP_DEVICE (self),
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
fid_data.subfactor = subfactor;
fid_data.identity_type = identity_type;
fid_data.identity_size = identity_size;
if ((subfactor != FPC_SUBTYPE_RESERVED) &&
(identity_type != FPC_IDENTITY_TYPE_RESERVED))
{ {
fp_info ("Incompatible template found (0x%x, 0x%x)", fp_info ("Incompatible template found (0x%x, 0x%x)",
fid_data->subfactor, fid_data->identity_type); subfactor, identity_type);
fpi_byte_reader_skip (&reader, SECURITY_MAX_SID_SIZE);
continue; continue;
} }
print = fpc_print_from_data (self, fid_data); if (!fpi_byte_reader_get_data_static (&reader, fid_data.identity))
{
fpi_device_list_complete (FP_DEVICE (self),
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
print = fpc_print_from_data (self, &fid_data);
g_ptr_array_add (list_result, g_object_ref_sink (print)); g_ptr_array_add (list_result, g_object_ref_sink (print));
} }
}
fp_info ("Query templates complete!"); fp_info ("Query templates complete!");
fpi_device_list_complete (device, fpi_device_list_complete (device,
@@ -716,7 +793,8 @@ fpc_enroll_create_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
FPC_BEGIN_ENROL *presp = NULL; FpiByteReader reader;
gint32 status;
if (!check_data (data, &error)) if (!check_data (data, &error))
{ {
@@ -725,13 +803,20 @@ fpc_enroll_create_cb (FpiDeviceFpcMoc *self,
return; return;
} }
presp = (FPC_BEGIN_ENROL *) data; fpi_byte_reader_init (&reader, data, sizeof (FPC_BEGIN_ENROL));
presp->status = GINT32_FROM_LE (presp->status);
if (presp->status != 0) if (!fpi_byte_reader_get_int32_le (&reader, &status))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (status != 0)
{ {
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"End Enroll failed: %d", "End Enroll failed: %d",
presp->status); status);
} }
if (error) if (error)
@@ -752,7 +837,9 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
FPC_ENROL *presp = NULL; FpiByteReader reader;
gint32 status;
guint32 remaining;
if (!check_data (data, &error)) if (!check_data (data, &error))
{ {
@@ -761,11 +848,18 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
return; return;
} }
presp = (FPC_ENROL *) data; fpi_byte_reader_init (&reader, data, sizeof (FPC_ENROL));
presp->status = GINT32_FROM_LE (presp->status);
presp->remaining = GUINT32_FROM_LE (presp->remaining); if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
fp_dbg ("Enrol Update status: %d, remaining: %d", presp->status, presp->remaining); !fpi_byte_reader_get_uint32_le (&reader, &remaining))
switch (presp->status) {
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
fp_dbg ("Enrol Update status: %d, remaining: %d", status, remaining);
switch (status)
{ {
case FPC_ENROL_STATUS_FAILED_COULD_NOT_COMPLETE: case FPC_ENROL_STATUS_FAILED_COULD_NOT_COMPLETE:
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL); error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
@@ -835,10 +929,10 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self,
break; break;
default: default:
fp_err ("%s Unknown result code: %d ", G_STRFUNC, presp->status); fp_err ("%s Unknown result code: %d ", G_STRFUNC, status);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Enroll failed: %d", "Enroll failed: %d",
presp->status); status);
break; break;
} }
@@ -859,25 +953,34 @@ fpc_enroll_complete_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
FPC_END_ENROL *presp = NULL; FpiByteReader reader;
gint32 status;
guint32 fid;
self->do_cleanup = FALSE; self->do_cleanup = FALSE;
if (check_data (data, &error)) if (check_data (data, &error))
{ {
presp = (FPC_END_ENROL *) data; fpi_byte_reader_init (&reader, data, sizeof (FPC_END_ENROL));
presp->status = GINT32_FROM_LE (presp->status);
presp->fid = GUINT32_FROM_LE (presp->fid); if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
if (presp->status != 0) !fpi_byte_reader_get_uint32_le (&reader, &fid))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (status != 0)
{ {
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"End Enroll failed: %d", "End Enroll failed: %d",
presp->status); status);
} }
else else
{ {
fp_dbg ("Enrol End status: %d, fid: 0x%x", fp_dbg ("Enrol End status: %d, fid: 0x%x",
presp->status, presp->fid); status, fid);
} }
} }
@@ -898,18 +1001,31 @@ fpc_enroll_check_duplicate_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
FPC_IDENTIFY *presp = NULL; FpiByteReader reader;
if (check_data (data, &error)) if (check_data (data, &error))
{ {
presp = (FPC_IDENTIFY *) data; gint32 status;
presp->status = GINT32_FROM_LE (presp->status); guint32 identity_type;
presp->identity_type = GUINT32_FROM_LE (presp->identity_type); guint32 identity_size;
presp->identity_size = GUINT32_FROM_LE (presp->identity_size); guint32 subfactor;
presp->subfactor = GUINT32_FROM_LE (presp->subfactor);
if ((presp->status == 0) && (presp->subfactor == FPC_SUBTYPE_RESERVED) && fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY));
(presp->identity_type == FPC_IDENTITY_TYPE_RESERVED) &&
(presp->identity_size <= SECURITY_MAX_SID_SIZE)) if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
!fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
!fpi_byte_reader_skip (&reader, 4) ||
!fpi_byte_reader_get_uint32_le (&reader, &identity_size) ||
!fpi_byte_reader_get_uint32_le (&reader, &subfactor))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if ((status == 0) && (subfactor == FPC_SUBTYPE_RESERVED) &&
(identity_type == FPC_IDENTITY_TYPE_RESERVED) &&
(identity_size <= SECURITY_MAX_SID_SIZE))
{ {
fp_info ("%s Got a duplicated template", G_STRFUNC); fp_info ("%s Got a duplicated template", G_STRFUNC);
error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE); error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE);
@@ -949,17 +1065,25 @@ fpc_enroll_commit_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
gint32 *result = NULL;
if (check_data (data, &error)) if (check_data (data, &error))
{ {
result = (gint32 *) data; FpiByteReader reader;
*result = GINT32_FROM_LE (*result); gint32 result;
if (*result != 0)
fpi_byte_reader_init (&reader, data, sizeof (gint32));
if (!fpi_byte_reader_get_int32_le (&reader, &result))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (result != 0)
{ {
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL, error = fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL,
"Save DB failed: %d", "Save DB failed: %d",
*result); result);
} }
} }
@@ -987,28 +1111,22 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
{ {
case FPC_ENROLL_ENUM: case FPC_ENROLL_ENUM:
{ {
FPC_FID_DATA pquery_data = {0}; guint8 buf[sizeof (FPC_FID_DATA)] = {0};
gsize query_data_len = 0; FpiByteWriter writer;
guint32 wildcard_value = GUINT32_TO_LE (FPC_IDENTITY_WILDCARD);
query_data_len = sizeof (FPC_FID_DATA);
pquery_data.identity_type = FPC_IDENTITY_TYPE_WILDCARD;
pquery_data.reserved = 16;
pquery_data.identity_size = sizeof (wildcard_value);
pquery_data.subfactor = (guint32) FPC_SUBTYPE_ANY;
memcpy (&pquery_data.data[0],
&wildcard_value, pquery_data.identity_size);
pquery_data.identity_type = GUINT32_TO_LE (pquery_data.identity_type); fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
pquery_data.reserved = GUINT32_TO_LE (pquery_data.reserved); fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD);
pquery_data.identity_size = GUINT32_TO_LE (pquery_data.identity_size); fpi_byte_writer_put_uint32_le (&writer, 16);
pquery_data.subfactor = GUINT32_TO_LE (pquery_data.subfactor); fpi_byte_writer_put_uint32_le (&writer, sizeof (guint32));
fpi_byte_writer_put_uint32_le (&writer, FPC_SUBTYPE_ANY);
fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_WILDCARD);
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA; cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
cmd_data.request = FPC_CMD_ENUM; cmd_data.request = FPC_CMD_ENUM;
cmd_data.value = 0x0; cmd_data.value = 0x0;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &pquery_data; cmd_data.data = buf;
cmd_data.data_len = query_data_len; cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_evt_cb; cmd_data.callback = fpc_evt_cb;
fpc_sensor_cmd (self, FALSE, &cmd_data); fpc_sensor_cmd (self, FALSE, &cmd_data);
@@ -1032,7 +1150,12 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
case FPC_ENROLL_CAPTURE: case FPC_ENROLL_CAPTURE:
{ {
guint32 capture_id = GUINT32_TO_LE (FPC_CAPTUREID_RESERVED); guint8 buf[4];
FpiByteWriter writer;
fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
fpi_byte_writer_put_uint32_le (&writer, FPC_CAPTUREID_RESERVED);
fpi_device_report_finger_status_changes (device, fpi_device_report_finger_status_changes (device,
FP_FINGER_STATUS_NEEDED, FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE); FP_FINGER_STATUS_NONE);
@@ -1040,8 +1163,8 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
cmd_data.request = FPC_CMD_ARM; cmd_data.request = FPC_CMD_ARM;
cmd_data.value = 0x1; cmd_data.value = 0x1;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &capture_id; cmd_data.data = buf;
cmd_data.data_len = sizeof (guint32); cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_evt_cb; cmd_data.callback = fpc_evt_cb;
fpc_sensor_cmd (self, TRUE, &cmd_data); fpc_sensor_cmd (self, TRUE, &cmd_data);
@@ -1109,15 +1232,14 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
case FPC_ENROLL_BINDID: case FPC_ENROLL_BINDID:
{ {
FPC_FID_DATA data = {0}; guint8 buf[sizeof (FPC_FID_DATA)] = {0};
gsize data_len = 0; FpiByteWriter writer;
FpPrint *print = NULL; FpPrint *print = NULL;
GVariant *fpi_data = NULL; GVariant *fpi_data = NULL;
GVariant *uid = NULL; GVariant *uid = NULL;
guint finger = FPC_SUBTYPE_RESERVED; guint finger = FPC_SUBTYPE_RESERVED;
g_autofree gchar *user_id = NULL; g_autofree gchar *user_id = NULL;
gssize user_id_len; gssize user_id_len;
g_autofree guint8 *payload = NULL;
fpi_device_get_enroll_data (device, &print); fpi_device_get_enroll_data (device, &print);
@@ -1141,25 +1263,19 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device)
fp_dbg ("user_id: %s, finger: 0x%x", user_id, finger); fp_dbg ("user_id: %s, finger: 0x%x", user_id, finger);
data_len = sizeof (FPC_FID_DATA); fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
data.identity_type = FPC_IDENTITY_TYPE_RESERVED; fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED);
data.reserved = 16; fpi_byte_writer_put_uint32_le (&writer, 16);
data.identity_size = user_id_len; fpi_byte_writer_put_uint32_le (&writer, user_id_len);
data.subfactor = (guint32) finger; fpi_byte_writer_put_uint32_le (&writer, finger);
memcpy (&data.data[0], fpi_byte_writer_put_data (&writer, (const guint8 *) user_id, user_id_len);
user_id, user_id_len);
data.identity_type = GUINT32_TO_LE (data.identity_type);
data.reserved = GUINT32_TO_LE (data.reserved);
data.identity_size = GUINT32_TO_LE (data.identity_size);
data.subfactor = GUINT32_TO_LE (data.subfactor);
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE; cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
cmd_data.request = FPC_CMD_BIND_IDENTITY; cmd_data.request = FPC_CMD_BIND_IDENTITY;
cmd_data.value = 0x0; cmd_data.value = 0x0;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &data; cmd_data.data = buf;
cmd_data.data_len = data_len; cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_enroll_bindid_cb; cmd_data.callback = fpc_enroll_bindid_cb;
fpc_sensor_cmd (self, FALSE, &cmd_data); fpc_sensor_cmd (self, FALSE, &cmd_data);
@@ -1252,7 +1368,11 @@ fpc_verify_cb (FpiDeviceFpcMoc *self,
FpDevice *device = FP_DEVICE (self); FpDevice *device = FP_DEVICE (self);
gboolean found = FALSE; gboolean found = FALSE;
FpiDeviceAction current_action; FpiDeviceAction current_action;
FPC_IDENTIFY *presp = NULL; FpiByteReader reader;
gint32 status;
guint32 identity_type;
guint32 identity_size;
guint32 subfactor;
if (!check_data (data, &error)) if (!check_data (data, &error))
{ {
@@ -1261,30 +1381,43 @@ fpc_verify_cb (FpiDeviceFpcMoc *self,
return; return;
} }
presp = (FPC_IDENTIFY *) data; fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY));
presp->status = GINT32_FROM_LE (presp->status);
presp->identity_type = GUINT32_FROM_LE (presp->identity_type); if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
presp->identity_size = GUINT32_FROM_LE (presp->identity_size); !fpi_byte_reader_get_uint32_le (&reader, &identity_type) ||
presp->subfactor = GUINT32_FROM_LE (presp->subfactor); !fpi_byte_reader_skip (&reader, 4) ||
!fpi_byte_reader_get_uint32_le (&reader, &identity_size) ||
!fpi_byte_reader_get_uint32_le (&reader, &subfactor))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
current_action = fpi_device_get_current_action (device); current_action = fpi_device_get_current_action (device);
g_assert (current_action == FPI_DEVICE_ACTION_VERIFY || g_assert (current_action == FPI_DEVICE_ACTION_VERIFY ||
current_action == FPI_DEVICE_ACTION_IDENTIFY); current_action == FPI_DEVICE_ACTION_IDENTIFY);
if ((presp->status == 0) && (presp->subfactor == FPC_SUBTYPE_RESERVED) && if ((status == 0) && (subfactor == FPC_SUBTYPE_RESERVED) &&
(presp->identity_type == FPC_IDENTITY_TYPE_RESERVED) && (identity_type == FPC_IDENTITY_TYPE_RESERVED) &&
(presp->identity_size <= SECURITY_MAX_SID_SIZE)) (identity_size <= SECURITY_MAX_SID_SIZE))
{ {
FpPrint *match = NULL; FpPrint *match = NULL;
FpPrint *print = NULL; FpPrint *print = NULL;
gint cnt = 0; gint cnt = 0;
fpc_fid_data_t fid_data = {0}; fpc_fid_data_t fid_data = {0};
fid_data.subfactor = presp->subfactor; fid_data.subfactor = subfactor;
fid_data.identity_type = presp->identity_type; fid_data.identity_type = identity_type;
fid_data.identity_size = presp->identity_size; fid_data.identity_size = identity_size;
memcpy (fid_data.identity, &presp->data[0],
fid_data.identity_size); if (!(fpi_byte_reader_get_data_static) (&reader, identity_size, fid_data.identity))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
match = fpc_print_from_data (self, &fid_data); match = fpc_print_from_data (self, &fid_data);
@@ -1345,7 +1478,12 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
{ {
case FPC_VERIFY_CAPTURE: case FPC_VERIFY_CAPTURE:
{ {
guint32 capture_id = GUINT32_TO_LE (FPC_CAPTUREID_RESERVED); guint8 buf[4];
FpiByteWriter writer;
fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
fpi_byte_writer_put_uint32_le (&writer, FPC_CAPTUREID_RESERVED);
fpi_device_report_finger_status_changes (device, fpi_device_report_finger_status_changes (device,
FP_FINGER_STATUS_NEEDED, FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE); FP_FINGER_STATUS_NONE);
@@ -1353,8 +1491,8 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device)
cmd_data.request = FPC_CMD_ARM; cmd_data.request = FPC_CMD_ARM;
cmd_data.value = 0x1; cmd_data.value = 0x1;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &capture_id; cmd_data.data = buf;
cmd_data.data_len = sizeof (guint32); cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_evt_cb; cmd_data.callback = fpc_evt_cb;
fpc_sensor_cmd (self, TRUE, &cmd_data); fpc_sensor_cmd (self, TRUE, &cmd_data);
@@ -1537,7 +1675,7 @@ fpc_init_load_db_cb (FpiDeviceFpcMoc *self,
void *data, void *data,
GError *error) GError *error)
{ {
FPC_LOAD_DB *presp = NULL; FpiByteReader reader;
if (error) if (error)
{ {
@@ -1552,58 +1690,82 @@ fpc_init_load_db_cb (FpiDeviceFpcMoc *self,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return; return;
} }
presp = (FPC_LOAD_DB *) data;
presp->status = GINT32_FROM_LE (presp->status); fpi_byte_reader_init (&reader, data, sizeof (FPC_LOAD_DB));
presp->database_id_size = GUINT32_FROM_LE (presp->database_id_size);
if (presp->status)
{ {
fp_err ("%s Load DB failed: %d - Expect to create a new one", G_STRFUNC, presp->status); gint32 status;
guint32 database_id_size;
const guint8 *db_data;
if (!fpi_byte_reader_get_int32_le (&reader, &status) ||
!fpi_byte_reader_skip (&reader, 4) ||
!fpi_byte_reader_get_uint32_le (&reader, &database_id_size) ||
!fpi_byte_reader_get_data (&reader, FPC_DB_ID_LEN, &db_data))
{
fpi_ssm_mark_failed (self->task_ssm,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
if (status)
{
fp_err ("%s Load DB failed: %d - Expect to create a new one", G_STRFUNC, status);
fpi_ssm_next_state (self->task_ssm); fpi_ssm_next_state (self->task_ssm);
return; return;
} }
g_clear_pointer (&self->dbid, g_free); g_clear_pointer (&self->dbid, g_free);
self->dbid = g_memdup2 (presp->data, FPC_DB_ID_LEN); self->dbid = g_memdup2 (db_data, FPC_DB_ID_LEN);
if (self->dbid == NULL) if (self->dbid == NULL)
{ {
fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
return; return;
} }
fp_dbg ("%s got dbid size: %d", G_STRFUNC, presp->database_id_size); fp_dbg ("%s got dbid size: %d", G_STRFUNC, database_id_size);
fp_dbg ("%s dbid: 0x%02x%02x%02x%02x-%02x%02x-%02x%02x-" \ fp_dbg ("%s dbid: 0x%02x%02x%02x%02x-%02x%02x-%02x%02x-" \
"%02x%02x-%02x%02x%02x%02x%02x%02x", "%02x%02x-%02x%02x%02x%02x%02x%02x",
G_STRFUNC, G_STRFUNC,
presp->data[0], presp->data[1], db_data[0], db_data[1],
presp->data[2], presp->data[3], db_data[2], db_data[3],
presp->data[4], presp->data[5], db_data[4], db_data[5],
presp->data[6], presp->data[7], db_data[6], db_data[7],
presp->data[8], presp->data[9], db_data[8], db_data[9],
presp->data[10], presp->data[11], db_data[10], db_data[11],
presp->data[12], presp->data[13], db_data[12], db_data[13],
presp->data[14], presp->data[15]); db_data[14], db_data[15]);
fpi_ssm_mark_completed (self->task_ssm); fpi_ssm_mark_completed (self->task_ssm);
}
} }
static void static void
fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device) fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device)
{ {
FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device); FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
guint32 session_id = GUINT32_TO_LE (FPC_SESSIONID_RESERVED);
CommandData cmd_data = {0}; CommandData cmd_data = {0};
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
case FPC_INIT: case FPC_INIT:
{
guint8 buf[4];
FpiByteWriter writer;
fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
fpi_byte_writer_put_uint32_le (&writer, FPC_SESSIONID_RESERVED);
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA; cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
cmd_data.request = FPC_CMD_INIT; cmd_data.request = FPC_CMD_INIT;
cmd_data.value = 0x1; cmd_data.value = 0x1;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &session_id; cmd_data.data = buf;
cmd_data.data_len = sizeof (session_id); cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_evt_cb; cmd_data.callback = fpc_evt_cb;
fpc_sensor_cmd (self, FALSE, &cmd_data); fpc_sensor_cmd (self, FALSE, &cmd_data);
}
break; break;
case FPC_INIT_LOAD_DB: case FPC_INIT_LOAD_DB:
@@ -1793,31 +1955,24 @@ fpc_dev_template_list (FpDevice *device)
{ {
FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device); FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device);
CommandData cmd_data = {0}; CommandData cmd_data = {0};
FPC_FID_DATA pquery_data = {0}; guint8 buf[sizeof (FPC_FID_DATA)] = {0};
gsize query_data_len = 0; FpiByteWriter writer;
guint32 wildcard_value = GUINT32_TO_LE (FPC_IDENTITY_WILDCARD);
fp_dbg ("%s enter -->", G_STRFUNC); fp_dbg ("%s enter -->", G_STRFUNC);
query_data_len = sizeof (FPC_FID_DATA); fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
pquery_data.identity_type = FPC_IDENTITY_TYPE_WILDCARD; fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD);
pquery_data.reserved = 16; fpi_byte_writer_put_uint32_le (&writer, 16);
pquery_data.identity_size = sizeof (wildcard_value); fpi_byte_writer_put_uint32_le (&writer, sizeof (guint32));
pquery_data.subfactor = (guint32) FPC_SUBTYPE_ANY; fpi_byte_writer_put_uint32_le (&writer, FPC_SUBTYPE_ANY);
memcpy (&pquery_data.data[0], fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_WILDCARD);
&wildcard_value, pquery_data.identity_size);
pquery_data.identity_type = GUINT32_TO_LE (pquery_data.identity_type);
pquery_data.reserved = GUINT32_TO_LE (pquery_data.reserved);
pquery_data.identity_size = GUINT32_TO_LE (pquery_data.identity_size);
pquery_data.subfactor = GUINT32_TO_LE (pquery_data.subfactor);
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA; cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA;
cmd_data.request = FPC_CMD_ENUM; cmd_data.request = FPC_CMD_ENUM;
cmd_data.value = 0x0; cmd_data.value = 0x0;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &pquery_data; cmd_data.data = buf;
cmd_data.data_len = query_data_len; cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_template_list_cb; cmd_data.callback = fpc_template_list_cb;
fpc_sensor_cmd (self, FALSE, &cmd_data); fpc_sensor_cmd (self, FALSE, &cmd_data);
@@ -1885,8 +2040,8 @@ fpc_dev_template_delete (FpDevice *device)
FpPrint *print = NULL; FpPrint *print = NULL;
g_autoptr(GVariant) fpi_data = NULL; g_autoptr(GVariant) fpi_data = NULL;
FPC_FID_DATA data = {0}; guint8 buf[sizeof (FPC_FID_DATA)] = {0};
gsize data_len = 0; FpiByteWriter writer;
guint8 finger = FPC_SUBTYPE_NOINFORMATION; guint8 finger = FPC_SUBTYPE_NOINFORMATION;
const guint8 *user_id; const guint8 *user_id;
gsize user_id_len = 0; gsize user_id_len = 0;
@@ -1904,24 +2059,19 @@ fpc_dev_template_delete (FpDevice *device)
return; return;
} }
data_len = sizeof (FPC_FID_DATA); fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE);
data.identity_type = FPC_IDENTITY_TYPE_RESERVED; fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED);
data.reserved = 16; fpi_byte_writer_put_uint32_le (&writer, 16);
data.identity_size = user_id_len; fpi_byte_writer_put_uint32_le (&writer, user_id_len);
data.subfactor = (guint32) finger; fpi_byte_writer_put_uint32_le (&writer, (guint32) finger);
memcpy (&data.data[0], user_id, user_id_len); fpi_byte_writer_put_data (&writer, user_id, user_id_len);
data.identity_type = GUINT32_TO_LE (data.identity_type);
data.reserved = GUINT32_TO_LE (data.reserved);
data.identity_size = GUINT32_TO_LE (data.identity_size);
data.subfactor = GUINT32_TO_LE (data.subfactor);
cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE; cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE;
cmd_data.request = FPC_CMD_DELETE_TEMPLATE; cmd_data.request = FPC_CMD_DELETE_TEMPLATE;
cmd_data.value = 0x0; cmd_data.value = 0x0;
cmd_data.index = 0x0; cmd_data.index = 0x0;
cmd_data.data = (guint8 *) &data; cmd_data.data = buf;
cmd_data.data_len = data_len; cmd_data.data_len = sizeof (buf);
cmd_data.callback = fpc_template_delete_cb; cmd_data.callback = fpc_template_delete_cb;
fpc_sensor_cmd (self, FALSE, &cmd_data); fpc_sensor_cmd (self, FALSE, &cmd_data);