From ef3519854d1a287acb8770d768b71f5f3a08e9cb Mon Sep 17 00:00:00 2001 From: Vincent Huang Date: Tue, 11 Jun 2019 10:40:38 +0200 Subject: [PATCH] lib: Add API to delete prints stored on sensors Some new fingerprint devices store the information required for matching on the sensor itself, without ever disclosing this data to the host. In this case we need to delete prints not only from local storage but also from the device storage. This commits adds the internal and external API required to do so. --- libfprint/fp_internal.h | 6 ++++ libfprint/fpi-async.c | 51 ++++++++++++++++++++++++++++++++ libfprint/fpi-async.h | 2 ++ libfprint/fpi-core.h | 1 + libfprint/fpi-dev.c | 14 +++++++++ libfprint/fpi-dev.h | 1 + libfprint/fpi-sync.c | 64 +++++++++++++++++++++++++++++++++++++++++ libfprint/fprint.h | 18 ++++++++++++ 8 files changed, 157 insertions(+) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index f90893e..6cd2906 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -77,6 +77,9 @@ enum fp_dev_state { DEV_STATE_CAPTURING, DEV_STATE_CAPTURE_DONE, DEV_STATE_CAPTURE_STOPPING, + DEV_STATE_DELETING, + DEV_STATE_DELETE_DONE, + DEV_STATE_DELETE_STOPPING, }; struct fp_dev { @@ -99,6 +102,7 @@ struct fp_dev { /* read-only to drivers */ struct fp_print_data *verify_data; + struct fp_print_data *delete_data; /* drivers should not mess with any of the below */ enum fp_dev_state state; @@ -127,6 +131,8 @@ struct fp_dev { void *capture_cb_data; fp_operation_stop_cb capture_stop_cb; void *capture_stop_cb_data; + fp_delete_cb delete_cb; + void *delete_cb_data; /* FIXME: better place to put this? */ struct fp_print_data **identify_gallery; diff --git a/libfprint/fpi-async.c b/libfprint/fpi-async.c index 5e2288c..d6ce8b0 100644 --- a/libfprint/fpi-async.c +++ b/libfprint/fpi-async.c @@ -707,3 +707,54 @@ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev, } return r; } + +/** + * fp_async_delete_finger: + * @dev: the struct #fp_dev device + * @data: data to delete. Must have been previously enrolled. + * @callback: the callback to call when data deleted. + * @user_data: user data to pass to the callback + * + * Request to delete data in sensor. + * + * Returns: 0 on success, non-zero on error + */ +API_EXPORTED int fp_async_delete_finger(struct fp_dev *dev, + struct fp_print_data *data, fp_delete_cb callback, void *user_data) +{ + struct fp_driver *drv; + int r; + + g_return_val_if_fail(dev != NULL, -ENODEV); + g_return_val_if_fail (callback != NULL, -EINVAL); + + drv = dev->drv; + + G_DEBUG_HERE(); + if (!drv->delete_finger) + return -ENOTSUP; + + dev->state = DEV_STATE_DELETING; + dev->delete_cb = callback; + dev->delete_cb_data = user_data; + dev->delete_data = data; + + r = drv->delete_finger(dev); + if (r < 0) { + dev->delete_cb = NULL; + dev->state = DEV_STATE_ERROR; + fp_err("failed to delete data, error %d", r); + } + return r; +} + +/* Drivers call this when delete done */ +void fpi_drvcb_delete_complete(struct fp_dev *dev, int status) +{ + fp_dbg("status %d", status); + BUG_ON(dev->state != DEV_STATE_DELETING); + dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_DELETE_DONE; + + if (dev->delete_cb) + dev->delete_cb(dev, status, dev->delete_cb_data); +} diff --git a/libfprint/fpi-async.h b/libfprint/fpi-async.h index cf6fa32..b17663e 100644 --- a/libfprint/fpi-async.h +++ b/libfprint/fpi-async.h @@ -36,4 +36,6 @@ void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result, struct fp_img *img); void fpi_drvcb_verify_stopped(struct fp_dev *dev); +void fpi_drvcb_delete_complete(struct fp_dev *dev, int status); + #endif diff --git a/libfprint/fpi-core.h b/libfprint/fpi-core.h index 6e4b277..f122db4 100644 --- a/libfprint/fpi-core.h +++ b/libfprint/fpi-core.h @@ -108,6 +108,7 @@ struct fp_driver { int (*identify_stop)(struct fp_dev *dev, gboolean iterating); int (*capture_start)(struct fp_dev *dev); int (*capture_stop)(struct fp_dev *dev); + int (*delete_finger)(struct fp_dev *dev); }; /** diff --git a/libfprint/fpi-dev.c b/libfprint/fpi-dev.c index 8c28fd1..16281b8 100644 --- a/libfprint/fpi-dev.c +++ b/libfprint/fpi-dev.c @@ -175,3 +175,17 @@ fpi_dev_get_verify_data(struct fp_dev *dev) { return dev->verify_data; } + +/** + * fpi_dev_get_delete_data: + * @dev: a struct #fp_dev + * + * Returns the delete data associated with @dev. + * + * Returns: a struct #fp_print_data pointer or %NULL + */ +struct fp_print_data * +fpi_dev_get_delete_data(struct fp_dev *dev) +{ + return dev->delete_data; +} diff --git a/libfprint/fpi-dev.h b/libfprint/fpi-dev.h index c43ce78..e96638e 100644 --- a/libfprint/fpi-dev.h +++ b/libfprint/fpi-dev.h @@ -45,5 +45,6 @@ int fpi_dev_get_spi_dev(struct fp_dev *dev); void fpi_dev_set_nr_enroll_stages(struct fp_dev *dev, int nr_enroll_stages); struct fp_print_data *fpi_dev_get_verify_data(struct fp_dev *dev); +struct fp_print_data *fpi_dev_get_delete_data(struct fp_dev *dev); #endif diff --git a/libfprint/fpi-sync.c b/libfprint/fpi-sync.c index e5a64f8..896ef7f 100644 --- a/libfprint/fpi-sync.c +++ b/libfprint/fpi-sync.c @@ -441,6 +441,70 @@ API_EXPORTED int fp_verify_finger(struct fp_dev *dev, return fp_verify_finger_img(dev, enrolled_print, NULL); } +struct sync_delete_data { + gboolean populated; + int result; +}; + +static void sync_delete_cb(struct fp_dev *dev, int result, void *user_data) +{ + struct sync_delete_data *ddata = user_data; + ddata->result = result; + ddata->populated = TRUE; +} + +/** + * fp_delete_finger: + * @dev: the struct #fp_dev device to perform the operation. + * @enrolled_data: the id need to delete on sensor. This id is + * returned in previously enrolled with a MIS device. + * + * Perform a delete data operation on sensor. When print data is stored on + * sensor, this function is needed when host deletes enrolled finger. + * + * Returns: negative code on error, otherwise a code from #fp_delete_result + */ + +API_EXPORTED int fp_delete_finger(struct fp_dev *dev, + struct fp_print_data *enrolled_data) +{ + struct sync_delete_data *ddata; + gboolean stopped = FALSE; + int r; + + if (!enrolled_data) { + fp_err("no print given"); + return -EINVAL; + } + + if (!fp_dev_supports_print_data(dev, enrolled_data)) { + fp_err("print is not compatible with device"); + return -EINVAL; + } + + fp_dbg("to be handled by %s", dev->drv->name); + ddata = g_malloc0(sizeof(struct sync_delete_data)); + r = fp_async_delete_finger(dev, enrolled_data, sync_delete_cb, ddata); + if (r < 0) { + fp_dbg("delete_finger error %d", r); + g_free(ddata); + return r; + } + + while (!ddata->populated) { + r = fp_handle_events(); + if (r < 0) + goto out; + } + + r = ddata->result; + fp_dbg("delete_finger result %d", r); + +out: + g_free(ddata); + return r; +} + struct sync_identify_data { gboolean populated; int result; diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 4b68e4a..1f7a06e 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -273,6 +273,9 @@ int fp_identify_finger_img(struct fp_dev *dev, int fp_identify_finger(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset); +int fp_delete_finger(struct fp_dev *dev, + struct fp_print_data *enrolled_print); + /* Data handling */ int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data) LIBFPRINT_DEPRECATED; @@ -451,6 +454,21 @@ int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_img_operati int fp_async_capture_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); +/** + * fp_delete_result: + * @FP_DELETE_COMPLETE: Delete completed successfully. + * @FP_DELETE_FAIL: Delete failed + * + */ +enum fp_delete_result { + FP_DELETE_COMPLETE = 0, + FP_DELETE_FAIL = 1, +}; + +typedef void (*fp_delete_cb)(struct fp_dev *dev, int status, void *user_data); + +int fp_async_delete_finger(struct fp_dev *dev, struct fp_print_data *data, fp_delete_cb callback, void *user_data); + #ifdef __cplusplus } #endif