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.
This commit is contained in:
Vincent Huang 2019-06-11 10:40:38 +02:00 committed by Benjamin Berg
parent 0240e0801c
commit ef3519854d
8 changed files with 157 additions and 0 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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);
};
/**

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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