working poc

This commit is contained in:
Felix 2024-12-19 11:41:34 +01:00 committed by Xelef2000
parent 4a117b45e2
commit c95ec7ff65
2 changed files with 124 additions and 83 deletions

View file

@ -170,81 +170,6 @@ crfpmoc_get_print_data(FpPrint *print, guint8 **frame, size_t *frame_size) {
static FpPrint *
crfpmoc_create_empty_frame_print (FpDevice *self, FpPrint *in_print)
{
g_return_val_if_fail(in_print != NULL, NULL);
FpPrint *out_print = fp_print_new(self); // Create a new FpPrint object
if (!out_print)
return NULL;
g_autofree gchar *descr = NULL;
GVariant *print_id_var = NULL;
GVariant *fpi_data = NULL;
GVariant *frame_var = NULL;
// Get the print data descriptor from the input print object
descr = get_print_data_descriptor(in_print, 0); // Assuming template is 0 for simplicity
if (!descr)
{
g_object_unref(out_print);
return NULL;
}
// Create a GVariant for the print ID
print_id_var = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, descr, strlen(descr), sizeof(guchar));
if (!print_id_var)
{
g_object_unref(out_print);
return NULL;
}
// Create an empty array for the frame
frame_var = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, NULL, 0, sizeof(guint8));
if (!frame_var)
{
g_object_unref(out_print);
return NULL;
}
// Combine the print ID and empty frame into a GVariant
fpi_data = g_variant_new("(@ay@ay)", print_id_var, frame_var);
if (!fpi_data)
{
g_object_unref(out_print);
return NULL;
}
// Set the properties of the new print object
fpi_print_set_type(out_print, FPI_PRINT_RAW);
g_object_set(out_print, "fpi-data", fpi_data, NULL);
return out_print;
}
// required since the downloaded frame data is encrypted and 2 downloads are not the same
// so a compare function, that ignores frame_var is required and only compares on the print_id_var
static gboolean
crfpmoc_print_equal (FpPrint *self, FpPrint *other, FpDevice *device)
{
gboolean is_equal = FALSE;
FpPrint *print1 = crfpmoc_create_empty_frame_print(device, self);
FpPrint *print2 = crfpmoc_create_empty_frame_print(device, other);
is_equal = fp_print_equal(print1, print2);
g_object_unref(print1);
g_object_unref(print2);
return is_equal;
}
static gboolean
crfpmoc_ec_command (FpiDeviceCrfpMoc *self,
int command,
@ -293,8 +218,7 @@ crfpmoc_ec_command (FpiDeviceCrfpMoc *self,
return FALSE;
}
// sleep 0.1 seconds to prevent the device from being overwhelmed
usleep(10000);
usleep(100);
return TRUE;
}
@ -390,6 +314,84 @@ crfpmoc_cmd_fp_seed (FpiDeviceCrfpMoc *self,const char* seed, GError **error)
return TRUE;
}
static gboolean
crfpmoc_fp_set_context (FpiDeviceCrfpMoc *self,
const char *context,
GError **error)
{
struct crfpmoc_ec_params_fp_context_v1 p;
gboolean rv = FALSE;
gint tries = 20; // Wait at most 2 seconds (20 * 100ms)
fp_dbg ("Setting context to '%s'", context);
// Ensure context is of the correct size
if (!context || strlen((const gchar *)context) != sizeof(p.userid)) {
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
"Context must be exactly %zu bytes.",
sizeof(p.userid));
return FALSE;
}
// Set the initial context action
p.action = CRFPMOC_FP_CONTEXT_ASYNC;
memcpy(p.userid, context, sizeof(p.userid));
// Send the initial command to set the context
rv = crfpmoc_ec_command(self,
CRFPMOC_EC_CMD_FP_CONTEXT,
1,
&p,
sizeof(p),
NULL,
0,
error);
if (!rv) {
g_prefix_error(error, "Initiating context setting failed: ");
fp_dbg("Initiating context setting failed. Error: %s", (*error)->message);
return FALSE;
}
// Poll for the result with retries
while (tries-- > 0) {
g_usleep(100000); // Sleep for 100ms
p.action = CRFPMOC_FP_CONTEXT_GET_RESULT;
rv = crfpmoc_ec_command(self,
CRFPMOC_EC_CMD_FP_CONTEXT,
1,
&p,
sizeof(p),
NULL,
0,
error);
if (rv) {
fp_dbg("Context set successfully.");
// TODO: clear error
return TRUE;
}
fp_dbg("Context setting is still in progress.");
// TODO: Only continue if the error is "EC result 16 (BUSY)"
}
// If we exhaust retries, set a timeout error
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_TIMED_OUT,
"Failed to set context: operation timed out.");
return FALSE;
}
static gboolean
crfpmoc_cmd_fp_info (FpiDeviceCrfpMoc *self, guint16 *enrolled_templates, GError **error)
{
@ -693,7 +695,6 @@ crfpmoc_open (FpDevice *device)
const char *file = fpi_device_get_udev_data (FP_DEVICE (device), FPI_DEVICE_UDEV_SUBTYPE_MISC);
GError *err = NULL;
gboolean r;
guint32 mode;
fp_dbg ("Opening device %s", file);
@ -709,10 +710,11 @@ crfpmoc_open (FpDevice *device)
fpi_device_open_complete (device, err);
return;
}
self->fd = fd;
r = crfmoc_cmd_fp_enshure_seed (self, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &err);
r = crfmoc_cmd_fp_enshure_seed (self, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb", &err);
if (!r)
{
g_clear_error (&err);
@ -720,9 +722,16 @@ crfpmoc_open (FpDevice *device)
fpi_device_open_complete (device, err);
}
usleep(1000);
usleep(200);
r = crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_RESET_SENSOR, &mode, &err);
// clear any already uploaded prints
// not needed with set context
// guint32 mode;
// r = crfpmoc_cmd_fp_mode (self, CRFPMOC_FP_MODE_RESET_SENSOR, &mode, &err);
// set user context
// crfpmoc_fp_set_context (self, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &err);
@ -896,9 +905,16 @@ static void
crfpmoc_enroll (FpDevice *device)
{
fp_dbg ("Enroll");
GError *error = NULL;
FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device);
EnrollPrint *enroll_print = g_new0 (EnrollPrint, 1);
crfpmoc_fp_set_context (self, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &error);
// TODO: check if successful
fpi_device_get_enroll_data (device, &enroll_print->print);
enroll_print->stage = 0;
@ -926,7 +942,10 @@ crfpmoc_verify_run_state (FpiSsm *ssm, FpDevice *device)
switch (fpi_ssm_get_cur_state (ssm))
{
case VERIFY_SENSOR_MATCH:
usleep(1000);
usleep(100);
gboolean is_identify = fpi_device_get_current_action (device) == FPI_DEVICE_ACTION_IDENTIFY;
@ -1022,10 +1041,11 @@ crfpmoc_verify_run_state (FpiSsm *ssm, FpDevice *device)
if (is_identify)
{
fpi_device_get_identify_data (device, &prints);
fpi_device_identify_report (device, g_ptr_array_index (prints, template), print, NULL);
}
else
{
{
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, print, NULL);
}
}
@ -1045,6 +1065,10 @@ crfpmoc_identify_verify (FpDevice *device)
{
fp_dbg ("Identify or Verify");
FpiDeviceCrfpMoc *self = FPI_DEVICE_CRFPMOC (device);
GError *error = NULL;
crfpmoc_fp_set_context (self, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &error);
// TODO: check if successful
g_assert (self->task_ssm == NULL);
self->task_ssm = fpi_ssm_new (device, crfpmoc_verify_run_state, VERIFY_STATES);

View file

@ -189,6 +189,23 @@ struct crfpmoc_ec_params_fp_seed {
} __attribute__((packed));
/* Clear the current fingerprint user context and set a new one */
#define CRFPMOC_EC_CMD_FP_CONTEXT 0x0406
enum crfpmoc_fp_context_action {
CRFPMOC_FP_CONTEXT_ASYNC = 0,
CRFPMOC_FP_CONTEXT_GET_RESULT = 1,
};
/* Version 1 of the command is "asynchronous". */
struct crfpmoc_ec_params_fp_context_v1 {
guint8 action; /**< enum fp_context_action */
guint8 reserved[3]; /**< padding for alignment */
guint32 userid[CRFPMOC_FP_CONTEXT_USERID_WORDS];
} __attribute__((packed));
struct crfpmoc_ec_response_fp_info
{
/* Sensor identification */