Add function to delete data in sensor.
Add example test app to test delete function. Remove sync database function in Synaptics driver.
This commit is contained in:
parent
e513848871
commit
65483d51b7
13 changed files with 358 additions and 200 deletions
115
examples/delete.c
Normal file
115
examples/delete.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Example fingerprint delete finger program, which delete the right index
|
||||
* finger which has been previously enrolled to disk.
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||
{
|
||||
struct fp_dscv_dev *ddev = discovered_devs[0];
|
||||
struct fp_driver *drv;
|
||||
if (!ddev)
|
||||
return NULL;
|
||||
|
||||
drv = fp_dscv_dev_get_driver(ddev);
|
||||
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
|
||||
return ddev;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r = 1;
|
||||
struct fp_dscv_dev *ddev;
|
||||
struct fp_dscv_dev **discovered_devs;
|
||||
struct fp_dev *dev;
|
||||
struct fp_print_data *data;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
fprintf(stderr, "Could not discover devices\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ddev = discover_device(discovered_devs);
|
||||
if (!ddev) {
|
||||
fprintf(stderr, "No devices detected.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = fp_dev_open(ddev);
|
||||
fp_dscv_devs_free(discovered_devs);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Could not open device.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Opened device. Loading previously enrolled right index finger "
|
||||
"data...\n");
|
||||
|
||||
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
|
||||
fprintf(stderr, "Did you remember to enroll your right index finger "
|
||||
"first?\n");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
printf("Print loaded. delete data in sensor.\n");
|
||||
if(!fp_dev_supports_data_in_sensor(dev))
|
||||
{
|
||||
printf("This driver doesn't support to store data in sensor.\n");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
r = fp_delete_finger(dev, data);
|
||||
fp_print_data_free(data);
|
||||
if (r) {
|
||||
printf("delete finger failed with error %d :(\n", r);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sensor data deleted. now delete host data");
|
||||
r = fp_print_data_delete(dev, RIGHT_INDEX);
|
||||
if (r < 0) {
|
||||
printf("Delete sensor data successfully but delete host data failed. %d :(\n", r);
|
||||
}
|
||||
}
|
||||
|
||||
out_close:
|
||||
fp_dev_close(dev);
|
||||
out:
|
||||
fp_exit();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ]
|
||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture', 'delete' ]
|
||||
foreach example: examples
|
||||
executable(example,
|
||||
example + '.c',
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef enum syna_state
|
|||
SYNA_STATE_IDENTIFY_DELAY_RESULT ,
|
||||
SYNA_STATE_VERIFY ,
|
||||
SYNA_STATE_VERIFY_DELAY_RESULT ,
|
||||
SYNA_STATE_DELETE ,
|
||||
} syna_state_t;
|
||||
|
||||
typedef struct synaptics_dev_s
|
||||
|
@ -57,11 +58,6 @@ typedef struct synaptics_dev_s
|
|||
struct syna_enroll_resp_data enroll_resp_data;
|
||||
gboolean isFingerOnSensor;
|
||||
syna_state_t state;
|
||||
pthread_mutex_t op_mutex;
|
||||
pthread_cond_t op_cond;
|
||||
int op_finished;
|
||||
GSList* file_gslist;
|
||||
GSList* sensor_gslist;
|
||||
}synaptics_dev;
|
||||
|
||||
#endif //__synaptics_h__
|
||||
|
|
|
@ -190,9 +190,6 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
|||
return -1;
|
||||
}
|
||||
sdev->usb_config->product_id = dsc.idProduct;
|
||||
|
||||
pthread_mutex_init(&sdev->op_mutex, NULL);
|
||||
pthread_cond_init(&sdev->op_cond, NULL);
|
||||
|
||||
result = bmkt_init(&(sdev->ctx));
|
||||
if (result != BMKT_SUCCESS)
|
||||
|
@ -263,18 +260,6 @@ static void dev_exit(struct fp_dev *dev)
|
|||
}
|
||||
|
||||
bmkt_exit(sdev->ctx);
|
||||
|
||||
ret = pthread_mutex_destroy(&sdev->op_mutex);
|
||||
if (ret)
|
||||
{
|
||||
fp_err("failed to destroy mutex");
|
||||
}
|
||||
|
||||
ret = pthread_cond_destroy(&sdev->op_cond);
|
||||
if (ret)
|
||||
{
|
||||
fp_err("failed to destroy cond ");
|
||||
}
|
||||
|
||||
g_free(sdev);
|
||||
fpi_drvcb_close_complete(dev);
|
||||
|
@ -299,121 +284,6 @@ static gboolean rand_string(char *str, size_t size)
|
|||
|
||||
#define TEMPLATE_ID_SIZE 20
|
||||
|
||||
void get_file_data(struct fp_dev *dev, const char *basepath)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct dirent *dp;
|
||||
DIR *dir = opendir(basepath);
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
if(!dir)
|
||||
return;
|
||||
while( (dp = readdir(dir)) != NULL)
|
||||
{
|
||||
if(strcmp(dp->d_name, ".")!=0 && strcmp(dp->d_name,"..")!=0)
|
||||
{
|
||||
strcpy(path,basepath);
|
||||
strcat(path,"/");
|
||||
strcat(path,dp->d_name);
|
||||
fp_info("%s type is %d ",dp->d_name,dp->d_type);
|
||||
if(dp->d_type == DT_REG)
|
||||
{
|
||||
gsize length;
|
||||
gchar *contents;
|
||||
GError *err = NULL;
|
||||
struct fp_print_data *fdata;
|
||||
fp_info(" load file %s ", path);
|
||||
g_file_get_contents(path, &contents, &length, &err);
|
||||
if (err) {
|
||||
fp_err("load file failed ");
|
||||
}
|
||||
else
|
||||
{
|
||||
fdata = fp_print_data_from_data(contents, length);
|
||||
struct fp_print_data_item *item = fdata->prints->data;
|
||||
struct syna_mis_print_data *print_data =(struct syna_mis_print_data *) item -> data;
|
||||
|
||||
char *data_node=(char *)g_malloc0(strlen(print_data->user_id) + 1);
|
||||
memcpy(data_node, print_data->user_id, strlen(print_data->user_id) + 1);
|
||||
sdev->file_gslist = g_slist_append(sdev->file_gslist, data_node);
|
||||
g_free(contents);
|
||||
}
|
||||
}
|
||||
else
|
||||
get_file_data(dev, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_enrolled_users_resp(bmkt_response_t *resp, void *ctx)
|
||||
{
|
||||
|
||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
|
||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
||||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_QUERY_FAIL:
|
||||
fp_info("Failed to query enrolled users: %d", resp->result);
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
sdev->op_finished = 1;
|
||||
pthread_cond_signal(&sdev->op_cond);
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
break;
|
||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
sdev->op_finished = 1;
|
||||
pthread_cond_signal(&sdev->op_cond);
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
fp_info("Query complete!");
|
||||
break;
|
||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||
|
||||
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||
{
|
||||
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
||||
continue;
|
||||
|
||||
fp_info("![query %d of %d] template %d: status=0x%x, userId=%s, fingerId=%d",
|
||||
get_enroll_templates_resp->query_sequence,
|
||||
get_enroll_templates_resp->total_query_messages,
|
||||
n,
|
||||
get_enroll_templates_resp->templates[n].template_status,
|
||||
get_enroll_templates_resp->templates[n].user_id,
|
||||
get_enroll_templates_resp->templates[n].finger_id);
|
||||
char *data_node = (char *)g_malloc0(strlen(get_enroll_templates_resp->templates[n].user_id) + 1);
|
||||
memcpy(data_node, get_enroll_templates_resp->templates[n].user_id,
|
||||
strlen(get_enroll_templates_resp->templates[n].user_id) + 1 );
|
||||
sdev->sensor_gslist = g_slist_prepend(sdev->sensor_gslist, data_node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_sensor_data(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result;
|
||||
sdev->op_finished = 0;
|
||||
result = bmkt_get_enrolled_users(sdev->sensor, get_enrolled_users_resp, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to get enrolled users: %d", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_info("get enrolled data started.");
|
||||
}
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
if(sdev->op_finished == 0)
|
||||
{
|
||||
pthread_cond_wait(&sdev->op_cond, &sdev->op_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
}
|
||||
|
||||
static int del_enrolled_user_resp(bmkt_response_t *resp, void *ctx)
|
||||
{
|
||||
bmkt_del_user_resp_t *del_user_resp = &resp->response.del_user_resp;
|
||||
|
@ -428,84 +298,33 @@ static int del_enrolled_user_resp(bmkt_response_t *resp, void *ctx)
|
|||
break;
|
||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||
fp_info("Failed to delete enrolled user: %d", resp->result);
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
sdev->op_finished = 1;
|
||||
pthread_cond_signal(&sdev->op_cond);
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
if(sdev->state == SYNA_STATE_DELETE)
|
||||
{
|
||||
/* Return result complete when record doesn't exist, otherwise host data
|
||||
won't be deleted. */
|
||||
if(resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_COMPLETE);
|
||||
else
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_FAIL);
|
||||
}
|
||||
break;
|
||||
case BMKT_RSP_DEL_USER_FP_OK:
|
||||
fp_info("Successfully deleted enrolled user");
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
sdev->op_finished = 1;
|
||||
pthread_cond_signal(&sdev->op_cond);
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
if(sdev->state == SYNA_STATE_DELETE)
|
||||
{
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_COMPLETE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char FPRINTD_DATAPATH[]="/usr/local/var/lib/fprint";
|
||||
/*
|
||||
* Delete the data which doesn't exist in fprintd folder from sensor database,
|
||||
* otherwise, new finger may have problem to be recognized if it
|
||||
* already exists in sensor.
|
||||
*/
|
||||
void sync_database(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
int sindex, findex;
|
||||
GSList* snode;
|
||||
GSList* fnode;
|
||||
|
||||
get_file_data(dev, FPRINTD_DATAPATH);
|
||||
get_sensor_data(dev);
|
||||
|
||||
for(sindex = 0; (snode = g_slist_nth(sdev->sensor_gslist, sindex)); sindex++)
|
||||
{
|
||||
for(findex = 0; (fnode = g_slist_nth(sdev->file_gslist, findex)); findex++)
|
||||
{
|
||||
if(strlen(snode->data) == strlen(fnode->data) &&
|
||||
strncmp(snode->data, fnode->data, strlen(snode->data)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!fnode)
|
||||
{
|
||||
sdev->op_finished = 0;
|
||||
result = bmkt_delete_enrolled_user(sdev->sensor, 1, snode->data,
|
||||
strlen(snode->data), del_enrolled_user_resp, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to delete enrolled user: %d", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&sdev->op_mutex);
|
||||
if(sdev->op_finished == 0)
|
||||
{
|
||||
pthread_cond_wait(&sdev->op_cond, &sdev->op_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&sdev->op_mutex);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free(sdev->file_gslist);
|
||||
g_slist_free(sdev->sensor_gslist);
|
||||
}
|
||||
static int enroll_start(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
char userid[TEMPLATE_ID_SIZE + 1];
|
||||
|
||||
sync_database(dev);
|
||||
|
||||
fp_info("enroll_start");
|
||||
|
||||
|
@ -587,7 +406,49 @@ static int verify_response(bmkt_response_t *resp, void *ctx)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int delete_finger(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
struct fp_print_data *print = fpi_dev_get_delete_data(dev);;
|
||||
struct fp_print_data_item *item = print->prints->data;
|
||||
struct syna_mis_print_data *print_data;
|
||||
bmkt_user_id_t user;
|
||||
|
||||
if(item->length != sizeof(struct syna_mis_print_data))
|
||||
{
|
||||
fp_err("print data is incorrect !");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
print_data = (struct syna_mis_print_data *)item->data;
|
||||
|
||||
memset(&user, 0, sizeof(bmkt_user_id_t));
|
||||
memcpy(user.user_id, print_data->user_id, sizeof(print_data->user_id));
|
||||
|
||||
fp_info("delete finger !");
|
||||
|
||||
user.user_id_len = strlen(user.user_id);
|
||||
if (user.user_id_len <= 0 || user.user_id[0] == ' ')
|
||||
{
|
||||
fp_err("Invalid user name.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sdev->state = SYNA_STATE_DELETE;
|
||||
result = bmkt_delete_enrolled_user(sdev->sensor, 1, print_data->user_id,
|
||||
user.user_id_len, del_enrolled_user_resp, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to delete enrolled user: %d", result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
return -1;
|
||||
}
|
||||
static int verify_start(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
@ -658,6 +519,7 @@ struct fp_driver synaptics_driver = {
|
|||
.enroll_stop = enroll_stop,
|
||||
.verify_start = verify_start,
|
||||
.verify_stop = verify_stop,
|
||||
.delete_finger = delete_finger,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -96,6 +99,9 @@ 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;
|
||||
int __enroll_stage;
|
||||
|
@ -123,6 +129,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;
|
||||
|
|
|
@ -680,3 +680,58 @@ 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_img_operation_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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,4 +36,7 @@ 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
|
||||
|
|
|
@ -703,6 +703,21 @@ API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
|
|||
return dev->drv->identify_start != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_dev_supports_data_in_sensor:
|
||||
* @dev: the struct #fp_dev device
|
||||
*
|
||||
* Determines if a device is capable of storing print data in sensor.
|
||||
* Not all devices support this functionality.
|
||||
*
|
||||
* Returns: 1 if the device is capable of storing data in sensor, 0 otherwise.
|
||||
*/
|
||||
API_EXPORTED int fp_dev_supports_data_in_sensor(struct fp_dev *dev)
|
||||
{
|
||||
return dev->drv->delete_finger != NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fp_dev_get_img_width:
|
||||
* @dev: the struct #fp_dev device
|
||||
|
|
|
@ -87,6 +87,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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -148,3 +148,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,5 +43,7 @@ libusb_device_handle *fpi_dev_get_usb_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
|
||||
|
|
|
@ -441,6 +441,72 @@ 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;
|
||||
|
|
|
@ -267,12 +267,17 @@ int fp_verify_finger(struct fp_dev *dev,
|
|||
struct fp_print_data *enrolled_print);
|
||||
|
||||
int fp_dev_supports_identification(struct fp_dev *dev);
|
||||
int fp_dev_supports_data_in_sensor(struct fp_dev *dev);
|
||||
|
||||
int fp_identify_finger_img(struct fp_dev *dev,
|
||||
struct fp_print_data **print_gallery, size_t *match_offset,
|
||||
struct fp_img **img);
|
||||
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 +456,22 @@ 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_img_operation_cb callback, void *user_data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue