mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Public async API implementation
Involved some internal overhaul/reorganisation. Nice side effect is that the synchronous API is now expressed purely in terms of the public async API.
This commit is contained in:
268
libfprint/drv.c
268
libfprint/drv.c
@@ -19,277 +19,11 @@
|
||||
|
||||
#define FP_COMPONENT "drv"
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "fp_internal.h"
|
||||
|
||||
/* Lib-driver: start device initialisation */
|
||||
int fpi_drv_init(struct fp_dev *dev, unsigned long driver_data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
if (!drv->init) {
|
||||
fpi_drvcb_init_complete(dev, 0);
|
||||
return 0;
|
||||
}
|
||||
dev->state = DEV_STATE_INITIALIZING;
|
||||
return drv->init(dev, driver_data);
|
||||
}
|
||||
|
||||
/* Driver-lib: device initialisation complete */
|
||||
void fpi_drvcb_init_complete(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("status %d", status);
|
||||
BUG_ON(dev->state != DEV_STATE_INITIALIZING);
|
||||
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
/* Lib-driver: start device deinitialisation */
|
||||
void fpi_drv_deinit(struct fp_dev *dev)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
if (!drv->deinit) {
|
||||
fpi_drvcb_deinit_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
dev->state = DEV_STATE_DEINITIALIZING;
|
||||
drv->deinit(dev);
|
||||
}
|
||||
|
||||
/* Driver-lib: device deinitialisation complete */
|
||||
void fpi_drvcb_deinit_complete(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
|
||||
dev->state = DEV_STATE_DEINITIALIZED;
|
||||
}
|
||||
|
||||
/* Lib-driver: start enrollment */
|
||||
int fpi_drv_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
int r;
|
||||
fp_dbg("");
|
||||
if (!drv->enroll_start)
|
||||
return -ENOTSUP;
|
||||
dev->state = DEV_STATE_ENROLL_STARTING;
|
||||
dev->enroll_cb = callback;
|
||||
r = drv->enroll_start(dev);
|
||||
if (r < 0) {
|
||||
dev->enroll_cb = NULL;
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Driver-lib: enrollment has now started, expect results soon */
|
||||
void fpi_drvcb_enroll_started(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("status %d", status);
|
||||
BUG_ON(dev->state != DEV_STATE_ENROLL_STARTING);
|
||||
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_ENROLLING;
|
||||
}
|
||||
|
||||
/* Driver-lib: an enroll stage has completed */
|
||||
void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
|
||||
struct fp_print_data *data, struct fp_img *img)
|
||||
{
|
||||
BUG_ON(dev->state != DEV_STATE_ENROLLING);
|
||||
fp_dbg("result %d", result);
|
||||
if (!dev->enroll_cb) {
|
||||
fp_dbg("ignoring enroll result as no callback is subscribed");
|
||||
return;
|
||||
}
|
||||
if (result == FP_ENROLL_COMPLETE && !data) {
|
||||
fp_err("BUG: complete but no data?");
|
||||
result = FP_ENROLL_FAIL;
|
||||
}
|
||||
dev->enroll_cb(dev, result, data, img);
|
||||
}
|
||||
|
||||
/* Lib-driver: stop enrollment */
|
||||
int fpi_drv_enroll_stop(struct fp_dev *dev)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
fp_dbg("");
|
||||
dev->enroll_cb = NULL;
|
||||
|
||||
if (!drv->enroll_start)
|
||||
return -ENOTSUP;
|
||||
if (!drv->enroll_stop) {
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->state = DEV_STATE_ENROLL_STOPPING;
|
||||
return drv->enroll_stop(dev);
|
||||
}
|
||||
|
||||
/* Driver-lib: enrollment has stopped */
|
||||
void fpi_drvcb_enroll_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_ENROLL_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
/* Lib-driver: start verification */
|
||||
int fpi_drv_verify_start(struct fp_dev *dev, fp_verify_cb callback,
|
||||
struct fp_print_data *data)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
if (!drv->verify_start)
|
||||
return -ENOTSUP;
|
||||
dev->state = DEV_STATE_VERIFY_STARTING;
|
||||
dev->verify_cb = callback;
|
||||
dev->verify_data = data;
|
||||
r = drv->verify_start(dev);
|
||||
if (r < 0) {
|
||||
dev->verify_cb = NULL;
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Driver-lib: verification has started, expect results soon */
|
||||
void fpi_drvcb_verify_started(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_VERIFY_STARTING);
|
||||
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_VERIFYING;
|
||||
}
|
||||
|
||||
/* Driver-lib: report a verify result (which might mark completion) */
|
||||
void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result,
|
||||
struct fp_img *img)
|
||||
{
|
||||
fp_dbg("result %d", result);
|
||||
BUG_ON(dev->state != DEV_STATE_VERIFYING);
|
||||
if (result < 0 || result == FP_VERIFY_NO_MATCH
|
||||
|| result == FP_VERIFY_MATCH) {
|
||||
dev->state = DEV_STATE_VERIFY_DONE;
|
||||
}
|
||||
|
||||
if (!dev->verify_cb) {
|
||||
fp_dbg("ignoring verify result as no callback is subscribed");
|
||||
return;
|
||||
}
|
||||
dev->verify_cb(dev, result, img);
|
||||
}
|
||||
|
||||
/* Lib-driver: stop verification */
|
||||
int fpi_drv_verify_stop(struct fp_dev *dev)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
gboolean iterating = (dev->state == DEV_STATE_VERIFYING);
|
||||
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_ERROR
|
||||
&& dev->state != DEV_STATE_VERIFYING
|
||||
&& dev->state != DEV_STATE_VERIFY_DONE);
|
||||
dev->verify_cb = NULL;
|
||||
|
||||
if (!drv->verify_start)
|
||||
return -ENOTSUP;
|
||||
if (!drv->verify_stop) {
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->state = DEV_STATE_VERIFY_STOPPING;
|
||||
return drv->verify_stop(dev, iterating);
|
||||
}
|
||||
|
||||
/* Driver-lib: verification has stopped */
|
||||
void fpi_drvcb_verify_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_VERIFY_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
|
||||
/* Lib-driver: start identification */
|
||||
int fpi_drv_identify_start(struct fp_dev *dev, fp_identify_cb callback,
|
||||
struct fp_print_data **gallery)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
int r;
|
||||
|
||||
fp_dbg("");
|
||||
if (!drv->identify_start)
|
||||
return -ENOTSUP;
|
||||
dev->state = DEV_STATE_IDENTIFY_STARTING;
|
||||
dev->identify_cb = callback;
|
||||
dev->identify_data = gallery;
|
||||
r = drv->identify_start(dev);
|
||||
if (r < 0) {
|
||||
dev->identify_cb = NULL;
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Driver-lib: identification has started, expect results soon */
|
||||
void fpi_drvcb_identify_started(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFY_STARTING);
|
||||
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_IDENTIFYING;
|
||||
}
|
||||
|
||||
/* Driver-lib: report a verify result (which might mark completion) */
|
||||
void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
||||
size_t match_offset, struct fp_img *img)
|
||||
{
|
||||
fp_dbg("result %d", result);
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
|
||||
&& dev->state != DEV_STATE_ERROR);
|
||||
if (result < 0 || result == FP_VERIFY_NO_MATCH
|
||||
|| result == FP_VERIFY_MATCH) {
|
||||
dev->state = DEV_STATE_IDENTIFY_DONE;
|
||||
}
|
||||
|
||||
if (!dev->identify_cb) {
|
||||
fp_dbg("ignoring verify result as no callback is subscribed");
|
||||
return;
|
||||
}
|
||||
dev->identify_cb(dev, result, match_offset, img);
|
||||
}
|
||||
|
||||
/* Lib-driver: stop identification */
|
||||
int fpi_drv_identify_stop(struct fp_dev *dev)
|
||||
{
|
||||
struct fp_driver *drv = dev->drv;
|
||||
gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING);
|
||||
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
|
||||
&& dev->state != DEV_STATE_IDENTIFY_DONE);
|
||||
dev->identify_cb = NULL;
|
||||
|
||||
if (!drv->identify_start)
|
||||
return -ENOTSUP;
|
||||
if (!drv->identify_stop) {
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->state = DEV_STATE_IDENTIFY_STOPPING;
|
||||
return drv->identify_stop(dev, iterating);
|
||||
}
|
||||
|
||||
/* Driver-lib: identification has stopped */
|
||||
void fpi_drvcb_identify_stopped(struct fp_dev *dev)
|
||||
{
|
||||
fp_dbg("");
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFY_STOPPING);
|
||||
dev->state = DEV_STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
/* SSM: sequential state machine
|
||||
* Asynchronous driver design encourages some kind of state machine behind it.
|
||||
* In most cases, the state machine is entirely linear - you only go to the
|
||||
|
||||
Reference in New Issue
Block a user