From 050476e1ba7e69925551c5b7d68e43093270976e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 1 Jul 2026 15:31:37 +0200 Subject: [PATCH] fpcmoc: Use fpi-byte-{reader,writer} to parse/build the device data In this way we have not endianness limitations --- libfprint/drivers/fpcmoc/fpc.c | 640 ++++++++++++++++++++------------- 1 file changed, 395 insertions(+), 245 deletions(-) diff --git a/libfprint/drivers/fpcmoc/fpc.c b/libfprint/drivers/fpcmoc/fpc.c index 314f857b..42954908 100644 --- a/libfprint/drivers/fpcmoc/fpc.c +++ b/libfprint/drivers/fpcmoc/fpc.c @@ -18,6 +18,7 @@ #include "drivers_api.h" #include "fpc.h" +#include "fpi-byte-writer.h" #define FP_COMPONENT "fpcmoc" #define MAX_ENROLL_SAMPLES (25) @@ -59,6 +60,7 @@ typedef struct guint16 index; guint8 *data; gsize data_len; + gsize resp_len; SynCmdMsgCallback callback; } 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 fpc_cmd_receive_cb (FpiUsbTransfer *transfer, FpDevice *device, @@ -190,7 +164,6 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer, 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); if (transfer->actual_length == 0) { @@ -200,11 +173,10 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer, return; } - memcpy (&evt_data, transfer->buffer, transfer->actual_length); - fpc_evt_data_from_le (&evt_data); + data->resp_len = transfer->actual_length; if (data->callback) - data->callback (self, (guint8 *) &evt_data, NULL); + data->callback (self, transfer->buffer, NULL); fpi_ssm_mark_completed (transfer->ssm); return; @@ -220,6 +192,8 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer, return; } + data->resp_len = transfer->actual_length; + if (data->callback) data->callback (self, transfer->buffer, NULL); @@ -447,7 +421,10 @@ fpc_evt_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - pfpc_cmd_response_t presp = NULL; + FpiByteReader reader; + guint32 cmdid; + guint32 evt_length; + guint32 evt_status; if (!check_data (data, &error)) { @@ -456,36 +433,82 @@ fpc_evt_cb (FpiDeviceFpcMoc *self, 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: - fp_dbg ("%s Enum Fids: status = %d, NumFids = %d", G_STRFUNC, - presp->evt_enum_fids.status, presp->evt_enum_fids.num_ids); - if (presp->evt_enum_fids.status || (presp->evt_enum_fids.num_ids > FPC_TEMPLATES_MAX)) - { - fpi_ssm_mark_failed (self->task_ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, - "Get Fids failed")); - return; - } + { + 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, + enum_status, num_ids); + if (enum_status || (num_ids > FPC_TEMPLATES_MAX)) + { + fpi_ssm_mark_failed (self->task_ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, + "Get Fids failed")); + return; + } + } break; 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, - presp->evt_inited.hw_id, presp->evt_inited.img_w, presp->evt_inited.img_h); + { + guint16 sensor; + 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; 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), FP_FINGER_STATUS_PRESENT, FP_FINGER_STATUS_NONE); - if (presp->evt_hdr.status != 0) + if (evt_status != 0) { /* Redo the current task state if capture failed */ 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: fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, - "Unknown Evt (0x%x)!", presp->evt_hdr.cmdid)); + "Unknown Evt (0x%x)!", cmdid)); return; } @@ -633,7 +656,10 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self, { g_autoptr(GPtrArray) list_result = NULL; FpDevice *device = FP_DEVICE (self); - pfpc_cmd_response_t presp = NULL; + FpiByteReader reader; + guint32 cmdid; + guint32 evt_length; + guint32 evt_status; if (error) { @@ -650,54 +676,105 @@ fpc_template_list_cb (FpiDeviceFpcMoc *self, return; } - presp = (pfpc_cmd_response_t) data; - if (presp->evt_hdr.cmdid != FPC_EVT_FID_DATA) + fpi_byte_reader_init (&reader, data, EP_IN_MAX_BUF_SIZE); + + 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), NULL, fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, "Recv evt is incorrect: 0x%x", - presp->evt_hdr.cmdid)); + cmdid)); return; } - if (presp->evt_enum_fids.num_ids > FPC_TEMPLATES_MAX) - { - fpi_device_list_complete (FP_DEVICE (self), - NULL, - fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL, - "Database is full")); - return; - } + { + gint enum_status; + guint32 num_ids; - list_result = g_ptr_array_new_with_free_func (g_object_unref); + 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 (presp->evt_enum_fids.num_ids == 0) - { - fp_info ("Database is empty"); - fpi_device_list_complete (device, - g_steal_pointer (&list_result), - NULL); - return; - } + if (num_ids > FPC_TEMPLATES_MAX) + { + fpi_device_list_complete (FP_DEVICE (self), + NULL, + fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_FULL, + "Database is full")); + return; + } - for (int n = 0; n < presp->evt_enum_fids.num_ids; n++) - { - FpPrint *print = NULL; - fpc_fid_data_t *fid_data = &presp->evt_enum_fids.fid_data[n]; + list_result = g_ptr_array_new_with_free_func (g_object_unref); - if ((fid_data->subfactor != FPC_SUBTYPE_RESERVED) && - (fid_data->identity_type != FPC_IDENTITY_TYPE_RESERVED)) - { - fp_info ("Incompatible template found (0x%x, 0x%x)", - fid_data->subfactor, fid_data->identity_type); - continue; - } + if (num_ids == 0) + { + fp_info ("Database is empty"); + fpi_device_list_complete (device, + g_steal_pointer (&list_result), + NULL); + return; + } - print = fpc_print_from_data (self, fid_data); + for (guint32 n = 0; n < num_ids; n++) + { + FpPrint *print = NULL; + fpc_fid_data_t fid_data = {0}; + guint8 subfactor; + guint32 identity_type; + guint32 identity_size; - g_ptr_array_add (list_result, g_object_ref_sink (print)); - } + if (!fpi_byte_reader_get_uint8 (&reader, &subfactor) || + !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)", + subfactor, identity_type); + fpi_byte_reader_skip (&reader, SECURITY_MAX_SID_SIZE); + continue; + } + + 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)); + } + } fp_info ("Query templates complete!"); fpi_device_list_complete (device, @@ -716,7 +793,8 @@ fpc_enroll_create_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - FPC_BEGIN_ENROL *presp = NULL; + FpiByteReader reader; + gint32 status; if (!check_data (data, &error)) { @@ -725,13 +803,20 @@ fpc_enroll_create_cb (FpiDeviceFpcMoc *self, return; } - presp = (FPC_BEGIN_ENROL *) data; - presp->status = GINT32_FROM_LE (presp->status); - if (presp->status != 0) + fpi_byte_reader_init (&reader, data, sizeof (FPC_BEGIN_ENROL)); + + 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, "End Enroll failed: %d", - presp->status); + status); } if (error) @@ -752,7 +837,9 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - FPC_ENROL *presp = NULL; + FpiByteReader reader; + gint32 status; + guint32 remaining; if (!check_data (data, &error)) { @@ -761,11 +848,18 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self, return; } - presp = (FPC_ENROL *) data; - presp->status = GINT32_FROM_LE (presp->status); - presp->remaining = GUINT32_FROM_LE (presp->remaining); - fp_dbg ("Enrol Update status: %d, remaining: %d", presp->status, presp->remaining); - switch (presp->status) + fpi_byte_reader_init (&reader, data, sizeof (FPC_ENROL)); + + if (!fpi_byte_reader_get_int32_le (&reader, &status) || + !fpi_byte_reader_get_uint32_le (&reader, &remaining)) + { + 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: error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL); @@ -835,10 +929,10 @@ fpc_enroll_update_cb (FpiDeviceFpcMoc *self, break; 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, "Enroll failed: %d", - presp->status); + status); break; } @@ -859,25 +953,34 @@ fpc_enroll_complete_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - FPC_END_ENROL *presp = NULL; + FpiByteReader reader; + gint32 status; + guint32 fid; self->do_cleanup = FALSE; if (check_data (data, &error)) { - presp = (FPC_END_ENROL *) data; - presp->status = GINT32_FROM_LE (presp->status); - presp->fid = GUINT32_FROM_LE (presp->fid); - if (presp->status != 0) + fpi_byte_reader_init (&reader, data, sizeof (FPC_END_ENROL)); + + if (!fpi_byte_reader_get_int32_le (&reader, &status) || + !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, "End Enroll failed: %d", - presp->status); + status); } else { 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, GError *error) { - FPC_IDENTIFY *presp = NULL; + FpiByteReader reader; if (check_data (data, &error)) { - presp = (FPC_IDENTIFY *) data; - presp->status = GINT32_FROM_LE (presp->status); - presp->identity_type = GUINT32_FROM_LE (presp->identity_type); - presp->identity_size = GUINT32_FROM_LE (presp->identity_size); - presp->subfactor = GUINT32_FROM_LE (presp->subfactor); - if ((presp->status == 0) && (presp->subfactor == FPC_SUBTYPE_RESERVED) && - (presp->identity_type == FPC_IDENTITY_TYPE_RESERVED) && - (presp->identity_size <= SECURITY_MAX_SID_SIZE)) + gint32 status; + guint32 identity_type; + guint32 identity_size; + guint32 subfactor; + + fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY)); + + 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); error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_DUPLICATE); @@ -949,17 +1065,25 @@ fpc_enroll_commit_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - gint32 *result = NULL; - if (check_data (data, &error)) { - result = (gint32 *) data; - *result = GINT32_FROM_LE (*result); - if (*result != 0) + FpiByteReader reader; + gint32 result; + + 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, "Save DB failed: %d", - *result); + result); } } @@ -987,28 +1111,22 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) { case FPC_ENROLL_ENUM: { - FPC_FID_DATA pquery_data = {0}; - gsize query_data_len = 0; - 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); + guint8 buf[sizeof (FPC_FID_DATA)] = {0}; + FpiByteWriter writer; - 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); + fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE); + fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD); + fpi_byte_writer_put_uint32_le (&writer, 16); + 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.request = FPC_CMD_ENUM; cmd_data.value = 0x0; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &pquery_data; - cmd_data.data_len = query_data_len; + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_evt_cb; fpc_sensor_cmd (self, FALSE, &cmd_data); @@ -1032,7 +1150,12 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) 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, FP_FINGER_STATUS_NEEDED, 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.value = 0x1; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &capture_id; - cmd_data.data_len = sizeof (guint32); + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_evt_cb; fpc_sensor_cmd (self, TRUE, &cmd_data); @@ -1109,15 +1232,14 @@ fpc_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) case FPC_ENROLL_BINDID: { - FPC_FID_DATA data = {0}; - gsize data_len = 0; + guint8 buf[sizeof (FPC_FID_DATA)] = {0}; + FpiByteWriter writer; FpPrint *print = NULL; GVariant *fpi_data = NULL; GVariant *uid = NULL; guint finger = FPC_SUBTYPE_RESERVED; g_autofree gchar *user_id = NULL; gssize user_id_len; - g_autofree guint8 *payload = NULL; 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); - data_len = sizeof (FPC_FID_DATA); - data.identity_type = FPC_IDENTITY_TYPE_RESERVED; - data.reserved = 16; - data.identity_size = user_id_len; - data.subfactor = (guint32) finger; - memcpy (&data.data[0], - 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); + fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE); + fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED); + fpi_byte_writer_put_uint32_le (&writer, 16); + fpi_byte_writer_put_uint32_le (&writer, user_id_len); + fpi_byte_writer_put_uint32_le (&writer, finger); + fpi_byte_writer_put_data (&writer, (const guint8 *) user_id, user_id_len); cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE; cmd_data.request = FPC_CMD_BIND_IDENTITY; cmd_data.value = 0x0; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &data; - cmd_data.data_len = data_len; + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_enroll_bindid_cb; fpc_sensor_cmd (self, FALSE, &cmd_data); @@ -1252,7 +1368,11 @@ fpc_verify_cb (FpiDeviceFpcMoc *self, FpDevice *device = FP_DEVICE (self); gboolean found = FALSE; FpiDeviceAction current_action; - FPC_IDENTIFY *presp = NULL; + FpiByteReader reader; + gint32 status; + guint32 identity_type; + guint32 identity_size; + guint32 subfactor; if (!check_data (data, &error)) { @@ -1261,30 +1381,43 @@ fpc_verify_cb (FpiDeviceFpcMoc *self, return; } - presp = (FPC_IDENTIFY *) data; - presp->status = GINT32_FROM_LE (presp->status); - presp->identity_type = GUINT32_FROM_LE (presp->identity_type); - presp->identity_size = GUINT32_FROM_LE (presp->identity_size); - presp->subfactor = GUINT32_FROM_LE (presp->subfactor); + fpi_byte_reader_init (&reader, data, sizeof (FPC_IDENTIFY)); + + 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; + } + current_action = fpi_device_get_current_action (device); g_assert (current_action == FPI_DEVICE_ACTION_VERIFY || current_action == FPI_DEVICE_ACTION_IDENTIFY); - if ((presp->status == 0) && (presp->subfactor == FPC_SUBTYPE_RESERVED) && - (presp->identity_type == FPC_IDENTITY_TYPE_RESERVED) && - (presp->identity_size <= SECURITY_MAX_SID_SIZE)) + if ((status == 0) && (subfactor == FPC_SUBTYPE_RESERVED) && + (identity_type == FPC_IDENTITY_TYPE_RESERVED) && + (identity_size <= SECURITY_MAX_SID_SIZE)) { FpPrint *match = NULL; FpPrint *print = NULL; gint cnt = 0; fpc_fid_data_t fid_data = {0}; - fid_data.subfactor = presp->subfactor; - fid_data.identity_type = presp->identity_type; - fid_data.identity_size = presp->identity_size; - memcpy (fid_data.identity, &presp->data[0], - fid_data.identity_size); + fid_data.subfactor = subfactor; + fid_data.identity_type = identity_type; + fid_data.identity_size = 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); @@ -1345,7 +1478,12 @@ fpc_verify_sm_run_state (FpiSsm *ssm, FpDevice *device) { 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, FP_FINGER_STATUS_NEEDED, 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.value = 0x1; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &capture_id; - cmd_data.data_len = sizeof (guint32); + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_evt_cb; fpc_sensor_cmd (self, TRUE, &cmd_data); @@ -1537,7 +1675,7 @@ fpc_init_load_db_cb (FpiDeviceFpcMoc *self, void *data, GError *error) { - FPC_LOAD_DB *presp = NULL; + FpiByteReader reader; if (error) { @@ -1552,58 +1690,82 @@ fpc_init_load_db_cb (FpiDeviceFpcMoc *self, fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID)); return; } - presp = (FPC_LOAD_DB *) data; - presp->status = GINT32_FROM_LE (presp->status); - 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); - fpi_ssm_next_state (self->task_ssm); - return; - } - g_clear_pointer (&self->dbid, g_free); - self->dbid = g_memdup2 (presp->data, FPC_DB_ID_LEN); - if (self->dbid == NULL) - { - fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); - return; - } + fpi_byte_reader_init (&reader, data, sizeof (FPC_LOAD_DB)); - fp_dbg ("%s got dbid size: %d", G_STRFUNC, presp->database_id_size); - fp_dbg ("%s dbid: 0x%02x%02x%02x%02x-%02x%02x-%02x%02x-" \ - "%02x%02x-%02x%02x%02x%02x%02x%02x", - G_STRFUNC, - presp->data[0], presp->data[1], - presp->data[2], presp->data[3], - presp->data[4], presp->data[5], - presp->data[6], presp->data[7], - presp->data[8], presp->data[9], - presp->data[10], presp->data[11], - presp->data[12], presp->data[13], - presp->data[14], presp->data[15]); - fpi_ssm_mark_completed (self->task_ssm); + { + 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); + return; + } + + g_clear_pointer (&self->dbid, g_free); + self->dbid = g_memdup2 (db_data, FPC_DB_ID_LEN); + if (self->dbid == NULL) + { + fpi_ssm_mark_failed (self->task_ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); + return; + } + + 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-" \ + "%02x%02x-%02x%02x%02x%02x%02x%02x", + G_STRFUNC, + db_data[0], db_data[1], + db_data[2], db_data[3], + db_data[4], db_data[5], + db_data[6], db_data[7], + db_data[8], db_data[9], + db_data[10], db_data[11], + db_data[12], db_data[13], + db_data[14], db_data[15]); + + fpi_ssm_mark_completed (self->task_ssm); + } } static void fpc_init_sm_run_state (FpiSsm *ssm, FpDevice *device) { FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device); - guint32 session_id = GUINT32_TO_LE (FPC_SESSIONID_RESERVED); CommandData cmd_data = {0}; switch (fpi_ssm_get_cur_state (ssm)) { case FPC_INIT: - cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE_EVTDATA; - cmd_data.request = FPC_CMD_INIT; - cmd_data.value = 0x1; - cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &session_id; - cmd_data.data_len = sizeof (session_id); - cmd_data.callback = fpc_evt_cb; + { + guint8 buf[4]; + FpiByteWriter writer; - fpc_sensor_cmd (self, FALSE, &cmd_data); + 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.request = FPC_CMD_INIT; + cmd_data.value = 0x1; + cmd_data.index = 0x0; + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); + cmd_data.callback = fpc_evt_cb; + + fpc_sensor_cmd (self, FALSE, &cmd_data); + } break; case FPC_INIT_LOAD_DB: @@ -1793,31 +1955,24 @@ fpc_dev_template_list (FpDevice *device) { FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (device); CommandData cmd_data = {0}; - FPC_FID_DATA pquery_data = {0}; - gsize query_data_len = 0; - guint32 wildcard_value = GUINT32_TO_LE (FPC_IDENTITY_WILDCARD); + guint8 buf[sizeof (FPC_FID_DATA)] = {0}; + FpiByteWriter writer; fp_dbg ("%s enter -->", G_STRFUNC); - 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); - 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); + fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE); + fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_WILDCARD); + fpi_byte_writer_put_uint32_le (&writer, 16); + 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.request = FPC_CMD_ENUM; cmd_data.value = 0x0; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &pquery_data; - cmd_data.data_len = query_data_len; + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_template_list_cb; fpc_sensor_cmd (self, FALSE, &cmd_data); @@ -1885,8 +2040,8 @@ fpc_dev_template_delete (FpDevice *device) FpPrint *print = NULL; g_autoptr(GVariant) fpi_data = NULL; - FPC_FID_DATA data = {0}; - gsize data_len = 0; + guint8 buf[sizeof (FPC_FID_DATA)] = {0}; + FpiByteWriter writer; guint8 finger = FPC_SUBTYPE_NOINFORMATION; const guint8 *user_id; gsize user_id_len = 0; @@ -1904,24 +2059,19 @@ fpc_dev_template_delete (FpDevice *device) return; } - data_len = sizeof (FPC_FID_DATA); - data.identity_type = FPC_IDENTITY_TYPE_RESERVED; - data.reserved = 16; - data.identity_size = user_id_len; - data.subfactor = (guint32) finger; - memcpy (&data.data[0], 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); + fpi_byte_writer_init_with_data (&writer, buf, sizeof (buf), FALSE); + fpi_byte_writer_put_uint32_le (&writer, FPC_IDENTITY_TYPE_RESERVED); + fpi_byte_writer_put_uint32_le (&writer, 16); + fpi_byte_writer_put_uint32_le (&writer, user_id_len); + fpi_byte_writer_put_uint32_le (&writer, (guint32) finger); + fpi_byte_writer_put_data (&writer, user_id, user_id_len); cmd_data.cmdtype = FPC_CMDTYPE_TO_DEVICE; cmd_data.request = FPC_CMD_DELETE_TEMPLATE; cmd_data.value = 0x0; cmd_data.index = 0x0; - cmd_data.data = (guint8 *) &data; - cmd_data.data_len = data_len; + cmd_data.data = buf; + cmd_data.data_len = sizeof (buf); cmd_data.callback = fpc_template_delete_cb; fpc_sensor_cmd (self, FALSE, &cmd_data);