mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
19 Commits
benzea/ci-
...
benzea/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc3f622b2a | ||
|
|
5de49b33e6 | ||
|
|
81e198c034 | ||
|
|
c0895a858d | ||
|
|
5d5995f201 | ||
|
|
f71045b743 | ||
|
|
0274d0783b | ||
|
|
5c5a4f6907 | ||
|
|
5b6f5c9aad | ||
|
|
41e05b1133 | ||
|
|
579e01359b | ||
|
|
cc887c1a37 | ||
|
|
fdd2d6abf8 | ||
|
|
6bf29108a1 | ||
|
|
d0751ae06b | ||
|
|
a218a5efdd | ||
|
|
c6ae8e58a4 | ||
|
|
87c7894c28 | ||
|
|
e7ff4f705c |
@@ -207,6 +207,8 @@ fpi_print_set_type
|
||||
fpi_print_set_device_stored
|
||||
fpi_print_add_from_image
|
||||
fpi_print_bz3_match
|
||||
fpi_print_generate_user_id
|
||||
fpi_print_fill_from_user_id
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Example fingerprint enrollment program
|
||||
* Enrolls your choosen finger and saves the print to disk
|
||||
* Enrolls your chosen finger and saves the print to disk
|
||||
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*
|
||||
|
||||
@@ -733,7 +733,7 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
fp_dbg ("calibration failed");
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Callibration failed!"));
|
||||
"Calibration failed!"));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -859,21 +859,29 @@ m_capture_state (FpiSsm *ssm, FpDevice *dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
FpImage *img;
|
||||
unsigned int img_size;
|
||||
/* Remove empty parts 2 times for the 2 frames */
|
||||
process_removefpi_end (self);
|
||||
process_removefpi_end (self);
|
||||
img_size = self->fp_height * FE_WIDTH;
|
||||
img = fp_image_new (FE_WIDTH, self->fp_height);
|
||||
/* Images received are white on black, so invert it. */
|
||||
/* TODO detect sweep direction */
|
||||
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
|
||||
img->height = self->fp_height;
|
||||
process_4to8_bpp (self->fp, img_size / 2, img->data);
|
||||
fp_dbg ("Sending the raw fingerprint image (%dx%d)",
|
||||
img->width, img->height);
|
||||
fpi_image_device_image_captured (idev, img);
|
||||
|
||||
if (self->fp_height >= FE_WIDTH)
|
||||
{
|
||||
FpImage *img = fp_image_new (FE_WIDTH, self->fp_height);
|
||||
unsigned int img_size = self->fp_height * FE_WIDTH;
|
||||
|
||||
/* Images received are white on black, so invert it. */
|
||||
/* TODO detect sweep direction */
|
||||
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
|
||||
img->height = self->fp_height;
|
||||
process_4to8_bpp (self->fp, img_size / 2, img->data);
|
||||
fp_dbg ("Sending the raw fingerprint image (%dx%d)",
|
||||
img->width, img->height);
|
||||
fpi_image_device_image_captured (idev, img);
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_image_device_retry_scan (idev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
}
|
||||
|
||||
fpi_image_device_report_finger_status (idev, FALSE);
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ typedef struct bmkt_init_resp
|
||||
*/
|
||||
typedef struct bmkt_enroll_resp
|
||||
{
|
||||
int progress; /**< Shows current progress stutus [0-100] */
|
||||
int progress; /**< Shows current progress status [0-100] */
|
||||
uint8_t finger_id; /**< User's finger id [1-10] */
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
|
||||
} bmkt_enroll_resp_t;
|
||||
|
||||
@@ -35,7 +35,7 @@ static const FpIdEntry id_table[] = {
|
||||
|
||||
|
||||
static void
|
||||
cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||
cmd_receive_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device,
|
||||
gpointer user_data,
|
||||
GError *error)
|
||||
@@ -234,7 +234,7 @@ synaptics_cmd_run_state (FpiSsm *ssm,
|
||||
fpi_usb_transfer_submit (transfer,
|
||||
5000,
|
||||
NULL,
|
||||
cmd_recieve_cb,
|
||||
cmd_receive_cb,
|
||||
fpi_ssm_get_data (ssm));
|
||||
|
||||
break;
|
||||
@@ -321,7 +321,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
||||
g_assert (payload || payload_len == 0);
|
||||
|
||||
/* seq_num of 0 means a normal command, -1 means the current commands
|
||||
* sequence number should not be udpated (i.e. second async command which
|
||||
* sequence number should not be updated (i.e. second async command which
|
||||
* may only be a cancellation currently). */
|
||||
if (seq_num <= 0)
|
||||
{
|
||||
@@ -515,39 +515,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
||||
g_object_set (print, "fpi-data", data, NULL);
|
||||
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
|
||||
|
||||
/* The format has 24 bytes at the start and some dashes in the right places */
|
||||
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
|
||||
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
|
||||
{
|
||||
g_autofree gchar *copy = g_strdup (userid);
|
||||
g_autoptr(GDate) date = NULL;
|
||||
gint32 date_ymd;
|
||||
gint32 finger;
|
||||
gchar *username;
|
||||
/* Try to parse information from the string. */
|
||||
|
||||
copy[12] = '\0';
|
||||
date_ymd = g_ascii_strtod (copy + 4, NULL);
|
||||
if (date_ymd > 0)
|
||||
date = g_date_new_dmy (date_ymd % 100,
|
||||
(date_ymd / 100) % 100,
|
||||
date_ymd / 10000);
|
||||
else
|
||||
date = g_date_new ();
|
||||
|
||||
fp_print_set_enroll_date (print, date);
|
||||
|
||||
copy[14] = '\0';
|
||||
finger = g_ascii_strtoll (copy + 13, NULL, 16);
|
||||
fp_print_set_finger (print, finger);
|
||||
|
||||
/* We ignore the next chunk, it is just random data.
|
||||
* Then comes the username; nobody is the default if the metadata
|
||||
* is unknown */
|
||||
username = copy + 24;
|
||||
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
|
||||
fp_print_set_username (print, username);
|
||||
}
|
||||
fpi_print_fill_from_user_id (print, userid);
|
||||
|
||||
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
|
||||
}
|
||||
@@ -635,7 +603,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
||||
else if (resp->result == BMKT_FP_NO_MATCH)
|
||||
{
|
||||
fp_info ("Print didn't match");
|
||||
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
|
||||
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL);
|
||||
verify_complete_after_finger_removal (self);
|
||||
}
|
||||
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||
@@ -730,7 +698,7 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
|
||||
if (enroll_resp->progress < 100)
|
||||
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
|
||||
|
||||
/* Emit a retry error if there has been no discernable
|
||||
/* Emit a retry error if there has been no discernible
|
||||
* progress. Some firmware revisions report more required
|
||||
* touches. */
|
||||
if (self->enroll_stage == done_stages)
|
||||
@@ -795,8 +763,6 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
|
||||
}
|
||||
}
|
||||
|
||||
#define TEMPLATE_ID_SIZE 20
|
||||
|
||||
static void
|
||||
enroll (FpDevice *device)
|
||||
{
|
||||
@@ -804,52 +770,21 @@ enroll (FpDevice *device)
|
||||
FpPrint *print = NULL;
|
||||
GVariant *data = NULL;
|
||||
GVariant *uid = NULL;
|
||||
const gchar *username;
|
||||
guint finger;
|
||||
g_autofree gchar *user_id = NULL;
|
||||
gssize user_id_len;
|
||||
g_autofree guint8 *payload = NULL;
|
||||
const GDate *date;
|
||||
gint y, m, d;
|
||||
gint32 rand_id = 0;
|
||||
|
||||
fpi_device_get_enroll_data (device, &print);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
date = fp_print_get_enroll_date (print);
|
||||
if (date && g_date_valid (date))
|
||||
{
|
||||
y = g_date_get_year (date);
|
||||
m = g_date_get_month (date);
|
||||
d = g_date_get_day (date);
|
||||
}
|
||||
else
|
||||
{
|
||||
y = 0;
|
||||
m = 0;
|
||||
d = 0;
|
||||
}
|
||||
|
||||
username = fp_print_get_username (print);
|
||||
if (!username)
|
||||
username = "nobody";
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
rand_id = 0;
|
||||
else
|
||||
rand_id = g_random_int ();
|
||||
|
||||
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
|
||||
y, m, d,
|
||||
fp_print_get_finger (print),
|
||||
rand_id,
|
||||
username);
|
||||
user_id = fpi_print_generate_user_id (print);
|
||||
|
||||
user_id_len = strlen (user_id);
|
||||
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
|
||||
|
||||
/* We currently always use finger 1 from the devices piont of view */
|
||||
/* We currently always use finger 1 from the devices point of view */
|
||||
finger = 1;
|
||||
|
||||
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
@@ -1029,7 +964,7 @@ dev_probe (FpDevice *device)
|
||||
|
||||
if (!read_ok)
|
||||
{
|
||||
g_warning ("Transfer in response to verison query was too short");
|
||||
g_warning ("Transfer in response to version query was too short");
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
@@ -1119,7 +1119,6 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
|
||||
else
|
||||
{
|
||||
GVariant *fp_data;
|
||||
print = fp_print_new (dev);
|
||||
|
||||
fpi_device_get_enroll_data (dev, &print);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/*
|
||||
* This is a virtual driver to debug the image based drivers. A small
|
||||
* python script is provided to connect to it via a socket, allowing
|
||||
* prints to be sent to this device programatically.
|
||||
* prints to be sent to this device programmatically.
|
||||
* Using this it is possible to test libfprint and fprintd.
|
||||
*/
|
||||
|
||||
|
||||
@@ -94,22 +94,21 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
|
||||
FpContext *context;
|
||||
FpContextPrivate *priv;
|
||||
|
||||
device = (FpDevice *) g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error);
|
||||
if (!device)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
context = FP_CONTEXT (user_data);
|
||||
priv = fp_context_get_instance_private (context);
|
||||
priv->pending_devices--;
|
||||
g_message ("Ignoring device due to initialization error: %s", error->message);
|
||||
return;
|
||||
}
|
||||
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
|
||||
res, &error));
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
context = FP_CONTEXT (user_data);
|
||||
priv = fp_context_get_instance_private (context);
|
||||
priv->pending_devices--;
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_message ("Ignoring device due to initialization error: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
g_ptr_array_add (priv->devices, device);
|
||||
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* @title: Internal FpDevice
|
||||
* @short_description: Internal device routines
|
||||
*
|
||||
* The methods that are availabe for drivers to manipulate a device. See
|
||||
* The methods that are available for drivers to manipulate a device. See
|
||||
* #FpDeviceClass for more information. Also note that most of these are
|
||||
* not relevant for image based devices, see #FpImageDeviceClass in that
|
||||
* case.
|
||||
@@ -339,7 +339,7 @@ fp_device_class_init (FpDeviceClass *klass)
|
||||
properties[PROP_OPEN] =
|
||||
g_param_spec_boolean ("open",
|
||||
"Opened",
|
||||
"Wether the device is open or not", FALSE,
|
||||
"Whether the device is open or not", FALSE,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,7 +79,7 @@ typedef enum {
|
||||
|
||||
/**
|
||||
* FpDeviceError:
|
||||
* @FP_DEVICE_ERROR_GENERAL: A general error occured.
|
||||
* @FP_DEVICE_ERROR_GENERAL: A general error occurred.
|
||||
* @FP_DEVICE_ERROR_NOT_SUPPORTED: The device does not support the requested
|
||||
* operation.
|
||||
* @FP_DEVICE_ERROR_NOT_OPEN: The device needs to be opened to start this
|
||||
@@ -113,7 +113,7 @@ GQuark fp_device_error_quark (void);
|
||||
* FpEnrollProgress:
|
||||
* @device: a #FpDevice
|
||||
* @completed_stages: Number of completed stages
|
||||
* @print: (nullable) (transfer none): The last scaned print
|
||||
* @print: (nullable) (transfer none): The last scanned print
|
||||
* @user_data: (nullable) (transfer none): User provided data
|
||||
* @error: (nullable) (transfer none): #GError or %NULL
|
||||
*
|
||||
|
||||
@@ -100,7 +100,7 @@ fp_image_device_close (FpDevice *device)
|
||||
* 1. We are inactive
|
||||
* -> immediately close
|
||||
* 2. We are waiting for finger off
|
||||
* -> imediately deactivate
|
||||
* -> immediately deactivate
|
||||
* 3. We are deactivating
|
||||
* -> handled by deactivate_complete */
|
||||
|
||||
|
||||
@@ -184,10 +184,8 @@ fp_image_detect_minutiae_cb (GObject *source_object,
|
||||
GTask *task = G_TASK (res);
|
||||
FpImage *image;
|
||||
DetectMinutiaeData *data = g_task_get_task_data (task);
|
||||
GCancellable *cancellable;
|
||||
|
||||
cancellable = g_task_get_cancellable (task);
|
||||
if (!cancellable || !g_cancellable_is_cancelled (cancellable))
|
||||
if (!g_task_had_error (task))
|
||||
{
|
||||
gint i;
|
||||
image = FP_IMAGE (source_object);
|
||||
@@ -316,6 +314,14 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data->minutiae || data->minutiae->num == 0)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No minutiae found");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ enum {
|
||||
PROP_IMAGE,
|
||||
|
||||
/* The following is metadata that is stored by default for each print.
|
||||
* Drivers may make use of these during enrollment (e.g. to additionaly store
|
||||
* Drivers may make use of these during enrollment (e.g. to additionally store
|
||||
* the metadata on the device). */
|
||||
PROP_FINGER,
|
||||
PROP_USERNAME,
|
||||
@@ -588,7 +588,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
|
||||
}
|
||||
else if (self->type == FPI_PRINT_NBIS)
|
||||
{
|
||||
gint i;
|
||||
guint i;
|
||||
|
||||
if (self->prints->len != other->prints->len)
|
||||
return FALSE;
|
||||
@@ -661,7 +661,7 @@ fp_print_serialize (FpPrint *print,
|
||||
if (print->type == FPI_PRINT_NBIS)
|
||||
{
|
||||
GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))"));
|
||||
gint i;
|
||||
guint i;
|
||||
|
||||
g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)"));
|
||||
for (i = 0; i < print->prints->len; i++)
|
||||
@@ -812,7 +812,7 @@ fp_print_deserialize (const guchar *data,
|
||||
if (type == FPI_PRINT_NBIS)
|
||||
{
|
||||
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
|
||||
gint i;
|
||||
guint i;
|
||||
|
||||
result = g_object_new (FP_TYPE_PRINT,
|
||||
"driver", driver,
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* @title: Internal FpDevice
|
||||
* @short_description: Internal device routines
|
||||
*
|
||||
* The methods that are availabe for drivers to manipulate a device. See
|
||||
* The methods that are available for drivers to manipulate a device. See
|
||||
* #FpDeviceClass for more information. Also note that most of these are
|
||||
* not relevant for image based devices, see #FpImageDeviceClass in that
|
||||
* case.
|
||||
@@ -100,7 +100,7 @@ fpi_device_error_new (FpDeviceError error)
|
||||
switch (error)
|
||||
{
|
||||
case FP_DEVICE_ERROR_GENERAL:
|
||||
msg = "An unspecified error occured!";
|
||||
msg = "An unspecified error occurred!";
|
||||
break;
|
||||
|
||||
case FP_DEVICE_ERROR_NOT_SUPPORTED:
|
||||
@@ -138,7 +138,7 @@ fpi_device_error_new (FpDeviceError error)
|
||||
default:
|
||||
g_warning ("Unsupported error, returning general error instead!");
|
||||
error = FP_DEVICE_ERROR_GENERAL;
|
||||
msg = "An unspecified error occured!";
|
||||
msg = "An unspecified error occurred!";
|
||||
}
|
||||
|
||||
return g_error_new_literal (FP_DEVICE_ERROR, error, msg);
|
||||
|
||||
@@ -65,10 +65,10 @@ struct _FpIdEntry
|
||||
* @probe: Called immediately for all devices. Most drivers will not need to
|
||||
* implement this. Drivers should setup the device identifier from the probe
|
||||
* callback which will be used to verify the compatibility of stored
|
||||
* #FpPrint's. It is permissable to temporarily open the USB device if this
|
||||
* #FpPrint's. It is permissible to temporarily open the USB device if this
|
||||
* is required for the operation. If an error is returned, then the device
|
||||
* will be destroyed again immediately and never reported to the API user.
|
||||
* @open: Open the device for futher operations. Any of the normal actions are
|
||||
* @open: Open the device for further operations. Any of the normal actions are
|
||||
* guaranteed to only happen when the device is open (this includes delete).
|
||||
* @close: Close the device again
|
||||
* @enroll: Start an enroll operation
|
||||
|
||||
@@ -171,7 +171,16 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
||||
print = fp_print_new (device);
|
||||
fpi_print_set_type (print, FPI_PRINT_NBIS);
|
||||
if (!fpi_print_add_from_image (print, image, &error))
|
||||
g_clear_object (&print);
|
||||
{
|
||||
g_clear_object (&print);
|
||||
|
||||
if (error->domain != FP_DEVICE_RETRY)
|
||||
{
|
||||
fpi_device_action_error (device, error);
|
||||
fpi_image_device_deactivate (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (action == FPI_DEVICE_ACTION_ENROLL)
|
||||
|
||||
@@ -247,3 +247,115 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
|
||||
|
||||
return FPI_MATCH_FAIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_print_generate_user_id:
|
||||
* @print: #FpPrint to generate the ID for
|
||||
*
|
||||
* Generates a string identifier for the represented print. This identifier
|
||||
* encodes some metadata about the print. It also includes a random string
|
||||
* and may be assumed to be unique.
|
||||
*
|
||||
* This is useful if devices are able to store a string identifier, but more
|
||||
* storing more metadata may be desirable. In effect, this means the driver
|
||||
* can provide somewhat more meaningful data to fp_device_list_prints().
|
||||
*
|
||||
* The generated ID may be truncated after 23 characters. However, more space
|
||||
* is required to include the username, and it is recommended to store at
|
||||
* at least 31 bytes.
|
||||
*
|
||||
* The generated format may change in the future. It is versioned though and
|
||||
* decoding should remain functional.
|
||||
*
|
||||
* Returns: A unique string of 23 + strlen(username) characters
|
||||
*/
|
||||
gchar *
|
||||
fpi_print_generate_user_id (FpPrint *print)
|
||||
{
|
||||
const gchar *username = NULL;
|
||||
gchar *user_id = NULL;
|
||||
const GDate *date;
|
||||
gint y = 0, m = 0, d = 0;
|
||||
gint32 rand_id = 0;
|
||||
|
||||
g_assert (print);
|
||||
date = fp_print_get_enroll_date (print);
|
||||
if (date && g_date_valid (date))
|
||||
{
|
||||
y = g_date_get_year (date);
|
||||
m = g_date_get_month (date);
|
||||
d = g_date_get_day (date);
|
||||
}
|
||||
|
||||
username = fp_print_get_username (print);
|
||||
if (!username)
|
||||
username = "nobody";
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
rand_id = 0;
|
||||
else
|
||||
rand_id = g_random_int ();
|
||||
|
||||
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
|
||||
y, m, d,
|
||||
fp_print_get_finger (print),
|
||||
rand_id,
|
||||
username);
|
||||
|
||||
return user_id;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_print_fill_from_user_id:
|
||||
* @print: #FpPrint to fill metadata into
|
||||
* @user_id: An ID that was likely encoded using fpi_print_generate_user_id()
|
||||
*
|
||||
* This is the reverse operation of fpi_print_generate_user_id(), allowing
|
||||
* the driver to encode some print metadata in a string.
|
||||
*
|
||||
* Returns: Whether a valid ID was found
|
||||
*/
|
||||
gboolean
|
||||
fpi_print_fill_from_user_id (FpPrint *print, const char *user_id)
|
||||
{
|
||||
g_return_val_if_fail (user_id, FALSE);
|
||||
|
||||
/* The format has 24 bytes at the start and some dashes in the right places */
|
||||
if (g_str_has_prefix (user_id, "FP1-") && strlen (user_id) >= 24 &&
|
||||
user_id[12] == '-' && user_id[14] == '-' && user_id[23] == '-')
|
||||
{
|
||||
g_autofree gchar *copy = g_strdup (user_id);
|
||||
g_autoptr(GDate) date = NULL;
|
||||
gint32 date_ymd;
|
||||
gint32 finger;
|
||||
gchar *username;
|
||||
/* Try to parse information from the string. */
|
||||
|
||||
copy[12] = '\0';
|
||||
date_ymd = g_ascii_strtod (copy + 4, NULL);
|
||||
if (date_ymd > 0)
|
||||
date = g_date_new_dmy (date_ymd % 100,
|
||||
(date_ymd / 100) % 100,
|
||||
date_ymd / 10000);
|
||||
else
|
||||
date = g_date_new ();
|
||||
|
||||
fp_print_set_enroll_date (print, date);
|
||||
|
||||
copy[14] = '\0';
|
||||
finger = g_ascii_strtoll (copy + 13, NULL, 16);
|
||||
fp_print_set_finger (print, finger);
|
||||
|
||||
/* We ignore the next chunk, it is just random data.
|
||||
* Then comes the username; nobody is the default if the metadata
|
||||
* is unknown */
|
||||
username = copy + 24;
|
||||
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
|
||||
fp_print_set_username (print, username);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef enum {
|
||||
|
||||
/**
|
||||
* FpiMatchResult:
|
||||
* @FPI_MATCH_ERROR: An error occured during matching
|
||||
* @FPI_MATCH_ERROR: An error occurred during matching
|
||||
* @FPI_MATCH_FAIL: The prints did not match
|
||||
* @FPI_MATCH_SUCCESS: The prints matched
|
||||
*/
|
||||
@@ -47,4 +47,9 @@ FpiMatchResult fpi_print_bz3_match (FpPrint * template,
|
||||
gint bz3_threshold,
|
||||
GError **error);
|
||||
|
||||
/* Helpers to encode metadata into user ID strings. */
|
||||
gchar * fpi_print_generate_user_id (FpPrint *print);
|
||||
gboolean fpi_print_fill_from_user_id (FpPrint *print,
|
||||
const char *user_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -366,7 +366,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
|
||||
*
|
||||
* Note that #FpiUsbTransfer will be stolen when this function is called.
|
||||
* So that all associated data will be free'ed automatically, after the
|
||||
* callback ran unless fpi_usb_transfer_ref() is explictly called.
|
||||
* callback ran unless fpi_usb_transfer_ref() is explicitly called.
|
||||
*/
|
||||
void
|
||||
fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
|
||||
|
||||
@@ -61,7 +61,7 @@ typedef enum {
|
||||
* @length: The requested length of the transfer in bytes.
|
||||
* @actual_length: The actual length of the transfer
|
||||
* (see also fpi_usb_transfer_set_short_error())
|
||||
* @buffer: The transfered data.
|
||||
* @buffer: The transferred data.
|
||||
*
|
||||
* Helper for handling USB transfers.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
|
||||
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
||||
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
|
||||
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
|
||||
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
||||
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
|
||||
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -959,7 +959,7 @@ test_driver_verify_complete_retry (void)
|
||||
|
||||
g_test_assert_expected_messages ();
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
|
||||
g_steal_pointer (&fake_dev->user_data);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
|
||||
g_assert_true (match_data->called);
|
||||
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
@@ -981,7 +981,7 @@ test_driver_verify_complete_retry (void)
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
|
||||
g_steal_pointer (&fake_dev->user_data);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
|
||||
g_assert_true (match_data->called);
|
||||
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
@@ -1001,7 +1001,7 @@ test_driver_verify_complete_retry (void)
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
|
||||
g_steal_pointer (&fake_dev->user_data);
|
||||
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
|
||||
g_assert_true (match_data->called);
|
||||
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
|
||||
@@ -1296,7 +1296,7 @@ test_driver_identify_complete_retry (void)
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
|
||||
g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
|
||||
g_steal_pointer (&fake_dev->user_data);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
|
||||
g_assert_true (match_data->called);
|
||||
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
import sys
|
||||
try:
|
||||
import gi
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint, GLib, Gio
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from gi.repository import GLib, Gio
|
||||
|
||||
import unittest
|
||||
import socket
|
||||
import struct
|
||||
@@ -20,6 +19,8 @@ except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
FPrint = None
|
||||
|
||||
# Re-run the test with the passed wrapper if set
|
||||
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
|
||||
if wrapper:
|
||||
@@ -101,12 +102,14 @@ class VirtualImage(unittest.TestCase):
|
||||
del self.con
|
||||
self.dev.close_sync()
|
||||
|
||||
def send_retry(self, retry_error=FPrint.DeviceRetry.TOO_SHORT, iterate=True):
|
||||
def send_retry(self, retry_error=None, iterate=True):
|
||||
retry_error = retry_error if retry_error else FPrint.DeviceRetry.TOO_SHORT
|
||||
self.con.sendall(struct.pack('ii', -1, retry_error))
|
||||
while iterate and ctx.pending():
|
||||
ctx.iteration(False)
|
||||
|
||||
def send_error(self, device_error=FPrint.DeviceError.GENERAL, iterate=True):
|
||||
def send_error(self, device_error=None, iterate=True):
|
||||
device_error = device_error if device_error else FPrint.DeviceError.GENERAL
|
||||
self.con.sendall(struct.pack('ii', -2, device_error))
|
||||
while iterate and ctx.pending():
|
||||
ctx.iteration(False)
|
||||
@@ -346,5 +349,12 @@ class VirtualImage(unittest.TestCase):
|
||||
assert(not self._verify_match)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint
|
||||
except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
# avoid writing to stderr
|
||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
||||
|
||||
Reference in New Issue
Block a user