libfprint/libfprint/drivers/vfs301.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

272 lines
6.8 KiB
C
Raw Normal View History

/*
* vfs301/vfs300 fingerprint reader driver
* https://github.com/andree182/vfs301
*
* Copyright (c) 2011-2012 Andrej Krutak <dev@andree.sk>
*
* 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
*/
#define FP_COMPONENT "vfs301"
#include "drivers_api.h"
#include "vfs301.h"
G_DEFINE_TYPE (FpDeviceVfs301, fpi_device_vfs301, FP_TYPE_IMAGE_DEVICE)
/************************** GENERIC STUFF *************************************/
static int
submit_image (FpiSsm *ssm,
FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
int height;
FpImage *img;
#if 0
/* XXX: This is probably handled by libfprint automagically? */
if (vdev->scanline_count < 20)
{
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
return 0;
}
#endif
img = fp_image_new (VFS301_FP_OUTPUT_WIDTH, self->scanline_count);
if (img == NULL)
return 0;
vfs301_extract_image (self, img->data, &height);
/* TODO: how to detect flip? should the resulting image be
* oriented so that it is equal e.g. to a fingerprint on a paper,
* or to the finger when I look at it?) */
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
/* The image buffer is larger at this point, but that does not
* matter. */
img->width = VFS301_FP_OUTPUT_WIDTH;
img->height = height;
fpi_image_device_image_captured (dev, img);
return 1;
}
/* Loop ssm states */
enum {
/* Step 0 - Scan finger */
M_REQUEST_PRINT,
M_WAIT_PRINT,
M_CHECK_PRINT,
M_READ_PRINT_START,
M_READ_PRINT_WAIT,
M_READ_PRINT_POLL,
M_SUBMIT_PRINT,
2019-11-19 20:13:11 +00:00
/* Number of states */
M_LOOP_NUM_STATES,
};
/* Exec loop sequential state machine */
static void
m_loop_state (FpiSsm *ssm, FpDevice *_dev)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
2019-11-19 20:13:11 +00:00
switch (fpi_ssm_get_cur_state (ssm))
{
case M_REQUEST_PRINT:
vfs301_proto_request_fingerprint (self);
fpi_ssm_next_state (ssm);
break;
2019-11-19 20:13:11 +00:00
case M_WAIT_PRINT:
/* Wait fingerprint scanning */
fpi_ssm_next_state_delayed (ssm, 200);
break;
2019-11-19 20:13:11 +00:00
case M_CHECK_PRINT:
if (!vfs301_proto_peek_event (self))
fpi_ssm_jump_to_state (ssm, M_WAIT_PRINT);
else
fpi_ssm_next_state (ssm);
break;
2019-11-19 20:13:11 +00:00
case M_READ_PRINT_START:
fpi_image_device_report_finger_status (dev, TRUE);
vfs301_proto_process_event_start (self);
fpi_ssm_next_state (ssm);
break;
2019-11-19 20:13:11 +00:00
case M_READ_PRINT_WAIT:
/* Wait fingerprint scanning */
fpi_ssm_next_state_delayed (ssm, 200);
break;
2019-11-19 20:13:11 +00:00
case M_READ_PRINT_POLL:
{
int rv = vfs301_proto_process_event_poll (self);
g_assert (rv != VFS301_FAILURE);
if (rv == VFS301_ONGOING)
fpi_ssm_jump_to_state (ssm, M_READ_PRINT_WAIT);
else
fpi_ssm_next_state (ssm);
}
break;
2019-11-19 20:13:11 +00:00
case M_SUBMIT_PRINT:
if (submit_image (ssm, dev))
{
fpi_ssm_mark_completed (ssm);
/* NOTE: finger off is expected only after submitting image... */
fpi_image_device_report_finger_status (dev, FALSE);
}
else
{
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
}
break;
2019-11-19 20:13:11 +00:00
default:
g_assert_not_reached ();
}
}
/* Exec init sequential state machine */
static void
m_init_state (FpiSsm *ssm, FpDevice *_dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
g_assert (fpi_ssm_get_cur_state (ssm) == 0);
vfs301_proto_init (self);
fpi_ssm_mark_completed (ssm);
}
/* Complete init sequential state machine */
static void
m_init_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
{
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
}
/* Activate device */
static void
dev_activate (FpImageDevice *dev)
{
FpiSsm *ssm;
/* Start init ssm */
ssm = fpi_ssm_new (FP_DEVICE (dev), m_init_state, 1);
fpi_ssm_start (ssm, m_init_complete);
}
/* Deactivate device */
static void
dev_deactivate (FpImageDevice *dev)
{
FpDeviceVfs301 *self;
self = FPI_DEVICE_VFS301 (dev);
vfs301_proto_deinit (self);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
{
FpiSsm *ssm_loop;
if (state != FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
return;
/* Start a capture operation. */
ssm_loop = fpi_ssm_new (FP_DEVICE (dev), m_loop_state, M_LOOP_NUM_STATES);
fpi_ssm_start (ssm_loop, NULL);
}
static void
dev_open (FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
GError *error = NULL;
/* Claim usb interface */
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
/* Initialize private structure */
self->scanline_count = 0;
/* Notify open complete */
fpi_image_device_open_complete (dev, error);
}
static void
dev_close (FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
GError *error = NULL;
2018-05-28 14:06:02 +00:00
/* Release private structure */
g_clear_pointer (&self->scanline_buf, g_free);
/* Release usb interface */
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
/* Notify close complete */
fpi_image_device_close_complete (dev, error);
}
/* Usb id table of device */
static const FpIdEntry id_table[] = {
{ /* vfs301 */ .vid = 0x138a, .pid = 0x0005, },
{ /* vfs300 */ .vid = 0x138a, .pid = 0x0008, },
{ .vid = 0, .pid = 0, .driver_data = 0 },
};
static void
fpi_device_vfs301_init (FpDeviceVfs301 *self)
{
}
static void
fpi_device_vfs301_class_init (FpDeviceVfs301Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
dev_class->id = "vfs301";
dev_class->full_name = "Validity VFS301";
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->id_table = id_table;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->img_open = dev_open;
img_class->img_close = dev_close;
img_class->activate = dev_activate;
img_class->deactivate = dev_deactivate;
img_class->change_state = dev_change_state;
img_class->bz3_threshold = 24;
img_class->img_width = VFS301_FP_WIDTH;
img_class->img_height = -1;
}