mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
1 Commits
vincenth/s
...
wip/hadess
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e8deba37 |
@@ -1,64 +1,20 @@
|
|||||||
image: fedora:rawhide
|
image: fedora:rawhide
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
|
DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
|
||||||
gcc gcc-c++ glibc-devel libX11-devel libXv-devel gtk3-devel flatpak-builder
|
gcc gcc-c++ glibc-devel libX11-devel libXv-devel
|
||||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
|
||||||
|
|
||||||
.build_one_driver_template: &build_one_driver
|
|
||||||
script:
|
|
||||||
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
|
|
||||||
# Build with a driver that doesn't need imaging, or nss
|
|
||||||
- meson -Ddrivers=elan . _build
|
|
||||||
- ninja -C _build
|
|
||||||
- rm -rf _build/
|
|
||||||
|
|
||||||
.build_template: &build
|
before_script:
|
||||||
script:
|
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
|
||||||
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
|
|
||||||
# And build with everything
|
|
||||||
- meson -Ddrivers=all . _build
|
|
||||||
- ninja -C _build
|
|
||||||
- ninja -C _build install
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
stage: build
|
stage: build
|
||||||
<<: *build_one_driver
|
script:
|
||||||
<<: *build
|
- meson . _build
|
||||||
|
- ninja -C _build
|
||||||
|
- ninja -C _build install
|
||||||
|
|
||||||
.flatpak_script_template: &flatpak_script
|
|
||||||
script:
|
|
||||||
- flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH}
|
|
||||||
# Make sure to keep this in sync with the Flatpak manifest, all arguments
|
|
||||||
# are passed except the config-args because we build it ourselves
|
|
||||||
- flatpak build app meson --prefix=/app --libdir=lib ${MESON_ARGS} _build
|
|
||||||
- flatpak build app ninja -C _build install
|
|
||||||
- flatpak build app rm -rf /app/include/ /app/lib/pkgconfig/
|
|
||||||
- flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH}
|
|
||||||
# Generate a Flatpak bundle
|
|
||||||
- flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${DBUS_ID}
|
|
||||||
|
|
||||||
.flatpak_artifacts_template: &flatpak_artifacts
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- ${BUNDLE}
|
|
||||||
when: always
|
|
||||||
expire_in: 30 days
|
|
||||||
|
|
||||||
.flatpak_template: &flatpak
|
|
||||||
<<: *flatpak_script
|
|
||||||
<<: *flatpak_artifacts
|
|
||||||
|
|
||||||
flatpak master:
|
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
|
||||||
stage: test
|
|
||||||
variables:
|
|
||||||
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
|
||||||
# From demo/org.freedesktop.libfprint.Demo.json
|
|
||||||
MESON_ARGS: "-Dudev_rules=false -Dx11-examples=false -Dgtk-examples=true"
|
|
||||||
FLATPAK_MODULE: "libfprint"
|
|
||||||
DBUS_ID: "org.freedesktop.libfprint.Demo"
|
|
||||||
<<: *flatpak
|
|
||||||
|
|||||||
31
NEWS
31
NEWS
@@ -1,37 +1,6 @@
|
|||||||
This file lists notable changes in each release. For the full history of all
|
This file lists notable changes in each release. For the full history of all
|
||||||
changes, see ChangeLog.
|
changes, see ChangeLog.
|
||||||
|
|
||||||
2018-12-14: v0.99.0 release
|
|
||||||
* Library:
|
|
||||||
- All the internal API for device driver writers is now covered by the
|
|
||||||
documentation and has been enhanced to make it easier to write drivers
|
|
||||||
- Update internal NBIS fingerprint data processing library to one that's
|
|
||||||
nearly 10 years newer
|
|
||||||
- Re-add accessor for minutia coordinates which was used in the very
|
|
||||||
old fprint_demo program, but also by our new GTK+ test program (see below)
|
|
||||||
- Fix a crash when too many minutiae were detected in a capture
|
|
||||||
|
|
||||||
* Drivers:
|
|
||||||
- Support more devices in the Elan driver, stability improvements
|
|
||||||
|
|
||||||
* Tools:
|
|
||||||
- Add a test GTK+ application that will eventually be used for testing
|
|
||||||
drivers without modifying the OS installed version. Note that this
|
|
||||||
application currently requires manually changing permissions of USB
|
|
||||||
devices, this will be fixed when the infrastructure exists to access
|
|
||||||
those devices without additional permissions, as a normal user.
|
|
||||||
|
|
||||||
2018-07-15: v0.8.2 release
|
|
||||||
* Drivers:
|
|
||||||
- Add USB ID for TNP Nano USB Fingerprint Reader
|
|
||||||
- Fix UPEKTS enrollment never finishing on some devices
|
|
||||||
|
|
||||||
* Library:
|
|
||||||
- Fix fp_get_pollfds() retval type, a small ABI change
|
|
||||||
- Downgrade fatal errors to run-time warnings, as a number of drivers
|
|
||||||
used to throw silent errors and we made them fatal. Those will now
|
|
||||||
be visible warnings, hopefully helping with fixing them.
|
|
||||||
|
|
||||||
2018-06-12: v0.8.1 release
|
2018-06-12: v0.8.1 release
|
||||||
- Brown paperbag release to install the udev rules file in the correct
|
- Brown paperbag release to install the udev rules file in the correct
|
||||||
directory if the udev pkg-config file doesn't have a trailing slash
|
directory if the udev pkg-config file doesn't have a trailing slash
|
||||||
|
|||||||
10
README
10
README
@@ -39,13 +39,3 @@ We include bozorth3 from the US export controlled distribution. We have
|
|||||||
determined that it is fine to ship bozorth3 in an open source project,
|
determined that it is fine to ship bozorth3 in an open source project,
|
||||||
see https://fprint.freedesktop.org/us-export-control.html
|
see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
|
||||||
## Historical links
|
|
||||||
|
|
||||||
Older versions of libfprint are available at:
|
|
||||||
https://sourceforge.net/projects/fprint/files/
|
|
||||||
|
|
||||||
Historical mailing-list archives:
|
|
||||||
http://www.reactivated.net/fprint_list_archives/
|
|
||||||
|
|
||||||
Historical website:
|
|
||||||
http://web.archive.org/web/*/https://www.freedesktop.org/wiki/Software/fprint/
|
|
||||||
|
|||||||
@@ -1,523 +0,0 @@
|
|||||||
/*
|
|
||||||
* Example libfprint GTK+ image capture program
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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 "config.h"
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <libfprint/fprint.h>
|
|
||||||
|
|
||||||
#include "loop.h"
|
|
||||||
|
|
||||||
typedef GtkApplication LibfprintDemo;
|
|
||||||
typedef GtkApplicationClass LibfprintDemoClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (LibfprintDemo, libfprint_demo, GTK_TYPE_APPLICATION)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
IMAGE_DISPLAY_NONE = 0,
|
|
||||||
IMAGE_DISPLAY_MINUTIAE = 1 << 0,
|
|
||||||
IMAGE_DISPLAY_BINARY = 1 << 1
|
|
||||||
} ImageDisplayFlags;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GtkApplicationWindow parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *header_bar;
|
|
||||||
GtkWidget *mode_stack;
|
|
||||||
GtkWidget *capture_button;
|
|
||||||
GtkWidget *capture_image;
|
|
||||||
GtkWidget *spinner;
|
|
||||||
GtkWidget *instructions;
|
|
||||||
|
|
||||||
struct fp_dscv_dev *ddev;
|
|
||||||
struct fp_dev *dev;
|
|
||||||
|
|
||||||
struct fp_img *img;
|
|
||||||
ImageDisplayFlags img_flags;
|
|
||||||
} LibfprintDemoWindow;
|
|
||||||
|
|
||||||
typedef GtkApplicationWindowClass LibfprintDemoWindowClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (LibfprintDemoWindow, libfprint_demo_window, GTK_TYPE_APPLICATION_WINDOW)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EMPTY_MODE,
|
|
||||||
NOIMAGING_MODE,
|
|
||||||
CAPTURE_MODE,
|
|
||||||
SPINNER_MODE,
|
|
||||||
ERROR_MODE
|
|
||||||
} LibfprintDemoMode;
|
|
||||||
|
|
||||||
static void libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
|
||||||
LibfprintDemoMode mode);
|
|
||||||
|
|
||||||
static void
|
|
||||||
pixbuf_destroy (guchar *pixels, gpointer data)
|
|
||||||
{
|
|
||||||
if (pixels == NULL)
|
|
||||||
return;
|
|
||||||
g_free (pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char *
|
|
||||||
img_to_rgbdata (struct fp_img *img,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
int size = width * height;
|
|
||||||
unsigned char *imgdata = fp_img_get_data (img);
|
|
||||||
unsigned char *rgbdata = g_malloc (size * 3);
|
|
||||||
size_t i;
|
|
||||||
size_t rgb_offset = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
unsigned char pixel = imgdata[i];
|
|
||||||
|
|
||||||
rgbdata[rgb_offset++] = pixel;
|
|
||||||
rgbdata[rgb_offset++] = pixel;
|
|
||||||
rgbdata[rgb_offset++] = pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rgbdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
plot_minutiae (unsigned char *rgbdata,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
struct fp_minutia **minlist,
|
|
||||||
int nr_minutiae)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
#define write_pixel(num) do { \
|
|
||||||
rgbdata[((num) * 3)] = 0xff; \
|
|
||||||
rgbdata[((num) * 3) + 1] = 0; \
|
|
||||||
rgbdata[((num) * 3) + 2] = 0; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
for (i = 0; i < nr_minutiae; i++) {
|
|
||||||
struct fp_minutia *min = minlist[i];
|
|
||||||
int x, y;
|
|
||||||
size_t pixel_offset;
|
|
||||||
|
|
||||||
fp_minutia_get_coords(min, &x, &y);
|
|
||||||
pixel_offset = (y * width) + x;
|
|
||||||
write_pixel(pixel_offset - 2);
|
|
||||||
write_pixel(pixel_offset - 1);
|
|
||||||
write_pixel(pixel_offset);
|
|
||||||
write_pixel(pixel_offset + 1);
|
|
||||||
write_pixel(pixel_offset + 2);
|
|
||||||
|
|
||||||
write_pixel(pixel_offset - (width * 2));
|
|
||||||
write_pixel(pixel_offset - (width * 1) - 1);
|
|
||||||
write_pixel(pixel_offset - (width * 1));
|
|
||||||
write_pixel(pixel_offset - (width * 1) + 1);
|
|
||||||
write_pixel(pixel_offset + (width * 1) - 1);
|
|
||||||
write_pixel(pixel_offset + (width * 1));
|
|
||||||
write_pixel(pixel_offset + (width * 1) + 1);
|
|
||||||
write_pixel(pixel_offset + (width * 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkPixbuf *
|
|
||||||
img_to_pixbuf (struct fp_img *img,
|
|
||||||
ImageDisplayFlags flags)
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
unsigned char *rgbdata;
|
|
||||||
|
|
||||||
width = fp_img_get_width (img);
|
|
||||||
height = fp_img_get_height (img);
|
|
||||||
|
|
||||||
if (flags & IMAGE_DISPLAY_BINARY) {
|
|
||||||
struct fp_img *binary;
|
|
||||||
binary = fp_img_binarize (img);
|
|
||||||
rgbdata = img_to_rgbdata (binary, width, height);
|
|
||||||
fp_img_free (binary);
|
|
||||||
} else {
|
|
||||||
rgbdata = img_to_rgbdata (img, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & IMAGE_DISPLAY_MINUTIAE) {
|
|
||||||
struct fp_minutia **minlist;
|
|
||||||
int nr_minutiae;
|
|
||||||
|
|
||||||
minlist = fp_img_get_minutiae (img, &nr_minutiae);
|
|
||||||
plot_minutiae (rgbdata, width, height, minlist, nr_minutiae);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gdk_pixbuf_new_from_data (rgbdata, GDK_COLORSPACE_RGB,
|
|
||||||
FALSE, 8, width, height,
|
|
||||||
width * 3, pixbuf_destroy,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
update_image (LibfprintDemoWindow *win)
|
|
||||||
{
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
|
|
||||||
if (win->img == NULL) {
|
|
||||||
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_debug ("Updating image, minutiae %s, binary mode %s",
|
|
||||||
win->img_flags & IMAGE_DISPLAY_MINUTIAE ? "shown" : "hidden",
|
|
||||||
win->img_flags & IMAGE_DISPLAY_BINARY ? "on" : "off");
|
|
||||||
pixbuf = img_to_pixbuf (win->img, win->img_flags);
|
|
||||||
gtk_image_set_from_pixbuf (GTK_IMAGE (win->capture_image), pixbuf);
|
|
||||||
g_object_unref (pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_set_spinner_label (LibfprintDemoWindow *win,
|
|
||||||
const char *message)
|
|
||||||
{
|
|
||||||
char *label;
|
|
||||||
|
|
||||||
label = g_strdup_printf ("<b><span size=\"large\">%s</span></b>", message);
|
|
||||||
gtk_label_set_markup (GTK_LABEL (win->instructions), label);
|
|
||||||
g_free (label);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
|
|
||||||
{
|
|
||||||
struct fp_driver *drv;
|
|
||||||
enum fp_scan_type scan_type;
|
|
||||||
const char *message;
|
|
||||||
|
|
||||||
drv = fp_dscv_dev_get_driver (win->ddev);
|
|
||||||
scan_type = fp_driver_get_scan_type(drv);
|
|
||||||
|
|
||||||
switch (scan_type) {
|
|
||||||
case FP_SCAN_TYPE_PRESS:
|
|
||||||
message = "Place your finger on the fingerprint reader";
|
|
||||||
break;
|
|
||||||
case FP_SCAN_TYPE_SWIPE:
|
|
||||||
message = "Swipe your finger across the fingerprint reader";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
|
|
||||||
libfprint_demo_set_spinner_label (win, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dev_capture_start_cb (struct fp_dev *dev,
|
|
||||||
int result,
|
|
||||||
struct fp_img *img,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *win = user_data;
|
|
||||||
|
|
||||||
if (result < 0) {
|
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_async_capture_stop (dev, NULL, NULL);
|
|
||||||
|
|
||||||
win->img = img;
|
|
||||||
update_image (win);
|
|
||||||
|
|
||||||
libfprint_demo_set_mode (win, CAPTURE_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dev_open_cb (struct fp_dev *dev, int status, void *user_data)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *win = user_data;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (status < 0) {
|
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
libfprint_demo_set_capture_label (win);
|
|
||||||
|
|
||||||
win->dev = dev;
|
|
||||||
r = fp_async_capture_start (win->dev, FALSE, dev_capture_start_cb, user_data);
|
|
||||||
if (r < 0) {
|
|
||||||
g_warning ("fp_async_capture_start failed: %d", r);
|
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_capture (GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *win = user_data;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
libfprint_demo_set_mode (win, SPINNER_MODE);
|
|
||||||
g_clear_pointer (&win->img, fp_img_free);
|
|
||||||
|
|
||||||
if (win->dev != NULL) {
|
|
||||||
dev_open_cb (win->dev, 0, user_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
libfprint_demo_set_spinner_label (win, "Opening fingerprint reader");
|
|
||||||
|
|
||||||
r = fp_async_dev_open (win->ddev, dev_open_cb, user_data);
|
|
||||||
if (r < 0) {
|
|
||||||
g_warning ("fp_async_dev_open failed: %d", r);
|
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_quit (GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GtkApplication *app = user_data;
|
|
||||||
GtkWidget *win;
|
|
||||||
GList *list, *next;
|
|
||||||
|
|
||||||
list = gtk_application_get_windows (app);
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
win = list->data;
|
|
||||||
next = list->next;
|
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (win));
|
|
||||||
|
|
||||||
list = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_show_minutiae (GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *win = user_data;
|
|
||||||
GVariant *state;
|
|
||||||
gboolean new_state;
|
|
||||||
|
|
||||||
state = g_action_get_state (G_ACTION (action));
|
|
||||||
new_state = !g_variant_get_boolean (state);
|
|
||||||
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
|
||||||
g_variant_unref (state);
|
|
||||||
|
|
||||||
if (new_state)
|
|
||||||
win->img_flags |= IMAGE_DISPLAY_MINUTIAE;
|
|
||||||
else
|
|
||||||
win->img_flags &= ~IMAGE_DISPLAY_MINUTIAE;
|
|
||||||
|
|
||||||
update_image (win);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_show_binary (GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *win = user_data;
|
|
||||||
GVariant *state;
|
|
||||||
gboolean new_state;
|
|
||||||
|
|
||||||
state = g_action_get_state (G_ACTION (action));
|
|
||||||
new_state = !g_variant_get_boolean (state);
|
|
||||||
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
|
||||||
g_variant_unref (state);
|
|
||||||
|
|
||||||
if (new_state)
|
|
||||||
win->img_flags |= IMAGE_DISPLAY_BINARY;
|
|
||||||
else
|
|
||||||
win->img_flags &= ~IMAGE_DISPLAY_BINARY;
|
|
||||||
|
|
||||||
update_image (win);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
change_show_minutiae_state (GSimpleAction *action,
|
|
||||||
GVariant *state,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_simple_action_set_state (action, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
change_show_binary_state (GSimpleAction *action,
|
|
||||||
GVariant *state,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_simple_action_set_state (action, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GActionEntry app_entries[] = {
|
|
||||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
|
||||||
{ "show-minutiae", activate_show_minutiae, NULL, "false", change_show_minutiae_state },
|
|
||||||
{ "show-binary", activate_show_binary, NULL, "false", change_show_binary_state },
|
|
||||||
{ "capture", activate_capture, NULL, NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate (GApplication *app)
|
|
||||||
{
|
|
||||||
LibfprintDemoWindow *window;
|
|
||||||
|
|
||||||
window = g_object_new (libfprint_demo_window_get_type (),
|
|
||||||
"application", app,
|
|
||||||
NULL);
|
|
||||||
gtk_widget_show (GTK_WIDGET (window));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
|
||||||
LibfprintDemoMode mode)
|
|
||||||
{
|
|
||||||
struct fp_driver *drv;
|
|
||||||
char *title;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case EMPTY_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
|
||||||
case NOIMAGING_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
|
||||||
case CAPTURE_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "capture-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
|
||||||
|
|
||||||
drv = fp_dscv_dev_get_driver (win->ddev);
|
|
||||||
title = g_strdup_printf ("%s Test", fp_driver_get_full_name (drv));
|
|
||||||
gtk_header_bar_set_title (GTK_HEADER_BAR (win->header_bar), title);
|
|
||||||
g_free (title);
|
|
||||||
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
|
||||||
case SPINNER_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
|
||||||
case ERROR_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_init (LibfprintDemo *app)
|
|
||||||
{
|
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
|
||||||
app_entries, G_N_ELEMENTS (app_entries),
|
|
||||||
app);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_class_init (LibfprintDemoClass *class)
|
|
||||||
{
|
|
||||||
GApplicationClass *app_class = G_APPLICATION_CLASS (class);
|
|
||||||
|
|
||||||
app_class->activate = activate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_window_init (LibfprintDemoWindow *window)
|
|
||||||
{
|
|
||||||
struct fp_dscv_dev **discovered_devs;
|
|
||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (window));
|
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 700, 500);
|
|
||||||
|
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
|
||||||
win_entries, G_N_ELEMENTS (win_entries),
|
|
||||||
window);
|
|
||||||
|
|
||||||
if (fp_init () < 0) {
|
|
||||||
libfprint_demo_set_mode (window, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_pollfds ();
|
|
||||||
|
|
||||||
discovered_devs = fp_discover_devs();
|
|
||||||
if (!discovered_devs) {
|
|
||||||
libfprint_demo_set_mode (window, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Empty list? */
|
|
||||||
if (discovered_devs[0] == NULL) {
|
|
||||||
fp_dscv_devs_free (discovered_devs);
|
|
||||||
libfprint_demo_set_mode (window, EMPTY_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fp_driver_supports_imaging(fp_dscv_dev_get_driver(discovered_devs[0]))) {
|
|
||||||
libfprint_demo_set_mode (window, NOIMAGING_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->ddev = discovered_devs[0];
|
|
||||||
libfprint_demo_set_mode (window, CAPTURE_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
|
|
||||||
{
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/libfprint_demo/gtk-libfprint-test.ui");
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, header_bar);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, mode_stack);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, capture_button);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, capture_image);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, spinner);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, instructions);
|
|
||||||
|
|
||||||
//FIXME setup dispose
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
GtkApplication *app;
|
|
||||||
|
|
||||||
app = GTK_APPLICATION (g_object_new (libfprint_demo_get_type (),
|
|
||||||
"application-id", "org.freedesktop.libfprint.Demo",
|
|
||||||
"flags", G_APPLICATION_FLAGS_NONE,
|
|
||||||
NULL));
|
|
||||||
|
|
||||||
return g_application_run (G_APPLICATION (app), 0, NULL);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<gresources>
|
|
||||||
<gresource prefix="/libfprint_demo">
|
|
||||||
<file>gtk-libfprint-test.ui</file>
|
|
||||||
</gresource>
|
|
||||||
</gresources>
|
|
||||||
@@ -1,351 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Generated with glade 3.22.1 -->
|
|
||||||
<interface>
|
|
||||||
<requires lib="gtk+" version="3.20"/>
|
|
||||||
<template class="LibfprintDemoWindow" parent="GtkApplicationWindow">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="default_width">500</property>
|
|
||||||
<property name="default_height">400</property>
|
|
||||||
<property name="show_menubar">False</property>
|
|
||||||
<child type="titlebar">
|
|
||||||
<object class="GtkHeaderBar" id="header_bar">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="title">Fingerprint Reader Test</property>
|
|
||||||
<property name="subtitle">Capture test</property>
|
|
||||||
<property name="show_close_button">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuButton" id="option-menu-button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="menu-model">options-menu</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="icon_name">open-menu-symbolic</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="pack_type">end</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="capture_button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="action_name">win.capture</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="capture_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">_Capture</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<style>
|
|
||||||
<class name="text-button"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="pack_type">end</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkStack" id="mode_stack">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="spinner-mode">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="row_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSpinner" id="spinner">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_bottom">9</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="instructions">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_top">9</property>
|
|
||||||
<property name="label" translatable="yes"><b><span size="large">Please press finger on reader</span></b></property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">spinner-mode</property>
|
|
||||||
<property name="title">spinner-mode</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="empty-mode">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="row_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_bottom">9</property>
|
|
||||||
<property name="pixel_size">192</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_top">9</property>
|
|
||||||
<property name="label" translatable="yes"><b><span size="large">No fingerprint readers found</span></b></property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Please connect a supported fingerprint reader and start the application again</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">empty-mode</property>
|
|
||||||
<property name="title">empty-mode</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkAspectFrame" id="capture-mode">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label_xalign">0</property>
|
|
||||||
<property name="shadow_type">none</property>
|
|
||||||
<property name="ratio">1.2999999523162842</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage" id="capture_image">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">capture-mode</property>
|
|
||||||
<property name="title">capture-mode</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="error-mode">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="row_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_bottom">9</property>
|
|
||||||
<property name="pixel_size">192</property>
|
|
||||||
<property name="icon_name">dialog-warning-symbolic</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_top">9</property>
|
|
||||||
<property name="label" translatable="yes"><b><span size="large">An error occurred trying to access the fingerprint reader</span></b></property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Please consult the debugging output before restarting the application</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">error-mode</property>
|
|
||||||
<property name="title">error-mode</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="noimaging-mode">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="row_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_bottom">9</property>
|
|
||||||
<property name="pixel_size">192</property>
|
|
||||||
<property name="icon_name">scanner-symbolic</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_top">9</property>
|
|
||||||
<property name="label" translatable="yes"><b><span size="large">Fingerprint reader does not support capturing images</span></b></property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Please connect a supported fingerprint reader and start the application again</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">noimaging-mode</property>
|
|
||||||
<property name="title">noimaging-mode</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<menu id="options-menu">
|
|
||||||
<section>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">Show Minutiae</attribute>
|
|
||||||
<attribute name="action">win.show-minutiae</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">Show Binary</attribute>
|
|
||||||
<attribute name="action">win.show-binary</attribute>
|
|
||||||
</item>
|
|
||||||
</section>
|
|
||||||
</menu>
|
|
||||||
</interface>
|
|
||||||
196
demo/loop.c
196
demo/loop.c
@@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
* fprint D-Bus daemon
|
|
||||||
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <libfprint/fprint.h>
|
|
||||||
|
|
||||||
#include <poll.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "loop.h"
|
|
||||||
|
|
||||||
struct fdsource {
|
|
||||||
GSource source;
|
|
||||||
GSList *pollfds;
|
|
||||||
};
|
|
||||||
|
|
||||||
static gboolean source_prepare(GSource *source, gint *timeout)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
r = fp_get_next_timeout(&tv);
|
|
||||||
if (r == 0) {
|
|
||||||
*timeout = -1;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!timerisset(&tv))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
*timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean source_check(GSource *source)
|
|
||||||
{
|
|
||||||
struct fdsource *_fdsource = (struct fdsource *) source;
|
|
||||||
GSList *l;
|
|
||||||
struct timeval tv;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!_fdsource->pollfds)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (l = _fdsource->pollfds; l != NULL; l = l->next) {
|
|
||||||
GPollFD *pollfd = l->data;
|
|
||||||
|
|
||||||
if (pollfd->revents)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = fp_get_next_timeout(&tv);
|
|
||||||
if (r == 1 && !timerisset(&tv))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean source_dispatch(GSource *source, GSourceFunc callback,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
struct timeval zerotimeout = {
|
|
||||||
.tv_sec = 0,
|
|
||||||
.tv_usec = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* FIXME error handling */
|
|
||||||
fp_handle_events_timeout(&zerotimeout);
|
|
||||||
|
|
||||||
/* FIXME whats the return value used for? */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void source_finalize(GSource *source)
|
|
||||||
{
|
|
||||||
struct fdsource *_fdsource = (struct fdsource *) source;
|
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
if (!_fdsource->pollfds)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (l = _fdsource->pollfds; l != NULL; l = l->next) {
|
|
||||||
GPollFD *pollfd = l->data;
|
|
||||||
|
|
||||||
g_source_remove_poll((GSource *) _fdsource, pollfd);
|
|
||||||
g_slice_free(GPollFD, pollfd);
|
|
||||||
_fdsource->pollfds = g_slist_delete_link(_fdsource->pollfds, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_free(_fdsource->pollfds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GSourceFuncs sourcefuncs = {
|
|
||||||
.prepare = source_prepare,
|
|
||||||
.check = source_check,
|
|
||||||
.dispatch = source_dispatch,
|
|
||||||
.finalize = source_finalize,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct fdsource *fdsource = NULL;
|
|
||||||
|
|
||||||
static void pollfd_add(int fd, short events)
|
|
||||||
{
|
|
||||||
GPollFD *pollfd;
|
|
||||||
|
|
||||||
pollfd = g_slice_new(GPollFD);
|
|
||||||
pollfd->fd = fd;
|
|
||||||
pollfd->events = 0;
|
|
||||||
pollfd->revents = 0;
|
|
||||||
if (events & POLLIN)
|
|
||||||
pollfd->events |= G_IO_IN;
|
|
||||||
if (events & POLLOUT)
|
|
||||||
pollfd->events |= G_IO_OUT;
|
|
||||||
|
|
||||||
fdsource->pollfds = g_slist_prepend(fdsource->pollfds, pollfd);
|
|
||||||
g_source_add_poll((GSource *) fdsource, pollfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pollfd_added_cb(int fd, short events)
|
|
||||||
{
|
|
||||||
g_debug("now monitoring fd %d", fd);
|
|
||||||
pollfd_add(fd, events);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pollfd_removed_cb(int fd)
|
|
||||||
{
|
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
g_debug("no longer monitoring fd %d", fd);
|
|
||||||
|
|
||||||
if (!fdsource->pollfds) {
|
|
||||||
g_debug("cannot remove from list as list is empty?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = fdsource->pollfds; l != NULL; l = l->next) {
|
|
||||||
GPollFD *pollfd = l->data;
|
|
||||||
|
|
||||||
if (pollfd->fd != fd)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_source_remove_poll((GSource *) fdsource, pollfd);
|
|
||||||
g_slice_free(GPollFD, pollfd);
|
|
||||||
fdsource->pollfds = g_slist_delete_link(fdsource->pollfds, l);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_error("couldn't find fd %d in list\n", fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setup_pollfds(void)
|
|
||||||
{
|
|
||||||
ssize_t numfds;
|
|
||||||
size_t i;
|
|
||||||
struct fp_pollfd *fpfds;
|
|
||||||
GSource *gsource;
|
|
||||||
|
|
||||||
gsource = g_source_new(&sourcefuncs, sizeof(struct fdsource));
|
|
||||||
fdsource = (struct fdsource *) gsource;
|
|
||||||
fdsource->pollfds = NULL;
|
|
||||||
|
|
||||||
numfds = fp_get_pollfds(&fpfds);
|
|
||||||
if (numfds < 0) {
|
|
||||||
if (fpfds)
|
|
||||||
free(fpfds);
|
|
||||||
return (int) numfds;
|
|
||||||
} else if (numfds > 0) {
|
|
||||||
for (i = 0; i < numfds; i++) {
|
|
||||||
struct fp_pollfd *fpfd = &fpfds[i];
|
|
||||||
pollfd_add(fpfd->fd, fpfd->events);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(fpfds);
|
|
||||||
fp_set_pollfd_notifiers(pollfd_added_cb, pollfd_removed_cb);
|
|
||||||
g_source_attach(gsource, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
27
demo/loop.h
27
demo/loop.h
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef POLL_H
|
|
||||||
|
|
||||||
#define POLL_H
|
|
||||||
|
|
||||||
int setup_pollfds(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
gtk_test_resources = gnome.compile_resources('gtk-test-resources', 'gtk-libfprint-test.gresource.xml',
|
|
||||||
source_dir : '.',
|
|
||||||
c_name : 'gtk_test')
|
|
||||||
|
|
||||||
prefix = get_option('prefix')
|
|
||||||
bindir = join_paths(prefix, get_option('bindir'))
|
|
||||||
datadir = join_paths(prefix, get_option('datadir'))
|
|
||||||
|
|
||||||
executable('gtk-libfprint-test',
|
|
||||||
[ 'gtk-libfprint-test.c', 'loop.c', 'loop.h', gtk_test_resources ],
|
|
||||||
dependencies: [ libfprint_dep, gtk_dep ],
|
|
||||||
include_directories: [
|
|
||||||
root_inc,
|
|
||||||
],
|
|
||||||
c_args: [ common_cflags,
|
|
||||||
'-DPACKAGE_VERSION="' + meson.project_version() + '"' ],
|
|
||||||
install: true,
|
|
||||||
install_dir: bindir)
|
|
||||||
|
|
||||||
appdata = 'org.freedesktop.libfprint.Demo.appdata.xml'
|
|
||||||
install_data(appdata,
|
|
||||||
install_dir: join_paths(datadir, 'metainfo'))
|
|
||||||
|
|
||||||
desktop = 'org.freedesktop.libfprint.Demo.desktop'
|
|
||||||
install_data(desktop,
|
|
||||||
install_dir: join_paths(datadir, 'applications'))
|
|
||||||
|
|
||||||
icon = 'org.freedesktop.libfprint.Demo.png'
|
|
||||||
install_data(icon,
|
|
||||||
install_dir: join_paths(datadir, 'icons'))
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<component type="desktop">
|
|
||||||
<id>org.freedesktop.libfprint.Demo.desktop</id>
|
|
||||||
<name>Fingerprint Reader Demo</name>
|
|
||||||
<summary>Test fingerprint readers</summary>
|
|
||||||
<metadata_license>CC0-1.0</metadata_license>
|
|
||||||
<project_license>LGPL-2.1+</project_license>
|
|
||||||
<description>
|
|
||||||
<p>
|
|
||||||
Fingerprint Reader Demo is a test application for the libfprint
|
|
||||||
fingerprint reader library. Its purpose is to test drivers, new and old,
|
|
||||||
in a sandbox, to make sure that the drivers and associated functions
|
|
||||||
work correctly.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Fingerprint Reader Demo does not modify the system, or replace integration
|
|
||||||
in desktop environments.
|
|
||||||
</p>
|
|
||||||
</description>
|
|
||||||
<url type="homepage">https://fprint.freedesktop.org</url>
|
|
||||||
<screenshots>
|
|
||||||
<screenshot type="default" width="1024" height="576">https://git.gnome.org/browse/totem/plain/data/appdata/ss-main.png</screenshot>
|
|
||||||
<screenshot width="1024" height="576">https://git.gnome.org/browse/totem/plain/data/appdata/ss-music-playlist.png</screenshot>
|
|
||||||
</screenshots>
|
|
||||||
<updatecontact>hadess@hadess.net</updatecontact>
|
|
||||||
<!-- Incorrect, but appstream-util won't validate without it -->
|
|
||||||
<translation type="gettext">libfprint</translation>
|
|
||||||
</component>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Name=Fingerprint Reader Demo
|
|
||||||
Comment=Test fingerprint readers
|
|
||||||
Keywords=finger;print;fingerprint;fprint;demo;driver;reader;
|
|
||||||
Exec=gtk-libfprint-test
|
|
||||||
Icon=org.freedesktop.libfprint.Demo
|
|
||||||
Terminal=false
|
|
||||||
Type=Application
|
|
||||||
Categories=GTK;GNOME;Development;System;
|
|
||||||
StartupNotify=true
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
{
|
|
||||||
"app-id": "org.freedesktop.libfprint.Demo",
|
|
||||||
"runtime": "org.gnome.Platform",
|
|
||||||
"runtime-version": "master",
|
|
||||||
"sdk": "org.gnome.Sdk",
|
|
||||||
"command": "gtk-libfprint-test",
|
|
||||||
"finish-args": [
|
|
||||||
/* X11 + XShm access */
|
|
||||||
"--share=ipc", "--socket=x11",
|
|
||||||
/* Wayland access */
|
|
||||||
"--socket=wayland",
|
|
||||||
/* OpenGL access */
|
|
||||||
"--device=dri",
|
|
||||||
/* USB access */
|
|
||||||
"--device=all"
|
|
||||||
],
|
|
||||||
"cleanup": [ "/include", "/lib/pkgconfig/" ],
|
|
||||||
"modules": [
|
|
||||||
{
|
|
||||||
"name": "libusb",
|
|
||||||
"config-opts": [ "--disable-static", "--disable-udev" ],
|
|
||||||
"cleanup": [
|
|
||||||
"/lib/*.la",
|
|
||||||
"/lib/pkgconfig",
|
|
||||||
"/include"
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"type": "archive",
|
|
||||||
"url": "https://github.com/libusb/libusb/archive/v1.0.22.tar.gz",
|
|
||||||
"sha256": "3500f7b182750cd9ccf9be8b1df998f83df56a39ab264976bdb3307773e16f48"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"post-install": [
|
|
||||||
"install -Dm644 COPYING /app/share/licenses/libusb/COPYING"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "libfprint",
|
|
||||||
"buildsystem": "meson",
|
|
||||||
"config-opts": [ "-Dudev_rules=false", "-Dx11-examples=false", "-Dgtk-examples=true" ],
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://gitlab.freedesktop.org/libfprint/libfprint.git",
|
|
||||||
"branch": "wip/hadess/gtk-example"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB |
@@ -24,7 +24,7 @@
|
|||||||
</part>
|
</part>
|
||||||
|
|
||||||
<part>
|
<part>
|
||||||
<title>Library API Documentation</title>
|
<title>API Documentation</title>
|
||||||
<xi:include href="xml/events.xml"/>
|
<xi:include href="xml/events.xml"/>
|
||||||
<xi:include href="xml/discovery.xml"/>
|
<xi:include href="xml/discovery.xml"/>
|
||||||
|
|
||||||
@@ -36,31 +36,11 @@
|
|||||||
<xi:include href="xml/img.xml"/>
|
<xi:include href="xml/img.xml"/>
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
|
<!--
|
||||||
<part>
|
<part>
|
||||||
<title>Writing Drivers</title>
|
<title>Writing Drivers</title>
|
||||||
<chapter id="driver-helpers">
|
|
||||||
<title>Logging, and async machinery</title>
|
|
||||||
<xi:include href="xml/fpi-log.xml"/>
|
|
||||||
<xi:include href="xml/fpi-ssm.xml"/>
|
|
||||||
<xi:include href="xml/fpi-poll.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="driver-dev">
|
|
||||||
<title>Device and driver structures</title>
|
|
||||||
<xi:include href="xml/fpi-dev.xml"/>
|
|
||||||
<xi:include href="xml/fpi-dev-img.xml"/>
|
|
||||||
<xi:include href="xml/fpi-core.xml"/>
|
|
||||||
<xi:include href="xml/fpi-core-img.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="driver-img">
|
|
||||||
<title>Image manipulation</title>
|
|
||||||
<xi:include href="xml/fpi-img.xml"/>
|
|
||||||
<xi:include href="xml/fpi-assembling.xml"/>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<xi:include href="xml/fpi-usb.xml"/>
|
|
||||||
</part>
|
</part>
|
||||||
|
-->
|
||||||
|
|
||||||
<index id="api-index">
|
<index id="api-index">
|
||||||
<title>API Index</title>
|
<title>API Index</title>
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
<INCLUDE>fprint.h</INCLUDE>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>events</FILE>
|
<FILE>events</FILE>
|
||||||
<TITLE>Initialisation and events handling</TITLE>
|
<TITLE>Initialisation and events handling</TITLE>
|
||||||
LIBFPRINT_DEPRECATED
|
|
||||||
fp_set_debug
|
fp_set_debug
|
||||||
fp_init
|
fp_init
|
||||||
fp_exit
|
fp_exit
|
||||||
@@ -18,7 +17,6 @@ fp_set_pollfd_notifiers
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>discovery</FILE>
|
<FILE>discovery</FILE>
|
||||||
<TITLE>Device discovery</TITLE>
|
<TITLE>Device discovery</TITLE>
|
||||||
fp_dscv_dev
|
fp_dscv_dev
|
||||||
@@ -34,18 +32,15 @@ fp_dscv_dev_for_dscv_print
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>drv</FILE>
|
<FILE>drv</FILE>
|
||||||
fp_driver
|
fp_driver
|
||||||
fp_driver_get_name
|
fp_driver_get_name
|
||||||
fp_driver_get_full_name
|
fp_driver_get_full_name
|
||||||
fp_driver_get_driver_id
|
fp_driver_get_driver_id
|
||||||
fp_driver_get_scan_type
|
fp_driver_get_scan_type
|
||||||
fp_driver_supports_imaging
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>dev</FILE>
|
<FILE>dev</FILE>
|
||||||
fp_dev
|
fp_dev
|
||||||
fp_scan_type
|
fp_scan_type
|
||||||
@@ -96,10 +91,10 @@ fp_async_capture_stop
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>print_data</FILE>
|
<FILE>print_data</FILE>
|
||||||
fp_finger
|
fp_finger
|
||||||
fp_print_data
|
fp_print_data
|
||||||
|
fp_print_data
|
||||||
fp_print_data_get_data
|
fp_print_data_get_data
|
||||||
fp_print_data_from_data
|
fp_print_data_from_data
|
||||||
fp_print_data_save
|
fp_print_data_save
|
||||||
@@ -112,7 +107,6 @@ fp_print_data_get_devtype
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>dscv_print</FILE>
|
<FILE>dscv_print</FILE>
|
||||||
fp_dscv_print
|
fp_dscv_print
|
||||||
fp_discover_prints
|
fp_discover_prints
|
||||||
@@ -124,7 +118,6 @@ fp_dscv_print_delete
|
|||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fprint.h</INCLUDE>
|
|
||||||
<FILE>img</FILE>
|
<FILE>img</FILE>
|
||||||
fp_img
|
fp_img
|
||||||
fp_minutia
|
fp_minutia
|
||||||
@@ -136,136 +129,8 @@ fp_img_save_to_file
|
|||||||
fp_img_standardize
|
fp_img_standardize
|
||||||
fp_img_binarize
|
fp_img_binarize
|
||||||
fp_img_get_minutiae
|
fp_img_get_minutiae
|
||||||
fp_minutia_get_coords
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<INCLUDE>fpi-log.h</INCLUDE>
|
<FILE>poll</FILE>
|
||||||
<FILE>fpi-log</FILE>
|
|
||||||
fp_dbg
|
|
||||||
fp_info
|
|
||||||
fp_warn
|
|
||||||
fp_err
|
|
||||||
BUG_ON
|
|
||||||
BUG
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-ssm.h</INCLUDE>
|
|
||||||
<FILE>fpi-ssm</FILE>
|
|
||||||
fpi_ssm
|
|
||||||
ssm_completed_fn
|
|
||||||
ssm_handler_fn
|
|
||||||
|
|
||||||
fpi_ssm_new
|
|
||||||
fpi_ssm_free
|
|
||||||
fpi_ssm_start
|
|
||||||
fpi_ssm_start_subsm
|
|
||||||
|
|
||||||
fpi_ssm_next_state
|
|
||||||
fpi_ssm_next_state_timeout_cb
|
|
||||||
fpi_ssm_jump_to_state
|
|
||||||
fpi_ssm_mark_completed
|
|
||||||
fpi_ssm_mark_failed
|
|
||||||
fpi_ssm_get_user_data
|
|
||||||
fpi_ssm_get_error
|
|
||||||
fpi_ssm_get_cur_state
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-poll.h</INCLUDE>
|
|
||||||
<FILE>fpi-poll</FILE>
|
|
||||||
fpi_timeout
|
|
||||||
fpi_timeout_fn
|
|
||||||
fpi_timeout_add
|
|
||||||
fpi_timeout_set_name
|
|
||||||
fpi_timeout_cancel
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-dev.h</INCLUDE>
|
|
||||||
<FILE>fpi-dev</FILE>
|
|
||||||
fp_img_dev
|
|
||||||
|
|
||||||
FP_DEV
|
|
||||||
FP_IMG_DEV
|
|
||||||
fp_dev_set_instance_data
|
|
||||||
FP_INSTANCE_DATA
|
|
||||||
|
|
||||||
fpi_dev_get_usb_dev
|
|
||||||
fpi_dev_get_verify_data
|
|
||||||
fpi_dev_set_nr_enroll_stages
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-dev-img.h</INCLUDE>
|
|
||||||
<FILE>fpi-dev-img</FILE>
|
|
||||||
fp_imgdev_action
|
|
||||||
fp_imgdev_state
|
|
||||||
fp_imgdev_enroll_state
|
|
||||||
|
|
||||||
fpi_imgdev_abort_scan
|
|
||||||
fpi_imgdev_activate_complete
|
|
||||||
fpi_imgdev_close_complete
|
|
||||||
fpi_imgdev_deactivate_complete
|
|
||||||
fpi_imgdev_get_action
|
|
||||||
fpi_imgdev_get_action_result
|
|
||||||
fpi_imgdev_get_action_state
|
|
||||||
fpi_imgdev_image_captured
|
|
||||||
fpi_imgdev_open_complete
|
|
||||||
fpi_imgdev_report_finger_status
|
|
||||||
fpi_imgdev_session_error
|
|
||||||
fpi_imgdev_set_action_result
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-core.h</INCLUDE>
|
|
||||||
<FILE>fpi-core</FILE>
|
|
||||||
usb_id
|
|
||||||
fp_driver_type
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-core.h</INCLUDE>
|
|
||||||
<FILE>fpi-core-img</FILE>
|
|
||||||
FpiImgDriverFlags
|
|
||||||
fp_img_driver
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-img.h</INCLUDE>
|
|
||||||
<FILE>fpi-img</FILE>
|
|
||||||
FpiImgFlags
|
|
||||||
|
|
||||||
fpi_img_new
|
|
||||||
fpi_img_new_for_imgdev
|
|
||||||
fpi_img_realloc
|
|
||||||
fpi_img_resize
|
|
||||||
|
|
||||||
fpi_std_sq_dev
|
|
||||||
fpi_mean_sq_diff_norm
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-assembling.h</INCLUDE>
|
|
||||||
<FILE>fpi-assembling</FILE>
|
|
||||||
fpi_frame
|
|
||||||
fpi_frame_asmbl_ctx
|
|
||||||
fpi_line_asmbl_ctx
|
|
||||||
|
|
||||||
fpi_do_movement_estimation
|
|
||||||
fpi_assemble_frames
|
|
||||||
fpi_assemble_lines
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<INCLUDE>fpi-usb.h</INCLUDE>
|
|
||||||
<FILE>fpi-usb</FILE>
|
|
||||||
fpi_usb_transfer
|
|
||||||
|
|
||||||
fpi_usb_transfer_cb_fn
|
|
||||||
fpi_usb_alloc
|
|
||||||
fpi_usb_fill_bulk_transfer
|
|
||||||
fpi_usb_submit_transfer
|
|
||||||
fpi_usb_cancel_transfer
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ private_headers = [
|
|||||||
'aeslib.h',
|
'aeslib.h',
|
||||||
'assembling.h',
|
'assembling.h',
|
||||||
'fp_internal.h',
|
'fp_internal.h',
|
||||||
'nbis-helpers.h',
|
|
||||||
'fpi-async.h',
|
|
||||||
'fpi-data.h',
|
|
||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
'aes1660.h',
|
'aes1660.h',
|
||||||
@@ -19,7 +16,6 @@ private_headers = [
|
|||||||
'aesx660.h',
|
'aesx660.h',
|
||||||
'driver_ids.h',
|
'driver_ids.h',
|
||||||
'elan.h',
|
'elan.h',
|
||||||
'upek_proto.h',
|
|
||||||
'upeksonly.h',
|
'upeksonly.h',
|
||||||
'upektc.h',
|
'upektc.h',
|
||||||
'upektc_img.h',
|
'upektc_img.h',
|
||||||
@@ -27,7 +23,6 @@ private_headers = [
|
|||||||
'vfs301_proto_fragments.h',
|
'vfs301_proto_fragments.h',
|
||||||
'vfs301_proto.h',
|
'vfs301_proto.h',
|
||||||
'vfs5011_proto.h',
|
'vfs5011_proto.h',
|
||||||
'synaptics.h',
|
|
||||||
|
|
||||||
# NBIS
|
# NBIS
|
||||||
'morph.h',
|
'morph.h',
|
||||||
@@ -37,7 +32,6 @@ private_headers = [
|
|||||||
'log.h',
|
'log.h',
|
||||||
'bz_array.h',
|
'bz_array.h',
|
||||||
'lfs.h',
|
'lfs.h',
|
||||||
'mytime.h',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
html_images = [
|
html_images = [
|
||||||
@@ -60,6 +54,7 @@ gnome.gtkdoc('libfprint',
|
|||||||
content_files: content_files,
|
content_files: content_files,
|
||||||
expand_content_files: expand_content_files,
|
expand_content_files: expand_content_files,
|
||||||
scan_args: [
|
scan_args: [
|
||||||
|
'--rebuild-types',
|
||||||
'--ignore-decorators=API_EXPORTED',
|
'--ignore-decorators=API_EXPORTED',
|
||||||
'--ignore-headers=' + ' '.join(private_headers),
|
'--ignore-headers=' + ' '.join(private_headers),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +45,8 @@ struct fp_print_data *enroll(struct fp_dev *dev) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
struct fp_img *img = NULL;
|
struct fp_img *img = NULL;
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
printf("\nScan your finger now.\n");
|
printf("\nScan your finger now.\n");
|
||||||
|
|
||||||
r = fp_enroll_finger_img(dev, &enrolled_print, &img);
|
r = fp_enroll_finger_img(dev, &enrolled_print, &img);
|
||||||
@@ -142,10 +143,7 @@ int main(void)
|
|||||||
if (!data)
|
if (!data)
|
||||||
goto out_close;
|
goto out_close;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
r = fp_print_data_save(data, RIGHT_INDEX);
|
r = fp_print_data_save(data, RIGHT_INDEX);
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fprintf(stderr, "Data save failed, code %d\n", r);
|
fprintf(stderr, "Data save failed, code %d\n", r);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture', 'delete' ]
|
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ]
|
||||||
foreach example: examples
|
foreach example: examples
|
||||||
executable(example,
|
executable(example,
|
||||||
example + '.c',
|
example + '.c',
|
||||||
|
|||||||
@@ -117,10 +117,7 @@ int main(void)
|
|||||||
printf("Opened device. Loading previously enrolled right index finger "
|
printf("Opened device. Loading previously enrolled right index finger "
|
||||||
"data...\n");
|
"data...\n");
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
|
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
|
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
|
||||||
fprintf(stderr, "Did you remember to enroll your right index finger "
|
fprintf(stderr, "Did you remember to enroll your right index finger "
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ struct fp_print_data *enroll(struct fp_dev *dev) {
|
|||||||
"complete the process.\n", fp_dev_get_nr_enroll_stages(dev));
|
"complete the process.\n", fp_dev_get_nr_enroll_stages(dev));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
sleep(1);
|
||||||
printf("\nScan your finger now.\n");
|
printf("\nScan your finger now.\n");
|
||||||
r = fp_enroll_finger(dev, &enrolled_print);
|
r = fp_enroll_finger(dev, &enrolled_print);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libusb.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "fpi-usb.h"
|
#include "assembling.h"
|
||||||
#include "fpi-assembling.h"
|
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
|
|
||||||
#define MAX_REGWRITES_PER_REQUEST 16
|
#define MAX_REGWRITES_PER_REQUEST 16
|
||||||
@@ -73,16 +73,21 @@ static int do_write_regv(struct write_regv_data *wdata, int upper_bound)
|
|||||||
unsigned char *data = g_malloc(alloc_size);
|
unsigned char *data = g_malloc(alloc_size);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t data_offset = 0;
|
size_t data_offset = 0;
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
g_free(data);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = offset; i < offset + num; i++) {
|
for (i = offset; i < offset + num; i++) {
|
||||||
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
||||||
data[data_offset++] = regwrite->reg;
|
data[data_offset++] = regwrite->reg;
|
||||||
data[data_offset++] = regwrite->value;
|
data[data_offset++] = regwrite->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, FP_DEV(wdata->imgdev)->udev, EP_OUT, data,
|
libusb_fill_bulk_transfer(transfer, wdata->imgdev->udev, EP_OUT, data,
|
||||||
alloc_size, write_regv_trf_complete, wdata, BULK_TIMEOUT);
|
alloc_size, write_regv_trf_complete, wdata, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -144,10 +149,8 @@ static void continue_write_regv(struct write_regv_data *wdata)
|
|||||||
void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
||||||
unsigned int num_regs, aes_write_regv_cb callback, void *user_data)
|
unsigned int num_regs, aes_write_regv_cb callback, void *user_data)
|
||||||
{
|
{
|
||||||
struct write_regv_data *wdata;
|
struct write_regv_data *wdata = g_malloc(sizeof(*wdata));
|
||||||
|
|
||||||
fp_dbg("write %d regs", num_regs);
|
fp_dbg("write %d regs", num_regs);
|
||||||
wdata = g_malloc(sizeof(*wdata));
|
|
||||||
wdata->imgdev = dev;
|
wdata->imgdev = dev;
|
||||||
wdata->num_regs = num_regs;
|
wdata->num_regs = num_regs;
|
||||||
wdata->regs = regs;
|
wdata->regs = regs;
|
||||||
@@ -155,8 +158,6 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
|||||||
wdata->callback = callback;
|
wdata->callback = callback;
|
||||||
wdata->user_data = user_data;
|
wdata->user_data = user_data;
|
||||||
continue_write_regv(wdata);
|
continue_write_regv(wdata);
|
||||||
|
|
||||||
g_free(wdata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
@@ -29,18 +29,7 @@
|
|||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "fpi-assembling.h"
|
#include "assembling.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-assembling
|
|
||||||
* @title: Image frame assembly
|
|
||||||
* @short_description: Image frame assembly helpers
|
|
||||||
*
|
|
||||||
* Those are the helpers to manipulate capture data from fingerprint readers
|
|
||||||
* into a uniform image that can be further processed. This is usually used
|
|
||||||
* by drivers for devices which have a small sensor and thus need to capture
|
|
||||||
* data in small stripes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned int calc_error(struct fpi_frame_asmbl_ctx *ctx,
|
static unsigned int calc_error(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
struct fpi_frame *first_frame,
|
struct fpi_frame *first_frame,
|
||||||
@@ -163,22 +152,6 @@ static unsigned int do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
|||||||
return total_error / num_stripes;
|
return total_error / num_stripes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_do_movement_estimation:
|
|
||||||
* @ctx: #fpi_frame_asmbl_ctx - frame assembling context
|
|
||||||
* @stripes: a singly-linked list of #fpi_frame
|
|
||||||
* @num_stripes: number of items in @stripes to process
|
|
||||||
*
|
|
||||||
* fpi_do_movement_estimation() estimates the movement between adjacent
|
|
||||||
* frames, populating @delta_x and @delta_y values for each #fpi_frame.
|
|
||||||
*
|
|
||||||
* This function is used for devices that don't do movement estimation
|
|
||||||
* in hardware. If hardware movement estimation is supported, the driver
|
|
||||||
* should populate @delta_x and @delta_y instead.
|
|
||||||
*
|
|
||||||
* Note that @num_stripes might be shorter than the length of the list,
|
|
||||||
* if some stripes should be skipped.
|
|
||||||
*/
|
|
||||||
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
GSList *stripes, size_t num_stripes)
|
GSList *stripes, size_t num_stripes)
|
||||||
{
|
{
|
||||||
@@ -252,22 +225,8 @@ static inline void aes_blit_stripe(struct fpi_frame_asmbl_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_assemble_frames:
|
|
||||||
* @ctx: #fpi_frame_asmbl_ctx - frame assembling context
|
|
||||||
* @stripes: linked list of #fpi_frame
|
|
||||||
* @num_stripes: number of items in @stripes to process
|
|
||||||
*
|
|
||||||
* fpi_assemble_frames() assembles individual frames into a single image.
|
|
||||||
* It expects @delta_x and @delta_y of #fpi_frame to be populated.
|
|
||||||
*
|
|
||||||
* Note that @num_stripes might be shorter than the length of the list,
|
|
||||||
* if some stripes should be skipped.
|
|
||||||
*
|
|
||||||
* Returns: a newly allocated #fp_img.
|
|
||||||
*/
|
|
||||||
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
GSList *stripes, size_t num_stripes)
|
GSList *stripes, size_t stripes_len)
|
||||||
{
|
{
|
||||||
GSList *stripe;
|
GSList *stripe;
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
@@ -276,8 +235,7 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
|||||||
gboolean reverse = FALSE;
|
gboolean reverse = FALSE;
|
||||||
struct fpi_frame *fpi_frame;
|
struct fpi_frame *fpi_frame;
|
||||||
|
|
||||||
//FIXME g_return_if_fail
|
BUG_ON(stripes_len == 0);
|
||||||
BUG_ON(num_stripes == 0);
|
|
||||||
BUG_ON(ctx->image_width < ctx->frame_width);
|
BUG_ON(ctx->image_width < ctx->frame_width);
|
||||||
|
|
||||||
/* Calculate height */
|
/* Calculate height */
|
||||||
@@ -294,7 +252,7 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
|||||||
height += fpi_frame->delta_y;
|
height += fpi_frame->delta_y;
|
||||||
i++;
|
i++;
|
||||||
stripe = g_slist_next(stripe);
|
stripe = g_slist_next(stripe);
|
||||||
} while (i < num_stripes);
|
} while (i < stripes_len);
|
||||||
|
|
||||||
fp_dbg("height is %d", height);
|
fp_dbg("height is %d", height);
|
||||||
|
|
||||||
@@ -336,7 +294,7 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
|||||||
|
|
||||||
stripe = g_slist_next(stripe);
|
stripe = g_slist_next(stripe);
|
||||||
i++;
|
i++;
|
||||||
} while (i < num_stripes);
|
} while (i < stripes_len);
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
@@ -392,45 +350,34 @@ static void interpolate_lines(struct fpi_line_asmbl_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static int min(int a, int b) {return (a < b) ? a : b; }
|
||||||
* fpi_assemble_lines:
|
|
||||||
* @ctx: #fpi_frame_asmbl_ctx - frame assembling context
|
/* Rescale image to account for variable swiping speed */
|
||||||
* @lines: linked list of lines
|
|
||||||
* @num_lines: number of items in @lines to process
|
|
||||||
*
|
|
||||||
* #fpi_assemble_lines assembles individual lines into a single image.
|
|
||||||
* It also rescales image to account variable swiping speed.
|
|
||||||
*
|
|
||||||
* Note that @num_lines might be shorter than the length of the list,
|
|
||||||
* if some lines should be skipped.
|
|
||||||
*
|
|
||||||
* Returns: a newly allocated #fp_img.
|
|
||||||
*/
|
|
||||||
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
||||||
GSList *lines, size_t num_lines)
|
GSList *lines, size_t lines_len)
|
||||||
{
|
{
|
||||||
/* Number of output lines per distance between two scanners */
|
/* Number of output lines per distance between two scanners */
|
||||||
int i;
|
int i;
|
||||||
GSList *row1, *row2;
|
GSList *row1, *row2;
|
||||||
float y = 0.0;
|
float y = 0.0;
|
||||||
int line_ind = 0;
|
int line_ind = 0;
|
||||||
int *offsets = (int *)g_malloc0((num_lines / 2) * sizeof(int));
|
int *offsets = (int *)g_malloc0((lines_len / 2) * sizeof(int));
|
||||||
unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height);
|
unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height);
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
g_return_val_if_fail (lines != NULL, NULL);
|
g_return_val_if_fail (lines != NULL, NULL);
|
||||||
g_return_val_if_fail (num_lines >= 2, NULL);
|
g_return_val_if_fail (lines_len > 0, NULL);
|
||||||
|
|
||||||
fp_dbg("%"G_GINT64_FORMAT, g_get_real_time());
|
fp_dbg("%"G_GINT64_FORMAT, g_get_real_time());
|
||||||
|
|
||||||
row1 = lines;
|
row1 = lines;
|
||||||
for (i = 0; (i < num_lines - 1) && row1; i += 2) {
|
for (i = 0; (i < lines_len - 1) && row1; i += 2) {
|
||||||
int bestmatch = i;
|
int bestmatch = i;
|
||||||
int bestdiff = 0;
|
int bestdiff = 0;
|
||||||
int j, firstrow, lastrow;
|
int j, firstrow, lastrow;
|
||||||
|
|
||||||
firstrow = i + 1;
|
firstrow = i + 1;
|
||||||
lastrow = MIN(i + ctx->max_search_offset, num_lines - 1);
|
lastrow = min(i + ctx->max_search_offset, lines_len - 1);
|
||||||
|
|
||||||
row2 = g_slist_next(row1);
|
row2 = g_slist_next(row1);
|
||||||
for (j = firstrow; j <= lastrow; j++) {
|
for (j = firstrow; j <= lastrow; j++) {
|
||||||
@@ -450,13 +397,13 @@ struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
|||||||
row1 = g_slist_next(row1);
|
row1 = g_slist_next(row1);
|
||||||
}
|
}
|
||||||
|
|
||||||
median_filter(offsets, (num_lines / 2) - 1, ctx->median_filter_size);
|
median_filter(offsets, (lines_len / 2) - 1, ctx->median_filter_size);
|
||||||
|
|
||||||
fp_dbg("offsets_filtered: %"G_GINT64_FORMAT, g_get_real_time());
|
fp_dbg("offsets_filtered: %"G_GINT64_FORMAT, g_get_real_time());
|
||||||
for (i = 0; i <= (num_lines / 2) - 1; i++)
|
for (i = 0; i <= (lines_len / 2) - 1; i++)
|
||||||
fp_dbg("%d", offsets[i]);
|
fp_dbg("%d", offsets[i]);
|
||||||
row1 = lines;
|
row1 = lines;
|
||||||
for (i = 0; i < num_lines - 1; i++, row1 = g_slist_next(row1)) {
|
for (i = 0; i < lines_len - 1; i++, row1 = g_slist_next(row1)) {
|
||||||
int offset = offsets[i/2];
|
int offset = offsets[i/2];
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
float ynext = y + (float)ctx->resolution / offset;
|
float ynext = y + (float)ctx->resolution / offset;
|
||||||
65
libfprint/assembling.h
Normal file
65
libfprint/assembling.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Image assembling routines
|
||||||
|
* Shared functions between libfprint Authentec drivers
|
||||||
|
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||||
|
* Copyright (C) 2015 Vasily Khoruzhick <anarsoul@gmail.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLING_H__
|
||||||
|
#define __ASSEMBLING_H__
|
||||||
|
|
||||||
|
#include <fprint.h>
|
||||||
|
|
||||||
|
struct fpi_frame {
|
||||||
|
int delta_x;
|
||||||
|
int delta_y;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fpi_frame_asmbl_ctx {
|
||||||
|
unsigned frame_width;
|
||||||
|
unsigned frame_height;
|
||||||
|
unsigned image_width;
|
||||||
|
unsigned char (*get_pixel)(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
|
struct fpi_frame *frame,
|
||||||
|
unsigned x,
|
||||||
|
unsigned y);
|
||||||
|
};
|
||||||
|
|
||||||
|
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
|
GSList *stripes, size_t stripes_len);
|
||||||
|
|
||||||
|
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
||||||
|
GSList *stripes, size_t stripes_len);
|
||||||
|
|
||||||
|
struct fpi_line_asmbl_ctx {
|
||||||
|
unsigned line_width;
|
||||||
|
unsigned max_height;
|
||||||
|
unsigned resolution;
|
||||||
|
unsigned median_filter_size;
|
||||||
|
unsigned max_search_offset;
|
||||||
|
int (*get_deviation)(struct fpi_line_asmbl_ctx *ctx,
|
||||||
|
GSList *line1, GSList *line2);
|
||||||
|
unsigned char (*get_pixel)(struct fpi_line_asmbl_ctx *ctx,
|
||||||
|
GSList *line,
|
||||||
|
unsigned x);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
||||||
|
GSList *lines, size_t lines_len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,21 +20,11 @@
|
|||||||
#define FP_COMPONENT "async"
|
#define FP_COMPONENT "async"
|
||||||
|
|
||||||
#include "fp_internal.h"
|
#include "fp_internal.h"
|
||||||
#include "fpi-async.h"
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* SECTION:fpi-async
|
|
||||||
* @title: Asynchronous operations reporting
|
|
||||||
* @short_description: Asynchronous operations reporting functions
|
|
||||||
*
|
|
||||||
* Those functions are used by primitive drivers to report back their
|
|
||||||
* current status. Most drivers, imaging ones, do not need to use them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Drivers call this when device initialisation has completed */
|
/* Drivers call this when device initialisation has completed */
|
||||||
void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
|
void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
|
||||||
{
|
{
|
||||||
@@ -48,18 +38,11 @@ void fpi_drvcb_open_complete(struct fp_dev *dev, int status)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_dev_open:
|
* fp_async_dev_open:
|
||||||
* @ddev: the struct #fp_dscv_dev discovered device to open
|
* @ddev:
|
||||||
* @callback: the callback to call when the device has been opened
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data
|
||||||
*
|
*
|
||||||
* Opens and initialises a device. This is the function you call in order
|
* Returns:
|
||||||
* to convert a #fp_dscv_dev discovered device into an actual device handle
|
|
||||||
* that you can perform operations with.
|
|
||||||
*
|
|
||||||
* The error status of the opening will be provided as an argument to the
|
|
||||||
* #fp_dev_open_cb callback.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback,
|
API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
@@ -70,7 +53,6 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_return_val_if_fail(ddev != NULL, -ENODEV);
|
g_return_val_if_fail(ddev != NULL, -ENODEV);
|
||||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
|
||||||
|
|
||||||
drv = ddev->drv;
|
drv = ddev->drv;
|
||||||
|
|
||||||
@@ -111,7 +93,6 @@ void fpi_drvcb_close_complete(struct fp_dev *dev)
|
|||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
|
BUG_ON(dev->state != DEV_STATE_DEINITIALIZING);
|
||||||
dev->state = DEV_STATE_DEINITIALIZED;
|
dev->state = DEV_STATE_DEINITIALIZED;
|
||||||
fpi_timeout_cancel_all_for_dev(dev);
|
|
||||||
libusb_close(dev->udev);
|
libusb_close(dev->udev);
|
||||||
if (dev->close_cb)
|
if (dev->close_cb)
|
||||||
dev->close_cb(dev, dev->close_cb_data);
|
dev->close_cb(dev, dev->close_cb_data);
|
||||||
@@ -120,12 +101,9 @@ void fpi_drvcb_close_complete(struct fp_dev *dev)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_dev_close:
|
* fp_async_dev_close:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call when the device has been closed
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data
|
||||||
*
|
|
||||||
* Closes a device. You must call this function when you have finished using
|
|
||||||
* a fingerprint device.
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED void fp_async_dev_close(struct fp_dev *dev,
|
API_EXPORTED void fp_async_dev_close(struct fp_dev *dev,
|
||||||
fp_operation_stop_cb callback, void *user_data)
|
fp_operation_stop_cb callback, void *user_data)
|
||||||
@@ -169,15 +147,11 @@ void fpi_drvcb_enroll_started(struct fp_dev *dev, int status)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_enroll_start:
|
* fp_async_enroll_start:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call for each stage of the enrollment
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Starts an enrollment and calls @callback for each enrollment stage.
|
* Returns:
|
||||||
* See [Enrolling](libfprint-Devices-operations.html#enrolling)
|
|
||||||
* for an explanation of enroll stages.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev,
|
API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev,
|
||||||
fp_enroll_stage_cb callback, void *user_data)
|
fp_enroll_stage_cb callback, void *user_data)
|
||||||
@@ -186,7 +160,6 @@ API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
|
||||||
|
|
||||||
drv = dev->drv;
|
drv = dev->drv;
|
||||||
|
|
||||||
@@ -240,13 +213,11 @@ void fpi_drvcb_enroll_stopped(struct fp_dev *dev)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_enroll_stop:
|
* fp_async_enroll_stop:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call when the enrollment has been cancelled
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Stops an ongoing enrollment started with fp_async_enroll_start().
|
* Returns:
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
|
API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
|
||||||
fp_operation_stop_cb callback, void *user_data)
|
fp_operation_stop_cb callback, void *user_data)
|
||||||
@@ -283,17 +254,12 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_verify_start:
|
* fp_async_verify_start:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @data: the print to verify against. Must have been previously
|
* @data:
|
||||||
* enrolled with a device compatible to the device selected to perform the scan
|
* @callback:
|
||||||
* @callback: the callback to call when the verification has finished
|
* @user_data:
|
||||||
* @user_data: user data to pass to the callback
|
|
||||||
*
|
*
|
||||||
* Starts a verification and calls @callback when the verification has
|
* Returns:
|
||||||
* finished. See fp_verify_finger_img() for the synchronous API. When the
|
|
||||||
* @callback has been called, you must call fp_async_verify_stop().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
|
API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
|
||||||
struct fp_print_data *data, fp_img_operation_cb callback, void *user_data)
|
struct fp_print_data *data, fp_img_operation_cb callback, void *user_data)
|
||||||
@@ -302,7 +268,6 @@ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
|
||||||
|
|
||||||
drv = dev->drv;
|
drv = dev->drv;
|
||||||
|
|
||||||
@@ -370,13 +335,11 @@ void fpi_drvcb_verify_stopped(struct fp_dev *dev)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_verify_stop:
|
* fp_async_verify_stop:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call to finish a verification
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Finishes an ongoing verification started with fp_async_verify_start().
|
* Returns:
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
||||||
fp_operation_stop_cb callback, void *user_data)
|
fp_operation_stop_cb callback, void *user_data)
|
||||||
@@ -417,17 +380,12 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_identify_start:
|
* fp_async_identify_start:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @gallery: NULL-terminated array of pointers to the prints to
|
* @gallery:
|
||||||
* identify against. Each one must have been previously enrolled with a device
|
* @callback:
|
||||||
* compatible to the device selected to perform the scan
|
* @user_data:
|
||||||
* @callback: the callback to call when the identification has finished
|
|
||||||
* @user_data: user data to pass to the callback
|
|
||||||
*
|
*
|
||||||
* Performs a new scan and verifies it against a previously enrolled print.
|
* Returns:
|
||||||
* See also: fp_verify_finger_img()
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_identify_start(struct fp_dev *dev,
|
API_EXPORTED int fp_async_identify_start(struct fp_dev *dev,
|
||||||
struct fp_print_data **gallery, fp_identify_cb callback, void *user_data)
|
struct fp_print_data **gallery, fp_identify_cb callback, void *user_data)
|
||||||
@@ -436,7 +394,6 @@ API_EXPORTED int fp_async_identify_start(struct fp_dev *dev,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
|
||||||
|
|
||||||
drv = dev->drv;
|
drv = dev->drv;
|
||||||
|
|
||||||
@@ -494,13 +451,11 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_identify_stop:
|
* fp_async_identify_stop:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call when the identification has stopped
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Stops an ongoing identification started with fp_async_identify_start().
|
* Returns:
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
|
API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
|
||||||
fp_operation_stop_cb callback, void *user_data)
|
fp_operation_stop_cb callback, void *user_data)
|
||||||
@@ -551,17 +506,12 @@ void fpi_drvcb_identify_stopped(struct fp_dev *dev)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_capture_start:
|
* fp_async_capture_start:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @unconditional: whether to unconditionally capture an image, or to only capture when a finger is detected
|
* @unconditional:
|
||||||
* @callback: the callback to call when the capture has finished
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Start the capture of an #fp_img from a device. When the @callback has been called,
|
* Returns:
|
||||||
* you must call fp_async_capture_stop().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error. -ENOTSUP indicates that either the
|
|
||||||
* @unconditional flag was set but the device does not support this, or that the•
|
|
||||||
* device does not support imaging
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional,
|
API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional,
|
||||||
fp_img_operation_cb callback, void *user_data)
|
fp_img_operation_cb callback, void *user_data)
|
||||||
@@ -570,7 +520,6 @@ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
|
||||||
|
|
||||||
drv = dev->drv;
|
drv = dev->drv;
|
||||||
|
|
||||||
@@ -587,7 +536,7 @@ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
dev->capture_cb = NULL;
|
dev->capture_cb = NULL;
|
||||||
dev->state = DEV_STATE_ERROR;
|
dev->state = DEV_STATE_ERROR;
|
||||||
fp_err("failed to start capture, error %d", r);
|
fp_err("failed to start verification, error %d", r);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -637,13 +586,11 @@ void fpi_drvcb_capture_stopped(struct fp_dev *dev)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_async_capture_stop:
|
* fp_async_capture_stop:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev:
|
||||||
* @callback: the callback to call when the capture has been stopped
|
* @callback:
|
||||||
* @user_data: user data to pass to the callback
|
* @user_data:
|
||||||
*
|
*
|
||||||
* Stops an ongoing verification started with fp_async_capture_start().
|
* Returns:
|
||||||
*
|
|
||||||
* Returns: 0 on success, non-zero on error
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev,
|
API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev,
|
||||||
fp_operation_stop_cb callback, void *user_data)
|
fp_operation_stop_cb callback, void *user_data)
|
||||||
@@ -675,63 +622,8 @@ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev,
|
|||||||
|
|
||||||
r = drv->capture_stop(dev);
|
r = drv->capture_stop(dev);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("failed to stop capture");
|
fp_err("failed to stop verification");
|
||||||
dev->capture_stop_cb = NULL;
|
dev->capture_stop_cb = NULL;
|
||||||
}
|
}
|
||||||
return r;
|
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +33,6 @@ GSList *opened_devices = NULL;
|
|||||||
/**
|
/**
|
||||||
* SECTION:discovery
|
* SECTION:discovery
|
||||||
* @title: Device discovery
|
* @title: Device discovery
|
||||||
* @short_description: Device discovery functions
|
|
||||||
*
|
*
|
||||||
* These functions allow you to scan the system for supported fingerprint
|
* These functions allow you to scan the system for supported fingerprint
|
||||||
* scanning hardware. This is your starting point when integrating libfprint
|
* scanning hardware. This is your starting point when integrating libfprint
|
||||||
@@ -48,7 +47,6 @@ GSList *opened_devices = NULL;
|
|||||||
/**
|
/**
|
||||||
* SECTION:drv
|
* SECTION:drv
|
||||||
* @title: Driver operations
|
* @title: Driver operations
|
||||||
* @short_description: Driver operation functions
|
|
||||||
*
|
*
|
||||||
* Internally, libfprint is abstracted into various drivers to communicate
|
* Internally, libfprint is abstracted into various drivers to communicate
|
||||||
* with the different types of supported fingerprint readers. libfprint works
|
* with the different types of supported fingerprint readers. libfprint works
|
||||||
@@ -63,7 +61,6 @@ GSList *opened_devices = NULL;
|
|||||||
/**
|
/**
|
||||||
* SECTION:dev
|
* SECTION:dev
|
||||||
* @title: Devices operations
|
* @title: Devices operations
|
||||||
* @short_description: Device operation functions
|
|
||||||
*
|
*
|
||||||
* In order to interact with fingerprint scanners, your software will
|
* In order to interact with fingerprint scanners, your software will
|
||||||
* interface primarily with libfprint's representation of devices, detailed
|
* interface primarily with libfprint's representation of devices, detailed
|
||||||
@@ -114,27 +111,6 @@ GSList *opened_devices = NULL;
|
|||||||
* verification) on some devices which do not provide images.
|
* verification) on some devices which do not provide images.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-core
|
|
||||||
* @title: Driver structures
|
|
||||||
* @short_description: Driver structures
|
|
||||||
*
|
|
||||||
* Driver structures need to be defined inside each driver in
|
|
||||||
* order for the core library to know what function to call, and the capabilities
|
|
||||||
* of the driver and the devices it supports.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-core-img
|
|
||||||
* @title: Image driver structures
|
|
||||||
* @short_description: Image driver structures
|
|
||||||
*
|
|
||||||
* Image driver structures need to be defined inside each image driver in
|
|
||||||
* order for the core library to know what function to call, and the capabilities
|
|
||||||
* of the driver and the devices it supports. Its structure is based off the
|
|
||||||
* #fp_driver struct.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static GSList *registered_drivers = NULL;
|
static GSList *registered_drivers = NULL;
|
||||||
|
|
||||||
static void register_driver(struct fp_driver *drv)
|
static void register_driver(struct fp_driver *drv)
|
||||||
@@ -270,12 +246,10 @@ static struct fp_dscv_dev *discover_dev(libusb_device *udev)
|
|||||||
* fp_discover_devs:
|
* fp_discover_devs:
|
||||||
*
|
*
|
||||||
* Scans the system and returns a list of discovered devices. This is your
|
* Scans the system and returns a list of discovered devices. This is your
|
||||||
* entry point into finding a fingerprint reader to operate. Note that %NULL
|
* entry point into finding a fingerprint reader to operate.
|
||||||
* is only returned on error. When there are no supported readers available,
|
|
||||||
* an empty list is returned instead.
|
|
||||||
*
|
*
|
||||||
* Returns: a nul-terminated list of discovered devices or %NULL on error.
|
* Returns: a %NULL-terminated list of discovered devices. Must be freed with
|
||||||
* Must be freed with fp_dscv_devs_free() after use.
|
* fp_dscv_devs_free() after use.
|
||||||
*/
|
*/
|
||||||
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
|
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
|
||||||
{
|
{
|
||||||
@@ -285,7 +259,8 @@ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
|
|||||||
int r;
|
int r;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (registered_drivers != NULL, NULL);
|
if (registered_drivers == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
r = libusb_get_device_list(fpi_usb_ctx, &devs);
|
r = libusb_get_device_list(fpi_usb_ctx, &devs);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -346,8 +321,6 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
|
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, NULL);
|
|
||||||
|
|
||||||
return dev->drv;
|
return dev->drv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,15 +328,10 @@ API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
|
|||||||
* fp_dscv_dev_get_driver_id:
|
* fp_dscv_dev_get_driver_id:
|
||||||
* @dev: a discovered fingerprint device
|
* @dev: a discovered fingerprint device
|
||||||
*
|
*
|
||||||
* Returns a unique driver identifier for the underlying driver
|
* Returns: the ID for the underlying driver for that device
|
||||||
* for that device.
|
|
||||||
*
|
|
||||||
* Returns: the ID for #dev
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev)
|
API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev));
|
return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +345,6 @@ API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
|
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return dev->devtype;
|
return dev->devtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,9 +374,6 @@ enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv)
|
|||||||
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
|
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
|
||||||
struct fp_print_data *print)
|
struct fp_print_data *print)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
g_return_val_if_fail(print, 0);
|
|
||||||
|
|
||||||
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
||||||
fpi_driver_get_data_type(dev->drv), print->driver_id, print->devtype,
|
fpi_driver_get_data_type(dev->drv), print->driver_id, print->devtype,
|
||||||
print->type);
|
print->type);
|
||||||
@@ -431,9 +394,6 @@ API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
|
|||||||
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
|
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
|
||||||
struct fp_dscv_print *print)
|
struct fp_dscv_print *print)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
g_return_val_if_fail(print, 0);
|
|
||||||
|
|
||||||
return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
|
return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
|
||||||
print->driver_id, print->devtype, 0);
|
print->driver_id, print->devtype, 0);
|
||||||
}
|
}
|
||||||
@@ -457,9 +417,6 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev *
|
|||||||
struct fp_dscv_dev *ddev;
|
struct fp_dscv_dev *ddev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_val_if_fail(devs, NULL);
|
|
||||||
g_return_val_if_fail(print, NULL);
|
|
||||||
|
|
||||||
for (i = 0; (ddev = devs[i]); i++)
|
for (i = 0; (ddev = devs[i]); i++)
|
||||||
if (fp_dscv_dev_supports_print_data(ddev, print))
|
if (fp_dscv_dev_supports_print_data(ddev, print))
|
||||||
return ddev;
|
return ddev;
|
||||||
@@ -485,9 +442,6 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev *
|
|||||||
struct fp_dscv_dev *ddev;
|
struct fp_dscv_dev *ddev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_val_if_fail(devs, NULL);
|
|
||||||
g_return_val_if_fail(print, NULL);
|
|
||||||
|
|
||||||
for (i = 0; (ddev = devs[i]); i++) {
|
for (i = 0; (ddev = devs[i]); i++) {
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
@@ -500,7 +454,7 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev *
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_get_driver:
|
* fp_dev_get_driver:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the device
|
||||||
*
|
*
|
||||||
* Get the #fp_driver for a fingerprint device.
|
* Get the #fp_driver for a fingerprint device.
|
||||||
*
|
*
|
||||||
@@ -508,14 +462,12 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev *
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
|
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, NULL);
|
|
||||||
|
|
||||||
return dev->drv;
|
return dev->drv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_get_nr_enroll_stages:
|
* fp_dev_get_nr_enroll_stages:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the device
|
||||||
*
|
*
|
||||||
* Gets the number of [enroll stages](intro.html#enrollment) required to enroll a
|
* Gets the number of [enroll stages](intro.html#enrollment) required to enroll a
|
||||||
* fingerprint with the device.
|
* fingerprint with the device.
|
||||||
@@ -524,14 +476,12 @@ API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
|
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return dev->nr_enroll_stages;
|
return dev->nr_enroll_stages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_get_devtype:
|
* fp_dev_get_devtype:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the device
|
||||||
*
|
*
|
||||||
* Gets the [devtype](advanced-topics.html#device-types) for a device.
|
* Gets the [devtype](advanced-topics.html#device-types) for a device.
|
||||||
*
|
*
|
||||||
@@ -539,14 +489,12 @@ API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
|
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return dev->devtype;
|
return dev->devtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_supports_print_data:
|
* fp_dev_supports_print_data:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the device
|
||||||
* @data: the stored print
|
* @data: the stored print
|
||||||
*
|
*
|
||||||
* Determines if a stored print is compatible with a certain device.
|
* Determines if a stored print is compatible with a certain device.
|
||||||
@@ -556,9 +504,6 @@ API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
|
|||||||
API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
|
API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
|
||||||
struct fp_print_data *data)
|
struct fp_print_data *data)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
g_return_val_if_fail(data, 0);
|
|
||||||
|
|
||||||
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
||||||
fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
|
fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
|
||||||
data->type);
|
data->type);
|
||||||
@@ -566,7 +511,7 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_supports_dscv_print:
|
* fp_dev_supports_dscv_print:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the device
|
||||||
* @print: the discovered print
|
* @print: the discovered print
|
||||||
*
|
*
|
||||||
* Determines if a #fp_dscv_print discovered print appears to be compatible
|
* Determines if a #fp_dscv_print discovered print appears to be compatible
|
||||||
@@ -579,13 +524,54 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
|
|||||||
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
|
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
|
||||||
struct fp_dscv_print *print)
|
struct fp_dscv_print *print)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
g_return_val_if_fail(print, 0);
|
|
||||||
|
|
||||||
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
return fpi_print_data_compatible(dev->drv->id, dev->devtype,
|
||||||
0, print->driver_id, print->devtype, 0);
|
0, print->driver_id, print->devtype, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libusb_device_handle *
|
||||||
|
fpi_dev_get_usb_dev(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
return dev->udev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
fpi_dev_get_user_data (struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
return dev->priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fpi_dev_set_user_data (struct fp_dev *dev,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
dev->priv = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fpi_dev_get_nr_enroll_stages(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
return dev->nr_enroll_stages;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fpi_dev_set_nr_enroll_stages(struct fp_dev *dev,
|
||||||
|
int nr_enroll_stages)
|
||||||
|
{
|
||||||
|
dev->nr_enroll_stages = nr_enroll_stages;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fp_print_data *
|
||||||
|
fpi_dev_get_verify_data(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
return dev->verify_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fp_dev_state
|
||||||
|
fpi_dev_get_dev_state(struct fp_dev *dev)
|
||||||
|
{
|
||||||
|
return dev->state;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_driver_get_name:
|
* fp_driver_get_name:
|
||||||
* @drv: the driver
|
* @drv: the driver
|
||||||
@@ -596,8 +582,6 @@ API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
|
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(drv, NULL);
|
|
||||||
|
|
||||||
return drv->name;
|
return drv->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,8 +595,6 @@ API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
|
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(drv, NULL);
|
|
||||||
|
|
||||||
return drv->full_name;
|
return drv->full_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,8 +608,6 @@ API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
|
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(drv, 0);
|
|
||||||
|
|
||||||
return drv->id;
|
return drv->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,34 +621,19 @@ API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv)
|
API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(drv, FP_SCAN_TYPE_PRESS);
|
|
||||||
|
|
||||||
return drv->scan_type;
|
return drv->scan_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev)
|
||||||
* fp_driver_supports_imaging:
|
|
||||||
* @drv: the driver
|
|
||||||
*
|
|
||||||
* Determines if a driver has imaging capabilities. If a driver has imaging
|
|
||||||
* capabilities you are able to perform imaging operations such as retrieving
|
|
||||||
* scan images using fp_dev_img_capture(). However, not all drivers support
|
|
||||||
* imaging devices – some do all processing in hardware. This function will
|
|
||||||
* indicate which class a device in question falls into.
|
|
||||||
*
|
|
||||||
* Returns: 1 if the device is an imaging device, 0 if the device does not
|
|
||||||
* provide images to the host computer
|
|
||||||
*/
|
|
||||||
API_EXPORTED int fp_driver_supports_imaging(struct fp_driver *drv)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(drv, 0);
|
if (dev->drv->type != DRIVER_IMAGING)
|
||||||
|
return NULL;
|
||||||
return drv->capture_start != NULL;
|
return dev->priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_supports_imaging:
|
* fp_dev_supports_imaging:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the fingerprint device
|
||||||
*
|
*
|
||||||
* Determines if a device has imaging capabilities. If a device has imaging
|
* Determines if a device has imaging capabilities. If a device has imaging
|
||||||
* capabilities you are able to perform imaging operations such as retrieving
|
* capabilities you are able to perform imaging operations such as retrieving
|
||||||
@@ -681,14 +646,12 @@ API_EXPORTED int fp_driver_supports_imaging(struct fp_driver *drv)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
|
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return dev->drv->capture_start != NULL;
|
return dev->drv->capture_start != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_supports_identification:
|
* fp_dev_supports_identification:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the fingerprint device
|
||||||
*
|
*
|
||||||
* Determines if a device is capable of [identification](intro.html#identification)
|
* Determines if a device is capable of [identification](intro.html#identification)
|
||||||
* through fp_identify_finger() and similar. Not all devices support this
|
* through fp_identify_finger() and similar. Not all devices support this
|
||||||
@@ -698,29 +661,12 @@ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
|
API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, 0);
|
|
||||||
|
|
||||||
return dev->drv->identify_start != NULL;
|
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:
|
* fp_dev_get_img_width:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the fingerprint device
|
||||||
*
|
*
|
||||||
* Gets the expected width of images that will be captured from the device.
|
* Gets the expected width of images that will be captured from the device.
|
||||||
* This function will return -1 for devices that are not
|
* This function will return -1 for devices that are not
|
||||||
@@ -732,19 +678,18 @@ API_EXPORTED int fp_dev_supports_data_in_sensor(struct fp_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
|
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, -1);
|
struct fp_img_dev *imgdev = dev_to_img_dev(dev);
|
||||||
|
if (!imgdev) {
|
||||||
if (!dev->img_dev) {
|
|
||||||
fp_dbg("get image width for non-imaging device");
|
fp_dbg("get image width for non-imaging device");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fpi_imgdev_get_img_width(dev->img_dev);
|
return fpi_imgdev_get_img_width(imgdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_get_img_height:
|
* fp_dev_get_img_height:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the fingerprint device
|
||||||
*
|
*
|
||||||
* Gets the expected height of images that will be captured from the device.
|
* Gets the expected height of images that will be captured from the device.
|
||||||
* This function will return -1 for devices that are not
|
* This function will return -1 for devices that are not
|
||||||
@@ -756,14 +701,13 @@ API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
|
|||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
|
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(dev, -1);
|
struct fp_img_dev *imgdev = dev_to_img_dev(dev);
|
||||||
|
if (!imgdev) {
|
||||||
if (!dev->img_dev) {
|
|
||||||
fp_dbg("get image height for non-imaging device");
|
fp_dbg("get image height for non-imaging device");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fpi_imgdev_get_img_height(dev->img_dev);
|
return fpi_imgdev_get_img_height(imgdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,23 +32,9 @@
|
|||||||
|
|
||||||
#define DIR_PERMS 0700
|
#define DIR_PERMS 0700
|
||||||
|
|
||||||
struct fpi_print_data_fp2 {
|
|
||||||
char prefix[3];
|
|
||||||
uint16_t driver_id;
|
|
||||||
uint32_t devtype;
|
|
||||||
unsigned char data_type;
|
|
||||||
unsigned char data[0];
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
struct fpi_print_data_item_fp2 {
|
|
||||||
uint32_t length;
|
|
||||||
unsigned char data[0];
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION: print_data
|
* SECTION: print_data
|
||||||
* @title: Stored prints
|
* @title: Stored prints
|
||||||
* @short_description: Stored prints functions
|
|
||||||
*
|
*
|
||||||
* Stored prints are represented by a structure named #fp_print_data.
|
* Stored prints are represented by a structure named #fp_print_data.
|
||||||
* Stored prints are originally obtained from an enrollment function such as
|
* Stored prints are originally obtained from an enrollment function such as
|
||||||
@@ -56,25 +42,12 @@ struct fpi_print_data_item_fp2 {
|
|||||||
*
|
*
|
||||||
* This page documents the various operations you can do with a stored print.
|
* This page documents the various operations you can do with a stored print.
|
||||||
* Note that by default, "stored prints" are not actually stored anywhere
|
* Note that by default, "stored prints" are not actually stored anywhere
|
||||||
* except in RAM. Storage needs to be handled by the API user by using the
|
* except in RAM. For the simple scenarios, libfprint provides a simple API
|
||||||
* fp_print_data_get_data() and fp_print_data_from_data(). This API allows
|
* for you to save and load the stored prints referring to a single user in
|
||||||
* to convert print data into byte strings, and to reconstruct stored prints
|
* their home directory. For more advanced users, libfprint provides APIs for
|
||||||
|
* you to convert print data to a byte string, and to reconstruct stored prints
|
||||||
* from such data at a later point. You are welcome to store these byte strings
|
* from such data at a later point. You are welcome to store these byte strings
|
||||||
* in any fashion that suits you.
|
* in any fashion that suits you.
|
||||||
*
|
|
||||||
* The provided API to store data on disk is deprecated and should not be
|
|
||||||
* used anymore. This API stored the prints in the current user's home
|
|
||||||
* directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SECTION: fpi-data
|
|
||||||
* @title: Stored prints creation
|
|
||||||
* @short_description: Stored prints creation functions
|
|
||||||
*
|
|
||||||
* Stored print can be loaded and created by certain drivers which do their own
|
|
||||||
* print matching in hardware. Most drivers will not be using those functions.
|
|
||||||
* See #fp_print_data for the public API counterpart.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *base_store = NULL;
|
static char *base_store = NULL;
|
||||||
@@ -133,7 +106,7 @@ static struct fp_print_data *print_data_new(uint16_t driver_id,
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_print_data_item_free(struct fp_print_data_item *item)
|
void fpi_print_data_item_free(struct fp_print_data_item *item)
|
||||||
{
|
{
|
||||||
g_free(item);
|
g_free(item);
|
||||||
}
|
}
|
||||||
@@ -152,19 +125,6 @@ struct fp_print_data *fpi_print_data_new(struct fp_dev *dev)
|
|||||||
fpi_driver_get_data_type(dev->drv));
|
fpi_driver_get_data_type(dev->drv));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fp_print_data_item *
|
|
||||||
fpi_print_data_get_item(struct fp_print_data *data)
|
|
||||||
{
|
|
||||||
return data->prints->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fpi_print_data_add_item(struct fp_print_data *data,
|
|
||||||
struct fp_print_data_item *item)
|
|
||||||
{
|
|
||||||
data->prints = g_slist_prepend(data->prints, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_print_data_get_data:
|
* fp_print_data_get_data:
|
||||||
* @data: the stored print
|
* @data: the stored print
|
||||||
@@ -369,10 +329,6 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger)
|
|||||||
* directory beneath the current user's home directory.
|
* directory beneath the current user's home directory.
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, non-zero on error.
|
* Returns: 0 on success, non-zero on error.
|
||||||
*
|
|
||||||
* Deprecated: Data storage should be handled outside of libfprint.
|
|
||||||
* See <link linkend="libfprint-Stored-prints.description">stored prints description</link>
|
|
||||||
* for more information.
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
|
API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
|
||||||
enum fp_finger finger)
|
enum fp_finger finger)
|
||||||
@@ -398,7 +354,6 @@ API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
|
|||||||
r = g_mkdir_with_parents(dirpath, DIR_PERMS);
|
r = g_mkdir_with_parents(dirpath, DIR_PERMS);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("couldn't create storage directory");
|
fp_err("couldn't create storage directory");
|
||||||
free(buf);
|
|
||||||
g_free(path);
|
g_free(path);
|
||||||
g_free(dirpath);
|
g_free(dirpath);
|
||||||
return r;
|
return r;
|
||||||
@@ -485,16 +440,12 @@ static int load_from_file(char *path, struct fp_print_data **data)
|
|||||||
* obscure error conditions (e.g. corruption).
|
* obscure error conditions (e.g. corruption).
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, non-zero on error
|
* Returns: 0 on success, non-zero on error
|
||||||
*
|
|
||||||
* Deprecated: Data storage should be handled outside of libfprint.
|
|
||||||
* See <link linkend="libfprint-Stored-prints.description">stored prints description</link>
|
|
||||||
* for more information.
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
|
API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
|
||||||
enum fp_finger finger, struct fp_print_data **data)
|
enum fp_finger finger, struct fp_print_data **data)
|
||||||
{
|
{
|
||||||
gchar *path;
|
gchar *path;
|
||||||
struct fp_print_data *fdata = NULL;
|
struct fp_print_data *fdata;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!base_store)
|
if (!base_store)
|
||||||
@@ -524,10 +475,6 @@ API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
|
|||||||
* Removes a stored print from disk previously saved with fp_print_data_save().
|
* Removes a stored print from disk previously saved with fp_print_data_save().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, negative on error
|
* Returns: 0 on success, negative on error
|
||||||
*
|
|
||||||
* Deprecated: Data storage should be handled outside of libfprint.
|
|
||||||
* See <link linkend="libfprint-Stored-prints.description">stored prints description</link>
|
|
||||||
* for more information.
|
|
||||||
*/
|
*/
|
||||||
API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
|
API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
|
||||||
enum fp_finger finger)
|
enum fp_finger finger)
|
||||||
@@ -613,7 +560,6 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data)
|
|||||||
/**
|
/**
|
||||||
* SECTION:dscv_print
|
* SECTION:dscv_print
|
||||||
* @title: Print discovery (deprecated)
|
* @title: Print discovery (deprecated)
|
||||||
* @short_description: Print discovery functions
|
|
||||||
*
|
*
|
||||||
* The [stored print](libfprint-Stored-prints.html) documentation detailed a simple API
|
* The [stored print](libfprint-Stored-prints.html) documentation detailed a simple API
|
||||||
* for storing per-device prints for a single user, namely
|
* for storing per-device prints for a single user, namely
|
||||||
@@ -749,7 +695,9 @@ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
|
|||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
GSList *tmplist = NULL;
|
GSList *tmplist = NULL;
|
||||||
GSList *elem;
|
GSList *elem;
|
||||||
GPtrArray *array;
|
unsigned int tmplist_len;
|
||||||
|
struct fp_dscv_print **list;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (!base_store)
|
if (!base_store)
|
||||||
storage_setup();
|
storage_setup();
|
||||||
@@ -784,17 +732,15 @@ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_dir_close(dir);
|
g_dir_close(dir);
|
||||||
|
tmplist_len = g_slist_length(tmplist);
|
||||||
if (tmplist == NULL)
|
list = g_malloc(sizeof(*list) * (tmplist_len + 1));
|
||||||
return NULL;
|
elem = tmplist;
|
||||||
|
for (i = 0; i < tmplist_len; i++, elem = g_slist_next(elem))
|
||||||
array = g_ptr_array_new();
|
list[i] = elem->data;
|
||||||
for (elem = tmplist; elem != NULL; elem = elem->next)
|
list[tmplist_len] = NULL; /* NULL-terminate */
|
||||||
g_ptr_array_add(array, elem->data);
|
|
||||||
g_ptr_array_add(array, NULL);
|
|
||||||
|
|
||||||
g_slist_free(tmplist);
|
g_slist_free(tmplist);
|
||||||
return (struct fp_dscv_print **) g_ptr_array_free(array, FALSE);
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,9 +44,6 @@ static int adjust_gain(unsigned char *buffer, int status);
|
|||||||
|
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
#define FINGER_DETECTION_LEN 19
|
|
||||||
#define STRIP_CAPTURE_LEN 665
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The AES1610 is an imaging device using a swipe-type sensor. It samples
|
* The AES1610 is an imaging device using a swipe-type sensor. It samples
|
||||||
* the finger at preprogrammed intervals, sending a 128x8 frame to the
|
* the finger at preprogrammed intervals, sending a 128x8 frame to the
|
||||||
@@ -104,12 +101,12 @@ static void stub_capture_stop_cb(struct fp_img_dev *dev, int result, void *user_
|
|||||||
/* check that read succeeded but ignore all data */
|
/* check that read succeeded but ignore all data */
|
||||||
static void generic_ignore_data_cb(struct libusb_transfer *transfer)
|
static void generic_ignore_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else if (transfer->length != transfer->actual_length)
|
else if (transfer->length != transfer->actual_length)
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
||||||
@@ -120,22 +117,29 @@ static void generic_ignore_data_cb(struct libusb_transfer *transfer)
|
|||||||
static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, result);
|
fpi_ssm_mark_aborted(ssm, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the specified number of bytes from the IN endpoint but throw them
|
/* read the specified number of bytes from the IN endpoint but throw them
|
||||||
* away, then increment the SSM */
|
* away, then increment the SSM */
|
||||||
static void generic_read_ignore_data(fpi_ssm *ssm, struct fp_dev *dev, size_t bytes)
|
static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
struct fp_dev *dev;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(bytes);
|
data = g_malloc(bytes);
|
||||||
|
dev = fpi_ssm_get_dev(ssm);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes,
|
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes,
|
||||||
generic_ignore_data_cb, ssm, BULK_TIMEOUT);
|
generic_ignore_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
@@ -143,7 +147,7 @@ static void generic_read_ignore_data(fpi_ssm *ssm, struct fp_dev *dev, size_t by
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,9 +226,14 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_da
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
data = g_malloc(FINGER_DETECTION_LEN);
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, FINGER_DETECTION_LEN,
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = g_malloc(19);
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 19,
|
||||||
finger_det_data_cb, dev, BULK_TIMEOUT);
|
finger_det_data_cb, dev, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -238,7 +247,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_da
|
|||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
@@ -548,17 +557,17 @@ enum capture_states {
|
|||||||
static void capture_read_strip_cb(struct libusb_transfer *transfer)
|
static void capture_read_strip_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int sum, i;
|
int sum, i;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
} else if (transfer->length != transfer->actual_length) {
|
} else if (transfer->length != transfer->actual_length) {
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +594,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sum < 0) {
|
if (sum < 0) {
|
||||||
fpi_ssm_mark_failed(ssm, sum);
|
fpi_ssm_mark_aborted(ssm, sum);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
fp_dbg("sum=%d", sum);
|
fp_dbg("sum=%d", sum);
|
||||||
@@ -634,10 +643,10 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
@@ -648,7 +657,7 @@ static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
fp_dbg("read data");
|
fp_dbg("read data");
|
||||||
generic_read_ignore_data(ssm, _dev, STRIP_CAPTURE_LEN);
|
generic_read_ignore_data(ssm, 665);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_REQUEST_STRIP:
|
case CAPTURE_REQUEST_STRIP:
|
||||||
fp_dbg("request strip");
|
fp_dbg("request strip");
|
||||||
@@ -659,27 +668,32 @@ static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_STRIP: ;
|
case CAPTURE_READ_STRIP: ;
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = g_malloc(STRIP_CAPTURE_LEN);
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, STRIP_CAPTURE_LEN,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = g_malloc(665);
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 665,
|
||||||
capture_read_strip_cb, ssm, BULK_TIMEOUT);
|
capture_read_strip_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
if (aesdev->deactivating)
|
if (aesdev->deactivating)
|
||||||
@@ -693,16 +707,17 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,9 +738,9 @@ enum activate_states {
|
|||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
||||||
/* verify theres anything missing here */
|
/* verify theres anything missing here */
|
||||||
@@ -738,9 +753,9 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* jump to finger detection */
|
/* jump to finger detection */
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
||||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||||
|
|
||||||
@@ -751,9 +766,10 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
aesdev->read_regs_retry_count = 0;
|
aesdev->read_regs_retry_count = 0;
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -761,7 +777,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
/* FIXME: audit cancellation points, probably need more, specifically
|
/* FIXME: audit cancellation points, probably need more, specifically
|
||||||
* in error handling paths? */
|
* in error handling paths? */
|
||||||
aesdev->deactivating = TRUE;
|
aesdev->deactivating = TRUE;
|
||||||
@@ -769,7 +785,7 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
||||||
@@ -789,14 +805,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aes1610_dev *aesdev;
|
struct aes1610_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aes1610_dev));
|
aesdev = g_malloc0(sizeof(struct aes1610_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -804,9 +820,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes1610_dev *aesdev;
|
struct aes1610_dev *aesdev;
|
||||||
aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aesX660_dev *aesdev;
|
struct aesX660_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aesX660_dev));
|
aesdev = g_malloc0(sizeof(struct aesX660_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE);
|
aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE);
|
||||||
aesdev->init_seqs[0] = aes1660_init_1;
|
aesdev->init_seqs[0] = aes1660_init_1;
|
||||||
aesdev->init_seqs_len[0] = G_N_ELEMENTS(aes1660_init_1);
|
aesdev->init_seqs_len[0] = G_N_ELEMENTS(aes1660_init_1);
|
||||||
@@ -64,10 +64,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev->buffer);
|
g_free(aesdev->buffer);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,11 +36,6 @@ static void complete_deactivation(struct fp_img_dev *dev);
|
|||||||
|
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
#define FINGER_DETECTION_LEN 20
|
|
||||||
#define READ_REGS_LEN 126
|
|
||||||
#define READ_REGS_RESP_LEN 159
|
|
||||||
#define STRIP_CAPTURE_LEN 1705
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The AES2501 is an imaging device using a swipe-type sensor. It samples
|
* The AES2501 is an imaging device using a swipe-type sensor. It samples
|
||||||
* the finger at preprogrammed intervals, sending a 192x16 frame to the
|
* the finger at preprogrammed intervals, sending a 192x16 frame to the
|
||||||
@@ -88,12 +83,9 @@ struct aes2501_read_regs {
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void read_regs_data_cb(struct libusb_transfer *transfer,
|
static void read_regs_data_cb(struct libusb_transfer *transfer)
|
||||||
struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
struct aes2501_read_regs *rdata = user_data;
|
struct aes2501_read_regs *rdata = transfer->user_data;
|
||||||
unsigned char *retdata = NULL;
|
unsigned char *retdata = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -108,12 +100,14 @@ static void read_regs_data_cb(struct libusb_transfer *transfer,
|
|||||||
|
|
||||||
rdata->callback(rdata->dev, r, retdata, rdata->user_data);
|
rdata->callback(rdata->dev, r, retdata, rdata->user_data);
|
||||||
g_free(rdata);
|
g_free(rdata);
|
||||||
|
g_free(transfer->buffer);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
|
static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
|
||||||
{
|
{
|
||||||
struct aes2501_read_regs *rdata = user_data;
|
struct aes2501_read_regs *rdata = user_data;
|
||||||
fpi_usb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -121,18 +115,20 @@ static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
data = g_malloc(READ_REGS_LEN);
|
transfer = libusb_alloc_transfer(0);
|
||||||
transfer = fpi_usb_fill_bulk_transfer(FP_DEV(dev),
|
if (!transfer) {
|
||||||
NULL,
|
result = -ENOMEM;
|
||||||
EP_IN,
|
goto err;
|
||||||
data,
|
}
|
||||||
READ_REGS_LEN,
|
|
||||||
read_regs_data_cb,
|
|
||||||
rdata,
|
|
||||||
BULK_TIMEOUT);
|
|
||||||
|
|
||||||
r = fpi_usb_submit_transfer(transfer);
|
data = g_malloc(126);
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 126,
|
||||||
|
read_regs_data_cb, rdata, BULK_TIMEOUT);
|
||||||
|
|
||||||
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
result = -EIO;
|
result = -EIO;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -184,48 +180,53 @@ static int regval_from_dump(unsigned char *data, uint8_t target)
|
|||||||
static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, result);
|
fpi_ssm_mark_aborted(ssm, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that read succeeded but ignore all data */
|
/* check that read succeeded but ignore all data */
|
||||||
static void generic_ignore_data_cb(struct libusb_transfer *transfer,
|
static void generic_ignore_data_cb(struct libusb_transfer *transfer)
|
||||||
struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else if (transfer->length != transfer->actual_length)
|
else if (transfer->length != transfer->actual_length)
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
||||||
|
g_free(transfer->buffer);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the specified number of bytes from the IN endpoint but throw them
|
/* read the specified number of bytes from the IN endpoint but throw them
|
||||||
* away, then increment the SSM */
|
* away, then increment the SSM */
|
||||||
static void generic_read_ignore_data(fpi_ssm *ssm, struct fp_dev *dev, size_t bytes)
|
static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
|
||||||
{
|
{
|
||||||
fpi_usb_transfer *transfer;
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
data = g_malloc(bytes);
|
if (!transfer) {
|
||||||
transfer = fpi_usb_fill_bulk_transfer(dev,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
ssm,
|
return;
|
||||||
EP_IN,
|
}
|
||||||
data,
|
|
||||||
bytes,
|
|
||||||
generic_ignore_data_cb,
|
|
||||||
NULL,
|
|
||||||
BULK_TIMEOUT);
|
|
||||||
|
|
||||||
r = fpi_usb_submit_transfer(transfer);
|
data = g_malloc(bytes);
|
||||||
if (r < 0)
|
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes,
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
generic_ignore_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
|
r = libusb_submit_transfer(transfer);
|
||||||
|
if (r < 0) {
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** IMAGE PROCESSING ******/
|
/****** IMAGE PROCESSING ******/
|
||||||
@@ -281,22 +282,19 @@ static const struct aes_regwrite finger_det_reqs[] = {
|
|||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev);
|
static void start_finger_detection(struct fp_img_dev *dev);
|
||||||
|
|
||||||
static void finger_det_data_cb(struct libusb_transfer *transfer,
|
static void finger_det_data_cb(struct libusb_transfer *transfer)
|
||||||
struct fp_dev *_dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fp_img_dev *dev = transfer->user_data;
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
return;
|
goto out;
|
||||||
} else if (transfer->length != transfer->actual_length) {
|
} else if (transfer->length != transfer->actual_length) {
|
||||||
fpi_imgdev_session_error(dev, -EPROTO);
|
fpi_imgdev_session_error(dev, -EPROTO);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* examine histogram to determine finger presence */
|
/* examine histogram to determine finger presence */
|
||||||
@@ -310,12 +308,16 @@ static void finger_det_data_cb(struct libusb_transfer *transfer,
|
|||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(struct fp_img_dev *dev, int result,
|
static void finger_det_reqs_cb(struct fp_img_dev *dev, int result,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
fpi_usb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -324,24 +326,27 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = g_malloc(FINGER_DETECTION_LEN);
|
transfer = libusb_alloc_transfer(0);
|
||||||
transfer = fpi_usb_fill_bulk_transfer(FP_DEV(dev),
|
if (!transfer) {
|
||||||
NULL,
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
EP_IN,
|
return;
|
||||||
data,
|
}
|
||||||
FINGER_DETECTION_LEN,
|
|
||||||
finger_det_data_cb,
|
|
||||||
NULL,
|
|
||||||
BULK_TIMEOUT);
|
|
||||||
|
|
||||||
r = fpi_usb_submit_transfer(transfer);
|
data = g_malloc(20);
|
||||||
if (r < 0)
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 20,
|
||||||
|
finger_det_data_cb, dev, BULK_TIMEOUT);
|
||||||
|
|
||||||
|
r = libusb_submit_transfer(transfer);
|
||||||
|
if (r < 0) {
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
fpi_imgdev_session_error(dev, r);
|
fpi_imgdev_session_error(dev, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
@@ -428,37 +433,35 @@ enum capture_states {
|
|||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_read_strip_cb(struct libusb_transfer *transfer,
|
static void capture_read_strip_cb(struct libusb_transfer *transfer)
|
||||||
struct fp_dev *_dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int sum;
|
int sum;
|
||||||
int threshold;
|
int threshold;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
goto out;
|
||||||
} else if (transfer->length != transfer->actual_length) {
|
} else if (transfer->length != transfer->actual_length) {
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
|
threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
|
||||||
AES2501_REG_DATFMT);
|
AES2501_REG_DATFMT);
|
||||||
if (threshold < 0) {
|
if (threshold < 0) {
|
||||||
fpi_ssm_mark_failed(ssm, threshold);
|
fpi_ssm_mark_aborted(ssm, threshold);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f);
|
sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f);
|
||||||
if (sum < 0) {
|
if (sum < 0) {
|
||||||
fpi_ssm_mark_failed(ssm, sum);
|
fpi_ssm_mark_aborted(ssm, sum);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
fp_dbg("sum=%d", sum);
|
fp_dbg("sum=%d", sum);
|
||||||
|
|
||||||
@@ -511,12 +514,16 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer,
|
|||||||
|
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
|
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
@@ -525,14 +532,14 @@ static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA_1:
|
case CAPTURE_READ_DATA_1:
|
||||||
generic_read_ignore_data(ssm, _dev, READ_REGS_RESP_LEN);
|
generic_read_ignore_data(ssm, 159);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_WRITE_REQS_2:
|
case CAPTURE_WRITE_REQS_2:
|
||||||
aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
|
aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA_2:
|
case CAPTURE_READ_DATA_2:
|
||||||
generic_read_ignore_data(ssm, _dev, READ_REGS_RESP_LEN);
|
generic_read_ignore_data(ssm, 159);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_REQUEST_STRIP:
|
case CAPTURE_REQUEST_STRIP:
|
||||||
if (aesdev->deactivating)
|
if (aesdev->deactivating)
|
||||||
@@ -542,30 +549,32 @@ static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_STRIP: ;
|
case CAPTURE_READ_STRIP: ;
|
||||||
fpi_usb_transfer *transfer;
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = g_malloc(STRIP_CAPTURE_LEN);
|
if (!transfer) {
|
||||||
transfer = fpi_usb_fill_bulk_transfer(FP_DEV(dev),
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
ssm,
|
break;
|
||||||
EP_IN,
|
}
|
||||||
data,
|
|
||||||
STRIP_CAPTURE_LEN,
|
|
||||||
capture_read_strip_cb,
|
|
||||||
NULL,
|
|
||||||
BULK_TIMEOUT);
|
|
||||||
|
|
||||||
r = fpi_usb_submit_transfer(transfer);
|
data = g_malloc(1705);
|
||||||
if (r < 0)
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 1705,
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
capture_read_strip_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
|
r = libusb_submit_transfer(transfer);
|
||||||
|
if (r < 0) {
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
if (aesdev->deactivating)
|
if (aesdev->deactivating)
|
||||||
@@ -579,8 +588,8 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
@@ -590,8 +599,9 @@ static void start_capture(struct fp_img_dev *dev)
|
|||||||
aesdev->no_finger_cnt = 0;
|
aesdev->no_finger_cnt = 0;
|
||||||
/* Reset gain */
|
/* Reset gain */
|
||||||
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,11 +713,11 @@ enum activate_states {
|
|||||||
void activate_read_regs_cb(struct fp_img_dev *dev, int status,
|
void activate_read_regs_cb(struct fp_img_dev *dev, int status,
|
||||||
unsigned char *regs, void *user_data)
|
unsigned char *regs, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
fpi_ssm_mark_failed(ssm, status);
|
fpi_ssm_mark_aborted(ssm, status);
|
||||||
} else {
|
} else {
|
||||||
fp_dbg("reg 0xaf = %x", regs[0x5f]);
|
fp_dbg("reg 0xaf = %x", regs[0x5f]);
|
||||||
if (regs[0x5f] != 0x6b || ++aesdev->read_regs_retry_count == 13)
|
if (regs[0x5f] != 0x6b || ++aesdev->read_regs_retry_count == 13)
|
||||||
@@ -720,16 +730,16 @@ void activate_read_regs_cb(struct fp_img_dev *dev, int status,
|
|||||||
static void activate_init3_cb(struct fp_img_dev *dev, int result,
|
static void activate_init3_cb(struct fp_img_dev *dev, int result,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
fpi_ssm_jump_to_state(ssm, READ_REGS);
|
fpi_ssm_jump_to_state(ssm, READ_REGS);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, result);
|
fpi_ssm_mark_aborted(ssm, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
/* This state machine isn't as linear as it may appear. After doing init1
|
/* This state machine isn't as linear as it may appear. After doing init1
|
||||||
* and init2 register configuration writes, we have to poll a register
|
* and init2 register configuration writes, we have to poll a register
|
||||||
@@ -757,7 +767,7 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
break;
|
break;
|
||||||
case READ_DATA_1:
|
case READ_DATA_1:
|
||||||
fp_dbg("read data 1");
|
fp_dbg("read data 1");
|
||||||
generic_read_ignore_data(ssm, _dev, FINGER_DETECTION_LEN);
|
generic_read_ignore_data(ssm, 20);
|
||||||
break;
|
break;
|
||||||
case WRITE_INIT_2:
|
case WRITE_INIT_2:
|
||||||
aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2),
|
aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2),
|
||||||
@@ -781,9 +791,9 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
||||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||||
|
|
||||||
@@ -794,9 +804,10 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
aesdev->read_regs_retry_count = 0;
|
aesdev->read_regs_retry_count = 0;
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -804,7 +815,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
/* FIXME: audit cancellation points, probably need more, specifically
|
/* FIXME: audit cancellation points, probably need more, specifically
|
||||||
* in error handling paths? */
|
* in error handling paths? */
|
||||||
aesdev->deactivating = TRUE;
|
aesdev->deactivating = TRUE;
|
||||||
@@ -812,7 +823,7 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
||||||
@@ -831,23 +842,23 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aes2501_dev *aesdev;
|
struct aes2501_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aes2501_dev));
|
aesdev = g_malloc0(sizeof(struct aes2501_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,10 +125,15 @@ static void finger_det_reqs_cb(struct libusb_transfer *t)
|
|||||||
goto exit_free_transfer;
|
goto exit_free_transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
goto exit_free_transfer;
|
||||||
|
}
|
||||||
|
|
||||||
/* 2 bytes of result */
|
/* 2 bytes of result */
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
||||||
finger_det_data_cb, dev, BULK_TIMEOUT);
|
finger_det_data_cb, dev, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -144,7 +149,7 @@ exit_free_transfer:
|
|||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
@@ -153,8 +158,12 @@ static void start_finger_detection(struct fp_img_dev *dev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, finger_det_reqs,
|
if (!transfer) {
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, finger_det_reqs,
|
||||||
sizeof(finger_det_reqs), finger_det_reqs_cb, dev, BULK_TIMEOUT);
|
sizeof(finger_det_reqs), finger_det_reqs_cb, dev, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -191,10 +200,11 @@ enum capture_states {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static int process_strip_data(fpi_ssm *ssm, struct fp_img_dev *dev, unsigned char *data)
|
static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data)
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
struct fpi_frame *stripe;
|
struct fpi_frame *stripe;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -221,22 +231,22 @@ static int process_strip_data(fpi_ssm *ssm, struct fp_img_dev *dev, unsigned cha
|
|||||||
|
|
||||||
static void capture_reqs_cb(struct libusb_transfer *transfer)
|
static void capture_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer)
|
static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length) &&
|
(transfer->length == transfer->actual_length) &&
|
||||||
@@ -255,22 +265,22 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer)
|
|||||||
/* marking machine complete will re-trigger finger detection loop */
|
/* marking machine complete will re-trigger finger detection loop */
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fp_dbg("request is not completed, %d", transfer->status);
|
fp_dbg("request is not completed, %d", transfer->status);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,10 +290,10 @@ static void capture_read_data_cb(struct libusb_transfer *transfer)
|
|||||||
|
|
||||||
switch (transfer->actual_length) {
|
switch (transfer->actual_length) {
|
||||||
case AES2550_STRIP_SIZE:
|
case AES2550_STRIP_SIZE:
|
||||||
r = process_strip_data(ssm, dev, data);
|
r = process_strip_data(ssm, data);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_dbg("Processing strip data failed: %d", r);
|
fp_dbg("Processing strip data failed: %d", r);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
aesdev->heartbeat_cnt = 0;
|
aesdev->heartbeat_cnt = 0;
|
||||||
@@ -313,62 +323,73 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPTURE_WRITE_REQS:
|
case CAPTURE_WRITE_REQS:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, capture_reqs,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, capture_reqs,
|
||||||
sizeof(capture_reqs), capture_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(capture_reqs), capture_reqs_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
||||||
capture_read_data_cb, ssm, BULK_TIMEOUT);
|
capture_read_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_SET_IDLE:
|
case CAPTURE_SET_IDLE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, capture_set_idle_reqs,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, capture_set_idle_reqs,
|
||||||
sizeof(capture_set_idle_reqs), capture_set_idle_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(capture_set_idle_reqs), capture_set_idle_reqs_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg("Capture completed");
|
||||||
if (aesdev->deactivating)
|
if (aesdev->deactivating)
|
||||||
@@ -382,8 +403,8 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
@@ -391,8 +412,9 @@ static void start_capture(struct fp_img_dev *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
aesdev->heartbeat_cnt = 0;
|
aesdev->heartbeat_cnt = 0;
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,25 +444,25 @@ enum activate_states {
|
|||||||
|
|
||||||
static void init_reqs_cb(struct libusb_transfer *transfer)
|
static void init_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_read_data_cb(struct libusb_transfer *transfer)
|
static void init_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
@@ -450,89 +472,105 @@ static void init_read_data_cb(struct libusb_transfer *transfer)
|
|||||||
* need more info for implementaion */
|
* need more info for implementaion */
|
||||||
static void calibrate_read_data_cb(struct libusb_transfer *transfer)
|
static void calibrate_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case WRITE_INIT:
|
case WRITE_INIT:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, init_reqs,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, init_reqs,
|
||||||
sizeof(init_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(init_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_DATA:
|
case READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
||||||
init_read_data_cb, ssm, BULK_TIMEOUT);
|
init_read_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CALIBRATE:
|
case CALIBRATE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, calibrate_reqs,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, calibrate_reqs,
|
||||||
sizeof(calibrate_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(calibrate_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_CALIB_TABLE:
|
case READ_CALIB_TABLE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
||||||
calibrate_read_data_cb, ssm, BULK_TIMEOUT);
|
calibrate_read_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
||||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||||
|
|
||||||
@@ -543,22 +581,23 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
aesdev->deactivating = TRUE;
|
aesdev->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
aesdev->deactivating = FALSE;
|
aesdev->deactivating = FALSE;
|
||||||
@@ -574,14 +613,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aes2550_dev *aes2550_dev;
|
struct aes2550_dev *aes2550_dev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aes2550_dev = g_malloc0(sizeof(struct aes2550_dev));
|
aes2550_dev = g_malloc0(sizeof(struct aes2550_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aes2550_dev);
|
fpi_imgdev_set_user_data(dev, aes2550_dev);
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -589,9 +628,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev;
|
struct aes2550_dev *aesdev;
|
||||||
aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aesX660_dev *aesdev;
|
struct aesX660_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aesX660_dev));
|
aesdev = g_malloc0(sizeof(struct aesX660_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE);
|
aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE);
|
||||||
/* No scaling for AES2660 */
|
/* No scaling for AES2660 */
|
||||||
aesdev->init_seqs[0] = aes2660_init_1;
|
aesdev->init_seqs[0] = aes2660_init_1;
|
||||||
@@ -66,10 +66,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev;
|
struct aesX660_dev *aesdev;
|
||||||
aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev->buffer);
|
g_free(aesdev->buffer);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,14 +122,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aes3k_dev *aesdev;
|
struct aes3k_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aes3k_dev));
|
aesdev = g_malloc0(sizeof(struct aes3k_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
|
|
||||||
if (!aesdev)
|
if (!aesdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -148,9 +148,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static void aes3k_assemble_image(unsigned char *input, size_t width, size_t heig
|
|||||||
static void img_cb(struct libusb_transfer *transfer)
|
static void img_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = transfer->user_data;
|
struct fp_img_dev *dev = transfer->user_data;
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *ptr = transfer->buffer;
|
unsigned char *ptr = transfer->buffer;
|
||||||
struct fp_img *tmp;
|
struct fp_img *tmp;
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
@@ -94,7 +94,7 @@ static void img_cb(struct libusb_transfer *transfer)
|
|||||||
|
|
||||||
/* FIXME: this is an ugly hack to make the image big enough for NBIS
|
/* FIXME: this is an ugly hack to make the image big enough for NBIS
|
||||||
* to process reliably */
|
* to process reliably */
|
||||||
img = fpi_img_resize(tmp, aesdev->enlarge_factor, aesdev->enlarge_factor);
|
img = fpi_im_resize(tmp, aesdev->enlarge_factor, aesdev->enlarge_factor);
|
||||||
fp_img_free(tmp);
|
fp_img_free(tmp);
|
||||||
fpi_imgdev_image_captured(dev, img);
|
fpi_imgdev_image_captured(dev, img);
|
||||||
|
|
||||||
@@ -112,13 +112,18 @@ err:
|
|||||||
|
|
||||||
static void do_capture(struct fp_img_dev *dev)
|
static void do_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
aesdev->img_trf = fpi_usb_alloc();
|
aesdev->img_trf = libusb_alloc_transfer(0);
|
||||||
|
if (!aesdev->img_trf) {
|
||||||
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(aesdev->data_buflen);
|
data = g_malloc(aesdev->data_buflen);
|
||||||
libusb_fill_bulk_transfer(aesdev->img_trf, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data,
|
libusb_fill_bulk_transfer(aesdev->img_trf, fpi_imgdev_get_usb_dev(dev), EP_IN, data,
|
||||||
aesdev->data_buflen, img_cb, dev, 0);
|
aesdev->data_buflen, img_cb, dev, 0);
|
||||||
|
|
||||||
r = libusb_submit_transfer(aesdev->img_trf);
|
r = libusb_submit_transfer(aesdev->img_trf);
|
||||||
@@ -139,14 +144,14 @@ static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data)
|
|||||||
|
|
||||||
int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
aes_write_regv(dev, aesdev->init_reqs, aesdev->init_reqs_len, init_reqs_cb, NULL);
|
aes_write_regv(dev, aesdev->init_reqs, aesdev->init_reqs_len, init_reqs_cb, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes3k_dev_deactivate(struct fp_img_dev *dev)
|
void aes3k_dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* FIXME: should wait for cancellation to complete before returning
|
/* FIXME: should wait for cancellation to complete before returning
|
||||||
* from deactivation, otherwise app may legally exit before we've
|
* from deactivation, otherwise app may legally exit before we've
|
||||||
|
|||||||
@@ -119,14 +119,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct aes3k_dev *aesdev;
|
struct aes3k_dev *aesdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev = g_malloc0(sizeof(struct aes3k_dev));
|
aesdev = g_malloc0(sizeof(struct aes3k_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aesdev);
|
fpi_imgdev_set_user_data(dev, aesdev);
|
||||||
|
|
||||||
if (!aesdev)
|
if (!aesdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -145,9 +145,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(aesdev);
|
g_free(aesdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,57 +35,52 @@ static void complete_deactivation(struct fp_img_dev *dev);
|
|||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
#define FRAME_HEIGHT AESX660_FRAME_HEIGHT
|
#define FRAME_HEIGHT AESX660_FRAME_HEIGHT
|
||||||
|
|
||||||
#define ID_LEN 8
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#define INIT_LEN 4
|
|
||||||
#define CALIBRATE_DATA_LEN 4
|
|
||||||
#define FINGER_DET_DATA_LEN 4
|
|
||||||
|
|
||||||
static void
|
static void aesX660_send_cmd_timeout(struct fpi_ssm *ssm, const unsigned char *cmd,
|
||||||
aesX660_send_cmd_timeout(fpi_ssm *ssm,
|
size_t cmd_len, libusb_transfer_cb_fn callback, int timeout)
|
||||||
struct fp_dev *_dev,
|
|
||||||
const unsigned char *cmd,
|
|
||||||
size_t cmd_len,
|
|
||||||
libusb_transfer_cb_fn callback,
|
|
||||||
int timeout)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT,
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT,
|
||||||
(unsigned char *)cmd, cmd_len,
|
(unsigned char *)cmd, cmd_len,
|
||||||
callback, ssm, timeout);
|
callback, ssm, timeout);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_dbg("failed to submit transfer\n");
|
fp_dbg("failed to submit transfer\n");
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void aesX660_send_cmd(struct fpi_ssm *ssm, const unsigned char *cmd,
|
||||||
aesX660_send_cmd(fpi_ssm *ssm,
|
size_t cmd_len, libusb_transfer_cb_fn callback)
|
||||||
struct fp_dev *dev,
|
|
||||||
const unsigned char *cmd,
|
|
||||||
size_t cmd_len,
|
|
||||||
libusb_transfer_cb_fn callback)
|
|
||||||
{
|
{
|
||||||
return aesX660_send_cmd_timeout(ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
|
return aesX660_send_cmd_timeout(ssm, cmd, cmd_len, callback, BULK_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len,
|
||||||
aesX660_read_response(fpi_ssm *ssm,
|
libusb_transfer_cb_fn callback)
|
||||||
struct fp_dev *_dev,
|
|
||||||
size_t buf_len,
|
|
||||||
libusb_transfer_cb_fn callback)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(buf_len);
|
data = g_malloc(buf_len);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN,
|
||||||
data, buf_len,
|
data, buf_len,
|
||||||
callback, ssm, BULK_TIMEOUT);
|
callback, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
@@ -94,13 +89,13 @@ aesX660_read_response(fpi_ssm *ssm,
|
|||||||
fp_dbg("Failed to submit rx transfer: %d\n", r);
|
fp_dbg("Failed to submit rx transfer: %d\n", r);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_send_cmd_cb(struct libusb_transfer *transfer)
|
static void aesX660_send_cmd_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
@@ -108,25 +103,25 @@ static void aesX660_send_cmd_cb(struct libusb_transfer *transfer)
|
|||||||
} else {
|
} else {
|
||||||
fp_dbg("tx transfer status: %d, actual_len: %.4x\n",
|
fp_dbg("tx transfer status: %d, actual_len: %.4x\n",
|
||||||
transfer->status, transfer->actual_length);
|
transfer->status, transfer->actual_length);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_read_calibrate_data_cb(struct libusb_transfer *transfer)
|
static void aesX660_read_calibrate_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->length != transfer->actual_length)) {
|
(transfer->length != transfer->actual_length)) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Calibrate response was read correctly? */
|
/* Calibrate response was read correctly? */
|
||||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
|
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
|
||||||
fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
|
fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +143,9 @@ enum finger_det_states {
|
|||||||
|
|
||||||
static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer)
|
static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
aesdev->fd_data_transfer = NULL;
|
aesdev->fd_data_transfer = NULL;
|
||||||
@@ -164,13 +159,13 @@ static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer)
|
|||||||
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->length != transfer->actual_length)) {
|
(transfer->length != transfer->actual_length)) {
|
||||||
fp_dbg("Failed to read FD data\n");
|
fp_dbg("Failed to read FD data\n");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
|
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
|
||||||
fp_dbg("Bogus FD response: %.2x\n", data[0]);
|
fp_dbg("Bogus FD response: %.2x\n", data[0]);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,21 +184,21 @@ out:
|
|||||||
|
|
||||||
static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer)
|
static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void finger_det_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fp_dbg("Finger detection completed");
|
fp_dbg("Finger detection completed");
|
||||||
@@ -220,22 +215,23 @@ static void finger_det_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void finger_det_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case FINGER_DET_SEND_LED_CMD:
|
case FINGER_DET_SEND_LED_CMD:
|
||||||
aesX660_send_cmd(ssm, dev, led_blink_cmd, sizeof(led_blink_cmd),
|
aesX660_send_cmd(ssm, led_blink_cmd, sizeof(led_blink_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case FINGER_DET_SEND_FD_CMD:
|
case FINGER_DET_SEND_FD_CMD:
|
||||||
aesX660_send_cmd_timeout(ssm, dev, wait_for_finger_cmd, sizeof(wait_for_finger_cmd),
|
aesX660_send_cmd_timeout(ssm, wait_for_finger_cmd, sizeof(wait_for_finger_cmd),
|
||||||
aesX660_send_cmd_cb, 0);
|
aesX660_send_cmd_cb, 0);
|
||||||
break;
|
break;
|
||||||
case FINGER_DET_READ_FD_DATA:
|
case FINGER_DET_READ_FD_DATA:
|
||||||
aesX660_read_response(ssm, dev, FINGER_DET_DATA_LEN, finger_det_read_fd_data_cb);
|
/* Should return 4 byte of response */
|
||||||
|
aesX660_read_response(ssm, 4, finger_det_read_fd_data_cb);
|
||||||
break;
|
break;
|
||||||
case FINGER_DET_SET_IDLE:
|
case FINGER_DET_SET_IDLE:
|
||||||
aesX660_send_cmd(ssm, dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
|
||||||
finger_det_set_idle_cmd_cb);
|
finger_det_set_idle_cmd_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -243,15 +239,16 @@ static void finger_det_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_da
|
|||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), finger_det_run_state, FINGER_DET_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), finger_det_run_state, FINGER_DET_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, finger_det_sm_complete);
|
fpi_ssm_start(ssm, finger_det_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,11 +263,12 @@ enum capture_states {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static int process_stripe_data(fpi_ssm *ssm, struct fp_img_dev *dev, unsigned char *data)
|
static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data)
|
||||||
{
|
{
|
||||||
struct fpi_frame *stripe;
|
struct fpi_frame *stripe;
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
|
stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
@@ -288,17 +286,17 @@ static int process_stripe_data(fpi_ssm *ssm, struct fp_img_dev *dev, unsigned ch
|
|||||||
aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
|
aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
|
||||||
aesdev->strips_len++;
|
aesdev->strips_len++;
|
||||||
return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
|
return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(stripe);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
|
static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
@@ -315,28 +313,28 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
|
|||||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
fpi_imgdev_report_finger_status(dev, FALSE);
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_stripe_data_cb(struct libusb_transfer *transfer)
|
static void capture_read_stripe_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int finger_missing = 0;
|
int finger_missing = 0;
|
||||||
size_t copied, actual_len = transfer->actual_length;
|
size_t copied, actual_len = transfer->actual_length;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("Got %lu bytes of data", actual_len);
|
fp_dbg("Got %lu bytes of data", actual_len);
|
||||||
do {
|
do {
|
||||||
copied = MIN(aesdev->buffer_max - aesdev->buffer_size, actual_len);
|
copied = min(aesdev->buffer_max - aesdev->buffer_size, actual_len);
|
||||||
memcpy(aesdev->buffer + aesdev->buffer_size,
|
memcpy(aesdev->buffer + aesdev->buffer_size,
|
||||||
data,
|
data,
|
||||||
copied);
|
copied);
|
||||||
@@ -354,7 +352,7 @@ static void capture_read_stripe_data_cb(struct libusb_transfer *transfer)
|
|||||||
aesdev->buffer_max);
|
aesdev->buffer_max);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
finger_missing |= process_stripe_data(ssm, dev, aesdev->buffer);
|
finger_missing |= process_stripe_data(ssm, aesdev->buffer);
|
||||||
aesdev->buffer_max = AESX660_HEADER_SIZE;
|
aesdev->buffer_max = AESX660_HEADER_SIZE;
|
||||||
aesdev->buffer_size = 0;
|
aesdev->buffer_size = 0;
|
||||||
}
|
}
|
||||||
@@ -373,38 +371,39 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPTURE_SEND_LED_CMD:
|
case CAPTURE_SEND_LED_CMD:
|
||||||
aesX660_send_cmd(ssm, _dev, led_solid_cmd, sizeof(led_solid_cmd),
|
aesX660_send_cmd(ssm, led_solid_cmd, sizeof(led_solid_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_SEND_CAPTURE_CMD:
|
case CAPTURE_SEND_CAPTURE_CMD:
|
||||||
aesdev->buffer_size = 0;
|
aesdev->buffer_size = 0;
|
||||||
aesdev->buffer_max = AESX660_HEADER_SIZE;
|
aesdev->buffer_max = AESX660_HEADER_SIZE;
|
||||||
aesX660_send_cmd(ssm, _dev, aesdev->start_imaging_cmd,
|
aesX660_send_cmd(ssm, aesdev->start_imaging_cmd,
|
||||||
aesdev->start_imaging_cmd_len,
|
aesdev->start_imaging_cmd_len,
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_STRIPE_DATA:
|
case CAPTURE_READ_STRIPE_DATA:
|
||||||
aesX660_read_response(ssm, _dev, AESX660_BULK_TRANSFER_SIZE,
|
aesX660_read_response(ssm, AESX660_BULK_TRANSFER_SIZE,
|
||||||
capture_read_stripe_data_cb);
|
capture_read_stripe_data_cb);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_SET_IDLE:
|
case CAPTURE_SET_IDLE:
|
||||||
fp_dbg("Got %lu frames\n", aesdev->strips_len);
|
fp_dbg("Got %lu frames\n", aesdev->strips_len);
|
||||||
aesX660_send_cmd(ssm, _dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
|
||||||
capture_set_idle_cmd_cb);
|
capture_set_idle_cmd_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg("Capture completed");
|
||||||
@@ -420,16 +419,17 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (aesdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,15 +448,15 @@ enum activate_states {
|
|||||||
|
|
||||||
static void activate_read_id_cb(struct libusb_transfer *transfer)
|
static void activate_read_id_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->length != transfer->actual_length)) {
|
(transfer->length != transfer->actual_length)) {
|
||||||
fp_dbg("read_id cmd failed\n");
|
fp_dbg("read_id cmd failed\n");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* ID was read correctly */
|
/* ID was read correctly */
|
||||||
@@ -465,7 +465,7 @@ static void activate_read_id_cb(struct libusb_transfer *transfer)
|
|||||||
data[4], data[3], data[5], data[6], data[7]);
|
data[4], data[3], data[5], data[6], data[7]);
|
||||||
} else {
|
} else {
|
||||||
fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
|
fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +487,7 @@ static void activate_read_id_cb(struct libusb_transfer *transfer)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_dbg("Failed to init device! init status: %.2x\n", data[7]);
|
fp_dbg("Failed to init device! init status: %.2x\n", data[7]);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -499,9 +499,9 @@ out:
|
|||||||
|
|
||||||
static void activate_read_init_cb(struct libusb_transfer *transfer)
|
static void activate_read_init_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
fp_dbg("read_init_cb\n");
|
fp_dbg("read_init_cb\n");
|
||||||
@@ -509,14 +509,14 @@ static void activate_read_init_cb(struct libusb_transfer *transfer)
|
|||||||
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->length != transfer->actual_length)) {
|
(transfer->length != transfer->actual_length)) {
|
||||||
fp_dbg("read_init transfer status: %d, actual_len: %d\n", transfer->status, transfer->actual_length);
|
fp_dbg("read_init transfer status: %d, actual_len: %d\n", transfer->status, transfer->actual_length);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* ID was read correctly */
|
/* ID was read correctly */
|
||||||
if (data[0] != 0x42 || data[3] != 0x01) {
|
if (data[0] != 0x42 || data[3] != 0x01) {
|
||||||
fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
|
fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
|
||||||
data[3]);
|
data[3]);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
aesdev->init_cmd_idx++;
|
aesdev->init_cmd_idx++;
|
||||||
@@ -534,52 +534,55 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case ACTIVATE_SET_IDLE:
|
case ACTIVATE_SET_IDLE:
|
||||||
aesdev->init_seq_idx = 0;
|
aesdev->init_seq_idx = 0;
|
||||||
fp_dbg("Activate: set idle\n");
|
fp_dbg("Activate: set idle\n");
|
||||||
aesX660_send_cmd(ssm, _dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_SEND_READ_ID_CMD:
|
case ACTIVATE_SEND_READ_ID_CMD:
|
||||||
fp_dbg("Activate: read ID\n");
|
fp_dbg("Activate: read ID\n");
|
||||||
aesX660_send_cmd(ssm, _dev, read_id_cmd, sizeof(read_id_cmd),
|
aesX660_send_cmd(ssm, read_id_cmd, sizeof(read_id_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_READ_ID:
|
case ACTIVATE_READ_ID:
|
||||||
aesX660_read_response(ssm, _dev, ID_LEN, activate_read_id_cb);
|
/* Should return 8-byte response */
|
||||||
|
aesX660_read_response(ssm, 8, activate_read_id_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_SEND_INIT_CMD:
|
case ACTIVATE_SEND_INIT_CMD:
|
||||||
fp_dbg("Activate: send init seq #%d cmd #%d\n",
|
fp_dbg("Activate: send init seq #%d cmd #%d\n",
|
||||||
aesdev->init_seq_idx,
|
aesdev->init_seq_idx,
|
||||||
aesdev->init_cmd_idx);
|
aesdev->init_cmd_idx);
|
||||||
aesX660_send_cmd(ssm, _dev,
|
aesX660_send_cmd(ssm,
|
||||||
aesdev->init_seq[aesdev->init_cmd_idx].cmd,
|
aesdev->init_seq[aesdev->init_cmd_idx].cmd,
|
||||||
aesdev->init_seq[aesdev->init_cmd_idx].len,
|
aesdev->init_seq[aesdev->init_cmd_idx].len,
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_READ_INIT_RESPONSE:
|
case ACTIVATE_READ_INIT_RESPONSE:
|
||||||
fp_dbg("Activate: read init response\n");
|
fp_dbg("Activate: read init response\n");
|
||||||
aesX660_read_response(ssm, _dev, INIT_LEN, activate_read_init_cb);
|
/* Should return 4-byte response */
|
||||||
|
aesX660_read_response(ssm, 4, activate_read_init_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_SEND_CALIBRATE_CMD:
|
case ACTIVATE_SEND_CALIBRATE_CMD:
|
||||||
aesX660_send_cmd(ssm, _dev, calibrate_cmd, sizeof(calibrate_cmd),
|
aesX660_send_cmd(ssm, calibrate_cmd, sizeof(calibrate_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_READ_CALIBRATE_DATA:
|
case ACTIVATE_READ_CALIBRATE_DATA:
|
||||||
aesX660_read_response(ssm, _dev, CALIBRATE_DATA_LEN, aesX660_read_calibrate_data_cb);
|
/* Should return 4-byte response */
|
||||||
|
aesX660_read_response(ssm, 4, aesX660_read_calibrate_data_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
fp_dbg("status %d", err);
|
fp_dbg("status %d", err);
|
||||||
fpi_imgdev_activate_complete(dev, err);
|
fpi_imgdev_activate_complete(dev, err);
|
||||||
@@ -591,15 +594,16 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
|
|
||||||
int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aesX660_dev_deactivate(struct fp_img_dev *dev)
|
void aesX660_dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (aesdev->fd_data_transfer)
|
if (aesdev->fd_data_transfer)
|
||||||
libusb_cancel_transfer(aesdev->fd_data_transfer);
|
libusb_cancel_transfer(aesdev->fd_data_transfer);
|
||||||
@@ -609,7 +613,7 @@ void aesX660_dev_deactivate(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct aesX660_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
aesdev->deactivating = FALSE;
|
aesdev->deactivating = FALSE;
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ enum {
|
|||||||
VFS5011_ID = 19,
|
VFS5011_ID = 19,
|
||||||
VFS0050_ID = 20,
|
VFS0050_ID = 20,
|
||||||
ELAN_ID = 21,
|
ELAN_ID = 21,
|
||||||
SYNAPTICS_ID = 22,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,51 +21,26 @@
|
|||||||
#ifndef __ELAN_H
|
#ifndef __ELAN_H
|
||||||
#define __ELAN_H
|
#define __ELAN_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
#define ELAN_VEND_ID 0x04f3
|
/* number of pixels to discard on left and right (along raw image height)
|
||||||
|
* because they have different intensity from the rest of the frame */
|
||||||
/* a default device type */
|
#define ELAN_FRAME_MARGIN 12
|
||||||
#define ELAN_ALL_DEV 0
|
|
||||||
|
|
||||||
/* devices with quirks */
|
|
||||||
#define ELAN_0907 (1 << 0)
|
|
||||||
#define ELAN_0C03 (1 << 1)
|
|
||||||
#define ELAN_0C42 (1 << 2)
|
|
||||||
|
|
||||||
/* devices which don't require frame rotation before assembling */
|
|
||||||
#define ELAN_NOT_ROTATED ELAN_0C03
|
|
||||||
|
|
||||||
/* min FW version that supports calibration */
|
|
||||||
#define ELAN_MIN_CALIBRATION_FW 0x0138
|
|
||||||
|
|
||||||
/* max difference between background image mean and calibration mean
|
|
||||||
* (the response value of get_calib_mean_cmd)*/
|
|
||||||
#define ELAN_CALIBRATION_MAX_DELTA 500
|
|
||||||
|
|
||||||
/* times to retry reading calibration status during one session
|
|
||||||
* generally prevents calibration from looping indefinitely */
|
|
||||||
#define ELAN_CALIBRATION_ATTEMPTS 10
|
|
||||||
|
|
||||||
/* min and max frames in a capture */
|
/* min and max frames in a capture */
|
||||||
#define ELAN_MIN_FRAMES 7
|
#define ELAN_MIN_FRAMES 7
|
||||||
#define ELAN_MAX_FRAMES 30
|
#define ELAN_MAX_FRAMES 30
|
||||||
|
|
||||||
/* crop frames to this height to improve stitching */
|
|
||||||
#define ELAN_MAX_FRAME_HEIGHT 50
|
|
||||||
|
|
||||||
/* number of frames to drop at the end of capture because frames captured
|
/* number of frames to drop at the end of capture because frames captured
|
||||||
* while the finger is being lifted can be bad */
|
* while the finger is being lifted can be bad */
|
||||||
#define ELAN_SKIP_LAST_FRAMES 2
|
#define ELAN_SKIP_LAST_FRAMES 1
|
||||||
|
|
||||||
#define ELAN_CMD_LEN 0x2
|
#define ELAN_CMD_LEN 0x2
|
||||||
#define ELAN_EP_CMD_OUT (0x1 | LIBUSB_ENDPOINT_OUT)
|
#define ELAN_EP_CMD_OUT (0x1 | LIBUSB_ENDPOINT_OUT)
|
||||||
#define ELAN_EP_CMD_IN (0x3 | LIBUSB_ENDPOINT_IN)
|
#define ELAN_EP_CMD_IN (0x3 | LIBUSB_ENDPOINT_IN)
|
||||||
#define ELAN_EP_IMG_IN (0x2 | LIBUSB_ENDPOINT_IN)
|
#define ELAN_EP_IMG_IN (0x2 | LIBUSB_ENDPOINT_IN)
|
||||||
|
|
||||||
/* used as response length to tell the driver to skip reading response */
|
|
||||||
#define ELAN_CMD_SKIP_READ 0
|
|
||||||
|
|
||||||
/* usual command timeout and timeout for when we need to check if the finger is
|
/* usual command timeout and timeout for when we need to check if the finger is
|
||||||
* still on the device */
|
* still on the device */
|
||||||
#define ELAN_CMD_TIMEOUT 10000
|
#define ELAN_CMD_TIMEOUT 10000
|
||||||
@@ -75,150 +50,127 @@ struct elan_cmd {
|
|||||||
unsigned char cmd[ELAN_CMD_LEN];
|
unsigned char cmd[ELAN_CMD_LEN];
|
||||||
int response_len;
|
int response_len;
|
||||||
int response_in;
|
int response_in;
|
||||||
unsigned short devices;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_sensor_dim_cmd = {
|
static const struct elan_cmd get_sensor_dim_cmds[] = {
|
||||||
.cmd = {0x00, 0x0c},
|
{
|
||||||
.response_len = 0x4,
|
.cmd = {0x00, 0x0c},
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_len = 0x4,
|
||||||
.devices = ELAN_ALL_DEV,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_fw_ver_cmd = {
|
static const size_t get_sensor_dim_cmds_len =
|
||||||
.cmd = {0x40, 0x19},
|
G_N_ELEMENTS(get_sensor_dim_cmds);
|
||||||
.response_len = 0x2,
|
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
static const struct elan_cmd init_start_cmds[] = {
|
||||||
.devices = ELAN_ALL_DEV,
|
{
|
||||||
|
.cmd = {0x40, 0x19},
|
||||||
|
.response_len = 0x2,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = {0x40, 0x2a},
|
||||||
|
.response_len = 0x2,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* unknown, returns 0x0 0x1 on 0907 */
|
static const size_t init_start_cmds_len = G_N_ELEMENTS(init_start_cmds);
|
||||||
static const struct elan_cmd activate_cmd_1 = {
|
|
||||||
.cmd = {0x40, 0x2a},
|
|
||||||
.response_len = 0x2,
|
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
|
||||||
.devices = ELAN_0907,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct elan_cmd get_image_cmd = {
|
static const struct elan_cmd read_cmds[] = {
|
||||||
.cmd = {0x00, 0x09},
|
/* raw frame sizes are calculated from image dimesions reported by the
|
||||||
/* raw frame sizes are calculated from image dimensions reported by the
|
|
||||||
* device */
|
* device */
|
||||||
.response_len = -1,
|
{
|
||||||
.response_in = ELAN_EP_IMG_IN,
|
.cmd = {0x00, 0x09},
|
||||||
.devices = ELAN_ALL_DEV,
|
.response_len = -1,
|
||||||
|
.response_in = ELAN_EP_IMG_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd read_sensor_status_cmd = {
|
const size_t read_cmds_len = G_N_ELEMENTS(read_cmds);
|
||||||
.cmd = {0x40, 0x13},
|
|
||||||
.response_len = 0x1,
|
/* issued after data reads during init and calibration */
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
static const struct elan_cmd init_end_cmds[] = {
|
||||||
.devices = ELAN_ALL_DEV,
|
{
|
||||||
|
.cmd = {0x40, 0x24},
|
||||||
|
.response_len = 0x2,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_calib_status_cmd = {
|
static const size_t init_end_cmds_len = G_N_ELEMENTS(init_end_cmds);
|
||||||
.cmd = {0x40, 0x23},
|
|
||||||
.response_len = 0x1,
|
/* same command 2 times
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
* original driver may observe return value to determine how many times it
|
||||||
.devices = ELAN_ALL_DEV,
|
* should be repeated */
|
||||||
|
static const struct elan_cmd calibrate_start_cmds[] = {
|
||||||
|
{
|
||||||
|
.cmd = {0x40, 0x23},
|
||||||
|
.response_len = 0x1,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = {0x40, 0x23},
|
||||||
|
.response_len = 0x1,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_calib_mean_cmd = {
|
static const size_t calibrate_start_cmds_len =
|
||||||
.cmd = {0x40, 0x24},
|
G_N_ELEMENTS(calibrate_start_cmds);
|
||||||
.response_len = 0x2,
|
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
/* issued after data reads during init and calibration */
|
||||||
.devices = ELAN_ALL_DEV,
|
static const struct elan_cmd calibrate_end_cmds[] = {
|
||||||
|
{
|
||||||
|
.cmd = {0x40, 0x24},
|
||||||
|
.response_len = 0x2,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd led_on_cmd = {
|
static const size_t calibrate_end_cmds_len =
|
||||||
.cmd = {0x40, 0x31},
|
G_N_ELEMENTS(calibrate_end_cmds);
|
||||||
.response_len = ELAN_CMD_SKIP_READ,
|
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
static const struct elan_cmd capture_start_cmds[] = {
|
||||||
.devices = ELAN_ALL_DEV,
|
/* led on */
|
||||||
|
{
|
||||||
|
.cmd = {0x40, 0x31},
|
||||||
|
.response_len = 0x0,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* wait for finger
|
static size_t capture_start_cmds_len = G_N_ELEMENTS(capture_start_cmds);
|
||||||
* subsequent read will not complete until finger is placed on the reader */
|
|
||||||
static const struct elan_cmd pre_scan_cmd = {
|
static const struct elan_cmd capture_wait_finger_cmds[] = {
|
||||||
.cmd = {0x40, 0x3f},
|
/* wait for finger
|
||||||
.response_len = 0x1,
|
* subsequent read will not complete until finger is placed on the reader */
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
{
|
||||||
.devices = ELAN_ALL_DEV,
|
.cmd = {0x40, 0x3f},
|
||||||
|
.response_len = 0x1,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* led off, stop waiting for finger */
|
static size_t capture_wait_finger_cmds_len =
|
||||||
static const struct elan_cmd stop_cmd = {
|
G_N_ELEMENTS(capture_wait_finger_cmds);
|
||||||
.cmd = {0x00, 0x0b},
|
|
||||||
.response_len = ELAN_CMD_SKIP_READ,
|
static const struct elan_cmd deactivate_cmds[] = {
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
/* led off */
|
||||||
.devices = ELAN_ALL_DEV,
|
{
|
||||||
|
.cmd = {0x00, 0x0b},
|
||||||
|
.response_len = 0x0,
|
||||||
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_id elan_id_table[] = {
|
static const size_t deactivate_cmds_len = G_N_ELEMENTS(deactivate_cmds);
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0903,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0907,.driver_data = ELAN_0907},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c01,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c02,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c03,.driver_data = ELAN_0C03},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c04,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c05,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c06,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c07,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c08,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c09,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0a,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0b,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0c,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0d,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0e,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c0f,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c10,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c11,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c12,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c13,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c14,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c15,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c16,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c17,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c18,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c19,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1a,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1b,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1c,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1d,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1e,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c1f,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c20,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c21,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c22,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c23,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c24,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c25,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c26,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c27,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c28,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c29,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2a,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2b,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2c,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2d,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2e,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c2f,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c30,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c31,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c32,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c33,.driver_data = ELAN_ALL_DEV},
|
|
||||||
{.vendor = ELAN_VEND_ID,.product = 0x0c42,.driver_data = ELAN_0C42},
|
|
||||||
{0, 0, 0,},
|
|
||||||
};
|
|
||||||
|
|
||||||
static void elan_cmd_done(fpi_ssm *ssm);
|
static void elan_cmd_cb(struct libusb_transfer *transfer);
|
||||||
static void elan_cmd_read(fpi_ssm *ssm, struct fp_img_dev *dev);
|
static void elan_cmd_read(struct fpi_ssm *ssm);
|
||||||
|
static void elan_run_next_cmd(struct fpi_ssm *ssm);
|
||||||
|
|
||||||
static void elan_calibrate(struct fp_img_dev *dev);
|
|
||||||
static void elan_capture(struct fp_img_dev *dev);
|
static void elan_capture(struct fp_img_dev *dev);
|
||||||
static void elan_deactivate(struct fp_img_dev *dev);
|
|
||||||
|
|
||||||
static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -639,11 +639,14 @@ enum {
|
|||||||
static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb,
|
static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb,
|
||||||
void *cb_arg)
|
void *cb_arg)
|
||||||
{
|
{
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (ep == EP_OUT) {
|
if (ep == EP_OUT) {
|
||||||
buffer = (unsigned char *)dev->req;
|
buffer = (unsigned char *)dev->req;
|
||||||
length = dev->req_len;
|
length = dev->req_len;
|
||||||
@@ -653,7 +656,7 @@ static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb,
|
|||||||
} else {
|
} else {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(idev)), ep, buffer, length,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(idev), ep, buffer, length,
|
||||||
cb, cb_arg, BULK_TIMEOUT);
|
cb, cb_arg, BULK_TIMEOUT);
|
||||||
|
|
||||||
if (libusb_submit_transfer(transfer)) {
|
if (libusb_submit_transfer(transfer)) {
|
||||||
@@ -666,14 +669,14 @@ static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb,
|
|||||||
|
|
||||||
static void async_tx_cb(struct libusb_transfer *transfer)
|
static void async_tx_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fp_warn("transfer is not completed (status=%d)",
|
fp_warn("transfer is not completed (status=%d)",
|
||||||
transfer->status);
|
transfer->status);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
} else {
|
} else {
|
||||||
unsigned char endpoint = transfer->endpoint;
|
unsigned char endpoint = transfer->endpoint;
|
||||||
@@ -688,7 +691,7 @@ static void async_tx_cb(struct libusb_transfer *transfer)
|
|||||||
length, actual_length);
|
length, actual_length);
|
||||||
/* Chained with the answer */
|
/* Chained with the answer */
|
||||||
if (async_tx(idev, EP_IN, async_tx_cb, ssm))
|
if (async_tx(idev, EP_IN, async_tx_cb, ssm))
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
} else if (endpoint == EP_IN) {
|
} else if (endpoint == EP_IN) {
|
||||||
dev->ans_len = actual_length;
|
dev->ans_len = actual_length;
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
@@ -696,10 +699,10 @@ static void async_tx_cb(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_exit_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_exit_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case EXIT_SET_REGS_REQ:
|
case EXIT_SET_REGS_REQ:
|
||||||
@@ -721,12 +724,12 @@ static void m_exit_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_exit_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_exit_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
if (fpi_ssm_get_error(ssm)) {
|
if (fpi_ssm_get_error(ssm)) {
|
||||||
fp_err("Error switching the device to idle state");
|
fp_err("Error switching the device to idle state");
|
||||||
@@ -739,16 +742,17 @@ static void m_exit_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
static void m_exit_start(struct fp_img_dev *idev)
|
static void m_exit_start(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(idev), m_exit_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_exit_state,
|
||||||
EXIT_NUM_STATES, idev);
|
EXIT_NUM_STATES);
|
||||||
fp_dbg("Switching device to idle mode");
|
fp_dbg("Switching device to idle mode");
|
||||||
|
fpi_ssm_set_user_data(ssm, idev);
|
||||||
fpi_ssm_start(ssm, m_exit_complete);
|
fpi_ssm_start(ssm, m_exit_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_capture_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_capture_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (dev->is_active == FALSE) {
|
if (dev->is_active == FALSE) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
@@ -823,13 +827,13 @@ static void m_capture_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_capture_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_capture_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (fpi_ssm_get_error(ssm)) {
|
if (fpi_ssm_get_error(ssm)) {
|
||||||
if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) {
|
if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) {
|
||||||
@@ -848,10 +852,10 @@ static void m_capture_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_finger_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_finger_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (dev->is_active == FALSE) {
|
if (dev->is_active == FALSE) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
@@ -941,18 +945,19 @@ static void m_finger_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_finger_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_finger_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
fpi_ssm *ssm_cap;
|
struct fpi_ssm *ssm_cap;
|
||||||
ssm_cap = fpi_ssm_new(FP_DEV(idev), m_capture_state,
|
ssm_cap = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_capture_state,
|
||||||
CAP_NUM_STATES, idev);
|
CAP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm_cap, idev);
|
||||||
fpi_ssm_start(ssm_cap, m_capture_complete);
|
fpi_ssm_start(ssm_cap, m_capture_complete);
|
||||||
} else {
|
} else {
|
||||||
if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) {
|
if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) {
|
||||||
@@ -968,18 +973,19 @@ static void m_finger_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
|
|
||||||
static void m_start_fingerdetect(struct fp_img_dev *idev)
|
static void m_start_fingerdetect(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssmf;
|
struct fpi_ssm *ssmf;
|
||||||
ssmf = fpi_ssm_new(FP_DEV(idev), m_finger_state, FGR_NUM_STATES, idev);
|
ssmf = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_finger_state, FGR_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssmf, idev);
|
||||||
fpi_ssm_start(ssmf, m_finger_complete);
|
fpi_ssm_start(ssmf, m_finger_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tune value of VRT and VRB for contrast and brightness.
|
* Tune value of VRT and VRB for contrast and brightness.
|
||||||
*/
|
*/
|
||||||
static void m_tunevrb_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_tunevrb_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
float hist[5];
|
float hist[5];
|
||||||
|
|
||||||
if (dev->is_active == FALSE) {
|
if (dev->is_active == FALSE) {
|
||||||
@@ -1125,19 +1131,19 @@ static void m_tunevrb_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_tunevrb_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_tunevrb_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
fpi_imgdev_activate_complete(idev, fpi_ssm_get_error(ssm) != 0);
|
fpi_imgdev_activate_complete(idev, fpi_ssm_get_error(ssm) != 0);
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
fp_dbg("Tuning is done. Starting finger detection.");
|
fp_dbg("Tuning is done. Starting finger detection.");
|
||||||
m_start_fingerdetect(idev);
|
m_start_fingerdetect(idev);
|
||||||
} else {
|
} else {
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
fp_err("Error while tuning VRT");
|
fp_err("Error while tuning VRT");
|
||||||
dev->is_active = FALSE;
|
dev->is_active = FALSE;
|
||||||
reset_param(dev);
|
reset_param(dev);
|
||||||
@@ -1150,10 +1156,10 @@ static void m_tunevrb_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
* This function tunes the DCoffset value and adjusts the gain value if
|
* This function tunes the DCoffset value and adjusts the gain value if
|
||||||
* required.
|
* required.
|
||||||
*/
|
*/
|
||||||
static void m_tunedc_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_tunedc_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (dev->is_active == FALSE) {
|
if (dev->is_active == FALSE) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
@@ -1249,20 +1255,21 @@ static void m_tunedc_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_tunedc_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_tunedc_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
fpi_ssm *ssm_tune;
|
struct fpi_ssm *ssm_tune;
|
||||||
ssm_tune = fpi_ssm_new(FP_DEV(idev), m_tunevrb_state,
|
ssm_tune = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_tunevrb_state,
|
||||||
TUNEVRB_NUM_STATES, idev);
|
TUNEVRB_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm_tune, idev);
|
||||||
fpi_ssm_start(ssm_tune, m_tunevrb_complete);
|
fpi_ssm_start(ssm_tune, m_tunevrb_complete);
|
||||||
} else {
|
} else {
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
fp_err("Error while tuning DCOFFSET");
|
fp_err("Error while tuning DCOFFSET");
|
||||||
dev->is_active = FALSE;
|
dev->is_active = FALSE;
|
||||||
reset_param(dev);
|
reset_param(dev);
|
||||||
@@ -1271,10 +1278,10 @@ static void m_tunedc_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (dev->is_active == FALSE) {
|
if (dev->is_active == FALSE) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
@@ -1368,20 +1375,21 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
fpi_ssm *ssm_tune;
|
struct fpi_ssm *ssm_tune;
|
||||||
ssm_tune = fpi_ssm_new(FP_DEV(idev), m_tunedc_state,
|
ssm_tune = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_tunedc_state,
|
||||||
TUNEDC_NUM_STATES, idev);
|
TUNEDC_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm_tune, idev);
|
||||||
fpi_ssm_start(ssm_tune, m_tunedc_complete);
|
fpi_ssm_start(ssm_tune, m_tunedc_complete);
|
||||||
} else {
|
} else {
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(_dev);
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
fp_err("Error initializing the device");
|
fp_err("Error initializing the device");
|
||||||
dev->is_active = FALSE;
|
dev->is_active = FALSE;
|
||||||
reset_param(dev);
|
reset_param(dev);
|
||||||
@@ -1392,8 +1400,8 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
g_assert(dev);
|
g_assert(dev);
|
||||||
|
|
||||||
@@ -1408,14 +1416,16 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
if (dev->dcoffset == 0) {
|
if (dev->dcoffset == 0) {
|
||||||
fp_dbg("Tuning device...");
|
fp_dbg("Tuning device...");
|
||||||
ssm = fpi_ssm_new(FP_DEV(idev), m_init_state, INIT_NUM_STATES, idev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_init_state, INIT_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, idev);
|
||||||
fpi_ssm_start(ssm, m_init_complete);
|
fpi_ssm_start(ssm, m_init_complete);
|
||||||
} else {
|
} else {
|
||||||
fp_dbg("Using previous tuning (DCOFFSET=0x%02X,VRT=0x%02X,"
|
fp_dbg("Using previous tuning (DCOFFSET=0x%02X,VRT=0x%02X,"
|
||||||
"VRB=0x%02X,GAIN=0x%02X).", dev->dcoffset, dev->vrt,
|
"VRB=0x%02X,GAIN=0x%02X).", dev->dcoffset, dev->vrt,
|
||||||
dev->vrb, dev->gain);
|
dev->vrb, dev->gain);
|
||||||
fpi_imgdev_activate_complete(idev, 0);
|
fpi_imgdev_activate_complete(idev, 0);
|
||||||
ssm = fpi_ssm_new(FP_DEV(idev), m_finger_state, FGR_NUM_STATES, idev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_finger_state, FGR_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, idev);
|
||||||
fpi_ssm_start(ssm, m_finger_complete);
|
fpi_ssm_start(ssm, m_finger_complete);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1423,16 +1433,15 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *idev)
|
static void dev_deactivate(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
fp_dbg("deactivating");
|
fp_dbg("deactivating");
|
||||||
|
|
||||||
/* this can be called even if still activated. */
|
/* this can be called even if still activated. */
|
||||||
if (dev->is_active == TRUE) {
|
if (dev->is_active == TRUE) {
|
||||||
dev->is_active = FALSE;
|
dev->is_active = FALSE;
|
||||||
|
m_exit_start(idev);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_exit_start(idev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
||||||
@@ -1441,13 +1450,13 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
|||||||
struct etes603_dev *dev;
|
struct etes603_dev *dev;
|
||||||
|
|
||||||
dev = g_malloc0(sizeof(struct etes603_dev));
|
dev = g_malloc0(sizeof(struct etes603_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(idev), dev);
|
fpi_imgdev_set_user_data(idev, dev);
|
||||||
|
|
||||||
dev->req = g_malloc(sizeof(struct egis_msg));
|
dev->req = g_malloc(sizeof(struct egis_msg));
|
||||||
dev->ans = g_malloc(FE_SIZE);
|
dev->ans = g_malloc(FE_SIZE);
|
||||||
dev->fp = g_malloc(FE_SIZE * 4);
|
dev->fp = g_malloc(FE_SIZE * 4);
|
||||||
|
|
||||||
ret = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(idev)), 0);
|
ret = libusb_claim_interface(fpi_imgdev_get_usb_dev(idev), 0);
|
||||||
if (ret != LIBUSB_SUCCESS) {
|
if (ret != LIBUSB_SUCCESS) {
|
||||||
fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(ret));
|
fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(ret));
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1459,14 +1468,14 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_close(struct fp_img_dev *idev)
|
static void dev_close(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct etes603_dev *dev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
g_free(dev->req);
|
g_free(dev->req);
|
||||||
g_free(dev->ans);
|
g_free(dev->ans);
|
||||||
g_free(dev->fp);
|
g_free(dev->fp);
|
||||||
g_free(dev);
|
g_free(dev);
|
||||||
|
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(idev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(idev), 0);
|
||||||
fpi_imgdev_close_complete(idev);
|
fpi_imgdev_close_complete(idev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,25 +169,25 @@ capture(struct fp_img_dev *dev, gboolean unconditional,
|
|||||||
|
|
||||||
image = g_malloc0(RAW_IMAGE_SIZE);
|
image = g_malloc0(RAW_IMAGE_SIZE);
|
||||||
|
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_ON))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_ON))) {
|
||||||
fp_err("Command: LED_ON");
|
fp_err("Command: LED_ON");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READY))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_READY))) {
|
||||||
fp_err("Command: CAPTURE_READY");
|
fp_err("Command: CAPTURE_READY");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
read:
|
read:
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READ))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_READ))) {
|
||||||
fp_err("Command: CAPTURE_READ");
|
fp_err("Command: CAPTURE_READ");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we are ready to read from dev */
|
/* Now we are ready to read from dev */
|
||||||
|
|
||||||
r = libusb_bulk_transfer(fpi_dev_get_usb_dev(FP_DEV(dev)), &msg, &bytes, BULK_TIMEOUT * 10);
|
r = libusb_bulk_transfer(fpi_imgdev_get_usb_dev(dev), &msg, &bytes, BULK_TIMEOUT * 10);
|
||||||
if (r < 0 || bytes < 1)
|
if (r < 0 || bytes < 1)
|
||||||
goto read;
|
goto read;
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ read:
|
|||||||
p += sizeof SOL + 4;
|
p += sizeof SOL + 4;
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < RAW_IMAGE_WIDTH; j++) {
|
for (j = 0; j < RAW_IMAGE_WIDTH; j++) {
|
||||||
/*
|
/**
|
||||||
* Convert from 4 to 8 bits
|
* Convert from 4 to 8 bits
|
||||||
* The SECUGEN-FDU2000 has 4 lines of data, so we need to join 2 bytes into 1
|
* The SECUGEN-FDU2000 has 4 lines of data, so we need to join 2 bytes into 1
|
||||||
*/
|
*/
|
||||||
@@ -228,12 +228,12 @@ read:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END))) {
|
||||||
fp_err("Command: CAPTURE_END");
|
fp_err("Command: CAPTURE_END");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_OFF))) {
|
||||||
fp_err("Command: LED_OFF");
|
fp_err("Command: LED_OFF");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -254,27 +254,27 @@ static
|
|||||||
gint dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
gint dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||||
{
|
{
|
||||||
gint r;
|
gint r;
|
||||||
//if ( (r = usb_set_configuration(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 )
|
//if ( (r = usb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1)) < 0 )
|
||||||
// goto out;
|
// goto out;
|
||||||
|
|
||||||
if ( (r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0)) < 0 ) {
|
if ( (r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0)) < 0 ) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ( (r = usb_set_altinterface(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 )
|
//if ( (r = usb_set_altinterface(fpi_imgdev_get_usb_dev(dev), 1)) < 0 )
|
||||||
// goto out;
|
// goto out;
|
||||||
|
|
||||||
//if ( (r = usb_clear_halt(fpi_dev_get_usb_dev(FP_DEV(dev)), EP_CMD)) < 0 )
|
//if ( (r = usb_clear_halt(fpi_imgdev_get_usb_dev(dev), EP_CMD)) < 0 )
|
||||||
// goto out;
|
// goto out;
|
||||||
|
|
||||||
/* Make sure sensor mode is not capture_{ready|read} */
|
/* Make sure sensor mode is not capture_{ready|read} */
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END))) {
|
||||||
fp_err("Command: CAPTURE_END");
|
fp_err("Command: CAPTURE_END");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) {
|
if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_OFF))) {
|
||||||
fp_err("Command: LED_OFF");
|
fp_err("Command: LED_OFF");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -289,10 +289,10 @@ out:
|
|||||||
static
|
static
|
||||||
void dev_exit(struct fp_img_dev *dev)
|
void dev_exit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
if (bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))
|
if (bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END))
|
||||||
fp_err("Command: CAPTURE_END");
|
fp_err("Command: CAPTURE_END");
|
||||||
|
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct usb_id id_table[] = {
|
static const struct usb_id id_table[] = {
|
||||||
|
|||||||
@@ -1,260 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "bmkt_internal.h"
|
|
||||||
#include "bmkt_message.h"
|
|
||||||
#include "sensor.h"
|
|
||||||
|
|
||||||
struct bmkt_ctx
|
|
||||||
{
|
|
||||||
bmkt_sensor_t sensor;
|
|
||||||
};
|
|
||||||
|
|
||||||
bmkt_ctx_t g_ctx;
|
|
||||||
|
|
||||||
int bmkt_init(bmkt_ctx_t **ctx)
|
|
||||||
{
|
|
||||||
if (ctx == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&g_ctx, 0, sizeof(bmkt_ctx_t));
|
|
||||||
*ctx = &g_ctx;
|
|
||||||
|
|
||||||
bmkt_dbg_log("%s: context size: %ld", __func__, sizeof(bmkt_ctx_t));
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bmkt_exit(bmkt_ctx_t *ctx)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (ctx == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_open(bmkt_ctx_t *ctx, bmkt_sensor_t **sensor,
|
|
||||||
bmkt_general_error_cb_t err_cb, void *err_cb_ctx, libusb_device_handle *usb_handle)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (ctx == NULL || sensor == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sensor = &ctx->sensor;
|
|
||||||
|
|
||||||
memset(*sensor, 0, sizeof(bmkt_sensor_t));
|
|
||||||
|
|
||||||
(*sensor)->usb_xport.handle = usb_handle;
|
|
||||||
|
|
||||||
ret = bmkt_sensor_open(*sensor, err_cb, err_cb_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_init_fps(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *resp_buf;
|
|
||||||
int resp_len;
|
|
||||||
bmkt_response_t resp;
|
|
||||||
|
|
||||||
if (sensor->sensor_state != BMKT_SENSOR_STATE_UNINIT)
|
|
||||||
{
|
|
||||||
//sensor is already initialized
|
|
||||||
return BMKT_OPERATION_DENIED;
|
|
||||||
}
|
|
||||||
ret = bmkt_sensor_send_message_sync(sensor, BMKT_CMD_FPS_INIT, 0, NULL, &resp_buf, &resp_len, &resp);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.result != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return resp.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bmkt_sensor_init_fps(sensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_close(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
if (sensor == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bmkt_sensor_close(sensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int bmkt_delete_enrolled_user(bmkt_sensor_t *sensor, uint8_t finger_id, const char *user_id, uint32_t user_id_len,
|
|
||||||
bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + sizeof(finger_id)];
|
|
||||||
uint8_t payload_len;
|
|
||||||
|
|
||||||
if (sensor == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user_id_len > BMKT_MAX_USER_ID_LEN)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(payload, 0, sizeof(payload));
|
|
||||||
payload_len = user_id_len + sizeof(finger_id);
|
|
||||||
payload[0] = finger_id;
|
|
||||||
memcpy(&payload[1], user_id, user_id_len);
|
|
||||||
|
|
||||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_DEL_USER_FP, payload_len, payload, resp_cb, cb_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_enroll(bmkt_sensor_t *sensor, const uint8_t *user_id, uint32_t user_id_len,
|
|
||||||
uint8_t finger_id, bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
|
||||||
{
|
|
||||||
int ret = BMKT_GENERAL_ERROR;
|
|
||||||
/* Payload data for enroll_user [1 byte<backup option> 1 byte<finger Id> maximum length: 100 bytes]*/
|
|
||||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + 2];
|
|
||||||
uint8_t payload_len = 0;
|
|
||||||
/* Backup options is not supported for Prometheus. */
|
|
||||||
uint8_t backup_opt = 0;
|
|
||||||
|
|
||||||
if (sensor == NULL || user_id == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user_id_len > BMKT_MAX_USER_ID_LEN)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
payload_len = user_id_len + 2;
|
|
||||||
payload[0] = backup_opt;
|
|
||||||
payload[1] = finger_id;
|
|
||||||
memcpy(&payload[2], user_id, user_id_len);
|
|
||||||
|
|
||||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_ENROLL_USER, payload_len, payload, resp_cb, cb_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int bmkt_verify(bmkt_sensor_t *sensor, bmkt_user_id_t *user,
|
|
||||||
bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + 1];
|
|
||||||
uint8_t payload_len;
|
|
||||||
|
|
||||||
if (sensor == NULL || user == NULL || user->user_id == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user->user_id_len == 0 || user->user_id_len > BMKT_MAX_USER_ID_LEN)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
payload_len = user->user_id_len;
|
|
||||||
memset(payload, 0, sizeof(payload));
|
|
||||||
memcpy(&payload[0], user->user_id, user->user_id_len);
|
|
||||||
|
|
||||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_VERIFY_USER, payload_len, payload, resp_cb,
|
|
||||||
cb_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bmkt_op_set_state(bmkt_sensor_t* sensor, bmkt_op_state_t state)
|
|
||||||
{
|
|
||||||
sensor->op_state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bmkt_op_sm(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int len = 0;
|
|
||||||
bmkt_dbg_log("bmkt_op_sm state = %d", sensor->op_state);
|
|
||||||
switch(sensor->op_state)
|
|
||||||
{
|
|
||||||
case BMKT_OP_STATE_GET_RESP:
|
|
||||||
ret = usb_receive_resp_async(&sensor->usb_xport, &len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("bmkt_op_sm: usb_receive_resp_async failed %d", ret);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BMKT_OP_STATE_WAIT_INTERRUPT:
|
|
||||||
ret = usb_check_interrupt(&sensor->usb_xport);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("bmkt_op_sm: check_interrupt failed %d", ret);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BMKT_OP_STATE_SEND_ASYNC:
|
|
||||||
ret = bmkt_sensor_send_async_read_command(sensor);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("bmkt_op_sm: bmkt_sensor_send_async_read_command failed %d", ret);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BMKT_OP_STATE_COMPLETE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bmkt_op_next_state(bmkt_sensor_t* sensor)
|
|
||||||
{
|
|
||||||
if(sensor->op_state != BMKT_OP_STATE_COMPLETE)
|
|
||||||
sensor->op_state = (sensor->op_state + 1) % BMKT_OP_STATE_COMPLETE;
|
|
||||||
bmkt_op_sm(sensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,452 +0,0 @@
|
|||||||
/*
|
|
||||||
* Synaptics MiS Fingerprint Sensor Interface
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BMKT_H_
|
|
||||||
#define _BMKT_H_
|
|
||||||
|
|
||||||
/**< User ID maximum length allowed */
|
|
||||||
#define BMKT_MAX_USER_ID_LEN 100
|
|
||||||
/**< Software Part Number length */
|
|
||||||
#define BMKT_PART_NUM_LEN 10
|
|
||||||
/**< Software supplier identification length */
|
|
||||||
#define BMKT_SUPPLIER_ID_LEN 2
|
|
||||||
|
|
||||||
/**< Maximum namber of templates for storing in internal flash of the fingerprint sensor */
|
|
||||||
#define BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH 15
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "libusb-1.0/libusb.h"
|
|
||||||
#include "bmkt_response.h"
|
|
||||||
|
|
||||||
/*!
|
|
||||||
*******************************************************************************
|
|
||||||
** Type definition for result
|
|
||||||
*/
|
|
||||||
/** No error; Operation successfully completed. */
|
|
||||||
#define BMKT_SUCCESS 0
|
|
||||||
/** Fingerprint system not initialized */
|
|
||||||
#define BMKT_FP_SYSTEM_NOT_INITIALIZED 101
|
|
||||||
/** Fingerprint system busy performing another operation */
|
|
||||||
#define BMKT_FP_SYSTEM_BUSY 102
|
|
||||||
/** Operation not allowed */
|
|
||||||
#define BMKT_OPERATION_DENIED 103
|
|
||||||
/** System ran out of memory while performing operation */
|
|
||||||
#define BMKT_OUT_OF_MEMORY 104
|
|
||||||
/** Corrupt message, CRC check fail or truncated message */
|
|
||||||
#define BMKT_CORRUPT_MESSAGE 110
|
|
||||||
/** One of the command parameters is outside the range of valid values */
|
|
||||||
#define BMKT_INVALID_PARAM 111
|
|
||||||
/** Unrecognized message or message with invalid message ID */
|
|
||||||
#define BMKT_UNRECOGNIZED_MESSAGE 112
|
|
||||||
/** Operation time out */
|
|
||||||
#define BMKT_OP_TIME_OUT 113
|
|
||||||
/** General error – cause of error cannot be determined */
|
|
||||||
#define BMKT_GENERAL_ERROR 114
|
|
||||||
|
|
||||||
#define BMKT_SET_SECURITY_LEVEL_FAIL 120
|
|
||||||
#define BMKT_GET_SECURITY_LEVEL_FAIL 121
|
|
||||||
|
|
||||||
/** Fingerprint sensor reset while operation was being performed */
|
|
||||||
#define BMKT_SENSOR_RESET 201
|
|
||||||
/** Fingerprint sensor malfunctioned */
|
|
||||||
#define BMKT_SENSOR_MALFUNCTION 202
|
|
||||||
/** Fingerprint sensor cannot be accessed despite repeated attempts */
|
|
||||||
#define BMKT_SENSOR_TAMPERED 203
|
|
||||||
/**
|
|
||||||
* BMKT_SENSOR_NOT_INIT:
|
|
||||||
* Fingerprint sensor module not initialized yet – not ready for use
|
|
||||||
* (different from error code 101 which indicates that the entire system
|
|
||||||
* has not been initialized)
|
|
||||||
*/
|
|
||||||
#define BMKT_SENSOR_NOT_INIT 204
|
|
||||||
/** Number of re-pairing operations exceeded limit or re-pairing has been disabled */
|
|
||||||
#define BMKT_OWNERSHIP_RESET_MAX_EXCEEDED 205
|
|
||||||
/**
|
|
||||||
* BMKT_SENSOR_STIMULUS_ERROR:
|
|
||||||
* There is a finger or debris on the sensor that needs to be removed
|
|
||||||
* before issuing this command
|
|
||||||
*/
|
|
||||||
#define BMKT_SENSOR_STIMULUS_ERROR 213
|
|
||||||
/**
|
|
||||||
* BMKT_CORRUPT_TEMPLATE_DATA:
|
|
||||||
* One of the fingerprint templates stored on flash is corrupt.
|
|
||||||
* This error code is returned in case of failure in finding a fingerprint match
|
|
||||||
* during identify or verify operations while also detecting that one or more
|
|
||||||
* fingerprint templates stored on the flash has become corrupted
|
|
||||||
*/
|
|
||||||
#define BMKT_CORRUPT_TEMPLATE_DATA 300
|
|
||||||
/** Failed to extract features from fingerprint image acquired by sensor */
|
|
||||||
#define BMKT_FEATURE_EXTRACT_FAIL 301
|
|
||||||
/** Failed to generate fingerprint template */
|
|
||||||
#define BMKT_ENROLL_FAIL 302
|
|
||||||
/** Specified finger already enrolled for this user */
|
|
||||||
#define BMKT_ENROLLMENT_EXISTS 303
|
|
||||||
/** Invalid fingerprint image */
|
|
||||||
#define BMKT_INVALID_FP_IMAGE 304
|
|
||||||
/** No matching user fingerprint template found in database */
|
|
||||||
#define BMKT_FP_NO_MATCH 404
|
|
||||||
/** Fingerprint database is full */
|
|
||||||
#define BMKT_FP_DATABASE_FULL 501
|
|
||||||
/** Fingerprint database is empty */
|
|
||||||
#define BMKT_FP_DATABASE_EMPTY 502
|
|
||||||
/** Cannot access fingerprint database */
|
|
||||||
#define BMKT_FP_DATABASE_ACCESS_FAIL 503
|
|
||||||
/** Fingerprint template record does not exist */
|
|
||||||
#define BMKT_FP_DATABASE_NO_RECORD_EXISTS 504
|
|
||||||
/** Failed to read/write system parameters stored on flash */
|
|
||||||
#define BMKT_FP_PARAM_ACCESS_FAIL 505
|
|
||||||
/** Fingerprint is a spoof */
|
|
||||||
#define BMKT_FP_SPOOF_ALERT 801
|
|
||||||
/** Anti-spoof module failure */
|
|
||||||
#define BMKT_ANTI_SPOOF_MODULE_FAIL 802
|
|
||||||
|
|
||||||
#define BMKT_CORRUPT_UPDATE_IMAGE 901
|
|
||||||
#define BMKT_SYSTEM_UPDATE_FAIL 902
|
|
||||||
|
|
||||||
#define BMKT_EVENT_NOT_SET 1000
|
|
||||||
#define BMKT_SENSOR_NOT_READY 1001
|
|
||||||
#define BMKT_TIMEOUT 1002
|
|
||||||
#define BMKT_SENSOR_RESPONSE_PENDING 1003
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_mode:
|
|
||||||
* Fingerprint system operational mode values level 1
|
|
||||||
*/
|
|
||||||
typedef enum bmkt_mode
|
|
||||||
{
|
|
||||||
BMKT_STATE_UNINIT = 0xFF,
|
|
||||||
BMKT_STATE_IDLE = 0x00,
|
|
||||||
BMKT_STATE_ENROLL = 0x10,
|
|
||||||
BMKT_STATE_IDENTIFY = 0x20,
|
|
||||||
BMKT_STATE_VERIFY = 0x30,
|
|
||||||
BMKT_STATE_DB_OPS = 0x40,
|
|
||||||
BMKT_STATE_SYS_TEST = 0x50,
|
|
||||||
BMKT_STATE_SYS_OPS = 0x60,
|
|
||||||
} bmkt_mode_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_mode_level2:
|
|
||||||
* Fingerprint system operational mode values level 2
|
|
||||||
*/
|
|
||||||
typedef enum bmkt_mode_level2
|
|
||||||
{
|
|
||||||
BMKT_STATE_L2_IDLE = 0x00,
|
|
||||||
BMKT_STATE_L2_STARTING = 0x11,
|
|
||||||
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
|
|
||||||
BMKT_STATE_L2_CAPTURE_IMAGE = 0x13,
|
|
||||||
BMKT_STATE_L2_CAPTURE_COMPLETE = 0x14,
|
|
||||||
BMKT_STATE_L2_EXTRACT_FEATURE = 0x15,
|
|
||||||
BMKT_STATE_L2_CREATE_TEMPLATE = 0x16,
|
|
||||||
BMKT_STATE_L2_READING_FROM_FLASH = 0x17,
|
|
||||||
BMKT_STATE_L2_WRITING_TO_FLASH = 0x18,
|
|
||||||
BMKT_STATE_L2_FINISHING = 0x19,
|
|
||||||
BMKT_STATE_L2_CANCELING_OP = 0x20,
|
|
||||||
BMKT_STATE_L2_MATCHING = 0x21,
|
|
||||||
BMKT_STATE_L2_TRANSMITTING_RESPONSE = 0x22,
|
|
||||||
BMKT_STATE_L2_READY_POWER_DOWN = 0xF0,
|
|
||||||
} bmkt_mode_level2_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_transport_type:
|
|
||||||
* Fingerprint system transport types
|
|
||||||
*/
|
|
||||||
typedef enum bmkt_transport_type
|
|
||||||
{
|
|
||||||
BMKT_TRANSPORT_TYPE_USB = 0,
|
|
||||||
} bmkt_transport_type_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_usb_config:
|
|
||||||
* Structure represcontainingenting USB configuration details
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_usb_config
|
|
||||||
{
|
|
||||||
int product_id; /**< USB device product ID */
|
|
||||||
} bmkt_usb_config_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_transport_config_t:
|
|
||||||
* Union containing transport configuration details
|
|
||||||
*/
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
bmkt_usb_config_t usb_config;
|
|
||||||
} bmkt_transport_config_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_sensor_desc_t:
|
|
||||||
* Structure containing fingerprint system description
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_sensor_desc
|
|
||||||
{
|
|
||||||
int product_id;
|
|
||||||
int flags;
|
|
||||||
} bmkt_sensor_desc_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_finger_state_t:
|
|
||||||
* Finger state representation values.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BMKT_FINGER_STATE_UNKNOWN = 0,
|
|
||||||
BMKT_FINGER_STATE_ON_SENSOR,
|
|
||||||
BMKT_FINGER_STATE_NOT_ON_SENSOR,
|
|
||||||
} bmkt_finger_state_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_finger_event_t:
|
|
||||||
* Structure containing finger state
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_finger_event
|
|
||||||
{
|
|
||||||
bmkt_finger_state_t finger_state;
|
|
||||||
} bmkt_finger_event_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_user_id
|
|
||||||
{
|
|
||||||
uint8_t user_id_len;
|
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
|
||||||
} bmkt_user_id_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_ctx bmkt_ctx_t;
|
|
||||||
typedef struct bmkt_sensor bmkt_sensor_t;
|
|
||||||
typedef struct bmkt_sensor_desc bmkt_sensor_desc_t;
|
|
||||||
typedef struct bmkt_event bmkt_event_t;
|
|
||||||
|
|
||||||
typedef int (*bmkt_resp_cb_t)(bmkt_response_t *resp, void *cb_ctx);
|
|
||||||
typedef int (*bmkt_event_cb_t)(bmkt_finger_event_t *event, void *cb_ctx);
|
|
||||||
typedef int (*bmkt_general_error_cb_t)(uint16_t error, void *cb_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_init:
|
|
||||||
* @brief Initialize the bmkt library.
|
|
||||||
*
|
|
||||||
* @param[out] ctx A double pointer to return the created library module context pointer.
|
|
||||||
*
|
|
||||||
* @return BMKT_SUCCESS
|
|
||||||
* BMKT_INVALID_PARAM
|
|
||||||
*
|
|
||||||
* The bmkt_init function must be invoked to intialize the bmkt library before calling other functions.
|
|
||||||
* The library module context pointer is returned, which must be passed to all other library interface functions.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_init(
|
|
||||||
bmkt_ctx_t ** ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_exit:
|
|
||||||
* @brief Uninitialize the bmkt library.
|
|
||||||
*
|
|
||||||
* @param[in] ctx Context pointer created by bmkt_init.
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*
|
|
||||||
* The bmkt_exit function must be invoked when the module is no longer needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
bmkt_exit(
|
|
||||||
bmkt_ctx_t * ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_open:
|
|
||||||
* @brief Open the specified sensor module.
|
|
||||||
*
|
|
||||||
* @param[in] ctx Context pointer created by bmkt_init.
|
|
||||||
* @param[out] sensor A double pointer to return the created sensor module pointer
|
|
||||||
* @param[in] err_cb General Error callback function
|
|
||||||
* @param[in] err_cb_ctx General Error callback user context
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* The bmkt_open function must be called to open a specific sensor module. Returned sensor module pointer
|
|
||||||
* must be passed to all other interface functions that expect a sensor pointer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
bmkt_open(
|
|
||||||
bmkt_ctx_t * ctx,
|
|
||||||
bmkt_sensor_t ** sensor,
|
|
||||||
bmkt_general_error_cb_t err_cb,
|
|
||||||
void * err_cb_ctx,
|
|
||||||
libusb_device_handle * handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_close:
|
|
||||||
* @brief Close the specified sensor module, and release all the resources
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* The bmkt_close function must be invoked when the sensor module is no longer needed.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_close(
|
|
||||||
bmkt_sensor_t * sensor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_init_fps:
|
|
||||||
* @brief Initialize the sensor module.
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* Initializes the fingerprint sensor module. Must be the first command to be issued to the fingerprint sensor module, before any other commands are issued.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_init_fps(
|
|
||||||
bmkt_sensor_t * sensor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enroll:
|
|
||||||
* @brief Put the fingerprint sensor module into enrollment mode to Enroll a user’s fingerprint into the system.
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
* @param[in] user_id Enrolled User ID
|
|
||||||
* @param[in] user_id_len Enrolled User ID lenght
|
|
||||||
* @param[in] finger_id Enrolled finger ID
|
|
||||||
* @param[in] resp_cb Responce callback function. Available responses:
|
|
||||||
* - BMKT_RSP_ENROLL_READY
|
|
||||||
* - BMKT_RSP_CAPTURE_COMPLETE
|
|
||||||
* - BMKT_RSP_ENROLL_REPORT
|
|
||||||
* - BMKT_RSP_ENROLL_PAUSED
|
|
||||||
* - BMKT_RSP_ENROLL_RESUMED
|
|
||||||
* - BMKT_RSP_ENROLL_FAIL
|
|
||||||
* - BMKT_RSP_ENROLL_OK
|
|
||||||
|
|
||||||
* @param[in] cb_ctx Responce callback user context
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* Enrolled users have to touch the fingerprint sensor multiple times based on cues provided by the system.
|
|
||||||
* After successful enrollment, a template is generated from features of the user’s fingerprint and stored
|
|
||||||
* in encrypted storage within the fingerprint sensor module.
|
|
||||||
* When this command is being executed, fingerprint sensor module’s mode is: Enrollment
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_enroll(
|
|
||||||
bmkt_sensor_t * sensor,
|
|
||||||
const uint8_t * user_id,
|
|
||||||
uint32_t user_id_len,
|
|
||||||
uint8_t finger_id,
|
|
||||||
bmkt_resp_cb_t resp_cb,
|
|
||||||
void * cb_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_verify:
|
|
||||||
* @brief Put the fingerprint sensor module into verification mode.
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
* @param[in] user Enrolled User
|
|
||||||
* @param[in] resp_cb Responce callback function. Available responses:
|
|
||||||
* - BMKT_RSP_CAPTURE_COMPLETE
|
|
||||||
* - BMKT_RSP_VERIFY_READY
|
|
||||||
* - BMKT_RSP_VERIFY_FAIL
|
|
||||||
* - BMKT_RSP_VERIFY_OK
|
|
||||||
* @param[in] cb_ctx Responce callback user context
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* The user being verifyed has to touch the fingerprint sensor once based on a cue provided by the system.
|
|
||||||
* The Captured fingerprint is matched only against the stored templates corresponding to specifyed user ID,
|
|
||||||
* If a user’s fingerprint cannot be matched to any of the stored fingerprint templates of the specified user or
|
|
||||||
* if the fingerprint sensor module detects that the fingerprint being presented to the sensor is a spoof,
|
|
||||||
* then an error response is generated.
|
|
||||||
* When this command is being executed, fingerprint sensor module’s mode is: Verification
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_verify(
|
|
||||||
bmkt_sensor_t * sensor,
|
|
||||||
bmkt_user_id_t* user,
|
|
||||||
bmkt_resp_cb_t resp_cb,
|
|
||||||
void * cb_ctx);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_delete_enrolled_user:
|
|
||||||
* @brief Delete a specific fingerprint template of an enrolled user from the database.
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
* @param[in] finger_id Finger ID to be deleted
|
|
||||||
* @param[in] user_id User ID to be deleted
|
|
||||||
* @param[in] user_id_len User ID lenght
|
|
||||||
* @param[in] resp_cb Responce callback function. Available responses:
|
|
||||||
* - BMKT_RSP_DEL_USER_FP_FAIL
|
|
||||||
* - BMKT_RSP_DEL_USER_FP_OK
|
|
||||||
* @param[in] cb_ctx Responce callback user context
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* If the value of finger ID is set equal to 0 then all fingerprints of that user will be deleted from the database.
|
|
||||||
* If the value of user ID is set to an empty string (string with length 0) and the finger ID is set equal to 0 then
|
|
||||||
* all templates stored in the fingerprint database which are marked as corrupt will be deleted.
|
|
||||||
* When this command is being executed, fingerprint sensor module’s mode is: Database operations
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_delete_enrolled_user(
|
|
||||||
bmkt_sensor_t * sensor,
|
|
||||||
uint8_t finger_id,
|
|
||||||
const char * user_id,
|
|
||||||
uint32_t user_id_len,
|
|
||||||
bmkt_resp_cb_t resp_cb,
|
|
||||||
void * cb_ctx);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_register_finger_event_notification:
|
|
||||||
* @brief Register finger presence event callback function
|
|
||||||
*
|
|
||||||
* @param[in] sensor The sensor module pointer
|
|
||||||
* @param[in] cb Event callback function
|
|
||||||
* @param[in] cb_ctx Event callback user context
|
|
||||||
*
|
|
||||||
* @return VCS_RESULT_OK if success
|
|
||||||
*
|
|
||||||
* The registered callback function will be called whenever a finger is detected as being placed on the sensor or removed from the sensor.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bmkt_register_finger_event_notification(
|
|
||||||
bmkt_sensor_t * sensor,
|
|
||||||
bmkt_event_cb_t cb,
|
|
||||||
void * cb_ctx);
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BMKT_OP_STATE_START = -1,
|
|
||||||
BMKT_OP_STATE_GET_RESP,
|
|
||||||
BMKT_OP_STATE_WAIT_INTERRUPT,
|
|
||||||
BMKT_OP_STATE_SEND_ASYNC,
|
|
||||||
BMKT_OP_STATE_COMPLETE,
|
|
||||||
} bmkt_op_state_t;
|
|
||||||
void bmkt_op_set_state(bmkt_sensor_t* sensor, bmkt_op_state_t state);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _BMKT_H_ */
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BMKT_INTERNAL_H_
|
|
||||||
#define _BMKT_INTERNAL_H_
|
|
||||||
|
|
||||||
#include "bmkt.h"
|
|
||||||
#include "bmkt_message.h"
|
|
||||||
#include <time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "fp_internal.h"
|
|
||||||
|
|
||||||
uint32_t extract32(const uint8_t *buf, int *offset);
|
|
||||||
uint16_t extract16(const uint8_t *buf, int *offset);
|
|
||||||
uint8_t extract8(const uint8_t *buf, int *offset);
|
|
||||||
void print_buffer(uint8_t *buf, int len);
|
|
||||||
|
|
||||||
|
|
||||||
#define bmkt_dbg_log fp_dbg
|
|
||||||
#define bmkt_info_log fp_info
|
|
||||||
#define bmkt_warn_log fp_warn
|
|
||||||
#define bmkt_err_log fp_err
|
|
||||||
|
|
||||||
void bmkt_op_next_state(bmkt_sensor_t *sensor);
|
|
||||||
|
|
||||||
#endif /* _BMKT_INTERNAL_H_ */
|
|
||||||
@@ -1,397 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "bmkt_internal.h"
|
|
||||||
#include "bmkt_response.h"
|
|
||||||
#include "bmkt_message.h"
|
|
||||||
#include "usb_transport.h"
|
|
||||||
#include "sensor.h"
|
|
||||||
|
|
||||||
static int parse_error_response(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
if (msg_resp->payload_len != 2)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_init_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_init_resp_t *init_resp = &resp->response.init_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_resp->finger_presence = extract8(msg_resp->payload, NULL);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != sizeof(bmkt_fps_mode_resp_t))
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fps_mode_resp->mode = extract8(msg_resp->payload, &offset);
|
|
||||||
fps_mode_resp->level2_mode = extract8(msg_resp->payload, &offset);
|
|
||||||
fps_mode_resp->cmd_id = extract8(msg_resp->payload, &offset);
|
|
||||||
fps_mode_resp->finger_presence = extract8(msg_resp->payload, &offset);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_enroll_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
enroll_resp->progress = extract8(msg_resp->payload, NULL);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len < 1 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 1))
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
enroll_resp->finger_id = msg_resp->payload[0];
|
|
||||||
memcpy(enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_identify_resp_t *id_resp = &resp->response.id_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len < 3 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 3))
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
id_resp->match_result = (double)msg_resp->payload[0] + 0.01 * (double)msg_resp->payload[1];
|
|
||||||
id_resp->finger_id = msg_resp->payload[2];
|
|
||||||
memcpy(id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_security_level_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_set_sec_level_resp_t *sec_level_resp = &resp->response.sec_level_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec_level_resp->sec_level = extract8(msg_resp->payload, NULL);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_del_all_users_progress_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_del_all_users_resp_t *del_all_users_resp = &resp->response.del_all_users_resp;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
del_all_users_resp->progress = extract8(msg_resp->payload, NULL);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_get_db_capacity_resp_t *db_cap_resp = &resp->response.db_cap_resp;
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
db_cap_resp->total = extract8(msg_resp->payload, &offset);
|
|
||||||
db_cap_resp->empty = extract8(msg_resp->payload, &offset);
|
|
||||||
|
|
||||||
if (msg_resp->payload_len == 4)
|
|
||||||
{
|
|
||||||
db_cap_resp->bad_slots = extract8(msg_resp->payload, &offset);
|
|
||||||
db_cap_resp->corrupt_templates = extract8(msg_resp->payload, &offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len < 2)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
/* 2 bytes per finger so calculate the total number of fingers to process*/
|
|
||||||
int num_fingers = (msg_resp->payload_len) / 2;
|
|
||||||
|
|
||||||
bmkt_enrolled_fingers_resp_t *get_enrolled_fingers_resp = &resp->response.enrolled_fingers_resp;
|
|
||||||
|
|
||||||
for (i = 0; i < num_fingers; i++)
|
|
||||||
{
|
|
||||||
get_enrolled_fingers_resp->fingers[i].finger_id = extract8(msg_resp->payload, &offset);
|
|
||||||
get_enrolled_fingers_resp->fingers[i].template_status = extract8(msg_resp->payload, &offset);
|
|
||||||
|
|
||||||
}
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
/* the payload is 2 bytes + template data */
|
|
||||||
if (msg_resp->payload_len < 2)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
|
|
||||||
|
|
||||||
get_enroll_templates_resp->total_query_messages = extract8(msg_resp->payload, &offset);
|
|
||||||
get_enroll_templates_resp->query_sequence = extract8(msg_resp->payload, &offset);
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
|
||||||
{
|
|
||||||
if (offset >= msg_resp->payload_len)
|
|
||||||
break;
|
|
||||||
get_enroll_templates_resp->templates[n].user_id_len = extract8(msg_resp->payload, &offset) - 2;
|
|
||||||
if(get_enroll_templates_resp->templates[n].user_id_len > BMKT_MAX_USER_ID_LEN)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
get_enroll_templates_resp->templates[n].template_status = extract8(msg_resp->payload, &offset);
|
|
||||||
get_enroll_templates_resp->templates[n].finger_id = extract8(msg_resp->payload, &offset);
|
|
||||||
for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
|
|
||||||
{
|
|
||||||
get_enroll_templates_resp->templates[n].user_id[i] = extract8(msg_resp->payload, &offset);
|
|
||||||
}
|
|
||||||
get_enroll_templates_resp->templates[n].user_id[i] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
bmkt_get_version_resp_t *get_version_resp = &resp->response.get_version_resp;
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 15)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
|
|
||||||
offset += BMKT_PART_NUM_LEN;
|
|
||||||
get_version_resp->year = extract8(msg_resp->payload, &offset);
|
|
||||||
get_version_resp->week = extract8(msg_resp->payload, &offset);
|
|
||||||
get_version_resp->patch = extract8(msg_resp->payload, &offset);
|
|
||||||
memcpy(get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
|
||||||
uint8_t payload_size, uint8_t *payload)
|
|
||||||
{
|
|
||||||
int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
|
|
||||||
|
|
||||||
if (*cmd_len < message_len)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
|
|
||||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
|
||||||
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
|
||||||
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
|
||||||
memcpy(&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
|
||||||
|
|
||||||
*cmd_len = message_len;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
|
|
||||||
{
|
|
||||||
if (resp_buf[BMKT_MESSAGE_HEADER_ID_FIELD] != BMKT_MESSAGE_HEADER_ID)
|
|
||||||
{
|
|
||||||
return BMKT_CORRUPT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
|
|
||||||
msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
|
|
||||||
msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
|
|
||||||
if (msg_resp->payload_len > 0)
|
|
||||||
{
|
|
||||||
msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg_resp->payload = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
int ret = BMKT_SUCCESS;
|
|
||||||
|
|
||||||
memset(resp, 0, sizeof(bmkt_response_t));
|
|
||||||
|
|
||||||
resp->response_id = msg_resp->msg_id;
|
|
||||||
|
|
||||||
switch(msg_resp->msg_id)
|
|
||||||
{
|
|
||||||
case BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL:
|
|
||||||
case BMKT_RSP_SENSOR_MODULE_TEST_FAIL:
|
|
||||||
case BMKT_RSP_FPS_INIT_FAIL:
|
|
||||||
case BMKT_RSP_FPS_MODE_FAIL:
|
|
||||||
case BMKT_RSP_SET_SECURITY_LEVEL_FAIL:
|
|
||||||
case BMKT_RSP_GET_SECURITY_LEVEL_FAIL:
|
|
||||||
case BMKT_RSP_CANCEL_OP_FAIL:
|
|
||||||
case BMKT_RSP_ENROLL_FAIL:
|
|
||||||
case BMKT_RSP_ID_FAIL:
|
|
||||||
case BMKT_RSP_VERIFY_FAIL:
|
|
||||||
case BMKT_RSP_QUERY_FAIL:
|
|
||||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
|
||||||
case BMKT_RSP_DEL_FULL_DB_FAIL:
|
|
||||||
case BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
|
||||||
case BMKT_RSP_POWER_DOWN_FAIL:
|
|
||||||
case BMKT_RSP_GET_VERSION_FAIL:
|
|
||||||
case BMKT_RSP_DISABLE_PAIRING_FAIL:
|
|
||||||
case BMKT_RSP_QUERY_PAIRING_FAIL:
|
|
||||||
case BMKT_RSP_SENSOR_STATUS_FAIL:
|
|
||||||
case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
|
||||||
ret = parse_error_response(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_FPS_INIT_OK:
|
|
||||||
ret = parse_init_ok(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_CANCEL_OP_OK:
|
|
||||||
case BMKT_RSP_DEL_FULL_DB_OK:
|
|
||||||
case BMKT_RSP_DEL_USER_FP_OK:
|
|
||||||
/* responses with a payload of 0
|
|
||||||
so the response indicates success */
|
|
||||||
resp->result = BMKT_SUCCESS;
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_FPS_MODE_REPORT:
|
|
||||||
// parse_fps_mode
|
|
||||||
ret = parse_fps_mode_report(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
|
||||||
case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
|
||||||
/* parse security level result */
|
|
||||||
ret = parse_security_level_report(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_DELETE_PROGRESS:
|
|
||||||
ret = parse_del_all_users_progress_report(msg_resp, resp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
|
||||||
resp->result = BMKT_SUCCESS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_READY:
|
|
||||||
resp->result = BMKT_SUCCESS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_REPORT:
|
|
||||||
ret = parse_enroll_report(msg_resp, resp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_OK:
|
|
||||||
resp->complete = 1;
|
|
||||||
ret = parse_enroll_ok(msg_resp, resp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_ID_OK:
|
|
||||||
case BMKT_RSP_VERIFY_OK:
|
|
||||||
ret = parse_auth_ok(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
|
||||||
ret = parse_get_enrolled_fingers_report(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
case BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
|
||||||
resp->complete = 1;
|
|
||||||
ret = parse_db_cap_report(msg_resp, resp);
|
|
||||||
break;
|
|
||||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
|
||||||
ret = parse_get_enrolled_users_report(msg_resp, resp);
|
|
||||||
break;
|
|
||||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMKT_RSP_VERSION_INFO:
|
|
||||||
ret = parse_get_version_report(msg_resp, resp);
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BMKT_MESSAGE_H_
|
|
||||||
#define BMKT_MESSAGE_H_
|
|
||||||
|
|
||||||
#include "bmkt_internal.h"
|
|
||||||
|
|
||||||
#define BMKT_MESSAGE_HEADER_ID 0xFE
|
|
||||||
#define BMKT_MESSAGE_HEADER_LEN (4)
|
|
||||||
#define BMKT_MESSAGE_CRC32_LEN (4)
|
|
||||||
#define BMKT_MESSAGE_HEADER_ID_FIELD 0
|
|
||||||
#define BMKT_MESSAGE_SEQ_NUM_FIELD 1
|
|
||||||
#define BMKT_MESSAGE_ID_FIELD 2
|
|
||||||
#define BMKT_MESSAGE_PAYLOAD_LEN_FIELD 3
|
|
||||||
#define BMKT_MESSAGE_PAYLOAD_FIELD 4
|
|
||||||
|
|
||||||
// Command messages
|
|
||||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE 0x01
|
|
||||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE_STOP 0x04
|
|
||||||
#define BMKT_CMD_SENSOR_MODULE_TEST 0x06
|
|
||||||
#define BMKT_CMD_SENSOR_MODULE_TEST_START 0x08
|
|
||||||
#define BMKT_CMD_NEXT_TEST_REPORT_CHUNK 0x0B
|
|
||||||
#define BMKT_CMD_FPS_INIT 0x11
|
|
||||||
#define BMKT_CMD_GET_FPS_MODE 0x21
|
|
||||||
#define BMKT_CMD_SET_SECURITY_LEVEL 0x31
|
|
||||||
#define BMKT_CMD_GET_SECURITY_LEVEL 0x34
|
|
||||||
#define BMKT_CMD_CANCEL_OP 0x41
|
|
||||||
#define BMKT_CMD_ENROLL_USER 0x51
|
|
||||||
#define BMKT_CMD_ENROLL_PAUSE 0x52
|
|
||||||
#define BMKT_CMD_ENROLL_RESUME 0x53
|
|
||||||
#define BMKT_CMD_ID_USER 0x61
|
|
||||||
#define BMKT_CMD_VERIFY_USER 0x65
|
|
||||||
#define BMKT_CMD_GET_TEMPLATE_RECORDS 0x71
|
|
||||||
#define BMKT_CMD_GET_NEXT_QUERY_RESPONSE 0x72
|
|
||||||
#define BMKT_CMD_GET_ENROLLED_FINGERS 0x73
|
|
||||||
#define BMKT_CMD_GET_DATABASE_CAPACITY 0x74
|
|
||||||
#define BMKT_CMD_DEL_USER_FP 0x81
|
|
||||||
#define BMKT_CMD_DEL_FULL_DB 0x84
|
|
||||||
#define BMKT_CMD_REPEAT_LAST_RSP 0x92
|
|
||||||
#define BMKT_CMD_POWER_DOWN_NOTIFY 0xA1
|
|
||||||
#define BMKT_CMD_GET_VERSION 0xB1
|
|
||||||
#define BMKT_CMD_DISABLE_PAIRING 0xC2
|
|
||||||
#define BMKT_CMD_QUERY_PAIRING 0xC5
|
|
||||||
#define BMKT_CMD_SENSOR_STATUS 0xD1
|
|
||||||
#define BMKT_CMD_ID_USER_IN_ORDER 0xE1
|
|
||||||
#define BMKT_CMD_ID_NEXT_USER 0xE3
|
|
||||||
#define BMKT_CMD_VERIFY_USER_IN_ORDER 0xF1
|
|
||||||
#define BMKT_CMD_VERIFY_FINGERS_IN_ORDER 0xF2
|
|
||||||
#define BMKT_CMD_GET_FINAL_RESULT 0xE4
|
|
||||||
|
|
||||||
#define BMKT_EVT_FINGER_REPORT 0x91
|
|
||||||
|
|
||||||
#define BMKT_EVT_FINGER_STATE_NOT_ON_SENSOR 0x00
|
|
||||||
#define BMKT_EVT_FINGER_STATE_ON_SENSOR 0x01
|
|
||||||
|
|
||||||
typedef struct bmkt_msg_resp
|
|
||||||
{
|
|
||||||
uint8_t msg_id;
|
|
||||||
uint8_t seq_num;
|
|
||||||
uint8_t payload_len;
|
|
||||||
uint8_t *payload;
|
|
||||||
int result;
|
|
||||||
} bmkt_msg_resp_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_session_ctx
|
|
||||||
{
|
|
||||||
uint8_t seq_num;
|
|
||||||
bmkt_resp_cb_t resp_cb;
|
|
||||||
void *cb_ctx;
|
|
||||||
} bmkt_session_ctx_t;
|
|
||||||
|
|
||||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
|
||||||
uint8_t payload_size, uint8_t *payload);
|
|
||||||
|
|
||||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
|
||||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp);
|
|
||||||
#endif /* BMKT_MESSAGE_H_ */
|
|
||||||
@@ -1,487 +0,0 @@
|
|||||||
/*
|
|
||||||
* Synaptics MiS Fingerprint Sensor Response Data Interface
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _BMKT_RESPONSE_H_
|
|
||||||
#define _BMKT_RESPONSE_H_
|
|
||||||
|
|
||||||
/** List of response message IDs */
|
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL 0x02
|
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_READY 0x03
|
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_STOPPED 0x05
|
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_READY 0x07
|
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_FAIL 0x09
|
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_REPORT 0x0A
|
|
||||||
#define BMKT_RSP_NEXT_TEST_REPORT_CHUNK 0x0C
|
|
||||||
|
|
||||||
/*! \addtogroup init
|
|
||||||
* Response IDs returned by fingerprint initialization operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to initialize fingerprint sensor module */
|
|
||||||
#define BMKT_RSP_FPS_INIT_FAIL 0x12
|
|
||||||
/** Successfully initialized fingerprint sensor module */
|
|
||||||
#define BMKT_RSP_FPS_INIT_OK 0x13
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup mode
|
|
||||||
* Response IDs returned by get fingerprint mode operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to get fingerprint sensor module’s current operational mode */
|
|
||||||
#define BMKT_RSP_FPS_MODE_FAIL 0x22
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_FPS_MODE_REPORT:
|
|
||||||
* Response containing the current operational mode of the fingerprint sensor module
|
|
||||||
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_FPS_MODE_REPORT 0x23
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup setseclevel
|
|
||||||
* Response IDs returned by set security level operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to set fingerprint sensor module security level */
|
|
||||||
#define BMKT_RSP_SET_SECURITY_LEVEL_FAIL 0x32
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
|
||||||
* Security level of the fingerprint sensor module was set successfully
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_SET_SECURITY_LEVEL_REPORT 0x33
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup getseclevel
|
|
||||||
* Response IDs returned by get security level operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to get fingerprint sensor module security level */
|
|
||||||
#define BMKT_RSP_GET_SECURITY_LEVEL_FAIL 0x35
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
|
||||||
* Returns the current security level of the fingerprint sensor module
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_GET_SECURITY_LEVEL_REPORT 0x36
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup cancelop
|
|
||||||
* Response IDs returned by cancel_operation operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_CANCEL_OP_OK:
|
|
||||||
* Successfully canceled the current operation and returned
|
|
||||||
* fingerprint sensor module to idle mode
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_CANCEL_OP_OK 0x42
|
|
||||||
/** Failed to cancel the current operation */
|
|
||||||
#define BMKT_RSP_CANCEL_OP_FAIL 0x43
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup enrollment
|
|
||||||
* Response IDs returned by enrollment operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_ENROLL_READY:
|
|
||||||
* Fingerprint enrollment session has begun and the user can place
|
|
||||||
* their finger on the sensor
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_ENROLL_READY 0x54
|
|
||||||
/** Progress of the currently on-going fingerprint enrollment session */
|
|
||||||
#define BMKT_RSP_ENROLL_REPORT 0x55
|
|
||||||
/** Enrollment has been paused */
|
|
||||||
#define BMKT_RSP_ENROLL_PAUSED 0x56
|
|
||||||
/** Enrollment has been resume */
|
|
||||||
#define BMKT_RSP_ENROLL_RESUMED 0x57
|
|
||||||
/** The current enrollment session has encountered an error */
|
|
||||||
#define BMKT_RSP_ENROLL_FAIL 0x58
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_ENROLL_OK:
|
|
||||||
* User has been successfully enrolled into the fingerprint sensor module
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_ENROLL_OK 0x59
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_CAPTURE_COMPLETE:
|
|
||||||
* Fingerprint image capture is complete and it is safe for the user
|
|
||||||
* to lift their finger off the sensor
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_CAPTURE_COMPLETE 0x60
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup identify
|
|
||||||
* Response IDs returned by identify operation.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/* Fingerprint identification session has begun */
|
|
||||||
#define BMKT_RSP_ID_READY 0x62
|
|
||||||
/* Identification has failed */
|
|
||||||
#define BMKT_RSP_ID_FAIL 0x63
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_ID_OK:
|
|
||||||
* User has been successfully identified
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_ID_OK 0x64
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup verify
|
|
||||||
* Response IDs returned by identify operation.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Fingerprint verification session has begun */
|
|
||||||
#define BMKT_RSP_VERIFY_READY 0x66
|
|
||||||
/** Verification has failed */
|
|
||||||
#define BMKT_RSP_VERIFY_FAIL 0x67
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_VERIFY_OK:
|
|
||||||
* User’s identity has been successfully verified
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_VERIFY_OK 0x68
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
|
||||||
* Response ID returned by get enrolled users templates record operation
|
|
||||||
* <br>Returns list of template records containing user IDs and corresponding finger IDs
|
|
||||||
* <br>Payload data represented in \ref bmkt_enroll_templates_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_TEMPLATE_RECORDS_REPORT 0x75
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
|
||||||
* Response ID returned by get next query response operation
|
|
||||||
* <br>Complete sequence of messages containing the template records query response has been sent
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_QUERY_RESPONSE_COMPLETE 0x76
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
|
||||||
* Response ID returned by get enrolled fingers operation
|
|
||||||
* <br> Returns list of IDs of enrolled fingers for a specific user,
|
|
||||||
* along with template record status corresponding to each enrolled finger
|
|
||||||
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_GET_ENROLLED_FINGERS_REPORT 0x77
|
|
||||||
|
|
||||||
/*! \addtogroup dbcapacity
|
|
||||||
* Response IDs returned by get database capacity operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
|
||||||
* Response specifying total capacity of fingerprint template database and
|
|
||||||
* how much free capacity is remaining along with how many templates are corrupted and
|
|
||||||
* how many bad (permanently unusable) storage slots are there.
|
|
||||||
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_DATABASE_CAPACITY_REPORT 0x78
|
|
||||||
/** Failed to execute database query */
|
|
||||||
#define BMKT_RSP_QUERY_FAIL 0x79
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup deluser
|
|
||||||
* Response IDs returned by delete fingerprint of specific user operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to delete a user’s fingerprint template from the database */
|
|
||||||
#define BMKT_RSP_DEL_USER_FP_FAIL 0x82
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_DEL_USER_FP_OK:
|
|
||||||
* Fingerprint template successfully deleted from the database.
|
|
||||||
* Returns the user ID and finger ID deleted. If value of finger ID is set equal to 0,
|
|
||||||
* then all fingerprint templates for that user have been deleted from the database
|
|
||||||
* <br>Payload data represented in \ref bmkt_del_user_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_DEL_USER_FP_OK 0x83
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup delfulldb
|
|
||||||
* Response IDs returned by delete entire fingerprint template DB operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Failed to erase entire fingerprint template database */
|
|
||||||
#define BMKT_RSP_DEL_FULL_DB_FAIL 0x85
|
|
||||||
/** Successfully erased entire fingerprint template database */
|
|
||||||
#define BMKT_RSP_DEL_FULL_DB_OK 0x86
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_DELETE_PROGRESS:
|
|
||||||
* Notify progress made during the on-going deletion of the full template database
|
|
||||||
* <br>Payload data represented in \ref bmkt_del_all_users_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_DELETE_PROGRESS 0x87
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
|
||||||
* Response ID returned by repeate last response operation
|
|
||||||
* <br>Failed to retrieve and re-send last response
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL 0x93
|
|
||||||
|
|
||||||
/*! \addtogroup pwrdwn
|
|
||||||
* Response IDs returned by power down notify operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/** Fingerprint sensor module is ready to be powered down */
|
|
||||||
#define BMKT_RSP_POWER_DOWN_READY 0xA2
|
|
||||||
/** Failed to go into power down mode */
|
|
||||||
#define BMKT_RSP_POWER_DOWN_FAIL 0xA3
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/*! \addtogroup versioninfo
|
|
||||||
* Response IDs returned by get version operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_VERSION_INFO:
|
|
||||||
* System version information of the fingerprint sensor module
|
|
||||||
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_VERSION_INFO 0xB2
|
|
||||||
/* Failed to retrieve and send last response */
|
|
||||||
#define BMKT_RSP_GET_VERSION_FAIL 0xB3
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_GENERAL_ERROR:
|
|
||||||
* Not tied to a specific command-response session.
|
|
||||||
* <br>Could be caused by corrupt or truncated command message
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_GENERAL_ERROR 0xC1
|
|
||||||
#define BMKT_RSP_DISABLE_PAIRING_FAIL 0xC3
|
|
||||||
#define BMKT_RSP_DISABLE_PAIRING_OK 0xC4
|
|
||||||
#define BMKT_RSP_QUERY_PAIRING_FAIL 0xC6
|
|
||||||
#define BMKT_RSP_SENSOR_PAIRING_REPORT 0xC7
|
|
||||||
|
|
||||||
/*! \addtogroup versioninfo
|
|
||||||
* Response IDs returned by get sensor module status operation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_SENSOR_STATUS_REPORT:
|
|
||||||
* Response returning the current status of the sensor module
|
|
||||||
* <br>Payload data represented in bmkt_XXX struct
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_SENSOR_STATUS_REPORT 0xD2
|
|
||||||
/** Failed to retrieve sensor status */
|
|
||||||
#define BMKT_RSP_SENSOR_STATUS_FAIL 0xD3
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_SEND_NEXT_USER_ID:
|
|
||||||
* Response ID returned by identify user in order operation
|
|
||||||
* <br>Notify to send the next batch of user IDs in the priority list
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_SEND_NEXT_USER_ID 0xE2
|
|
||||||
/**
|
|
||||||
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
|
||||||
* Response IDs returned by retrieve final result operation
|
|
||||||
* <br>Failed to retrieve and re-send cached final result
|
|
||||||
*/
|
|
||||||
#define BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL 0xE5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Response payload data structure returned by sensor initialization operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_init_resp
|
|
||||||
{
|
|
||||||
uint8_t finger_presence; /**< Indicates finger existence on the sensor during startup */
|
|
||||||
} bmkt_init_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enroll_resp:
|
|
||||||
* Response payload data structure returned by enrollment operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_enroll_resp
|
|
||||||
{
|
|
||||||
int progress; /**< Shows current progress stutus [0-100] */
|
|
||||||
uint8_t finger_id; /**< User's finger id [1-10] */
|
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
|
|
||||||
} bmkt_enroll_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_auth_resp:
|
|
||||||
* Response payload data structure returned by identify and verify operations.
|
|
||||||
*/
|
|
||||||
struct bmkt_auth_resp
|
|
||||||
{
|
|
||||||
double match_result; /**< match result returned by matcher */
|
|
||||||
uint8_t finger_id; /**< Matched templates's finger id */
|
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< Matched template's user id */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct bmkt_auth_resp bmkt_verify_resp_t; /**< Returned by verify */
|
|
||||||
typedef struct bmkt_auth_resp bmkt_identify_resp_t; /**< Returned by identify */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_fps_mode_resp:
|
|
||||||
* Response payload data structure returned by get fingerprint mode operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_fps_mode_resp
|
|
||||||
{
|
|
||||||
uint8_t mode; /**< One of the Level I bmkt_mode_t values */
|
|
||||||
uint8_t level2_mode; /**< One of the Level II bmkt_mode_level2_t values */
|
|
||||||
uint8_t cmd_id; /**< Message ID of command being executed when bmkt_get_fps_mode was called */
|
|
||||||
uint8_t finger_presence; /**< Finger presence status value finger on sensor 1 / finger not on sensor 0 */
|
|
||||||
} bmkt_fps_mode_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_get_version_resp:
|
|
||||||
* Response payload data structure returned by get version operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_get_version_resp
|
|
||||||
{
|
|
||||||
uint8_t part[BMKT_PART_NUM_LEN]; /**< Software Part Number */
|
|
||||||
uint8_t year; /**< Software Version Year */
|
|
||||||
uint8_t week; /**< Software Version Week */
|
|
||||||
uint8_t patch; /**< Software Version Patch Level */
|
|
||||||
uint8_t supplier_id[BMKT_SUPPLIER_ID_LEN]; /**< Software Supplier Identification */
|
|
||||||
} bmkt_get_version_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_get_db_capacity_resp:
|
|
||||||
* Response payload data structure returned by get DB capacity operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_get_db_capacity_resp
|
|
||||||
{
|
|
||||||
uint8_t total; /**< Total Available Capacity: Total number of template records that can be stored */
|
|
||||||
uint8_t empty; /**< Free Capacity: Number of template records that can still be stored */
|
|
||||||
uint8_t bad_slots; /**< Number of bad template storage slots */
|
|
||||||
uint8_t corrupt_templates; /**< Number of corrupt templates */
|
|
||||||
} bmkt_get_db_capacity_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_sec_level:
|
|
||||||
* Security level values.
|
|
||||||
*/
|
|
||||||
typedef enum bmkt_sec_level
|
|
||||||
{
|
|
||||||
BMKT_SECURITY_LEVEL_LOW = 0x10,
|
|
||||||
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
|
|
||||||
BMKT_SECURITY_LEVEL_HIGH = 0x60,
|
|
||||||
} bmkt_sec_level_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_set_sec_level_resp:
|
|
||||||
* Response payload data structure returned by get/set security level operations.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_set_sec_level_resp
|
|
||||||
{
|
|
||||||
bmkt_sec_level_t sec_level; /**< One of the bmkt_sec_level_t values */
|
|
||||||
} bmkt_set_sec_level_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_del_all_users_resp:
|
|
||||||
* Response payload data structure returned by delete all enrolled users operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_del_all_users_resp
|
|
||||||
{
|
|
||||||
int progress; /**< Progress indicator as a percentage */
|
|
||||||
} bmkt_del_all_users_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_del_user_resp:
|
|
||||||
* Response payload data structure returned by delete enrolled user operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_del_user_resp
|
|
||||||
{
|
|
||||||
int progress; /**< Progress indicator as a percentage */
|
|
||||||
} bmkt_del_user_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enroll_template:
|
|
||||||
* Structure of enrolled users template record data.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_enroll_template
|
|
||||||
{
|
|
||||||
uint8_t user_id_len; /**< Length of user_id string */
|
|
||||||
uint8_t template_status; /**< Template record status */
|
|
||||||
uint8_t finger_id; /**< ID of enrolled finger */
|
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN + 1]; /**< Name of the enrolled user */
|
|
||||||
} bmkt_enroll_template_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enroll_templates_resp:
|
|
||||||
* Response payload data structure returned by get enrolled user list operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_enroll_templates_resp
|
|
||||||
{
|
|
||||||
uint8_t total_query_messages; /**< Total query response messages */
|
|
||||||
uint8_t query_sequence; /**< Query response sequence number */
|
|
||||||
bmkt_enroll_template_t templates[BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH]; /**< Enrolled user template records list */
|
|
||||||
} bmkt_enroll_templates_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enrolled_fingers:
|
|
||||||
* Structure of template record status corresponding to each enrolled finger.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_enrolled_fingers
|
|
||||||
{
|
|
||||||
uint8_t finger_id; /**< ID of enrolled finger */
|
|
||||||
uint8_t template_status; /**< Template record status of finger_id */
|
|
||||||
} bmkt_enrolled_fingers_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_enrolled_fingers_resp:
|
|
||||||
* Response payload data structure returned by get enrolled fingers operation.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_enrolled_fingers_resp
|
|
||||||
{
|
|
||||||
bmkt_enrolled_fingers_t fingers[10]; /**< List of enroled fingers, max number of supported fingers per user is 10 */
|
|
||||||
} bmkt_enrolled_fingers_resp_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_response_data_t:
|
|
||||||
* Union combining all response payload data types.
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
bmkt_init_resp_t init_resp;
|
|
||||||
bmkt_enroll_resp_t enroll_resp;
|
|
||||||
bmkt_verify_resp_t verify_resp;
|
|
||||||
bmkt_identify_resp_t id_resp;
|
|
||||||
bmkt_fps_mode_resp_t fps_mode_resp;
|
|
||||||
bmkt_get_version_resp_t get_version_resp;
|
|
||||||
bmkt_get_db_capacity_resp_t db_cap_resp;
|
|
||||||
bmkt_set_sec_level_resp_t sec_level_resp;
|
|
||||||
bmkt_del_all_users_resp_t del_all_users_resp;
|
|
||||||
bmkt_enroll_templates_resp_t enroll_templates_resp;
|
|
||||||
bmkt_del_user_resp_t del_user_resp;
|
|
||||||
bmkt_enrolled_fingers_resp_t enrolled_fingers_resp;
|
|
||||||
} bmkt_response_data_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bmkt_response:
|
|
||||||
* Structure to abstract different response structure types in one API
|
|
||||||
* to be used in bmkt_resp_cb_t callback function.
|
|
||||||
*/
|
|
||||||
typedef struct bmkt_response
|
|
||||||
{
|
|
||||||
int response_id; /**< Response message ID, one of th BMKT_RSP_XXX */
|
|
||||||
int result; /**< Operation execution result code */
|
|
||||||
int complete; /**< Operation completion status 1: complete / 0: not completed */
|
|
||||||
bmkt_response_data_t response; /**< Operation specific response union */
|
|
||||||
} bmkt_response_t;
|
|
||||||
|
|
||||||
#endif /* _BMKT_RESPONSE_H_ */
|
|
||||||
@@ -1,481 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "bmkt_internal.h"
|
|
||||||
#include "bmkt_message.h"
|
|
||||||
#include "sensor.h"
|
|
||||||
|
|
||||||
#define SENSOR_CMD_GET_VERSION 1
|
|
||||||
#define SENSOR_CMD_ACE_COMMAND 167
|
|
||||||
#define SENSOR_CMD_ASYNCMSG_READ 168
|
|
||||||
|
|
||||||
#define SENSOR_FW_CMD_HEADER_LEN 1
|
|
||||||
#define SENSOR_FW_REPLY_HEADER_LEN 2
|
|
||||||
|
|
||||||
static int get_version(bmkt_sensor_t *sensor, bmkt_sensor_version_t *mis_version)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *resp = NULL;
|
|
||||||
int resp_len = 40;
|
|
||||||
uint16_t status = 0;
|
|
||||||
uint8_t *cmd;
|
|
||||||
int cmd_len = 0;
|
|
||||||
int cmd_buf_len;
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_buf_len < SENSOR_FW_CMD_HEADER_LEN)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[0] = SENSOR_CMD_GET_VERSION;
|
|
||||||
cmd_len = 1;
|
|
||||||
ret = usb_send_command_sync(&sensor->usb_xport, cmd_len, &resp, &resp_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = extract16(resp, &offset);
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
bmkt_err_log("The sensor reported an error when sending get version command: 0x%x",
|
|
||||||
status);
|
|
||||||
return BMKT_SENSOR_MALFUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp_len < 38)
|
|
||||||
{
|
|
||||||
return BMKT_SENSOR_MALFUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
mis_version->build_time = extract32(resp, &offset);
|
|
||||||
mis_version->build_num = extract32(resp, &offset);
|
|
||||||
mis_version->version_major = extract8(resp, &offset);
|
|
||||||
mis_version->version_minor = extract8(resp, &offset);
|
|
||||||
mis_version->target = extract8(resp, &offset);
|
|
||||||
mis_version->product = extract8(resp, &offset);
|
|
||||||
|
|
||||||
ret = usb_release_command_buffer(&sensor->usb_xport);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("%s: failed to release command buffer: %d", __func__, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bmkt_session_ctx_t *get_empty_session_ctx(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
bmkt_session_ctx_t *ctx;
|
|
||||||
int i;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
|
||||||
{
|
|
||||||
idx = (sensor->empty_session_idx + i) % BMKT_MAX_PENDING_SESSIONS;
|
|
||||||
ctx = &sensor->pending_sessions[idx];
|
|
||||||
if (ctx->seq_num == 0)
|
|
||||||
{
|
|
||||||
sensor->empty_session_idx = (idx + 1) % BMKT_MAX_PENDING_SESSIONS;
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bmkt_session_ctx_t *get_session_ctx(bmkt_sensor_t *sensor, int seq_num)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bmkt_session_ctx_t *ctx;
|
|
||||||
|
|
||||||
/* Sequence number of 0 is not valid for a response to
|
|
||||||
a command.*/
|
|
||||||
if (seq_num == 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
|
||||||
{
|
|
||||||
ctx = &sensor->pending_sessions[i];
|
|
||||||
if (ctx->seq_num == seq_num)
|
|
||||||
{
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int release_session_ctx(bmkt_sensor_t *sensor, bmkt_session_ctx_t *ctx)
|
|
||||||
{
|
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(bmkt_session_ctx_t));
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_open(bmkt_sensor_t *sensor, bmkt_general_error_cb_t err_cb, void *err_cb_ctx)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
sensor->seq_num = 1;
|
|
||||||
|
|
||||||
sensor->sensor_state = BMKT_SENSOR_STATE_UNINIT;
|
|
||||||
sensor->usb_xport.sensor = sensor;
|
|
||||||
ret = usb_open(&sensor->usb_xport);
|
|
||||||
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_err_log("Failed to open transport: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
sensor->gen_err_cb = err_cb;
|
|
||||||
sensor->gen_err_cb_ctx = err_cb_ctx;
|
|
||||||
|
|
||||||
ret = get_version(sensor, &sensor->version);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_err_log("Failed to get version info: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bmkt_dbg_log("Build Time: %d", sensor->version.build_time);
|
|
||||||
bmkt_dbg_log("Build Num: %d", sensor->version.build_num);
|
|
||||||
bmkt_dbg_log("Version: %d.%d", sensor->version.version_major, sensor->version.version_minor);
|
|
||||||
bmkt_dbg_log("Target: %d", sensor->version.target);
|
|
||||||
bmkt_dbg_log("Product: %d", sensor->version.product);
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_close(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
sensor->sensor_state = BMKT_SENSOR_STATE_EXIT;
|
|
||||||
|
|
||||||
ret = usb_close(&sensor->usb_xport);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
sensor->sensor_state = BMKT_SENSOR_STATE_EXIT;
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_init_fps(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
sensor->sensor_state = BMKT_SENSOR_STATE_INIT;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_send_message(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
|
||||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *cmd;
|
|
||||||
int cmd_buf_len = 0;
|
|
||||||
int msg_len;
|
|
||||||
int seq_num = 0;
|
|
||||||
bmkt_session_ctx_t *session_ctx = get_empty_session_ctx(sensor);
|
|
||||||
|
|
||||||
if (session_ctx == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_OPERATION_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sensor->seq_num > 255) {
|
|
||||||
/* seq. number is in range [1 – 255]. After it reaches 255, it rolls over to 1 and starts over again.
|
|
||||||
(0 is reserved for special purposes) */
|
|
||||||
sensor->seq_num = 1;
|
|
||||||
}
|
|
||||||
session_ctx->seq_num = sensor->seq_num++;
|
|
||||||
session_ctx->resp_cb = resp_cb;
|
|
||||||
session_ctx->cb_ctx = cb_ctx;
|
|
||||||
|
|
||||||
bmkt_dbg_log("session_ctx->seq_num=%d, sensor->seq_num=%d", session_ctx->seq_num, sensor->seq_num);
|
|
||||||
|
|
||||||
bmkt_op_set_state(sensor, BMKT_OP_STATE_START);
|
|
||||||
|
|
||||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MIS sensors send ACE commands encapsulated in FW commands*/
|
|
||||||
cmd[0] = SENSOR_CMD_ACE_COMMAND;
|
|
||||||
msg_len = cmd_buf_len - SENSOR_FW_CMD_HEADER_LEN;
|
|
||||||
|
|
||||||
if (session_ctx != NULL)
|
|
||||||
{
|
|
||||||
seq_num = session_ctx->seq_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bmkt_compose_message(&cmd[1], &msg_len, msg_id, seq_num, payload_size, payload);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to compose ace message: %d", ret);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = usb_send_command(&sensor->usb_xport, msg_len + SENSOR_FW_CMD_HEADER_LEN);
|
|
||||||
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("%s: failed to send ACE command: %d", __func__, ret);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
usb_release_command_buffer(&sensor->usb_xport);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
release_session_ctx(sensor, session_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_send_async_read_command(bmkt_sensor_t *sensor)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *cmd;
|
|
||||||
int cmd_buf_len = 0;
|
|
||||||
|
|
||||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MIS sensors send ACE commands encapsulated in FW commands */
|
|
||||||
cmd[0] = SENSOR_CMD_ASYNCMSG_READ;
|
|
||||||
|
|
||||||
ret = usb_send_command(&sensor->usb_xport, SENSOR_FW_CMD_HEADER_LEN);
|
|
||||||
if (ret == BMKT_SENSOR_RESPONSE_PENDING)
|
|
||||||
{
|
|
||||||
/* The caller needs to handle the response before we can send this command */
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
if (ret != BMKT_SENSOR_NOT_READY)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("%s: failed to send ACE ASYNC READ command: %d", __func__, ret);
|
|
||||||
}
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
usb_release_command_buffer(&sensor->usb_xport);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_send_message_sync(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
|
||||||
uint8_t *payload, uint8_t **resp_buf, int *resp_len, bmkt_response_t *resp)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
uint8_t *cmd;
|
|
||||||
int cmd_buf_len = 0;
|
|
||||||
int msg_len;
|
|
||||||
bmkt_msg_resp_t msg_resp;
|
|
||||||
|
|
||||||
*resp_len = BMKT_MAX_TRANSFER_LEN;
|
|
||||||
|
|
||||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[0] = SENSOR_CMD_ACE_COMMAND;
|
|
||||||
msg_len = cmd_buf_len - SENSOR_FW_CMD_HEADER_LEN;
|
|
||||||
|
|
||||||
ret = bmkt_compose_message(&cmd[1], &msg_len, msg_id, sensor->seq_num++, payload_size,
|
|
||||||
payload);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to compose ace message: %d", ret);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = usb_send_command_sync(&sensor->usb_xport, msg_len + SENSOR_FW_CMD_HEADER_LEN,
|
|
||||||
resp_buf, resp_len);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("%s: failed to send ACE command: %d", __func__, ret);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bmkt_parse_message_header(&(*resp_buf)[2], *resp_len - 2, &msg_resp);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bmkt_parse_message_payload(&msg_resp, resp);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
ret = usb_release_command_buffer(&sensor->usb_xport);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("%s: failed to release command buffer: %d", __func__, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
bmkt_session_ctx_t *session_ctx;
|
|
||||||
bmkt_response_t resp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ret = bmkt_parse_message_header(&resp_buf[2], resp_len - 2, msg_resp);
|
|
||||||
if (ret == BMKT_CORRUPT_MESSAGE)
|
|
||||||
{
|
|
||||||
bmkt_warn_log("Corrupt Message Received");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg_resp->msg_id == BMKT_EVT_FINGER_REPORT)
|
|
||||||
{
|
|
||||||
/* finger event message */
|
|
||||||
bmkt_info_log("Finger event!");
|
|
||||||
bmkt_finger_event_t finger_event;
|
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
|
||||||
{
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg_resp->payload[0] == 0x01)
|
|
||||||
{
|
|
||||||
finger_event.finger_state = BMKT_FINGER_STATE_ON_SENSOR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
finger_event.finger_state = BMKT_FINGER_STATE_NOT_ON_SENSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sensor->finger_event_cb != NULL)
|
|
||||||
{
|
|
||||||
sensor->finger_event_cb(&finger_event, sensor->finger_cb_ctx);
|
|
||||||
}
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg_resp->seq_num == 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (msg_resp->msg_id == BMKT_RSP_GENERAL_ERROR)
|
|
||||||
{
|
|
||||||
/* report general error */
|
|
||||||
bmkt_info_log("General Error!");
|
|
||||||
uint16_t err;
|
|
||||||
|
|
||||||
if (sensor->gen_err_cb != NULL)
|
|
||||||
{
|
|
||||||
err = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
|
||||||
sensor->gen_err_cb(err, sensor->gen_err_cb_ctx);
|
|
||||||
}
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bmkt_parse_message_payload(msg_resp, &resp);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_warn_log("Failed to process response: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
session_ctx = get_session_ctx(sensor, msg_resp->seq_num);
|
|
||||||
if (session_ctx == NULL)
|
|
||||||
{
|
|
||||||
bmkt_warn_log("Response received with invalid sequence number: %d, return BMKT_UNRECOGNIZED_MESSAGE(112)", msg_resp->seq_num);
|
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session_ctx->resp_cb != NULL)
|
|
||||||
{
|
|
||||||
ret = session_ctx->resp_cb(&resp, session_ctx->cb_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_warn_log("response callback failed: %d", ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.complete == 1)
|
|
||||||
{
|
|
||||||
ret = release_session_ctx(sensor, session_ctx);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK && resp.result == BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
/* The previous commands have been canceled. Release all session ctx */
|
|
||||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
|
||||||
{
|
|
||||||
release_session_ctx(sensor, &sensor->pending_sessions[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bmkt_register_finger_event_notification(bmkt_sensor_t *sensor, bmkt_event_cb_t cb, void *cb_ctx)
|
|
||||||
{
|
|
||||||
if (sensor == NULL || cb == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
sensor->finger_event_cb = cb;
|
|
||||||
sensor->finger_cb_ctx = cb_ctx;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SENSOR_H_
|
|
||||||
#define _SENSOR_H_
|
|
||||||
|
|
||||||
#include "usb_transport.h"
|
|
||||||
#define BMKT_MAX_PENDING_SESSIONS 2
|
|
||||||
|
|
||||||
typedef enum bmkt_sensor_state
|
|
||||||
{
|
|
||||||
BMKT_SENSOR_STATE_UNINIT = 0,
|
|
||||||
BMKT_SENSOR_STATE_IDLE,
|
|
||||||
BMKT_SENSOR_STATE_INIT,
|
|
||||||
BMKT_SENSOR_STATE_EXIT,
|
|
||||||
} bmkt_sensor_state_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_sensor_drv bmkt_sensor_drv_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_sensor_version
|
|
||||||
{
|
|
||||||
uint32_t build_time;
|
|
||||||
uint32_t build_num;
|
|
||||||
uint8_t version_major;
|
|
||||||
uint8_t version_minor;
|
|
||||||
uint8_t target;
|
|
||||||
uint8_t product;
|
|
||||||
uint8_t silicon_rev;
|
|
||||||
uint8_t formal_release;
|
|
||||||
uint8_t platform;
|
|
||||||
uint8_t patch;
|
|
||||||
uint8_t serial_number[6];
|
|
||||||
uint16_t security;
|
|
||||||
uint8_t iface;
|
|
||||||
uint8_t device_type;
|
|
||||||
} bmkt_sensor_version_t;
|
|
||||||
|
|
||||||
typedef struct bmkt_sensor
|
|
||||||
{
|
|
||||||
bmkt_usb_transport_t usb_xport;
|
|
||||||
bmkt_sensor_version_t version;
|
|
||||||
bmkt_session_ctx_t pending_sessions[BMKT_MAX_PENDING_SESSIONS];
|
|
||||||
int empty_session_idx;
|
|
||||||
int flags;
|
|
||||||
int seq_num;
|
|
||||||
bmkt_sensor_state_t sensor_state;
|
|
||||||
bmkt_event_cb_t finger_event_cb;
|
|
||||||
void *finger_cb_ctx;
|
|
||||||
bmkt_general_error_cb_t gen_err_cb;
|
|
||||||
void *gen_err_cb_ctx;
|
|
||||||
bmkt_op_state_t op_state;
|
|
||||||
} bmkt_sensor_t;
|
|
||||||
|
|
||||||
int bmkt_sensor_open(bmkt_sensor_t *sensor,
|
|
||||||
bmkt_general_error_cb_t err_cb, void *err_cb_ctx);
|
|
||||||
int bmkt_sensor_close(bmkt_sensor_t *sensor);
|
|
||||||
|
|
||||||
int bmkt_sensor_init_fps(bmkt_sensor_t *sensor);
|
|
||||||
|
|
||||||
int bmkt_sensor_send_message(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
|
||||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *resp_data);
|
|
||||||
int bmkt_sensor_send_message_sync(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
|
||||||
uint8_t *payload, uint8_t **resp_buf, int *resp_len, bmkt_response_t *resp);
|
|
||||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
|
||||||
|
|
||||||
int bmkt_sensor_send_async_read_command(bmkt_sensor_t *sensor);
|
|
||||||
#endif /* _SENSOR_H_ */
|
|
||||||
@@ -1,488 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FP_COMPONENT "synaptics"
|
|
||||||
|
|
||||||
#include "drivers_api.h"
|
|
||||||
#include "fpi-async.h"
|
|
||||||
#include "fp_internal.h"
|
|
||||||
|
|
||||||
#include "synaptics.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const struct usb_id id_table[] = {
|
|
||||||
{ .vendor = SYNAPTICS_VENDOR_ID, .product = SYNAPTICS_PRODUCT_ID_A9, },
|
|
||||||
|
|
||||||
{ 0, 0, 0, }, /* terminating entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int general_error_callback(uint16_t error, void *ctx)
|
|
||||||
{
|
|
||||||
fp_err("Received General Error %d from the sensor", error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int finger_event_callback(bmkt_finger_event_t *event, void *ctx)
|
|
||||||
{
|
|
||||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
|
|
||||||
switch (event->finger_state)
|
|
||||||
{
|
|
||||||
case BMKT_FINGER_STATE_UNKNOWN:
|
|
||||||
fp_info("Finger state is not known");
|
|
||||||
break;
|
|
||||||
case BMKT_FINGER_STATE_ON_SENSOR:
|
|
||||||
sdev->isFingerOnSensor = TRUE;
|
|
||||||
fp_info("Finger in on the sensor");
|
|
||||||
break;
|
|
||||||
case BMKT_FINGER_STATE_NOT_ON_SENSOR:
|
|
||||||
sdev->isFingerOnSensor = FALSE;
|
|
||||||
fp_info("Finger is not on the sensor");
|
|
||||||
if(sdev->state == SYNA_STATE_VERIFY_DELAY_RESULT)
|
|
||||||
{
|
|
||||||
fp_info("verify no match");
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_NO_MATCH, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct syna_mis_print_data
|
|
||||||
{
|
|
||||||
uint8_t finger_id;
|
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
static int enroll_response(bmkt_response_t *resp, void *ctx)
|
|
||||||
{
|
|
||||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
|
||||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
|
|
||||||
switch (resp->response_id)
|
|
||||||
{
|
|
||||||
case BMKT_RSP_ENROLL_READY:
|
|
||||||
{
|
|
||||||
fpi_drvcb_enroll_started(dev, 0);
|
|
||||||
sdev->enroll_resp_data.progress = 0;
|
|
||||||
fp_info("Place Finger on the Sensor!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
|
||||||
{
|
|
||||||
fp_info("Fingerprint image capture complete!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_ENROLL_REPORT:
|
|
||||||
{
|
|
||||||
fp_info("Enrollment is %d %% ", enroll_resp->progress);
|
|
||||||
if(enroll_resp->progress < 100)
|
|
||||||
{
|
|
||||||
if(sdev->enroll_resp_data.progress == enroll_resp->progress)
|
|
||||||
fpi_drvcb_enroll_stage_completed(dev, FP_ENROLL_RETRY, NULL, NULL);
|
|
||||||
else
|
|
||||||
fpi_drvcb_enroll_stage_completed(dev, FP_ENROLL_PASS, NULL, NULL);
|
|
||||||
}
|
|
||||||
sdev->enroll_resp_data.progress = enroll_resp->progress;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_ENROLL_PAUSED:
|
|
||||||
{
|
|
||||||
fp_info("Enrollment has been paused!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_ENROLL_RESUMED:
|
|
||||||
{
|
|
||||||
fp_info("Enrollment has been resumed!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_ENROLL_FAIL:
|
|
||||||
{
|
|
||||||
fp_info("Enrollment has failed!: %d", resp->result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_ENROLL_OK:
|
|
||||||
{
|
|
||||||
struct syna_mis_print_data mis_data;
|
|
||||||
struct fp_print_data *fdata = NULL;
|
|
||||||
struct fp_print_data_item *item = NULL;
|
|
||||||
fdata = fpi_print_data_new(dev);
|
|
||||||
item = fpi_print_data_item_new(sizeof(mis_data));
|
|
||||||
fp_info("Enrollment was successful!");
|
|
||||||
mis_data.finger_id = enroll_resp->finger_id;
|
|
||||||
memcpy(mis_data.user_id, enroll_resp->user_id,
|
|
||||||
BMKT_MAX_USER_ID_LEN);
|
|
||||||
memcpy(item->data, &mis_data,
|
|
||||||
sizeof(struct syna_mis_print_data));
|
|
||||||
fdata->prints = g_slist_prepend(fdata->prints, item);
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
fpi_drvcb_enroll_stage_completed(dev, 1, fdata, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
|
||||||
{
|
|
||||||
synaptics_dev *sdev = NULL;
|
|
||||||
int result = 0, ret = 0;
|
|
||||||
|
|
||||||
fp_info("%s ", __func__);
|
|
||||||
|
|
||||||
/* Set enroll stage number */
|
|
||||||
fpi_dev_set_nr_enroll_stages(dev, ENROLL_SAMPLES);
|
|
||||||
|
|
||||||
/* Initialize private structure */
|
|
||||||
sdev = g_malloc0(sizeof(synaptics_dev));
|
|
||||||
|
|
||||||
result = bmkt_init(&(sdev->ctx));
|
|
||||||
if (result != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to initialize bmkt context: %d", result);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fp_info("bmkt_init successfully.");
|
|
||||||
|
|
||||||
result = bmkt_open(sdev->ctx, &sdev->sensor, general_error_callback, NULL, fpi_dev_get_usb_dev(dev));
|
|
||||||
if (result != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to open bmkt sensor: %d", result);
|
|
||||||
goto bmkt_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = bmkt_register_finger_event_notification(sdev->sensor, finger_event_callback, dev);
|
|
||||||
if (result != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to register finger event notification: %d", result);
|
|
||||||
goto bmkt_cleanup;
|
|
||||||
}
|
|
||||||
result = bmkt_init_fps(sdev->sensor);
|
|
||||||
if (result == BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_info("Successfully initialized the FPS");
|
|
||||||
}
|
|
||||||
else if (result == BMKT_OPERATION_DENIED)
|
|
||||||
{
|
|
||||||
/* sensor already intialized...allow operations to continue */
|
|
||||||
fp_info("FPS already initialized");
|
|
||||||
result = BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fp_err("Failed to initialize the FPS: %d", result);
|
|
||||||
goto bmkt_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_dev_set_instance_data(dev, sdev);
|
|
||||||
/* Notify open complete */
|
|
||||||
fpi_drvcb_open_complete(dev, 0);
|
|
||||||
return result;
|
|
||||||
|
|
||||||
bmkt_cleanup:
|
|
||||||
ret = bmkt_close(sdev->sensor);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to close bmkt sensor: %d", ret);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
bmkt_exit(sdev->ctx);
|
|
||||||
g_free(sdev);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
fpi_drvcb_open_complete(dev, 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
static void dev_exit(struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
ret = bmkt_close(sdev->sensor);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to close bmkt sensor: %d", ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bmkt_exit(sdev->ctx);
|
|
||||||
|
|
||||||
g_free(sdev);
|
|
||||||
fpi_drvcb_close_complete(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean rand_string(char *str, size_t size)
|
|
||||||
{
|
|
||||||
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
srand(time(NULL));
|
|
||||||
if (size) {
|
|
||||||
--size;
|
|
||||||
for (size_t n = 0; n < size; n++) {
|
|
||||||
int key = rand() % (int) (sizeof charset - 1);
|
|
||||||
str[n] = charset[key];
|
|
||||||
}
|
|
||||||
str[size] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TEMPLATE_ID_SIZE 20
|
|
||||||
|
|
||||||
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;
|
|
||||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
|
|
||||||
switch (resp->response_id)
|
|
||||||
{
|
|
||||||
case BMKT_RSP_DELETE_PROGRESS:
|
|
||||||
fp_info("Deleting Enrolled Users is %d%% complete",
|
|
||||||
del_user_resp->progress);
|
|
||||||
break;
|
|
||||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
|
||||||
fp_info("Failed to delete enrolled user: %d", resp->result);
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
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");
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
if(sdev->state == SYNA_STATE_DELETE)
|
|
||||||
{
|
|
||||||
fpi_drvcb_delete_complete(dev, FP_DELETE_COMPLETE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int enroll_start(struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
int result = 0;
|
|
||||||
char userid[TEMPLATE_ID_SIZE + 1];
|
|
||||||
|
|
||||||
fp_info("enroll_start");
|
|
||||||
|
|
||||||
|
|
||||||
rand_string(userid, TEMPLATE_ID_SIZE);
|
|
||||||
|
|
||||||
int useridlength =0;
|
|
||||||
int finger_id;
|
|
||||||
|
|
||||||
finger_id = 1;
|
|
||||||
useridlength = strlen(userid);
|
|
||||||
|
|
||||||
sdev->state = SYNA_STATE_ENROLL;
|
|
||||||
|
|
||||||
result = bmkt_enroll(sdev->sensor, userid, useridlength,
|
|
||||||
finger_id, enroll_response, dev);
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
fp_err("Failed to enroll finger: %d", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int enroll_stop(struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
fp_info("syna enroll stop");
|
|
||||||
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
sdev->state = SYNA_STATE_IDLE;
|
|
||||||
fpi_drvcb_enroll_stopped(dev);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int verify_response(bmkt_response_t *resp, void *ctx)
|
|
||||||
{
|
|
||||||
bmkt_verify_resp_t *verify_resp = &resp->response.verify_resp;
|
|
||||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
|
|
||||||
switch (resp->response_id)
|
|
||||||
{
|
|
||||||
case BMKT_RSP_VERIFY_READY:
|
|
||||||
{
|
|
||||||
fp_info("Place Finger on the Sensor!");
|
|
||||||
fpi_drvcb_verify_started(dev, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
|
||||||
{
|
|
||||||
fp_info("Fingerprint image capture complete!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_VERIFY_FAIL:
|
|
||||||
{
|
|
||||||
fp_err("Verify has failed!: %d", resp->result);
|
|
||||||
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR || resp->result == BMKT_FP_NO_MATCH)
|
|
||||||
{
|
|
||||||
sdev->state = SYNA_STATE_VERIFY_DELAY_RESULT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_NO_MATCH, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BMKT_RSP_VERIFY_OK:
|
|
||||||
{
|
|
||||||
fp_info("Verify was successful! for user: %s finger: %d score: %f",
|
|
||||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
|
||||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
|
||||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_MATCH, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
int result = 0;
|
|
||||||
struct fp_print_data *print = fpi_dev_get_verify_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("syna verify_start !");
|
|
||||||
|
|
||||||
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_VERIFY;
|
|
||||||
result = bmkt_verify(sdev->sensor, &user, verify_response, dev);
|
|
||||||
if (result != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
fp_err("Failed to verify finger: %d", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
fpi_drvcb_verify_started(dev, 1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int verify_stop(struct fp_dev *dev, gboolean iterating)
|
|
||||||
{
|
|
||||||
fp_info("syna verify_stop");
|
|
||||||
|
|
||||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
|
||||||
sdev->state = SYNA_STATE_IDLE;
|
|
||||||
fpi_drvcb_verify_stopped(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fp_driver synaptics_driver = {
|
|
||||||
.id = SYNAPTICS_ID,
|
|
||||||
.name = FP_COMPONENT,
|
|
||||||
.full_name = SYNAPTICS_DRIVER_FULLNAME,
|
|
||||||
.id_table = id_table,
|
|
||||||
.scan_type = FP_SCAN_TYPE_PRESS,
|
|
||||||
.open = dev_init,
|
|
||||||
.close = dev_exit,
|
|
||||||
.enroll_start = enroll_start,
|
|
||||||
.enroll_stop = enroll_stop,
|
|
||||||
.verify_start = verify_start,
|
|
||||||
.verify_stop = verify_stop,
|
|
||||||
.delete_finger = delete_finger,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __synaptics_h__
|
|
||||||
#define __synaptics_h__
|
|
||||||
|
|
||||||
#define SYNAPTICS_VENDOR_ID 0x06cb
|
|
||||||
#define SYNAPTICS_PRODUCT_ID_A9 0x00a9
|
|
||||||
|
|
||||||
/* Number of enroll stages */
|
|
||||||
#define ENROLL_SAMPLES 12
|
|
||||||
|
|
||||||
#define SYNAPTICS_DRIVER_FULLNAME "Synaptics Sensors"
|
|
||||||
#include "bmkt.h"
|
|
||||||
#include "bmkt_response.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct syna_enroll_resp_data
|
|
||||||
{
|
|
||||||
int progress;
|
|
||||||
};
|
|
||||||
typedef enum syna_state
|
|
||||||
{
|
|
||||||
SYNA_STATE_UNINIT = 0,
|
|
||||||
SYNA_STATE_IDLE ,
|
|
||||||
SYNA_STATE_ENROLL ,
|
|
||||||
SYNA_STATE_IDENTIFY ,
|
|
||||||
SYNA_STATE_IDENTIFY_DELAY_RESULT ,
|
|
||||||
SYNA_STATE_VERIFY ,
|
|
||||||
SYNA_STATE_VERIFY_DELAY_RESULT ,
|
|
||||||
SYNA_STATE_DELETE ,
|
|
||||||
} syna_state_t;
|
|
||||||
|
|
||||||
typedef struct synaptics_dev_s
|
|
||||||
{
|
|
||||||
bmkt_ctx_t *ctx;
|
|
||||||
bmkt_sensor_t *sensor;
|
|
||||||
struct syna_enroll_resp_data enroll_resp_data;
|
|
||||||
gboolean isFingerOnSensor;
|
|
||||||
syna_state_t state;
|
|
||||||
}synaptics_dev;
|
|
||||||
|
|
||||||
#endif //__synaptics_h__
|
|
||||||
@@ -1,386 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "bmkt_internal.h"
|
|
||||||
#include "sensor.h"
|
|
||||||
#include "drivers_api.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define USB_ASYNC_MESSAGE_PENDING 0x4
|
|
||||||
|
|
||||||
static void usb_int_callback(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
|
||||||
|
|
||||||
#ifdef TRANSPORT_DEBUG
|
|
||||||
bmkt_dbg_log("INTERRUPT: (%d) ", transfer->actual_length);
|
|
||||||
print_buffer(transfer->buffer, transfer->actual_length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (transfer->buffer[0] & USB_ASYNC_MESSAGE_PENDING)
|
|
||||||
{
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
bmkt_op_next_state(usb_xport->sensor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
libusb_submit_transfer(transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_check_interrupt(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct libusb_transfer *interrupt_xfer;
|
|
||||||
interrupt_xfer = libusb_alloc_transfer(0);
|
|
||||||
if (interrupt_xfer == NULL)
|
|
||||||
{
|
|
||||||
return BMKT_GENERAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
libusb_fill_interrupt_transfer(interrupt_xfer, usb_xport->handle, USB_EP_INTERRUPT,
|
|
||||||
usb_xport->interrupt_data, sizeof(usb_xport->interrupt_data), usb_int_callback, usb_xport, 0);
|
|
||||||
|
|
||||||
ret = libusb_submit_transfer(interrupt_xfer);
|
|
||||||
if (ret != LIBUSB_SUCCESS)
|
|
||||||
{
|
|
||||||
libusb_free_transfer(interrupt_xfer);
|
|
||||||
if (ret == LIBUSB_ERROR_NO_DEVICE)
|
|
||||||
{
|
|
||||||
return BMKT_SENSOR_MALFUNCTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return BMKT_GENERAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_open(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct libusb_config_descriptor *configDesc;
|
|
||||||
const struct libusb_interface *iface;
|
|
||||||
const struct libusb_interface_descriptor *ifaceDesc;
|
|
||||||
const struct libusb_endpoint_descriptor *endpointDesc;
|
|
||||||
int config;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
usb_xport->device = libusb_get_device(usb_xport->handle);
|
|
||||||
|
|
||||||
ret = libusb_reset_device(usb_xport->handle);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to reset device\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = libusb_get_config_descriptor(usb_xport->device, USB_DEFAULT_CONFIGURATION, &configDesc);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = libusb_get_configuration(usb_xport->handle, &config);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
goto free_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configDesc->bConfigurationValue != config)
|
|
||||||
{
|
|
||||||
ret = libusb_set_configuration(usb_xport->handle, config);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
goto free_config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = libusb_kernel_driver_active(usb_xport->handle, 0);
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
bmkt_err_log("Failed to detect kernel driver\n");
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
goto free_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = libusb_claim_interface(usb_xport->handle, USB_DEFAULT_INTERFACE);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
goto free_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
iface = configDesc->interface + USB_DEFAULT_INTERFACE;
|
|
||||||
ifaceDesc = iface->altsetting + USB_DEFAULT_ALT_SETTING;
|
|
||||||
endpointDesc = ifaceDesc->endpoint;
|
|
||||||
|
|
||||||
for (i = 0; i < ifaceDesc->bNumEndpoints; i++)
|
|
||||||
{
|
|
||||||
ret = libusb_clear_halt(usb_xport->handle, endpointDesc->bEndpointAddress);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = BMKT_SENSOR_MALFUNCTION;
|
|
||||||
goto free_config;
|
|
||||||
}
|
|
||||||
++endpointDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_config:
|
|
||||||
libusb_free_config_descriptor(configDesc);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_close(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
if (usb_xport->handle)
|
|
||||||
{
|
|
||||||
libusb_release_interface(usb_xport->handle, USB_DEFAULT_INTERFACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usb_in_cb(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
uint8_t *resp_buf;
|
|
||||||
int resp_len;
|
|
||||||
bmkt_msg_resp_t msg_resp;
|
|
||||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
|
||||||
|
|
||||||
#ifdef TRANSPORT_DEBUG
|
|
||||||
bmkt_dbg_log("RX_ASYNC: (%d) ", transfer->actual_length);
|
|
||||||
print_buffer(transfer->buffer, transfer->actual_length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
resp_buf = transfer->buffer;
|
|
||||||
resp_len = transfer->actual_length;
|
|
||||||
bmkt_sensor_handle_response(usb_xport->sensor, resp_buf, resp_len, &msg_resp);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
|
|
||||||
bmkt_op_next_state(usb_xport->sensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void usb_out_cb(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
|
|
||||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
|
||||||
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
bmkt_op_next_state(usb_xport->sensor);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bulk_transfer_async(bmkt_usb_transport_t *usb_xport, uint8_t *buf, int size, uint8_t endpoint,
|
|
||||||
int *transferred, uint32_t timeout, libusb_transfer_cb_fn callback)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct libusb_transfer *transfer;
|
|
||||||
|
|
||||||
#ifdef TRANSPORT_DEBUG
|
|
||||||
if (!(endpoint & 0x80))
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("TX2: (%d) ", size);
|
|
||||||
print_buffer(buf, size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
transfer = libusb_alloc_transfer(0);
|
|
||||||
libusb_fill_bulk_transfer( transfer, usb_xport->handle, endpoint,
|
|
||||||
buf, size, callback, usb_xport, 0);
|
|
||||||
|
|
||||||
ret = libusb_submit_transfer(transfer);
|
|
||||||
if (ret != LIBUSB_SUCCESS)
|
|
||||||
{
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
if (ret == LIBUSB_ERROR_NO_DEVICE)
|
|
||||||
{
|
|
||||||
return BMKT_SENSOR_MALFUNCTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return BMKT_GENERAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int bulk_transfer(bmkt_usb_transport_t *usb_xport, uint8_t *buf, int size, uint8_t endpoint,
|
|
||||||
int *transferred, uint32_t timeout)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
#ifdef TRANSPORT_DEBUG
|
|
||||||
if (!(endpoint & 0x80))
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("TX: (%d) ", size);
|
|
||||||
print_buffer(buf, size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = libusb_bulk_transfer(usb_xport->handle, endpoint, buf, size, transferred, timeout);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
bmkt_warn_log("libusb_bulk_transfer: bulk transfer failed: %d\n", ret);
|
|
||||||
if (ret == LIBUSB_ERROR_TIMEOUT)
|
|
||||||
{
|
|
||||||
return BMKT_OP_TIME_OUT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return BMKT_SENSOR_MALFUNCTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bmkt_dbg_log("transferred: %d\n", *transferred);
|
|
||||||
|
|
||||||
#ifdef TRANSPORT_DEBUG
|
|
||||||
if (endpoint & 0x80)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("RX: (%d) ", *transferred);
|
|
||||||
print_buffer(buf, *transferred);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_send_command(bmkt_usb_transport_t *usb_xport, int len)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int tx_len = 0;
|
|
||||||
|
|
||||||
ret = bulk_transfer_async(usb_xport, usb_xport->transfer, len, USB_EP_REQUEST, &tx_len, 0, usb_out_cb);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to send usb command\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int usb_get_command_buffer(bmkt_usb_transport_t *usb_xport, uint8_t **cmd, int *len)
|
|
||||||
{
|
|
||||||
|
|
||||||
*len = BMKT_MAX_TRANSFER_LEN;
|
|
||||||
*cmd = usb_xport->transfer;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_get_response_buffer(bmkt_usb_transport_t *usb_xport, uint8_t **resp, int *len)
|
|
||||||
{
|
|
||||||
*len = BMKT_MAX_TRANSFER_LEN;
|
|
||||||
*resp = usb_xport->transfer;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_receive_resp_async(bmkt_usb_transport_t *usb_xport, int *len)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
*len = BMKT_MAX_TRANSFER_LEN;
|
|
||||||
|
|
||||||
/* Check to make sure the buffer is clear */
|
|
||||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
|
||||||
|
|
||||||
ret = bulk_transfer_async(usb_xport, usb_xport->transfer, *len, USB_EP_REPLY, len, 0, usb_in_cb);
|
|
||||||
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to send usb command\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int usb_receive_resp(bmkt_usb_transport_t *usb_xport, int *len)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
*len = BMKT_MAX_TRANSFER_LEN;
|
|
||||||
|
|
||||||
/* Check to make sure the buffer is clear */
|
|
||||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
|
||||||
|
|
||||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, *len, USB_EP_REPLY, len, 0);
|
|
||||||
|
|
||||||
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to send usb command\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_send_command_sync(bmkt_usb_transport_t *usb_xport, int len, uint8_t **resp_buf,
|
|
||||||
int *resp_len)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int tx_len = 0;
|
|
||||||
|
|
||||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, len, USB_EP_REQUEST, &tx_len, 0);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to send usb command\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to make sure the buffer is clear */
|
|
||||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
|
||||||
|
|
||||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, *resp_len, USB_EP_REPLY, resp_len, 0);
|
|
||||||
if (ret != BMKT_SUCCESS)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("Failed to send usb command\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
*resp_buf = usb_xport->transfer;
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_reset(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
return BMKT_OPERATION_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usb_release_command_buffer(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
int usb_release_response_buffer(bmkt_usb_transport_t *usb_xport)
|
|
||||||
{
|
|
||||||
return BMKT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _USB_TRANSPORT_H_
|
|
||||||
#define _USB_TRANSPORT_H_
|
|
||||||
|
|
||||||
#include "bmkt_internal.h"
|
|
||||||
#include "libusb-1.0/libusb.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BMKT_MAX_TRANSFER_LEN 263 + 1 /* SPI Header */ + 2 /* VCSFW header */
|
|
||||||
|
|
||||||
#define BMKT_XPORT_INT_NONE 0x0
|
|
||||||
#define BMKT_XPORT_INT_RESPONSE 0x1
|
|
||||||
#define BMKT_XPORT_INT_FINGER 0x2
|
|
||||||
#define BMKT_XPORT_INT_ASYNC 0x4
|
|
||||||
|
|
||||||
#define USB_DEFAULT_CONFIGURATION 0
|
|
||||||
#define USB_DEFAULT_INTERFACE 0
|
|
||||||
#define USB_DEFAULT_ALT_SETTING 0
|
|
||||||
|
|
||||||
#define USB_EP_REQUEST 0x01
|
|
||||||
#define USB_EP_REPLY 0x81
|
|
||||||
#define USB_EP_FINGERPRINT 0x82
|
|
||||||
#define USB_EP_INTERRUPT 0x83
|
|
||||||
|
|
||||||
#define USB_INTERRUPT_DATA_SIZE 7
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct bmkt_usb_transport
|
|
||||||
{
|
|
||||||
libusb_context *ctx;
|
|
||||||
libusb_device *device;
|
|
||||||
libusb_device_handle *handle;
|
|
||||||
uint8_t interrupt_data[USB_INTERRUPT_DATA_SIZE];
|
|
||||||
bmkt_sensor_t *sensor;
|
|
||||||
uint8_t transfer[BMKT_MAX_TRANSFER_LEN];
|
|
||||||
} bmkt_usb_transport_t;
|
|
||||||
|
|
||||||
|
|
||||||
int usb_release_command_buffer(bmkt_usb_transport_t *xport);
|
|
||||||
int usb_release_response_buffer(bmkt_usb_transport_t *xport);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int usb_open(bmkt_usb_transport_t *xport);
|
|
||||||
int usb_close(bmkt_usb_transport_t *xport);
|
|
||||||
int usb_send_command(bmkt_usb_transport_t *xport, int len);
|
|
||||||
int usb_get_command_buffer(bmkt_usb_transport_t *xport, uint8_t **cmd, int *len);
|
|
||||||
int usb_get_response_buffer(bmkt_usb_transport_t *xport, uint8_t **resp, int *len);
|
|
||||||
int usb_receive_resp(bmkt_usb_transport_t *xport, int *len);
|
|
||||||
|
|
||||||
int usb_send_command_sync(bmkt_usb_transport_t *xport, int len, uint8_t **resp_buf,
|
|
||||||
int *resp_len);
|
|
||||||
int usb_receive_resp_async(bmkt_usb_transport_t *usb_xport, int *len);
|
|
||||||
int usb_check_interrupt(bmkt_usb_transport_t *usb_xport);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _USB_TRANSPORT_H_ */
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 "bmkt_internal.h"
|
|
||||||
#include "sensor.h"
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wformat-zero-length"
|
|
||||||
void print_buffer(uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("0x%02x ", buf[i]);
|
|
||||||
if ((i % 16) == 15)
|
|
||||||
{
|
|
||||||
bmkt_dbg_log("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bmkt_dbg_log("");
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
uint32_t extract32(const uint8_t *buf, int *offset)
|
|
||||||
{
|
|
||||||
uint32_t ret = 0;
|
|
||||||
int off = 0;
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
off = *offset;
|
|
||||||
}
|
|
||||||
ret = GUINT32_FROM_LE(*(uint32_t*)(buf + off));
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
*offset += 4;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t extract16(const uint8_t *buf, int *offset)
|
|
||||||
{
|
|
||||||
uint16_t ret = 0;
|
|
||||||
int off = 0;
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
off = *offset;
|
|
||||||
}
|
|
||||||
ret = GUINT16_FROM_LE(*(uint16_t*)(buf + off));
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
*offset += 2;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t extract8(const uint8_t *buf, int *offset)
|
|
||||||
{
|
|
||||||
uint8_t ret = 0;
|
|
||||||
int off = 0;
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
off = *offset;
|
|
||||||
}
|
|
||||||
ret = *(buf + off);
|
|
||||||
if (offset)
|
|
||||||
{
|
|
||||||
*offset += 1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* LGPL CRC code copied from GStreamer-0.10.10:
|
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
||||||
* Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
|
|
||||||
|
|
||||||
* 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; version
|
|
||||||
* 2.1 of the License.
|
|
||||||
*
|
|
||||||
* 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 "upek_proto.h"
|
|
||||||
|
|
||||||
static const uint16_t crc_table[256] = {
|
|
||||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
|
||||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
|
||||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
|
||||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
|
||||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
|
||||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
|
||||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
|
||||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
|
||||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
|
||||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
|
||||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
|
||||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
|
||||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
|
||||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
|
||||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
|
||||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
|
||||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
|
||||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
|
||||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
|
||||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
|
||||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
|
||||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
|
||||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
|
||||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
|
||||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
|
||||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
|
||||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
|
||||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
|
||||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
|
||||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
|
||||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
|
||||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
udf_crc(unsigned char *buffer, size_t size)
|
|
||||||
{
|
|
||||||
uint16_t crc = 0;
|
|
||||||
while (size--)
|
|
||||||
crc = (uint16_t) ((crc << 8) ^
|
|
||||||
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* LGPL CRC code copied from GStreamer-0.10.10:
|
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
||||||
* Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
|
|
||||||
|
|
||||||
* 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; version
|
|
||||||
* 2.1 of the License.
|
|
||||||
*
|
|
||||||
* 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 <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
uint16_t udf_crc(unsigned char *buffer, size_t size);
|
|
||||||
@@ -81,7 +81,7 @@ struct sonly_dev {
|
|||||||
int dev_model;
|
int dev_model;
|
||||||
int img_width;
|
int img_width;
|
||||||
|
|
||||||
fpi_ssm *loopsm;
|
struct fpi_ssm *loopsm;
|
||||||
struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS];
|
struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS];
|
||||||
struct img_transfer_data *img_transfer_data;
|
struct img_transfer_data *img_transfer_data;
|
||||||
int num_flying;
|
int num_flying;
|
||||||
@@ -100,21 +100,18 @@ struct sonly_dev {
|
|||||||
enum sonly_kill_transfers_action killing_transfers;
|
enum sonly_kill_transfers_action killing_transfers;
|
||||||
int kill_status_code;
|
int kill_status_code;
|
||||||
union {
|
union {
|
||||||
fpi_ssm *kill_ssm;
|
struct fpi_ssm *kill_ssm;
|
||||||
void (*kill_cb)(struct fp_img_dev *dev);
|
void (*kill_cb)(struct fp_img_dev *dev);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Calculate squared standard deviation of sum of two lines */
|
/* Calculade squared standand deviation of sum of two lines */
|
||||||
static int upeksonly_get_deviation2(struct fpi_line_asmbl_ctx *ctx,
|
static int upeksonly_get_deviation2(struct fpi_line_asmbl_ctx *ctx,
|
||||||
GSList *line1, GSList *line2)
|
GSList *line1, GSList *line2)
|
||||||
{
|
{
|
||||||
unsigned char *buf1 = line1->data, *buf2 = line2->data;
|
unsigned char *buf1 = line1->data, *buf2 = line2->data;
|
||||||
int res = 0, mean = 0, i;
|
int res = 0, mean = 0, i;
|
||||||
|
|
||||||
g_assert (ctx->line_width > 0);
|
|
||||||
|
|
||||||
for (i = 0; i < ctx->line_width; i+= 2)
|
for (i = 0; i < ctx->line_width; i+= 2)
|
||||||
mean += (int)buf1[i + 1] + (int)buf2[i];
|
mean += (int)buf1[i + 1] + (int)buf2[i];
|
||||||
|
|
||||||
@@ -179,11 +176,11 @@ static void free_img_transfers(struct sonly_dev *sdev)
|
|||||||
|
|
||||||
static void last_transfer_killed(struct fp_img_dev *dev)
|
static void last_transfer_killed(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
switch (sdev->killing_transfers) {
|
switch (sdev->killing_transfers) {
|
||||||
case ABORT_SSM:
|
case ABORT_SSM:
|
||||||
fp_dbg("abort ssm error %d", sdev->kill_status_code);
|
fp_dbg("abort ssm error %d", sdev->kill_status_code);
|
||||||
fpi_ssm_mark_failed(sdev->kill_ssm, sdev->kill_status_code);
|
fpi_ssm_mark_aborted(sdev->kill_ssm, sdev->kill_status_code);
|
||||||
return;
|
return;
|
||||||
case ITERATE_SSM:
|
case ITERATE_SSM:
|
||||||
fp_dbg("iterate ssm");
|
fp_dbg("iterate ssm");
|
||||||
@@ -200,7 +197,7 @@ static void last_transfer_killed(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void cancel_img_transfers(struct fp_img_dev *dev)
|
static void cancel_img_transfers(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (sdev->num_flying == 0) {
|
if (sdev->num_flying == 0) {
|
||||||
@@ -227,7 +224,7 @@ static gboolean is_capturing(struct sonly_dev *sdev)
|
|||||||
|
|
||||||
static void handoff_img(struct fp_img_dev *dev)
|
static void handoff_img(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
GSList *elem = sdev->rows;
|
GSList *elem = sdev->rows;
|
||||||
@@ -255,7 +252,7 @@ static void handoff_img(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void row_complete(struct fp_img_dev *dev)
|
static void row_complete(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
sdev->rowbuf_offset = -1;
|
sdev->rowbuf_offset = -1;
|
||||||
|
|
||||||
if (sdev->num_rows > 0) {
|
if (sdev->num_rows > 0) {
|
||||||
@@ -343,7 +340,7 @@ static void row_complete(struct fp_img_dev *dev)
|
|||||||
/* add data to row buffer */
|
/* add data to row buffer */
|
||||||
static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size)
|
static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
memcpy(sdev->rowbuf + sdev->rowbuf_offset, data, size);
|
memcpy(sdev->rowbuf + sdev->rowbuf_offset, data, size);
|
||||||
sdev->rowbuf_offset += size;
|
sdev->rowbuf_offset += size;
|
||||||
@@ -377,7 +374,7 @@ static int rowbuf_remaining(struct sonly_dev *sdev)
|
|||||||
|
|
||||||
static void handle_packet(struct fp_img_dev *dev, unsigned char *data)
|
static void handle_packet(struct fp_img_dev *dev, unsigned char *data)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
uint16_t seqnum = data[0] << 8 | data[1];
|
uint16_t seqnum = data[0] << 8 | data[1];
|
||||||
int abs_base_addr;
|
int abs_base_addr;
|
||||||
int for_rowbuf;
|
int for_rowbuf;
|
||||||
@@ -473,7 +470,7 @@ static void img_data_cb(struct libusb_transfer *transfer)
|
|||||||
{
|
{
|
||||||
struct img_transfer_data *idata = transfer->user_data;
|
struct img_transfer_data *idata = transfer->user_data;
|
||||||
struct fp_img_dev *dev = idata->dev;
|
struct fp_img_dev *dev = idata->dev;
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
idata->flying = FALSE;
|
idata->flying = FALSE;
|
||||||
@@ -523,7 +520,7 @@ static void img_data_cb(struct libusb_transfer *transfer)
|
|||||||
/***** STATE MACHINE HELPERS *****/
|
/***** STATE MACHINE HELPERS *****/
|
||||||
|
|
||||||
struct write_regs_data {
|
struct write_regs_data {
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
const struct sonly_regwrite *regs;
|
const struct sonly_regwrite *regs;
|
||||||
size_t num_regs;
|
size_t num_regs;
|
||||||
@@ -537,7 +534,7 @@ static void write_regs_finished(struct write_regs_data *wrdata, int result)
|
|||||||
if (result == 0)
|
if (result == 0)
|
||||||
fpi_ssm_next_state(wrdata->ssm);
|
fpi_ssm_next_state(wrdata->ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(wrdata->ssm, result);
|
fpi_ssm_mark_aborted(wrdata->ssm, result);
|
||||||
g_free(wrdata);
|
g_free(wrdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,18 +574,23 @@ static void write_regs_cb(struct libusb_transfer *transfer)
|
|||||||
write_regs_iterate(wrdata);
|
write_regs_iterate(wrdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_write_regs(struct fpi_ssm *ssm,
|
||||||
sm_write_regs(fpi_ssm *ssm,
|
const struct sonly_regwrite *regs, size_t num_regs)
|
||||||
struct fp_dev *dev,
|
|
||||||
const struct sonly_regwrite *regs,
|
|
||||||
size_t num_regs)
|
|
||||||
{
|
{
|
||||||
struct write_regs_data *wrdata = g_malloc(sizeof(*wrdata));
|
struct write_regs_data *wrdata = g_malloc(sizeof(*wrdata));
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
struct fp_dev *dev;
|
||||||
|
|
||||||
|
wrdata->transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!wrdata->transfer) {
|
||||||
|
g_free(wrdata);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wrdata->transfer = fpi_usb_alloc();
|
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
||||||
libusb_fill_control_setup(data, 0x40, 0x0c, 0, 0, 1);
|
libusb_fill_control_setup(data, 0x40, 0x0c, 0, 0, 1);
|
||||||
|
dev = fpi_ssm_get_dev(ssm);
|
||||||
libusb_fill_control_transfer(wrdata->transfer,
|
libusb_fill_control_transfer(wrdata->transfer,
|
||||||
fpi_dev_get_usb_dev(dev), data,
|
fpi_dev_get_usb_dev(dev), data,
|
||||||
write_regs_cb, wrdata, CTRL_TIMEOUT);
|
write_regs_cb, wrdata, CTRL_TIMEOUT);
|
||||||
@@ -603,29 +605,31 @@ sm_write_regs(fpi_ssm *ssm,
|
|||||||
|
|
||||||
static void sm_write_reg_cb(struct libusb_transfer *transfer)
|
static void sm_write_reg_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_write_reg(struct fpi_ssm *ssm, uint8_t reg, uint8_t value)
|
||||||
sm_write_reg(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint8_t reg,
|
|
||||||
uint8_t value)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("set %02x=%02x", reg, value);
|
fp_dbg("set %02x=%02x", reg, value);
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
||||||
libusb_fill_control_setup(data, 0x40, 0x0c, 0, reg, 1);
|
libusb_fill_control_setup(data, 0x40, 0x0c, 0, reg, 1);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)),
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev),
|
||||||
data, sm_write_reg_cb,
|
data, sm_write_reg_cb,
|
||||||
ssm, CTRL_TIMEOUT);
|
ssm, CTRL_TIMEOUT);
|
||||||
|
|
||||||
@@ -637,18 +641,18 @@ sm_write_reg(fpi_ssm *ssm,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm_read_reg_cb(struct libusb_transfer *transfer)
|
static void sm_read_reg_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
} else {
|
} else {
|
||||||
sdev->read_reg_result = libusb_control_transfer_get_data(transfer)[0];
|
sdev->read_reg_result = libusb_control_transfer_get_data(transfer)[0];
|
||||||
fp_dbg("read reg result = %02x", sdev->read_reg_result);
|
fp_dbg("read reg result = %02x", sdev->read_reg_result);
|
||||||
@@ -658,19 +662,22 @@ static void sm_read_reg_cb(struct libusb_transfer *transfer)
|
|||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_read_reg(struct fpi_ssm *ssm, uint8_t reg)
|
||||||
sm_read_reg(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint8_t reg)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("read reg %02x", reg);
|
fp_dbg("read reg %02x", reg);
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 8);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 8);
|
||||||
libusb_fill_control_setup(data, 0xc0, 0x0c, 0, reg, 8);
|
libusb_fill_control_setup(data, 0xc0, 0x0c, 0, reg, 8);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)),
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev),
|
||||||
data, sm_read_reg_cb,
|
data, sm_read_reg_cb,
|
||||||
ssm, CTRL_TIMEOUT);
|
ssm, CTRL_TIMEOUT);
|
||||||
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
|
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
|
||||||
@@ -680,19 +687,19 @@ sm_read_reg(fpi_ssm *ssm,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm_await_intr_cb(struct libusb_transfer *transfer)
|
static void sm_await_intr_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
fpi_ssm_mark_failed(ssm, transfer->status);
|
fpi_ssm_mark_aborted(ssm, transfer->status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,17 +713,21 @@ static void sm_await_intr_cb(struct libusb_transfer *transfer)
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_await_intr(struct fpi_ssm *ssm)
|
||||||
sm_await_intr(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
data = g_malloc(4);
|
data = g_malloc(4);
|
||||||
libusb_fill_interrupt_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)),
|
libusb_fill_interrupt_transfer(transfer, fpi_imgdev_get_usb_dev(dev),
|
||||||
0x83, data, 4,
|
0x83, data, 4,
|
||||||
sm_await_intr_cb, ssm, 0);
|
sm_await_intr_cb, ssm, 0);
|
||||||
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
|
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
|
||||||
@@ -726,7 +737,7 @@ sm_await_intr(fpi_ssm *ssm,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,61 +763,61 @@ enum awfsm_1000_states {
|
|||||||
AWFSM_1000_NUM_STATES,
|
AWFSM_1000_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void awfsm_2016_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void awfsm_2016_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case AWFSM_2016_WRITEV_1:
|
case AWFSM_2016_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, awfsm_2016_writev_1, G_N_ELEMENTS(awfsm_2016_writev_1));
|
sm_write_regs(ssm, awfsm_2016_writev_1, G_N_ELEMENTS(awfsm_2016_writev_1));
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_READ_01:
|
case AWFSM_2016_READ_01:
|
||||||
sm_read_reg(ssm, dev, 0x01);
|
sm_read_reg(ssm, 0x01);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITE_01:
|
case AWFSM_2016_WRITE_01:
|
||||||
if (sdev->read_reg_result != 0xc6)
|
if (sdev->read_reg_result != 0xc6)
|
||||||
sm_write_reg(ssm, dev, 0x01, 0x46);
|
sm_write_reg(ssm, 0x01, 0x46);
|
||||||
else
|
else
|
||||||
sm_write_reg(ssm, dev, 0x01, 0xc6);
|
sm_write_reg(ssm, 0x01, 0xc6);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITEV_2:
|
case AWFSM_2016_WRITEV_2:
|
||||||
sm_write_regs(ssm, _dev, awfsm_2016_writev_2, G_N_ELEMENTS(awfsm_2016_writev_2));
|
sm_write_regs(ssm, awfsm_2016_writev_2, G_N_ELEMENTS(awfsm_2016_writev_2));
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_READ_13:
|
case AWFSM_2016_READ_13:
|
||||||
sm_read_reg(ssm, dev, 0x13);
|
sm_read_reg(ssm, 0x13);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITE_13:
|
case AWFSM_2016_WRITE_13:
|
||||||
if (sdev->read_reg_result != 0x45)
|
if (sdev->read_reg_result != 0x45)
|
||||||
sm_write_reg(ssm, dev, 0x13, 0x05);
|
sm_write_reg(ssm, 0x13, 0x05);
|
||||||
else
|
else
|
||||||
sm_write_reg(ssm, dev, 0x13, 0x45);
|
sm_write_reg(ssm, 0x13, 0x45);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITEV_3:
|
case AWFSM_2016_WRITEV_3:
|
||||||
sm_write_regs(ssm, _dev, awfsm_2016_writev_3, G_N_ELEMENTS(awfsm_2016_writev_3));
|
sm_write_regs(ssm, awfsm_2016_writev_3, G_N_ELEMENTS(awfsm_2016_writev_3));
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_READ_07:
|
case AWFSM_2016_READ_07:
|
||||||
sm_read_reg(ssm, dev, 0x07);
|
sm_read_reg(ssm, 0x07);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITE_07:
|
case AWFSM_2016_WRITE_07:
|
||||||
if (sdev->read_reg_result != 0x10 && sdev->read_reg_result != 0x90)
|
if (sdev->read_reg_result != 0x10 && sdev->read_reg_result != 0x90)
|
||||||
fp_warn("odd reg7 value %x", sdev->read_reg_result);
|
fp_warn("odd reg7 value %x", sdev->read_reg_result);
|
||||||
sm_write_reg(ssm, dev, 0x07, sdev->read_reg_result);
|
sm_write_reg(ssm, 0x07, sdev->read_reg_result);
|
||||||
break;
|
break;
|
||||||
case AWFSM_2016_WRITEV_4:
|
case AWFSM_2016_WRITEV_4:
|
||||||
sm_write_regs(ssm, _dev, awfsm_2016_writev_4, G_N_ELEMENTS(awfsm_2016_writev_4));
|
sm_write_regs(ssm, awfsm_2016_writev_4, G_N_ELEMENTS(awfsm_2016_writev_4));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void awfsm_1000_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void awfsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case AWFSM_1000_WRITEV_1:
|
case AWFSM_1000_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, awfsm_1000_writev_1, G_N_ELEMENTS(awfsm_1000_writev_1));
|
sm_write_regs(ssm, awfsm_1000_writev_1, G_N_ELEMENTS(awfsm_1000_writev_1));
|
||||||
break;
|
break;
|
||||||
case AWFSM_1000_WRITEV_2:
|
case AWFSM_1000_WRITEV_2:
|
||||||
sm_write_regs(ssm, _dev, awfsm_1000_writev_2, G_N_ELEMENTS(awfsm_1000_writev_2));
|
sm_write_regs(ssm, awfsm_1000_writev_2, G_N_ELEMENTS(awfsm_1000_writev_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -840,19 +851,17 @@ enum capsm_1001_states {
|
|||||||
CAPSM_1001_NUM_STATES,
|
CAPSM_1001_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void capsm_fire_bulk(struct fpi_ssm *ssm)
|
||||||
capsm_fire_bulk(fpi_ssm *ssm,
|
|
||||||
struct fp_dev *_dev)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
||||||
int r = libusb_submit_transfer(sdev->img_transfer[i]);
|
int r = libusb_submit_transfer(sdev->img_transfer[i]);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
/* first one failed: easy peasy */
|
/* first one failed: easy peasy */
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,10 +881,10 @@ capsm_fire_bulk(fpi_ssm *ssm,
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capsm_2016_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capsm_2016_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPSM_2016_INIT:
|
case CAPSM_2016_INIT:
|
||||||
@@ -890,23 +899,24 @@ static void capsm_2016_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_2016_WRITE_15:
|
case CAPSM_2016_WRITE_15:
|
||||||
sm_write_reg(ssm, dev, 0x15, 0x20);
|
sm_write_reg(ssm, 0x15, 0x20);
|
||||||
break;
|
break;
|
||||||
case CAPSM_2016_WRITE_30:
|
case CAPSM_2016_WRITE_30:
|
||||||
sm_write_reg(ssm, dev, 0x30, 0xe0);
|
sm_write_reg(ssm, 0x30, 0xe0);
|
||||||
break;
|
break;
|
||||||
case CAPSM_2016_FIRE_BULK: ;
|
case CAPSM_2016_FIRE_BULK: ;
|
||||||
capsm_fire_bulk (ssm, _dev);
|
capsm_fire_bulk (ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_2016_WRITEV:
|
case CAPSM_2016_WRITEV:
|
||||||
sm_write_regs(ssm, _dev, capsm_2016_writev, G_N_ELEMENTS(capsm_2016_writev));
|
sm_write_regs(ssm, capsm_2016_writev, G_N_ELEMENTS(capsm_2016_writev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capsm_1000_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPSM_1000_INIT:
|
case CAPSM_1000_INIT:
|
||||||
@@ -921,17 +931,18 @@ static void capsm_1000_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_1000_FIRE_BULK: ;
|
case CAPSM_1000_FIRE_BULK: ;
|
||||||
capsm_fire_bulk (ssm, _dev);
|
capsm_fire_bulk (ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_1000_WRITEV:
|
case CAPSM_1000_WRITEV:
|
||||||
sm_write_regs(ssm, _dev, capsm_1000_writev, G_N_ELEMENTS(capsm_1000_writev));
|
sm_write_regs(ssm, capsm_1000_writev, G_N_ELEMENTS(capsm_1000_writev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capsm_1001_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capsm_1001_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPSM_1001_INIT:
|
case CAPSM_1001_INIT:
|
||||||
@@ -946,22 +957,22 @@ static void capsm_1001_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_FIRE_BULK: ;
|
case CAPSM_1001_FIRE_BULK: ;
|
||||||
capsm_fire_bulk (ssm, _dev);
|
capsm_fire_bulk (ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_WRITEV_1:
|
case CAPSM_1001_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, capsm_1001_writev_1, G_N_ELEMENTS(capsm_1001_writev_1));
|
sm_write_regs(ssm, capsm_1001_writev_1, G_N_ELEMENTS(capsm_1001_writev_1));
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_WRITEV_2:
|
case CAPSM_1001_WRITEV_2:
|
||||||
sm_write_regs(ssm, _dev, capsm_1001_writev_2, G_N_ELEMENTS(capsm_1001_writev_2));
|
sm_write_regs(ssm, capsm_1001_writev_2, G_N_ELEMENTS(capsm_1001_writev_2));
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_WRITEV_3:
|
case CAPSM_1001_WRITEV_3:
|
||||||
sm_write_regs(ssm, _dev, capsm_1001_writev_3, G_N_ELEMENTS(capsm_1001_writev_3));
|
sm_write_regs(ssm, capsm_1001_writev_3, G_N_ELEMENTS(capsm_1001_writev_3));
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_WRITEV_4:
|
case CAPSM_1001_WRITEV_4:
|
||||||
sm_write_regs(ssm, _dev, capsm_1001_writev_4, G_N_ELEMENTS(capsm_1001_writev_4));
|
sm_write_regs(ssm, capsm_1001_writev_4, G_N_ELEMENTS(capsm_1001_writev_4));
|
||||||
break;
|
break;
|
||||||
case CAPSM_1001_WRITEV_5:
|
case CAPSM_1001_WRITEV_5:
|
||||||
sm_write_regs(ssm, _dev, capsm_1001_writev_5, G_N_ELEMENTS(capsm_1001_writev_5));
|
sm_write_regs(ssm, capsm_1001_writev_5, G_N_ELEMENTS(capsm_1001_writev_5));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -983,29 +994,29 @@ enum deinitsm_1001_states {
|
|||||||
DEINITSM_1001_NUM_STATES,
|
DEINITSM_1001_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void deinitsm_2016_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void deinitsm_2016_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case DEINITSM_2016_WRITEV:
|
case DEINITSM_2016_WRITEV:
|
||||||
sm_write_regs(ssm, _dev, deinitsm_2016_writev, G_N_ELEMENTS(deinitsm_2016_writev));
|
sm_write_regs(ssm, deinitsm_2016_writev, G_N_ELEMENTS(deinitsm_2016_writev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deinitsm_1000_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void deinitsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case DEINITSM_1000_WRITEV:
|
case DEINITSM_1000_WRITEV:
|
||||||
sm_write_regs(ssm, _dev, deinitsm_1000_writev, G_N_ELEMENTS(deinitsm_1000_writev));
|
sm_write_regs(ssm, deinitsm_1000_writev, G_N_ELEMENTS(deinitsm_1000_writev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deinitsm_1001_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void deinitsm_1001_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case DEINITSM_1001_WRITEV:
|
case DEINITSM_1001_WRITEV:
|
||||||
sm_write_regs(ssm, _dev, deinitsm_1001_writev, G_N_ELEMENTS(deinitsm_1001_writev));
|
sm_write_regs(ssm, deinitsm_1001_writev, G_N_ELEMENTS(deinitsm_1001_writev));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1037,62 +1048,62 @@ enum initsm_1001_states {
|
|||||||
INITSM_1001_NUM_STATES,
|
INITSM_1001_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void initsm_2016_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void initsm_2016_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case INITSM_2016_WRITEV_1:
|
case INITSM_2016_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, initsm_2016_writev_1, G_N_ELEMENTS(initsm_2016_writev_1));
|
sm_write_regs(ssm, initsm_2016_writev_1, G_N_ELEMENTS(initsm_2016_writev_1));
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_READ_09:
|
case INITSM_2016_READ_09:
|
||||||
sm_read_reg(ssm, dev, 0x09);
|
sm_read_reg(ssm, 0x09);
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_WRITE_09:
|
case INITSM_2016_WRITE_09:
|
||||||
sm_write_reg(ssm, dev, 0x09, sdev->read_reg_result & ~0x08);
|
sm_write_reg(ssm, 0x09, sdev->read_reg_result & ~0x08);
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_READ_13:
|
case INITSM_2016_READ_13:
|
||||||
sm_read_reg(ssm, dev, 0x13);
|
sm_read_reg(ssm, 0x13);
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_WRITE_13:
|
case INITSM_2016_WRITE_13:
|
||||||
sm_write_reg(ssm, dev, 0x13, sdev->read_reg_result & ~0x10);
|
sm_write_reg(ssm, 0x13, sdev->read_reg_result & ~0x10);
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_WRITE_04:
|
case INITSM_2016_WRITE_04:
|
||||||
sm_write_reg(ssm, dev, 0x04, 0x00);
|
sm_write_reg(ssm, 0x04, 0x00);
|
||||||
break;
|
break;
|
||||||
case INITSM_2016_WRITE_05:
|
case INITSM_2016_WRITE_05:
|
||||||
sm_write_reg(ssm, dev, 0x05, 0x00);
|
sm_write_reg(ssm, 0x05, 0x00);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initsm_1000_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void initsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case INITSM_1000_WRITEV_1:
|
case INITSM_1000_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1));
|
sm_write_regs(ssm, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initsm_1001_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void initsm_1001_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case INITSM_1001_WRITEV_1:
|
case INITSM_1001_WRITEV_1:
|
||||||
sm_write_regs(ssm, _dev, initsm_1001_writev_1, G_N_ELEMENTS(initsm_1001_writev_1));
|
sm_write_regs(ssm, initsm_1001_writev_1, G_N_ELEMENTS(initsm_1001_writev_1));
|
||||||
break;
|
break;
|
||||||
case INITSM_1001_WRITEV_2:
|
case INITSM_1001_WRITEV_2:
|
||||||
sm_write_regs(ssm, _dev, initsm_1001_writev_2, G_N_ELEMENTS(initsm_1001_writev_2));
|
sm_write_regs(ssm, initsm_1001_writev_2, G_N_ELEMENTS(initsm_1001_writev_2));
|
||||||
break;
|
break;
|
||||||
case INITSM_1001_WRITEV_3:
|
case INITSM_1001_WRITEV_3:
|
||||||
sm_write_regs(ssm, _dev, initsm_1001_writev_3, G_N_ELEMENTS(initsm_1001_writev_3));
|
sm_write_regs(ssm, initsm_1001_writev_3, G_N_ELEMENTS(initsm_1001_writev_3));
|
||||||
break;
|
break;
|
||||||
case INITSM_1001_WRITEV_4:
|
case INITSM_1001_WRITEV_4:
|
||||||
sm_write_regs(ssm, _dev, initsm_1001_writev_4, G_N_ELEMENTS(initsm_1001_writev_4));
|
sm_write_regs(ssm, initsm_1001_writev_4, G_N_ELEMENTS(initsm_1001_writev_4));
|
||||||
break;
|
break;
|
||||||
case INITSM_1001_WRITEV_5:
|
case INITSM_1001_WRITEV_5:
|
||||||
sm_write_regs(ssm, _dev, initsm_1001_writev_5, G_N_ELEMENTS(initsm_1001_writev_5));
|
sm_write_regs(ssm, initsm_1001_writev_5, G_N_ELEMENTS(initsm_1001_writev_5));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1109,10 +1120,10 @@ enum loopsm_states {
|
|||||||
LOOPSM_NUM_STATES,
|
LOOPSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void loopsm_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void loopsm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case LOOPSM_RUN_AWFSM: ;
|
case LOOPSM_RUN_AWFSM: ;
|
||||||
@@ -1128,17 +1139,18 @@ static void loopsm_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
if (sdev->deactivating) {
|
if (sdev->deactivating) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm *awfsm = NULL;
|
struct fpi_ssm *awfsm = NULL;
|
||||||
switch (sdev->dev_model) {
|
switch (sdev->dev_model) {
|
||||||
case UPEKSONLY_2016:
|
case UPEKSONLY_2016:
|
||||||
awfsm = fpi_ssm_new(FP_DEV(dev), awfsm_2016_run_state,
|
awfsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), awfsm_2016_run_state,
|
||||||
AWFSM_2016_NUM_STATES, dev);
|
AWFSM_2016_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1000:
|
case UPEKSONLY_1000:
|
||||||
awfsm = fpi_ssm_new(FP_DEV(dev), awfsm_1000_run_state,
|
awfsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), awfsm_1000_run_state,
|
||||||
AWFSM_1000_NUM_STATES, dev);
|
AWFSM_1000_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fpi_ssm_set_user_data(awfsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, awfsm);
|
fpi_ssm_start_subsm(ssm, awfsm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1150,47 +1162,49 @@ static void loopsm_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sm_await_intr(ssm, dev);
|
sm_await_intr(ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOOPSM_RUN_CAPSM: ;
|
case LOOPSM_RUN_CAPSM: ;
|
||||||
fpi_ssm *capsm = NULL;
|
struct fpi_ssm *capsm = NULL;
|
||||||
switch (sdev->dev_model) {
|
switch (sdev->dev_model) {
|
||||||
case UPEKSONLY_2016:
|
case UPEKSONLY_2016:
|
||||||
capsm = fpi_ssm_new(FP_DEV(dev), capsm_2016_run_state,
|
capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_2016_run_state,
|
||||||
CAPSM_2016_NUM_STATES, dev);
|
CAPSM_2016_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1000:
|
case UPEKSONLY_1000:
|
||||||
capsm = fpi_ssm_new(FP_DEV(dev), capsm_1000_run_state,
|
capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_1000_run_state,
|
||||||
CAPSM_1000_NUM_STATES, dev);
|
CAPSM_1000_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1001:
|
case UPEKSONLY_1001:
|
||||||
capsm = fpi_ssm_new(FP_DEV(dev), capsm_1001_run_state,
|
capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_1001_run_state,
|
||||||
CAPSM_1001_NUM_STATES, dev);
|
CAPSM_1001_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fpi_ssm_set_user_data(capsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, capsm);
|
fpi_ssm_start_subsm(ssm, capsm);
|
||||||
break;
|
break;
|
||||||
case LOOPSM_CAPTURE:
|
case LOOPSM_CAPTURE:
|
||||||
break;
|
break;
|
||||||
case LOOPSM_RUN_DEINITSM: ;
|
case LOOPSM_RUN_DEINITSM: ;
|
||||||
fpi_ssm *deinitsm = NULL;
|
struct fpi_ssm *deinitsm = NULL;
|
||||||
switch (sdev->dev_model) {
|
switch (sdev->dev_model) {
|
||||||
case UPEKSONLY_2016:
|
case UPEKSONLY_2016:
|
||||||
deinitsm = fpi_ssm_new(FP_DEV(dev), deinitsm_2016_run_state,
|
deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_2016_run_state,
|
||||||
DEINITSM_2016_NUM_STATES, dev);
|
DEINITSM_2016_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1000:
|
case UPEKSONLY_1000:
|
||||||
deinitsm = fpi_ssm_new(FP_DEV(dev), deinitsm_1000_run_state,
|
deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_1000_run_state,
|
||||||
DEINITSM_1000_NUM_STATES, dev);
|
DEINITSM_1000_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1001:
|
case UPEKSONLY_1001:
|
||||||
deinitsm = fpi_ssm_new(FP_DEV(dev), deinitsm_1001_run_state,
|
deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_1001_run_state,
|
||||||
DEINITSM_1001_NUM_STATES, dev);
|
DEINITSM_1001_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sdev->capturing = FALSE;
|
sdev->capturing = FALSE;
|
||||||
|
fpi_ssm_set_user_data(deinitsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, deinitsm);
|
fpi_ssm_start_subsm(ssm, deinitsm);
|
||||||
break;
|
break;
|
||||||
case LOOPSM_FINAL:
|
case LOOPSM_FINAL:
|
||||||
@@ -1204,7 +1218,7 @@ static void loopsm_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
static void deactivate_done(struct fp_img_dev *dev)
|
static void deactivate_done(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
free_img_transfers(sdev);
|
free_img_transfers(sdev);
|
||||||
@@ -1221,7 +1235,7 @@ static void deactivate_done(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (!sdev->capturing) {
|
if (!sdev->capturing) {
|
||||||
deactivate_done(dev);
|
deactivate_done(dev);
|
||||||
@@ -1234,10 +1248,10 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
cancel_img_transfers(dev);
|
cancel_img_transfers(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void loopsm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -1253,10 +1267,10 @@ static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void initsm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(_dev);
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -1264,14 +1278,15 @@ static void initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sdev->loopsm = fpi_ssm_new(FP_DEV(dev), loopsm_run_state, LOOPSM_NUM_STATES, dev);
|
sdev->loopsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), loopsm_run_state, LOOPSM_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(sdev->loopsm, dev);
|
||||||
fpi_ssm_start(sdev->loopsm, loopsm_complete);
|
fpi_ssm_start(sdev->loopsm, loopsm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = NULL;
|
struct fpi_ssm *ssm = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sdev->deactivating = FALSE;
|
sdev->deactivating = FALSE;
|
||||||
@@ -1284,26 +1299,31 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
sdev->num_flying = 0;
|
sdev->num_flying = 0;
|
||||||
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
sdev->img_transfer[i] = fpi_usb_alloc();
|
sdev->img_transfer[i] = libusb_alloc_transfer(0);
|
||||||
|
if (!sdev->img_transfer[i]) {
|
||||||
|
free_img_transfers(sdev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
sdev->img_transfer_data[i].idx = i;
|
sdev->img_transfer_data[i].idx = i;
|
||||||
sdev->img_transfer_data[i].dev = dev;
|
sdev->img_transfer_data[i].dev = dev;
|
||||||
data = g_malloc(4096);
|
data = g_malloc(4096);
|
||||||
libusb_fill_bulk_transfer(sdev->img_transfer[i], fpi_dev_get_usb_dev(FP_DEV(dev)),
|
libusb_fill_bulk_transfer(sdev->img_transfer[i], fpi_imgdev_get_usb_dev(dev),
|
||||||
0x81, data,
|
0x81, data,
|
||||||
4096, img_data_cb, &sdev->img_transfer_data[i], 0);
|
4096, img_data_cb, &sdev->img_transfer_data[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sdev->dev_model) {
|
switch (sdev->dev_model) {
|
||||||
case UPEKSONLY_2016:
|
case UPEKSONLY_2016:
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), initsm_2016_run_state, INITSM_2016_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_2016_run_state, INITSM_2016_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1000:
|
case UPEKSONLY_1000:
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), initsm_1000_run_state, INITSM_1000_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_1000_run_state, INITSM_1000_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
case UPEKSONLY_1001:
|
case UPEKSONLY_1001:
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), initsm_1001_run_state, INITSM_1001_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_1001_run_state, INITSM_1001_NUM_STATES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, initsm_complete);
|
fpi_ssm_start(ssm, initsm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1313,9 +1333,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data);
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
void *user_data;
|
void *user_data;
|
||||||
user_data = FP_INSTANCE_DATA(FP_DEV(dev));
|
user_data = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(user_data);
|
g_free(user_data);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1367,20 +1387,20 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct sonly_dev *sdev;
|
struct sonly_dev *sdev;
|
||||||
|
|
||||||
r = libusb_set_configuration(fpi_dev_get_usb_dev(FP_DEV(dev)), 1);
|
r = libusb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not set configuration 1");
|
fp_err("could not set configuration 1");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdev = g_malloc0(sizeof(struct sonly_dev));
|
sdev = g_malloc0(sizeof(struct sonly_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), sdev);
|
fpi_imgdev_set_user_data(dev, sdev);
|
||||||
sdev->dev_model = (int)driver_data;
|
sdev->dev_model = (int)driver_data;
|
||||||
switch (driver_data) {
|
switch (driver_data) {
|
||||||
case UPEKSONLY_1000:
|
case UPEKSONLY_1000:
|
||||||
|
|||||||
@@ -56,11 +56,10 @@ enum activate_states {
|
|||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void upektc_next_init_cmd(struct fpi_ssm *ssm)
|
||||||
upektc_next_init_cmd(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
upekdev->init_idx += 1;
|
upekdev->init_idx += 1;
|
||||||
if (upekdev->init_idx == upekdev->setup_commands_len)
|
if (upekdev->init_idx == upekdev->setup_commands_len)
|
||||||
@@ -71,63 +70,70 @@ upektc_next_init_cmd(fpi_ssm *ssm,
|
|||||||
|
|
||||||
static void write_init_cb(struct libusb_transfer *transfer)
|
static void write_init_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
if (upekdev->setup_commands[upekdev->init_idx].response_len)
|
if (upekdev->setup_commands[upekdev->init_idx].response_len)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
else
|
else
|
||||||
upektc_next_init_cmd(ssm, dev);
|
upektc_next_init_cmd(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_init_data_cb(struct libusb_transfer *transfer)
|
static void read_init_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
upektc_next_init_cmd(ssm, dev);
|
upektc_next_init_cmd(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case WRITE_INIT:
|
case WRITE_INIT:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_out,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out,
|
||||||
(unsigned char*)upekdev->setup_commands[upekdev->init_idx].cmd,
|
(unsigned char*)upekdev->setup_commands[upekdev->init_idx].cmd,
|
||||||
UPEKTC_CMD_LEN, write_init_cb, ssm, BULK_TIMEOUT);
|
UPEKTC_CMD_LEN, write_init_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_DATA:
|
case READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(upekdev->setup_commands[upekdev->init_idx].response_len);
|
data = g_malloc(upekdev->setup_commands[upekdev->init_idx].response_len);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_in, data,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data,
|
||||||
upekdev->setup_commands[upekdev->init_idx].response_len,
|
upekdev->setup_commands[upekdev->init_idx].response_len,
|
||||||
read_init_data_cb, ssm, BULK_TIMEOUT);
|
read_init_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
@@ -135,16 +141,16 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
||||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||||
|
|
||||||
@@ -175,7 +181,7 @@ static int finger_present(unsigned char *img, size_t len, int sum_threshold)
|
|||||||
static void finger_det_data_cb(struct libusb_transfer *transfer)
|
static void finger_det_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = transfer->user_data;
|
struct fp_img_dev *dev = transfer->user_data;
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
@@ -208,7 +214,7 @@ static void finger_det_cmd_cb(struct libusb_transfer *t)
|
|||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
struct fp_img_dev *dev = t->user_data;
|
struct fp_img_dev *dev = t->user_data;
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (t->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (t->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fp_dbg("req transfer status %d\n", t->status);
|
fp_dbg("req transfer status %d\n", t->status);
|
||||||
@@ -220,9 +226,14 @@ static void finger_det_cmd_cb(struct libusb_transfer *t)
|
|||||||
goto exit_free_transfer;
|
goto exit_free_transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
goto exit_free_transfer;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(IMAGE_SIZE);
|
data = g_malloc(IMAGE_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_in, data, IMAGE_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data, IMAGE_SIZE,
|
||||||
finger_det_data_cb, dev, BULK_TIMEOUT);
|
finger_det_data_cb, dev, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -238,7 +249,7 @@ exit_free_transfer:
|
|||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
@@ -247,8 +258,12 @@ static void start_finger_detection(struct fp_img_dev *dev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_out,
|
if (!transfer) {
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out,
|
||||||
(unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
|
(unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
|
||||||
finger_det_cmd_cb, dev, BULK_TIMEOUT);
|
finger_det_cmd_cb, dev, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -268,31 +283,31 @@ enum capture_states {
|
|||||||
|
|
||||||
static void capture_cmd_cb(struct libusb_transfer *transfer)
|
static void capture_cmd_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fp_dbg("request is not completed, %d", transfer->status);
|
fp_dbg("request is not completed, %d", transfer->status);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
} else if (transfer->length != transfer->actual_length) {
|
} else if (transfer->length != transfer->actual_length) {
|
||||||
fp_dbg("expected %d, sent %d bytes", transfer->length, transfer->actual_length);
|
fp_dbg("expected %d, sent %d bytes", transfer->length, transfer->actual_length);
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,51 +321,59 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPTURE_WRITE_CMD:
|
case CAPTURE_WRITE_CMD:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_out,
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out,
|
||||||
(unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
|
(unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
|
||||||
capture_cmd_cb, ssm, BULK_TIMEOUT);
|
capture_cmd_cb, ssm, BULK_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(IMAGE_SIZE);
|
data = g_malloc(IMAGE_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), upekdev->ep_in, data, IMAGE_SIZE,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data, IMAGE_SIZE,
|
||||||
capture_read_data_cb, ssm, BULK_TIMEOUT);
|
capture_read_data_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg("Capture completed");
|
||||||
if (upekdev->deactivating)
|
if (upekdev->deactivating)
|
||||||
@@ -364,24 +387,26 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
if (upekdev->deactivating) {
|
if (upekdev->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
upekdev->init_idx = 0;
|
upekdev->init_idx = 0;
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -389,14 +414,14 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
upekdev->deactivating = TRUE;
|
upekdev->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
upekdev->deactivating = FALSE;
|
upekdev->deactivating = FALSE;
|
||||||
@@ -409,14 +434,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct upektc_dev *upekdev;
|
struct upektc_dev *upekdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
upekdev = g_malloc0(sizeof(struct upektc_dev));
|
upekdev = g_malloc0(sizeof(struct upektc_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), upekdev);
|
fpi_imgdev_set_user_data(dev, upekdev);
|
||||||
switch (driver_data) {
|
switch (driver_data) {
|
||||||
case UPEKTC_2015:
|
case UPEKTC_2015:
|
||||||
upekdev->ep_in = UPEKTC_EP_IN;
|
upekdev->ep_in = UPEKTC_EP_IN;
|
||||||
@@ -435,7 +460,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
default:
|
default:
|
||||||
fp_err("Device variant %lu is not known\n", driver_data);
|
fp_err("Device variant %lu is not known\n", driver_data);
|
||||||
g_free(upekdev);
|
g_free(upekdev);
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), NULL);
|
fpi_imgdev_set_user_data(dev, NULL);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -446,9 +471,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
void *user_data;
|
void *user_data;
|
||||||
user_data = FP_INSTANCE_DATA(FP_DEV(dev));
|
user_data = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(user_data);
|
g_free(user_data);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#define FP_COMPONENT "upektc_img"
|
#define FP_COMPONENT "upektc_img"
|
||||||
|
|
||||||
#include "drivers_api.h"
|
#include "drivers_api.h"
|
||||||
#include "upek_proto.h"
|
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
#include "upektc_img.h"
|
#include "upektc_img.h"
|
||||||
|
|
||||||
@@ -52,6 +51,50 @@ struct upektc_img_dev {
|
|||||||
|
|
||||||
/****** HELPERS ******/
|
/****** HELPERS ******/
|
||||||
|
|
||||||
|
static const uint16_t crc_table[256] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||||
|
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||||
|
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||||
|
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||||
|
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||||
|
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||||
|
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||||
|
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||||
|
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||||
|
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||||
|
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||||
|
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||||
|
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||||
|
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||||
|
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||||
|
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||||
|
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||||
|
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||||
|
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||||
|
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||||
|
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||||
|
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||||
|
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t udf_crc(unsigned char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
while (size--)
|
||||||
|
crc = (uint16_t) ((crc << 8) ^
|
||||||
|
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
static void upektc_img_cmd_fix_seq(unsigned char *cmd_buf, unsigned char seq)
|
static void upektc_img_cmd_fix_seq(unsigned char *cmd_buf, unsigned char seq)
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
@@ -71,58 +114,61 @@ static void upektc_img_cmd_update_crc(unsigned char *cmd_buf, size_t size)
|
|||||||
cmd_buf[size - 1] = (crc & 0xff00) >> 8;
|
cmd_buf[size - 1] = (crc & 0xff00) >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void upektc_img_submit_req(struct fpi_ssm *ssm,
|
||||||
upektc_img_submit_req(fpi_ssm *ssm,
|
const unsigned char *buf, size_t buf_size, unsigned char seq,
|
||||||
struct fp_img_dev *dev,
|
libusb_transfer_cb_fn cb)
|
||||||
const unsigned char *buf,
|
|
||||||
size_t buf_size,
|
|
||||||
unsigned char seq,
|
|
||||||
libusb_transfer_cb_fn cb)
|
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
BUG_ON(buf_size > MAX_CMD_SIZE);
|
BUG_ON(buf_size > MAX_CMD_SIZE);
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
|
|
||||||
memcpy(upekdev->cmd, buf, buf_size);
|
memcpy(upekdev->cmd, buf, buf_size);
|
||||||
upektc_img_cmd_fix_seq(upekdev->cmd, seq);
|
upektc_img_cmd_fix_seq(upekdev->cmd, seq);
|
||||||
upektc_img_cmd_update_crc(upekdev->cmd, buf_size);
|
upektc_img_cmd_update_crc(upekdev->cmd, buf_size);
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, upekdev->cmd, buf_size,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, upekdev->cmd, buf_size,
|
||||||
cb, ssm, BULK_TIMEOUT);
|
cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t buf_offset, libusb_transfer_cb_fn cb)
|
||||||
upektc_img_read_data(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
size_t buf_size,
|
|
||||||
size_t buf_offset,
|
|
||||||
libusb_transfer_cb_fn cb)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BUG_ON(buf_size > MAX_RESPONSE_SIZE);
|
BUG_ON(buf_size > MAX_RESPONSE_SIZE);
|
||||||
|
|
||||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, upekdev->response + buf_offset, buf_size,
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, upekdev->response + buf_offset, buf_size,
|
||||||
cb, ssm, BULK_TIMEOUT);
|
cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +187,11 @@ enum capture_states {
|
|||||||
|
|
||||||
static void capture_reqs_cb(struct libusb_transfer *transfer)
|
static void capture_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->length != transfer->actual_length)) {
|
(transfer->length != transfer->actual_length)) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
@@ -178,16 +224,16 @@ static int upektc_img_process_image_frame(unsigned char *image_buf, unsigned cha
|
|||||||
|
|
||||||
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = upekdev->response;
|
unsigned char *data = upekdev->response;
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
size_t response_size;
|
size_t response_size;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fp_dbg("request is not completed, %d", transfer->status);
|
fp_dbg("request is not completed, %d", transfer->status);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +334,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_err("Uknown response!\n");
|
fp_err("Uknown response!\n");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -297,51 +343,51 @@ static void capture_read_data_cb(struct libusb_transfer *transfer)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_err("Not handled response!\n");
|
fp_err("Not handled response!\n");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPTURE_INIT_CAPTURE:
|
case CAPTURE_INIT_CAPTURE:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_init_capture, sizeof(upek2020_init_capture),
|
upektc_img_submit_req(ssm, upek2020_init_capture, sizeof(upek2020_init_capture),
|
||||||
upekdev->seq, capture_reqs_cb);
|
upekdev->seq, capture_reqs_cb);
|
||||||
upekdev->seq++;
|
upekdev->seq++;
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
case CAPTURE_READ_DATA_TERM:
|
case CAPTURE_READ_DATA_TERM:
|
||||||
if (!upekdev->response_rest)
|
if (!upekdev->response_rest)
|
||||||
upektc_img_read_data(ssm, dev, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
|
upektc_img_read_data(ssm, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
|
||||||
else
|
else
|
||||||
upektc_img_read_data(ssm, dev, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
|
upektc_img_read_data(ssm, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
|
||||||
SHORT_RESPONSE_SIZE, capture_read_data_cb);
|
SHORT_RESPONSE_SIZE, capture_read_data_cb);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_ACK_00_28:
|
case CAPTURE_ACK_00_28:
|
||||||
case CAPTURE_ACK_00_28_TERM:
|
case CAPTURE_ACK_00_28_TERM:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_00_28, sizeof(upek2020_ack_00_28),
|
upektc_img_submit_req(ssm, upek2020_ack_00_28, sizeof(upek2020_ack_00_28),
|
||||||
upekdev->seq, capture_reqs_cb);
|
upekdev->seq, capture_reqs_cb);
|
||||||
upekdev->seq++;
|
upekdev->seq++;
|
||||||
break;
|
break;
|
||||||
case CAPTURE_ACK_08:
|
case CAPTURE_ACK_08:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_08, sizeof(upek2020_ack_08),
|
upektc_img_submit_req(ssm, upek2020_ack_08, sizeof(upek2020_ack_08),
|
||||||
0, capture_reqs_cb);
|
0, capture_reqs_cb);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_ACK_FRAME:
|
case CAPTURE_ACK_FRAME:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_frame, sizeof(upek2020_ack_frame),
|
upektc_img_submit_req(ssm, upek2020_ack_frame, sizeof(upek2020_ack_frame),
|
||||||
upekdev->seq, capture_reqs_cb);
|
upekdev->seq, capture_reqs_cb);
|
||||||
upekdev->seq++;
|
upekdev->seq++;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fp_dbg("Capture completed, %d", err);
|
fp_dbg("Capture completed, %d", err);
|
||||||
@@ -357,12 +403,13 @@ static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev)
|
static void start_capture(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
upekdev->image_size = 0;
|
upekdev->image_size = 0;
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,49 +423,49 @@ enum deactivate_states {
|
|||||||
|
|
||||||
static void deactivate_reqs_cb(struct libusb_transfer *transfer)
|
static void deactivate_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: process response properly */
|
/* TODO: process response properly */
|
||||||
static void deactivate_read_data_cb(struct libusb_transfer *transfer)
|
static void deactivate_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void deactivate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case DEACTIVATE_DEINIT:
|
case DEACTIVATE_DEINIT:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_deinit, sizeof(upek2020_deinit),
|
upektc_img_submit_req(ssm, upek2020_deinit, sizeof(upek2020_deinit),
|
||||||
upekdev->seq, deactivate_reqs_cb);
|
upekdev->seq, deactivate_reqs_cb);
|
||||||
upekdev->seq++;
|
upekdev->seq++;
|
||||||
break;
|
break;
|
||||||
case DEACTIVATE_READ_DEINIT_DATA:
|
case DEACTIVATE_READ_DEINIT_DATA:
|
||||||
upektc_img_read_data(ssm, dev, SHORT_RESPONSE_SIZE, 0, deactivate_read_data_cb);
|
upektc_img_read_data(ssm, SHORT_RESPONSE_SIZE, 0, deactivate_read_data_cb);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void deactivate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(_dev);
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fp_dbg("Deactivate completed");
|
fp_dbg("Deactivate completed");
|
||||||
@@ -435,12 +482,13 @@ static void deactivate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user
|
|||||||
|
|
||||||
static void start_deactivation(struct fp_img_dev *dev)
|
static void start_deactivation(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
upekdev->image_size = 0;
|
upekdev->image_size = 0;
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), deactivate_run_state, DEACTIVATE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deactivate_run_state, DEACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, deactivate_sm_complete);
|
fpi_ssm_start(ssm, deactivate_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,44 +510,45 @@ enum activate_states {
|
|||||||
|
|
||||||
static void init_reqs_ctrl_cb(struct libusb_transfer *transfer)
|
static void init_reqs_ctrl_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_reqs_cb(struct libusb_transfer *transfer)
|
static void init_reqs_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
||||||
(transfer->length == transfer->actual_length)) {
|
(transfer->length == transfer->actual_length)) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: process response properly */
|
/* TODO: process response properly */
|
||||||
static void init_read_data_cb(struct libusb_transfer *transfer)
|
static void init_read_data_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void activate_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
@@ -508,7 +557,11 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data
|
|||||||
{
|
{
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER |
|
transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER |
|
||||||
LIBUSB_TRANSFER_FREE_TRANSFER;
|
LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
|
|
||||||
@@ -521,24 +574,24 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_INIT_1:
|
case ACTIVATE_INIT_1:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_1, sizeof(upek2020_init_1),
|
upektc_img_submit_req(ssm, upek2020_init_1, sizeof(upek2020_init_1),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_INIT_2:
|
case ACTIVATE_INIT_2:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_2, sizeof(upek2020_init_2),
|
upektc_img_submit_req(ssm, upek2020_init_2, sizeof(upek2020_init_2),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_INIT_3:
|
case ACTIVATE_INIT_3:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_3, sizeof(upek2020_init_3),
|
upektc_img_submit_req(ssm, upek2020_init_3, sizeof(upek2020_init_3),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
case ACTIVATE_INIT_4:
|
case ACTIVATE_INIT_4:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_4, sizeof(upek2020_init_4),
|
upektc_img_submit_req(ssm, upek2020_init_4, sizeof(upek2020_init_4),
|
||||||
upekdev->seq, init_reqs_cb);
|
upekdev->seq, init_reqs_cb);
|
||||||
/* Seq should be updated after 4th init */
|
/* Seq should be updated after 4th init */
|
||||||
upekdev->seq++;
|
upekdev->seq++;
|
||||||
@@ -549,14 +602,14 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data
|
|||||||
case ACTIVATE_READ_INIT_2_RESP:
|
case ACTIVATE_READ_INIT_2_RESP:
|
||||||
case ACTIVATE_READ_INIT_3_RESP:
|
case ACTIVATE_READ_INIT_3_RESP:
|
||||||
case ACTIVATE_READ_INIT_4_RESP:
|
case ACTIVATE_READ_INIT_4_RESP:
|
||||||
upektc_img_read_data(ssm, idev, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
|
upektc_img_read_data(ssm, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int err = fpi_ssm_get_error(ssm);
|
int err = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -569,9 +622,10 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
upekdev->seq = 0;
|
upekdev->seq = 0;
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -579,7 +633,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
upekdev->deactivating = TRUE;
|
upekdev->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
@@ -590,23 +644,23 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
struct upektc_img_dev *upekdev;
|
struct upektc_img_dev *upekdev;
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
upekdev = g_malloc0(sizeof(struct upektc_img_dev));
|
upekdev = g_malloc0(sizeof(struct upektc_img_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), upekdev);
|
fpi_imgdev_set_user_data(dev, upekdev);
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(upekdev);
|
g_free(upekdev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,6 @@
|
|||||||
#define FP_COMPONENT "upekts"
|
#define FP_COMPONENT "upekts"
|
||||||
|
|
||||||
#include "drivers_api.h"
|
#include "drivers_api.h"
|
||||||
#include "fpi-async.h"
|
|
||||||
#include "upek_proto.h"
|
|
||||||
|
|
||||||
#define EP_IN (1 | LIBUSB_ENDPOINT_IN)
|
#define EP_IN (1 | LIBUSB_ENDPOINT_IN)
|
||||||
#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
|
#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
|
||||||
@@ -45,7 +43,49 @@ struct upekts_dev {
|
|||||||
uint8_t seq; /* FIXME: improve/automate seq handling */
|
uint8_t seq; /* FIXME: improve/automate seq handling */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint16_t crc_table[256] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||||
|
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||||
|
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||||
|
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||||
|
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||||
|
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||||
|
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||||
|
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||||
|
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||||
|
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||||
|
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||||
|
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||||
|
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||||
|
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||||
|
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||||
|
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||||
|
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||||
|
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||||
|
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||||
|
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||||
|
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||||
|
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||||
|
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t udf_crc(unsigned char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
while (size--)
|
||||||
|
crc = (uint16_t) ((crc << 8) ^
|
||||||
|
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MESSAGE FORMAT
|
* MESSAGE FORMAT
|
||||||
@@ -91,7 +131,7 @@ static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev,
|
|||||||
unsigned char seq_a, unsigned char seq_b, const unsigned char *data,
|
unsigned char seq_a, unsigned char seq_b, const unsigned char *data,
|
||||||
uint16_t len, libusb_transfer_cb_fn callback, void *user_data)
|
uint16_t len, libusb_transfer_cb_fn callback, void *user_data)
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
const char *ciao = "Ciao";
|
const char *ciao = "Ciao";
|
||||||
|
|
||||||
@@ -100,6 +140,9 @@ static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev,
|
|||||||
size_t urblen = len + 9;
|
size_t urblen = len + 9;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!data && len > 0) {
|
if (!data && len > 0) {
|
||||||
fp_err("len>0 but no data?");
|
fp_err("len>0 but no data?");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -135,7 +178,7 @@ static struct libusb_transfer *alloc_send_cmd28_transfer(struct fp_dev *dev,
|
|||||||
uint16_t _innerlen = innerlen;
|
uint16_t _innerlen = innerlen;
|
||||||
size_t len = innerlen + 6;
|
size_t len = innerlen + 6;
|
||||||
unsigned char *buf = g_malloc0(len);
|
unsigned char *buf = g_malloc0(len);
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT;
|
uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT;
|
||||||
struct libusb_transfer *ret;
|
struct libusb_transfer *ret;
|
||||||
|
|
||||||
@@ -365,9 +408,12 @@ static void read_msg_cb(struct libusb_transfer *transfer)
|
|||||||
* to read the remainder. This is handled below. */
|
* to read the remainder. This is handled below. */
|
||||||
if (len > MAX_DATA_IN_READ_BUF) {
|
if (len > MAX_DATA_IN_READ_BUF) {
|
||||||
int needed = len - MAX_DATA_IN_READ_BUF;
|
int needed = len - MAX_DATA_IN_READ_BUF;
|
||||||
struct libusb_transfer *etransfer = fpi_usb_alloc();
|
struct libusb_transfer *etransfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
goto err;
|
||||||
|
|
||||||
fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed);
|
fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed);
|
||||||
data = g_realloc((gpointer) data, MSG_READ_BUF_SIZE + needed);
|
data = g_realloc((gpointer) data, MSG_READ_BUF_SIZE + needed);
|
||||||
|
|
||||||
@@ -402,9 +448,14 @@ out:
|
|||||||
static int __read_msg_async(struct read_msg_data *udata)
|
static int __read_msg_async(struct read_msg_data *udata)
|
||||||
{
|
{
|
||||||
unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE);
|
unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE);
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
g_free(buf);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(udata->dev), EP_IN, buf,
|
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(udata->dev), EP_IN, buf,
|
||||||
MSG_READ_BUF_SIZE, read_msg_cb, udata, TIMEOUT);
|
MSG_READ_BUF_SIZE, read_msg_cb, udata, TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -474,28 +525,25 @@ enum initsm_states {
|
|||||||
INITSM_NUM_STATES,
|
INITSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void initsm_read_msg_response_cb(struct fpi_ssm *ssm,
|
||||||
initsm_read_msg_response_cb(fpi_ssm *ssm,
|
enum read_msg_status status, uint8_t seq,
|
||||||
struct fp_dev *dev,
|
unsigned char expect_subcmd, unsigned char subcmd)
|
||||||
enum read_msg_status status,
|
|
||||||
uint8_t seq,
|
|
||||||
unsigned char expect_subcmd,
|
|
||||||
unsigned char subcmd)
|
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (status != READ_MSG_RESPONSE) {
|
if (status != READ_MSG_RESPONSE) {
|
||||||
fp_err("expected response, got %d seq=%x in state %d", status, seq,
|
fp_err("expected response, got %d seq=%x in state %d", status, seq,
|
||||||
fpi_ssm_get_cur_state(ssm));
|
fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else if (subcmd != expect_subcmd) {
|
} else if (subcmd != expect_subcmd) {
|
||||||
fp_warn("expected response to subcmd 0x%02x, got response to %02x in "
|
fp_warn("expected response to subcmd 0x%02x, got response to %02x in "
|
||||||
"state %d", expect_subcmd, subcmd, fpi_ssm_get_cur_state(ssm));
|
"state %d", expect_subcmd, subcmd, fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else if (seq != upekdev->seq) {
|
} else if (seq != upekdev->seq) {
|
||||||
fp_err("expected response to cmd seq=%02x, got response to %02x "
|
fp_err("expected response to cmd seq=%02x, got response to %02x "
|
||||||
"in state %d", upekdev->seq, seq, fpi_ssm_get_cur_state(ssm));
|
"in state %d", upekdev->seq, seq, fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else {
|
} else {
|
||||||
fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm));
|
fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
@@ -506,7 +554,7 @@ static void read28_0b_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_response_cb((fpi_ssm *) user_data, dev, status, seq,
|
initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
|
||||||
0x0b, subcmd);
|
0x0b, subcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +562,7 @@ static void read28_0c_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_response_cb((fpi_ssm *) user_data, dev, status, seq,
|
initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
|
||||||
0x0c, subcmd);
|
0x0c, subcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +570,7 @@ static void read28_08_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_response_cb((fpi_ssm *) user_data, dev, status, seq,
|
initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
|
||||||
0x08, subcmd);
|
0x08, subcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,7 +578,7 @@ static void read28_07_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_response_cb((fpi_ssm *) user_data, dev, status, seq,
|
initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
|
||||||
0x07, subcmd);
|
0x07, subcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,33 +586,30 @@ static void read28_06_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_response_cb((fpi_ssm *) user_data, dev, status, seq,
|
initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
|
||||||
0x06, subcmd);
|
0x06, subcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm,
|
||||||
initsm_read_msg_cmd_cb(fpi_ssm *ssm,
|
enum read_msg_status status, uint8_t expect_seq, uint8_t seq)
|
||||||
struct fp_dev *dev,
|
|
||||||
enum read_msg_status status,
|
|
||||||
uint8_t expect_seq,
|
|
||||||
uint8_t seq)
|
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (status == READ_MSG_ERROR) {
|
if (status == READ_MSG_ERROR) {
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
} else if (status != READ_MSG_CMD) {
|
} else if (status != READ_MSG_CMD) {
|
||||||
fp_err("expected command, got %d seq=%x in state %d", status, seq,
|
fp_err("expected command, got %d seq=%x in state %d", status, seq,
|
||||||
fpi_ssm_get_cur_state(ssm));
|
fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
upekdev->seq = seq;
|
upekdev->seq = seq;
|
||||||
if (seq != expect_seq) {
|
if (seq != expect_seq) {
|
||||||
fp_err("expected seq=%x, got %x in state %d", expect_seq, seq,
|
fp_err("expected seq=%x, got %x in state %d", expect_seq, seq,
|
||||||
fpi_ssm_get_cur_state(ssm));
|
fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,43 +620,41 @@ static void read_msg05_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_cmd_cb((fpi_ssm *) user_data, dev, status, 5, seq);
|
initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 5, seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_msg03_cb(struct fp_dev *dev, enum read_msg_status status,
|
static void read_msg03_cb(struct fp_dev *dev, enum read_msg_status status,
|
||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
initsm_read_msg_cmd_cb((fpi_ssm *) user_data, dev, status, 3, seq);
|
initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 3, seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ctrl400_cb(struct libusb_transfer *transfer)
|
static void ctrl400_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
/* FIXME check length? */
|
/* FIXME check length? */
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void initsm_read_msg_handler(struct fpi_ssm *ssm,
|
||||||
initsm_read_msg_handler(fpi_ssm *ssm,
|
read_msg_cb_fn callback)
|
||||||
struct fp_dev *dev,
|
|
||||||
read_msg_cb_fn callback)
|
|
||||||
{
|
{
|
||||||
int r = read_msg_async(dev, callback, ssm);
|
int r = read_msg_async(fpi_ssm_get_dev(ssm), callback, ssm);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("async read msg failed in state %d", fpi_ssm_get_cur_state(ssm));
|
fp_err("async read msg failed in state %d", fpi_ssm_get_cur_state(ssm));
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initsm_send_msg_cb(struct libusb_transfer *transfer)
|
static void initsm_send_msg_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED
|
||||||
&& transfer->length == transfer->actual_length) {
|
&& transfer->length == transfer->actual_length) {
|
||||||
fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm));
|
fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm));
|
||||||
@@ -619,25 +662,22 @@ static void initsm_send_msg_cb(struct libusb_transfer *transfer)
|
|||||||
} else {
|
} else {
|
||||||
fp_err("failed, state=%d rqlength=%d actual_length=%d", fpi_ssm_get_cur_state(ssm),
|
fp_err("failed, state=%d rqlength=%d actual_length=%d", fpi_ssm_get_cur_state(ssm),
|
||||||
transfer->length, transfer->actual_length);
|
transfer->length, transfer->actual_length);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void initsm_send_msg28_handler(struct fpi_ssm *ssm,
|
||||||
initsm_send_msg28_handler(fpi_ssm *ssm,
|
unsigned char subcmd, const unsigned char *data, uint16_t innerlen)
|
||||||
struct fp_dev *dev,
|
|
||||||
unsigned char subcmd,
|
|
||||||
const unsigned char *data,
|
|
||||||
uint16_t innerlen)
|
|
||||||
{
|
{
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
transfer = alloc_send_cmd28_transfer(dev, subcmd, data, innerlen,
|
transfer = alloc_send_cmd28_transfer(dev, subcmd, data, innerlen,
|
||||||
initsm_send_msg_cb, ssm);
|
initsm_send_msg_cb, ssm);
|
||||||
if (!transfer) {
|
if (!transfer) {
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,13 +686,14 @@ initsm_send_msg28_handler(fpi_ssm *ssm,
|
|||||||
fp_err("urb submission failed error %d in state %d", r, fpi_ssm_get_cur_state(ssm));
|
fp_err("urb submission failed error %d in state %d", r, fpi_ssm_get_cur_state(ssm));
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initsm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void initsm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -660,7 +701,12 @@ static void initsm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
|||||||
case WRITE_CTRL400: ;
|
case WRITE_CTRL400: ;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
||||||
libusb_fill_control_setup(data,
|
libusb_fill_control_setup(data,
|
||||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1);
|
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1);
|
||||||
@@ -671,17 +717,17 @@ static void initsm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_MSG03:
|
case READ_MSG03:
|
||||||
initsm_read_msg_handler(ssm, dev, read_msg03_cb);
|
initsm_read_msg_handler(ssm, read_msg03_cb);
|
||||||
break;
|
break;
|
||||||
case SEND_RESP03: ;
|
case SEND_RESP03: ;
|
||||||
transfer = alloc_send_cmdresponse_transfer(dev, ++upekdev->seq,
|
transfer = alloc_send_cmdresponse_transfer(dev, ++upekdev->seq,
|
||||||
init_resp03, sizeof(init_resp03), initsm_send_msg_cb, ssm);
|
init_resp03, sizeof(init_resp03), initsm_send_msg_cb, ssm);
|
||||||
if (!transfer) {
|
if (!transfer) {
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,52 +735,51 @@ static void initsm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_MSG05:
|
case READ_MSG05:
|
||||||
initsm_read_msg_handler(ssm, dev, read_msg05_cb);
|
initsm_read_msg_handler(ssm, read_msg05_cb);
|
||||||
break;
|
break;
|
||||||
case SEND28_06: ;
|
case SEND28_06: ;
|
||||||
unsigned char dummy28_06 = 0x04;
|
unsigned char dummy28_06 = 0x04;
|
||||||
upekdev->seq = 0xf0;
|
upekdev->seq = 0xf0;
|
||||||
initsm_send_msg28_handler(ssm, dev, 0x06, &dummy28_06, 1);
|
initsm_send_msg28_handler(ssm, 0x06, &dummy28_06, 1);
|
||||||
break;
|
break;
|
||||||
case READ28_06:
|
case READ28_06:
|
||||||
initsm_read_msg_handler(ssm, dev, read28_06_cb);
|
initsm_read_msg_handler(ssm, read28_06_cb);
|
||||||
break;
|
break;
|
||||||
case SEND28_07: ;
|
case SEND28_07: ;
|
||||||
unsigned char dummy28_07 = 0x04;
|
unsigned char dummy28_07 = 0x04;
|
||||||
initsm_send_msg28_handler(ssm, dev, 0x07, &dummy28_07, 1);
|
initsm_send_msg28_handler(ssm, 0x07, &dummy28_07, 1);
|
||||||
break;
|
break;
|
||||||
case READ28_07:
|
case READ28_07:
|
||||||
initsm_read_msg_handler(ssm, dev, read28_07_cb);
|
initsm_read_msg_handler(ssm, read28_07_cb);
|
||||||
break;
|
break;
|
||||||
case SEND28_08:
|
case SEND28_08:
|
||||||
initsm_send_msg28_handler(ssm, dev, 0x08, init28_08, sizeof(init28_08));
|
initsm_send_msg28_handler(ssm, 0x08, init28_08, sizeof(init28_08));
|
||||||
break;
|
break;
|
||||||
case READ28_08:
|
case READ28_08:
|
||||||
initsm_read_msg_handler(ssm, dev, read28_08_cb);
|
initsm_read_msg_handler(ssm, read28_08_cb);
|
||||||
break;
|
break;
|
||||||
case SEND28_0C:
|
case SEND28_0C:
|
||||||
initsm_send_msg28_handler(ssm, dev, 0x0c, init28_0c, sizeof(init28_0c));
|
initsm_send_msg28_handler(ssm, 0x0c, init28_0c, sizeof(init28_0c));
|
||||||
break;
|
break;
|
||||||
case READ28_0C:
|
case READ28_0C:
|
||||||
initsm_read_msg_handler(ssm, dev, read28_0c_cb);
|
initsm_read_msg_handler(ssm, read28_0c_cb);
|
||||||
break;
|
break;
|
||||||
case SEND28_0B:
|
case SEND28_0B:
|
||||||
initsm_send_msg28_handler(ssm, dev, 0x0b, init28_0b, sizeof(init28_0b));
|
initsm_send_msg28_handler(ssm, 0x0b, init28_0b, sizeof(init28_0b));
|
||||||
break;
|
break;
|
||||||
case READ28_0B:
|
case READ28_0B:
|
||||||
initsm_read_msg_handler(ssm, dev, read28_0b_cb);
|
initsm_read_msg_handler(ssm, read28_0b_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static fpi_ssm *initsm_new(struct fp_dev *dev,
|
static struct fpi_ssm *initsm_new(struct fp_dev *dev)
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
return fpi_ssm_new(dev, initsm_run_state, INITSM_NUM_STATES, user_data);
|
return fpi_ssm_new(dev, initsm_run_state, INITSM_NUM_STATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum deinitsm_states {
|
enum deinitsm_states {
|
||||||
@@ -745,11 +790,11 @@ enum deinitsm_states {
|
|||||||
|
|
||||||
static void send_resp07_cb(struct libusb_transfer *transfer)
|
static void send_resp07_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else if (transfer->length != transfer->actual_length)
|
else if (transfer->length != transfer->actual_length)
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
@@ -759,29 +804,30 @@ static void read_msg01_cb(struct fp_dev *dev, enum read_msg_status status,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (status == READ_MSG_ERROR) {
|
if (status == READ_MSG_ERROR) {
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
} else if (status != READ_MSG_CMD) {
|
} else if (status != READ_MSG_CMD) {
|
||||||
fp_err("expected command, got %d seq=%x", status, seq);
|
fp_err("expected command, got %d seq=%x", status, seq);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
upekdev->seq = seq;
|
upekdev->seq = seq;
|
||||||
if (seq != 1) {
|
if (seq != 1) {
|
||||||
fp_err("expected seq=1, got %x", seq);
|
fp_err("expected seq=1, got %x", seq);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deinitsm_state_handler(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void deinitsm_state_handler(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
@@ -792,7 +838,7 @@ static void deinitsm_state_handler(fpi_ssm *ssm, struct fp_dev *dev, void *user_
|
|||||||
transfer = alloc_send_cmdresponse_transfer(dev, 0x07, &dummy, 1,
|
transfer = alloc_send_cmdresponse_transfer(dev, 0x07, &dummy, 1,
|
||||||
send_resp07_cb, ssm);
|
send_resp07_cb, ssm);
|
||||||
if (!transfer) {
|
if (!transfer) {
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,20 +846,20 @@ static void deinitsm_state_handler(fpi_ssm *ssm, struct fp_dev *dev, void *user_
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_MSG01: ;
|
case READ_MSG01: ;
|
||||||
r = read_msg_async(dev, read_msg01_cb, ssm);
|
r = read_msg_async(dev, read_msg01_cb, ssm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static fpi_ssm *deinitsm_new(struct fp_dev *dev)
|
static struct fpi_ssm *deinitsm_new(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
return fpi_ssm_new(dev, deinitsm_state_handler, DEINITSM_NUM_STATES, NULL);
|
return fpi_ssm_new(dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
||||||
@@ -829,7 +875,7 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
upekdev = g_malloc(sizeof(*upekdev));
|
upekdev = g_malloc(sizeof(*upekdev));
|
||||||
upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */
|
upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */
|
||||||
fp_dev_set_instance_data(dev, upekdev);
|
fpi_dev_set_user_data(dev, upekdev);
|
||||||
fpi_dev_set_nr_enroll_stages(dev, 3);
|
fpi_dev_set_nr_enroll_stages(dev, 3);
|
||||||
|
|
||||||
fpi_drvcb_open_complete(dev, 0);
|
fpi_drvcb_open_complete(dev, 0);
|
||||||
@@ -838,10 +884,10 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_exit(struct fp_dev *dev)
|
static void dev_exit(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
void *user_data;
|
||||||
|
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(dev), 0);
|
libusb_release_interface(fpi_dev_get_usb_dev(dev), 0);
|
||||||
g_free(upekdev);
|
user_data = fpi_dev_get_user_data(dev);
|
||||||
|
g_free(user_data);
|
||||||
fpi_drvcb_close_complete(dev);
|
fpi_drvcb_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,14 +909,14 @@ enum enroll_start_sm_states {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Called when the device initialization state machine completes */
|
/* Called when the device initialization state machine completes */
|
||||||
static void enroll_start_sm_cb_initsm(fpi_ssm *initsm, struct fp_dev *_dev, void *user_data)
|
static void enroll_start_sm_cb_initsm(struct fpi_ssm *initsm)
|
||||||
{
|
{
|
||||||
fpi_ssm *enroll_start_ssm = user_data;
|
struct fpi_ssm *enroll_start_ssm = fpi_ssm_get_user_data(initsm);
|
||||||
int error = fpi_ssm_get_error(initsm);
|
int error = fpi_ssm_get_error(initsm);
|
||||||
|
|
||||||
fpi_ssm_free(initsm);
|
fpi_ssm_free(initsm);
|
||||||
if (error)
|
if (error)
|
||||||
fpi_ssm_mark_failed(enroll_start_ssm, error);
|
fpi_ssm_mark_aborted(enroll_start_ssm, error);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(enroll_start_ssm);
|
fpi_ssm_next_state(enroll_start_ssm);
|
||||||
}
|
}
|
||||||
@@ -878,11 +924,11 @@ static void enroll_start_sm_cb_initsm(fpi_ssm *initsm, struct fp_dev *_dev, void
|
|||||||
/* called when enroll init URB has completed */
|
/* called when enroll init URB has completed */
|
||||||
static void enroll_start_sm_cb_init(struct libusb_transfer *transfer)
|
static void enroll_start_sm_cb_init(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else if (transfer->length != transfer->actual_length)
|
else if (transfer->length != transfer->actual_length)
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
@@ -892,32 +938,34 @@ static void enroll_start_sm_cb_msg28(struct fp_dev *dev,
|
|||||||
enum read_msg_status status, uint8_t seq, unsigned char subcmd,
|
enum read_msg_status status, uint8_t seq, unsigned char subcmd,
|
||||||
unsigned char *data, size_t data_len, void *user_data)
|
unsigned char *data, size_t data_len, void *user_data)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
|
|
||||||
if (status != READ_MSG_RESPONSE) {
|
if (status != READ_MSG_RESPONSE) {
|
||||||
fp_err("expected response, got %d seq=%x", status, seq);
|
fp_err("expected response, got %d seq=%x", status, seq);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else if (subcmd != 0) {
|
} else if (subcmd != 0) {
|
||||||
fp_warn("expected response to subcmd 0, got response to %02x",
|
fp_warn("expected response to subcmd 0, got response to %02x",
|
||||||
subcmd);
|
subcmd);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else if (seq != upekdev->seq) {
|
} else if (seq != upekdev->seq) {
|
||||||
fp_err("expected response to cmd seq=%02x, got response to %02x",
|
fp_err("expected response to cmd seq=%02x, got response to %02x",
|
||||||
upekdev->seq, seq);
|
upekdev->seq, seq);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enroll_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void enroll_start_sm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case RUN_INITSM: ;
|
case RUN_INITSM: ;
|
||||||
fpi_ssm *initsm = initsm_new(dev, ssm);
|
struct fpi_ssm *initsm = initsm_new(dev);
|
||||||
|
fpi_ssm_set_user_data(initsm, ssm);
|
||||||
fpi_ssm_start(initsm, enroll_start_sm_cb_initsm);
|
fpi_ssm_start(initsm, enroll_start_sm_cb_initsm);
|
||||||
break;
|
break;
|
||||||
case ENROLL_INIT: ;
|
case ENROLL_INIT: ;
|
||||||
@@ -925,7 +973,7 @@ static void enroll_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *us
|
|||||||
transfer = alloc_send_cmd28_transfer(dev, 0x02, enroll_init,
|
transfer = alloc_send_cmd28_transfer(dev, 0x02, enroll_init,
|
||||||
sizeof(enroll_init), enroll_start_sm_cb_init, ssm);
|
sizeof(enroll_init), enroll_start_sm_cb_init, ssm);
|
||||||
if (!transfer) {
|
if (!transfer) {
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,7 +981,7 @@ static void enroll_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *us
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_ENROLL_MSG28: ;
|
case READ_ENROLL_MSG28: ;
|
||||||
@@ -943,7 +991,7 @@ static void enroll_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *us
|
|||||||
* include a 30 01 poll somewhere? */
|
* include a 30 01 poll somewhere? */
|
||||||
r = read_msg_async(dev, enroll_start_sm_cb_msg28, ssm);
|
r = read_msg_async(dev, enroll_start_sm_cb_msg28, ssm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -953,7 +1001,7 @@ static void enroll_iterate(struct fp_dev *dev);
|
|||||||
static void e_handle_resp00(struct fp_dev *dev, unsigned char *data,
|
static void e_handle_resp00(struct fp_dev *dev, unsigned char *data,
|
||||||
size_t data_len)
|
size_t data_len)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
unsigned char status;
|
unsigned char status;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
@@ -970,9 +1018,6 @@ static void e_handle_resp00(struct fp_dev *dev, unsigned char *data,
|
|||||||
case 0x0c:
|
case 0x0c:
|
||||||
case 0x0d:
|
case 0x0d:
|
||||||
case 0x0e:
|
case 0x0e:
|
||||||
case 0x26:
|
|
||||||
case 0x27:
|
|
||||||
case 0x2e:
|
|
||||||
/* if we previously completed a non-last enrollment stage, we'll
|
/* if we previously completed a non-last enrollment stage, we'll
|
||||||
* get this code to indicate successful stage completion */
|
* get this code to indicate successful stage completion */
|
||||||
if (upekdev->enroll_passed) {
|
if (upekdev->enroll_passed) {
|
||||||
@@ -1042,7 +1087,7 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
|
|||||||
item = fpi_print_data_item_new(data_len - sizeof(scan_comp));
|
item = fpi_print_data_item_new(data_len - sizeof(scan_comp));
|
||||||
memcpy(item->data, data + sizeof(scan_comp),
|
memcpy(item->data, data + sizeof(scan_comp),
|
||||||
data_len - sizeof(scan_comp));
|
data_len - sizeof(scan_comp));
|
||||||
fpi_print_data_add_item(fdata, item);
|
fdata->prints = g_slist_prepend(fdata->prints, item);
|
||||||
|
|
||||||
result = FP_ENROLL_COMPLETE;
|
result = FP_ENROLL_COMPLETE;
|
||||||
}
|
}
|
||||||
@@ -1105,8 +1150,9 @@ static void enroll_iterate(struct fp_dev *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enroll_started(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void enroll_started(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
fpi_drvcb_enroll_started(dev, fpi_ssm_get_error(ssm));
|
fpi_drvcb_enroll_started(dev, fpi_ssm_get_error(ssm));
|
||||||
|
|
||||||
if (!fpi_ssm_get_error(ssm))
|
if (!fpi_ssm_get_error(ssm))
|
||||||
@@ -1117,41 +1163,41 @@ static void enroll_started(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
|||||||
|
|
||||||
static int enroll_start(struct fp_dev *dev)
|
static int enroll_start(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
/* do_init state machine first */
|
/* do_init state machine first */
|
||||||
fpi_ssm *ssm = fpi_ssm_new(dev, enroll_start_sm_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(dev, enroll_start_sm_run_state,
|
||||||
ENROLL_START_NUM_STATES, NULL);
|
ENROLL_START_NUM_STATES);
|
||||||
|
|
||||||
upekdev->enroll_passed = FALSE;
|
upekdev->enroll_passed = FALSE;
|
||||||
fpi_ssm_start(ssm, enroll_started);
|
fpi_ssm_start(ssm, enroll_started);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enroll_stop_deinit_cb(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void enroll_stop_deinit_cb(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
/* don't really care about errors */
|
/* don't really care about errors */
|
||||||
fpi_drvcb_enroll_stopped(dev);
|
fpi_drvcb_enroll_stopped(fpi_ssm_get_dev(ssm));
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enroll_stop(struct fp_dev *dev)
|
static int enroll_stop(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = deinitsm_new(dev);
|
struct fpi_ssm *ssm = deinitsm_new(dev);
|
||||||
fpi_ssm_start(ssm, enroll_stop_deinit_cb);
|
fpi_ssm_start(ssm, enroll_stop_deinit_cb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verify_stop_deinit_cb(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void verify_stop_deinit_cb(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
/* don't really care about errors */
|
/* don't really care about errors */
|
||||||
fpi_drvcb_verify_stopped(dev);
|
fpi_drvcb_verify_stopped(fpi_ssm_get_dev(ssm));
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_verify_stop(struct fp_dev *dev)
|
static void do_verify_stop(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = deinitsm_new(dev);
|
struct fpi_ssm *ssm = deinitsm_new(dev);
|
||||||
fpi_ssm_start(ssm, verify_stop_deinit_cb);
|
fpi_ssm_start(ssm, verify_stop_deinit_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1168,14 +1214,14 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Called when the device initialization state machine completes */
|
/* Called when the device initialization state machine completes */
|
||||||
static void verify_start_sm_cb_initsm(fpi_ssm *initsm, struct fp_dev *_dev, void *user_data)
|
static void verify_start_sm_cb_initsm(struct fpi_ssm *initsm)
|
||||||
{
|
{
|
||||||
fpi_ssm *verify_start_ssm = user_data;
|
struct fpi_ssm *verify_start_ssm = fpi_ssm_get_user_data(initsm);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = fpi_ssm_get_error(initsm);
|
err = fpi_ssm_get_error(initsm);
|
||||||
if (err)
|
if (err)
|
||||||
fpi_ssm_mark_failed(verify_start_ssm, err);
|
fpi_ssm_mark_aborted(verify_start_ssm, err);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(verify_start_ssm);
|
fpi_ssm_next_state(verify_start_ssm);
|
||||||
fpi_ssm_free(initsm);
|
fpi_ssm_free(initsm);
|
||||||
@@ -1183,28 +1229,30 @@ static void verify_start_sm_cb_initsm(fpi_ssm *initsm, struct fp_dev *_dev, void
|
|||||||
|
|
||||||
static void verify_init_2803_cb(struct libusb_transfer *transfer)
|
static void verify_init_2803_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else if (transfer->length != transfer->actual_length)
|
else if (transfer->length != transfer->actual_length)
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_ssm_mark_aborted(ssm, -EPROTO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verify_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void verify_start_sm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case VERIFY_RUN_INITSM: ;
|
case VERIFY_RUN_INITSM: ;
|
||||||
fpi_ssm *initsm = initsm_new(dev, ssm);
|
struct fpi_ssm *initsm = initsm_new(dev);
|
||||||
|
fpi_ssm_set_user_data(initsm, ssm);
|
||||||
fpi_ssm_start(initsm, verify_start_sm_cb_initsm);
|
fpi_ssm_start(initsm, verify_start_sm_cb_initsm);
|
||||||
break;
|
break;
|
||||||
case VERIFY_INIT: ;
|
case VERIFY_INIT: ;
|
||||||
struct fp_print_data *print = fpi_dev_get_verify_data(dev);
|
struct fp_print_data *print = fpi_dev_get_verify_data(dev);
|
||||||
struct fp_print_data_item *item = fpi_print_data_get_item(print);
|
struct fp_print_data_item *item = print->prints->data;
|
||||||
size_t data_len = sizeof(verify_hdr) + item->length;
|
size_t data_len = sizeof(verify_hdr) + item->length;
|
||||||
unsigned char *data = g_malloc(data_len);
|
unsigned char *data = g_malloc(data_len);
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
@@ -1215,7 +1263,7 @@ static void verify_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *us
|
|||||||
verify_init_2803_cb, ssm);
|
verify_init_2803_cb, ssm);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
if (!transfer) {
|
if (!transfer) {
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1223,7 +1271,7 @@ static void verify_start_sm_run_state(fpi_ssm *ssm, struct fp_dev *dev, void *us
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(transfer->buffer);
|
g_free(transfer->buffer);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1309,7 +1357,7 @@ static void verify_rd2800_cb(struct fp_dev *dev, enum read_msg_status msgstat,
|
|||||||
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (msgstat != READ_MSG_RESPONSE) {
|
if (msgstat != READ_MSG_RESPONSE) {
|
||||||
fp_err("expected response, got %d seq=%x", msgstat, seq);
|
fp_err("expected response, got %d seq=%x", msgstat, seq);
|
||||||
@@ -1348,7 +1396,7 @@ static void verify_wr2800_cb(struct libusb_transfer *transfer)
|
|||||||
|
|
||||||
static void verify_iterate(struct fp_dev *dev)
|
static void verify_iterate(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (upekdev->stop_verify) {
|
if (upekdev->stop_verify) {
|
||||||
do_verify_stop(dev);
|
do_verify_stop(dev);
|
||||||
@@ -1381,9 +1429,10 @@ static void verify_iterate(struct fp_dev *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verify_started(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
static void verify_started(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct fp_dev *dev = fpi_ssm_get_dev(ssm);
|
||||||
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
fpi_drvcb_verify_started(dev, fpi_ssm_get_error(ssm));
|
fpi_drvcb_verify_started(dev, fpi_ssm_get_error(ssm));
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
@@ -1396,9 +1445,9 @@ static void verify_started(fpi_ssm *ssm, struct fp_dev *dev, void *user_data)
|
|||||||
|
|
||||||
static int verify_start(struct fp_dev *dev)
|
static int verify_start(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(dev, verify_start_sm_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(dev, verify_start_sm_run_state,
|
||||||
VERIFY_NUM_STATES, NULL);
|
VERIFY_NUM_STATES);
|
||||||
upekdev->stop_verify = FALSE;
|
upekdev->stop_verify = FALSE;
|
||||||
fpi_ssm_start(ssm, verify_started);
|
fpi_ssm_start(ssm, verify_started);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1406,7 +1455,7 @@ static int verify_start(struct fp_dev *dev)
|
|||||||
|
|
||||||
static int verify_stop(struct fp_dev *dev, gboolean iterating)
|
static int verify_stop(struct fp_dev *dev, gboolean iterating)
|
||||||
{
|
{
|
||||||
struct upekts_dev *upekdev = FP_INSTANCE_DATA(dev);
|
struct upekts_dev *upekdev = fpi_dev_get_user_data(dev);
|
||||||
|
|
||||||
if (!iterating)
|
if (!iterating)
|
||||||
do_verify_stop(dev);
|
do_verify_stop(dev);
|
||||||
|
|||||||
@@ -120,10 +120,9 @@ struct uru4k_dev {
|
|||||||
unsigned char last_reg_rd[16];
|
unsigned char last_reg_rd[16];
|
||||||
unsigned char last_hwstat;
|
unsigned char last_hwstat;
|
||||||
|
|
||||||
fpi_usb_transfer *irq_transfer;
|
struct libusb_transfer *irq_transfer;
|
||||||
fpi_usb_transfer *img_transfer;
|
struct libusb_transfer *img_transfer;
|
||||||
void *img_data;
|
void *img_data;
|
||||||
int img_data_actual_length;
|
|
||||||
uint16_t img_lines_done, img_block;
|
uint16_t img_lines_done, img_block;
|
||||||
uint32_t img_enc_seed;
|
uint32_t img_enc_seed;
|
||||||
|
|
||||||
@@ -136,7 +135,7 @@ struct uru4k_dev {
|
|||||||
unsigned char powerup_hwstat;
|
unsigned char powerup_hwstat;
|
||||||
|
|
||||||
int scanpwr_irq_timeouts;
|
int scanpwr_irq_timeouts;
|
||||||
fpi_timeout *scanpwr_irq_timeout;
|
struct fpi_timeout *scanpwr_irq_timeout;
|
||||||
|
|
||||||
int fwfixer_offset;
|
int fwfixer_offset;
|
||||||
unsigned char fwfixer_value;
|
unsigned char fwfixer_value;
|
||||||
@@ -187,10 +186,13 @@ static int write_regs(struct fp_img_dev *dev, uint16_t first_reg,
|
|||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
struct write_regs_data *wrdata;
|
struct write_regs_data *wrdata;
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
wrdata = g_malloc(sizeof(*wrdata));
|
wrdata = g_malloc(sizeof(*wrdata));
|
||||||
wrdata->dev = dev;
|
wrdata->dev = dev;
|
||||||
wrdata->callback = callback;
|
wrdata->callback = callback;
|
||||||
@@ -199,7 +201,7 @@ static int write_regs(struct fp_img_dev *dev, uint16_t first_reg,
|
|||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs);
|
||||||
memcpy(data + LIBUSB_CONTROL_SETUP_SIZE, values, num_regs);
|
memcpy(data + LIBUSB_CONTROL_SETUP_SIZE, values, num_regs);
|
||||||
libusb_fill_control_setup(data, CTRL_OUT, USB_RQ, first_reg, 0, num_regs);
|
libusb_fill_control_setup(data, CTRL_OUT, USB_RQ, first_reg, 0, num_regs);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), data, write_regs_cb,
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, write_regs_cb,
|
||||||
wrdata, CTRL_TIMEOUT);
|
wrdata, CTRL_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -251,10 +253,13 @@ static int read_regs(struct fp_img_dev *dev, uint16_t first_reg,
|
|||||||
uint16_t num_regs, read_regs_cb_fn callback, void *user_data)
|
uint16_t num_regs, read_regs_cb_fn callback, void *user_data)
|
||||||
{
|
{
|
||||||
struct read_regs_data *rrdata;
|
struct read_regs_data *rrdata;
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
rrdata = g_malloc(sizeof(*rrdata));
|
rrdata = g_malloc(sizeof(*rrdata));
|
||||||
rrdata->dev = dev;
|
rrdata->dev = dev;
|
||||||
rrdata->callback = callback;
|
rrdata->callback = callback;
|
||||||
@@ -262,7 +267,7 @@ static int read_regs(struct fp_img_dev *dev, uint16_t first_reg,
|
|||||||
|
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs);
|
||||||
libusb_fill_control_setup(data, CTRL_IN, USB_RQ, first_reg, 0, num_regs);
|
libusb_fill_control_setup(data, CTRL_IN, USB_RQ, first_reg, 0, num_regs);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), data, read_regs_cb,
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, read_regs_cb,
|
||||||
rrdata, CTRL_TIMEOUT);
|
rrdata, CTRL_TIMEOUT);
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
@@ -296,30 +301,30 @@ static int read_regs(struct fp_img_dev *dev, uint16_t first_reg,
|
|||||||
*
|
*
|
||||||
* BIT 1: IRQ PENDING
|
* BIT 1: IRQ PENDING
|
||||||
* Just had a brainwave. This bit is set when the device is trying to deliver
|
* Just had a brainwave. This bit is set when the device is trying to deliver
|
||||||
* an interrupt to the host. Maybe?
|
* and interrupt to the host. Maybe?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void response_cb(struct fp_img_dev *dev, int status, void *user_data)
|
static void response_cb(struct fp_img_dev *dev, int status, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, status);
|
fpi_ssm_mark_aborted(ssm, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void challenge_cb(struct fp_img_dev *dev, int status,
|
static void challenge_cb(struct fp_img_dev *dev, int status,
|
||||||
uint16_t num_regs, unsigned char *data, void *user_data)
|
uint16_t num_regs, unsigned char *data, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *respdata;
|
unsigned char *respdata;
|
||||||
PK11Context *ctx;
|
PK11Context *ctx;
|
||||||
int r, outlen;
|
int r, outlen;
|
||||||
|
|
||||||
r = status;
|
r = status;
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
fpi_ssm_mark_failed(ssm, status);
|
fpi_ssm_mark_aborted(ssm, status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +346,7 @@ static void challenge_cb(struct fp_img_dev *dev, int status,
|
|||||||
g_free(respdata);
|
g_free(respdata);
|
||||||
}
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -349,16 +354,15 @@ static void challenge_cb(struct fp_img_dev *dev, int status,
|
|||||||
* authentication scheme, where the device challenges the authenticity of the
|
* authentication scheme, where the device challenges the authenticity of the
|
||||||
* driver.
|
* driver.
|
||||||
*/
|
*/
|
||||||
static void
|
static void sm_do_challenge_response(struct fpi_ssm *ssm)
|
||||||
sm_do_challenge_response(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
r = read_regs(dev, REG_CHALLENGE, CR_LENGTH, challenge_cb, ssm);
|
r = read_regs(dev, REG_CHALLENGE, CR_LENGTH, challenge_cb, ssm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** INTERRUPT HANDLING *****/
|
/***** INTERRUPT HANDLING *****/
|
||||||
@@ -367,13 +371,10 @@ sm_do_challenge_response(fpi_ssm *ssm,
|
|||||||
|
|
||||||
static int start_irq_handler(struct fp_img_dev *dev);
|
static int start_irq_handler(struct fp_img_dev *dev);
|
||||||
|
|
||||||
static void irq_handler(struct libusb_transfer *transfer,
|
static void irq_handler(struct libusb_transfer *transfer)
|
||||||
struct fp_dev *_dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = FP_IMG_DEV(_dev);
|
struct fp_img_dev *dev = transfer->user_data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@@ -395,6 +396,8 @@ static void irq_handler(struct libusb_transfer *transfer,
|
|||||||
|
|
||||||
type = GUINT16_FROM_BE(*((uint16_t *) data));
|
type = GUINT16_FROM_BE(*((uint16_t *) data));
|
||||||
fp_dbg("recv irq type %04x", type);
|
fp_dbg("recv irq type %04x", type);
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
|
|
||||||
/* The 0800 interrupt seems to indicate imminent failure (0 bytes transfer)
|
/* The 0800 interrupt seems to indicate imminent failure (0 bytes transfer)
|
||||||
* of the next scan. It still appears on occasion. */
|
* of the next scan. It still appears on occasion. */
|
||||||
@@ -410,43 +413,47 @@ static void irq_handler(struct libusb_transfer *transfer,
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
transfer = NULL;
|
||||||
|
data = NULL;
|
||||||
err:
|
err:
|
||||||
if (urudev->irq_cb)
|
if (urudev->irq_cb)
|
||||||
urudev->irq_cb(dev, r, 0, urudev->irq_cb_data);
|
urudev->irq_cb(dev, r, 0, urudev->irq_cb_data);
|
||||||
out:
|
out:
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
urudev->irq_transfer = NULL;
|
urudev->irq_transfer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start_irq_handler(struct fp_img_dev *dev)
|
static int start_irq_handler(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_usb_transfer *transfer;
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
data = g_malloc(IRQ_LENGTH);
|
data = g_malloc(IRQ_LENGTH);
|
||||||
transfer = fpi_usb_fill_bulk_transfer(FP_DEV(dev),
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_INTR, data, IRQ_LENGTH,
|
||||||
NULL,
|
irq_handler, dev, 0);
|
||||||
EP_INTR,
|
|
||||||
data,
|
|
||||||
IRQ_LENGTH,
|
|
||||||
irq_handler,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
|
|
||||||
urudev->irq_transfer = transfer;
|
urudev->irq_transfer = transfer;
|
||||||
r = fpi_usb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
|
g_free(data);
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
urudev->irq_transfer = NULL;
|
urudev->irq_transfer = NULL;
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_irq_handler(struct fp_img_dev *dev, irqs_stopped_cb_fn cb)
|
static void stop_irq_handler(struct fp_img_dev *dev, irqs_stopped_cb_fn cb)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_usb_transfer *transfer = urudev->irq_transfer;
|
struct libusb_transfer *transfer = urudev->irq_transfer;
|
||||||
if (transfer) {
|
if (transfer) {
|
||||||
fpi_usb_cancel_transfer(transfer);
|
libusb_cancel_transfer(transfer);
|
||||||
urudev->irqs_stopped_cb = cb;
|
urudev->irqs_stopped_cb = cb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,7 +484,7 @@ static void change_state_write_reg_cb(struct fp_img_dev *dev, int status,
|
|||||||
|
|
||||||
static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case IMGDEV_STATE_INACTIVE:
|
case IMGDEV_STATE_INACTIVE:
|
||||||
@@ -501,43 +508,37 @@ static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void sm_write_reg_cb(struct fp_img_dev *dev, int result, void *user_data)
|
static void sm_write_reg_cb(struct fp_img_dev *dev, int result, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
fpi_ssm_mark_failed(ssm, result);
|
fpi_ssm_mark_aborted(ssm, result);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_write_regs(struct fpi_ssm *ssm, uint16_t first_reg, uint16_t num_regs,
|
||||||
sm_write_regs(fpi_ssm *ssm,
|
void *data)
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint16_t first_reg,
|
|
||||||
uint16_t num_regs,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int r = write_regs(dev, first_reg, num_regs, data, sm_write_reg_cb, ssm);
|
int r = write_regs(dev, first_reg, num_regs, data, sm_write_reg_cb, ssm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_write_reg(struct fpi_ssm *ssm, uint16_t reg,
|
||||||
sm_write_reg(fpi_ssm *ssm,
|
unsigned char value)
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint16_t reg,
|
|
||||||
unsigned char value)
|
|
||||||
{
|
{
|
||||||
sm_write_regs(ssm, dev, reg, 1, &value);
|
sm_write_regs(ssm, reg, 1, &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm_read_reg_cb(struct fp_img_dev *dev, int result,
|
static void sm_read_reg_cb(struct fp_img_dev *dev, int result,
|
||||||
uint16_t num_regs, unsigned char *data, void *user_data)
|
uint16_t num_regs, unsigned char *data, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
fpi_ssm_mark_failed(ssm, result);
|
fpi_ssm_mark_aborted(ssm, result);
|
||||||
} else {
|
} else {
|
||||||
memcpy(urudev->last_reg_rd, data, num_regs);
|
memcpy(urudev->last_reg_rd, data, num_regs);
|
||||||
fp_dbg("reg value %x", urudev->last_reg_rd[0]);
|
fp_dbg("reg value %x", urudev->last_reg_rd[0]);
|
||||||
@@ -545,42 +546,32 @@ static void sm_read_reg_cb(struct fp_img_dev *dev, int result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define member_size(type, member) sizeof(((type *)0)->member)
|
static void sm_read_regs(struct fpi_ssm *ssm, uint16_t reg, uint16_t num_regs)
|
||||||
|
|
||||||
static void
|
|
||||||
sm_read_regs(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint16_t reg,
|
|
||||||
uint16_t num_regs)
|
|
||||||
{
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (num_regs > member_size(struct uru4k_dev, last_reg_rd)) {
|
if (num_regs > sizeof(urudev->last_reg_rd)) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("read %d regs at %x", num_regs, reg);
|
fp_dbg("read %d regs at %x", num_regs, reg);
|
||||||
r = read_regs(dev, reg, num_regs, sm_read_reg_cb, ssm);
|
r = read_regs(dev, reg, num_regs, sm_read_reg_cb, ssm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_read_reg(struct fpi_ssm *ssm, uint16_t reg)
|
||||||
sm_read_reg(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
uint16_t reg)
|
|
||||||
{
|
{
|
||||||
sm_read_regs(ssm, dev, reg, 1);
|
sm_read_regs(ssm, reg, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_set_hwstat(struct fpi_ssm *ssm, unsigned char value)
|
||||||
sm_set_hwstat(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned char value)
|
|
||||||
{
|
{
|
||||||
fp_dbg("set %02x", value);
|
fp_dbg("set %02x", value);
|
||||||
sm_write_reg(ssm, dev, REG_HWSTAT, value);
|
sm_write_reg(ssm, REG_HWSTAT, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** IMAGING LOOP *****/
|
/***** IMAGING LOOP *****/
|
||||||
@@ -594,6 +585,28 @@ enum imaging_states {
|
|||||||
IMAGING_NUM_STATES
|
IMAGING_NUM_STATES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void image_transfer_cb(struct libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
|
if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
|
||||||
|
fp_dbg("cancelled");
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ECANCELED);
|
||||||
|
} else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
|
fp_dbg("error");
|
||||||
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
|
} else {
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BLOCKF_CHANGE_KEY = 0x80,
|
||||||
|
BLOCKF_NO_KEY_UPDATE = 0x04,
|
||||||
|
BLOCKF_ENCRYPTED = 0x02,
|
||||||
|
BLOCKF_NOT_PRESENT = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
struct uru4k_image {
|
struct uru4k_image {
|
||||||
uint8_t unknown_00[4];
|
uint8_t unknown_00[4];
|
||||||
uint16_t num_lines;
|
uint16_t num_lines;
|
||||||
@@ -607,33 +620,6 @@ struct uru4k_image {
|
|||||||
uint8_t data[IMAGE_HEIGHT][IMAGE_WIDTH];
|
uint8_t data[IMAGE_HEIGHT][IMAGE_WIDTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void image_transfer_cb(struct libusb_transfer *transfer,
|
|
||||||
struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
|
|
||||||
fp_dbg("cancelled");
|
|
||||||
fpi_ssm_mark_failed(ssm, -ECANCELED);
|
|
||||||
} else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
|
||||||
fp_dbg("error");
|
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
|
||||||
} else {
|
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(dev);
|
|
||||||
|
|
||||||
urudev->img_data = g_memdup(transfer->buffer, sizeof(struct uru4k_image));
|
|
||||||
urudev->img_data_actual_length = transfer->actual_length;
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BLOCKF_CHANGE_KEY = 0x80,
|
|
||||||
BLOCKF_NO_KEY_UPDATE = 0x04,
|
|
||||||
BLOCKF_ENCRYPTED = 0x02,
|
|
||||||
BLOCKF_NOT_PRESENT = 0x01,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t update_key(uint32_t key)
|
static uint32_t update_key(uint32_t key)
|
||||||
{
|
{
|
||||||
/* linear feedback shift register
|
/* linear feedback shift register
|
||||||
@@ -701,35 +687,35 @@ static int calc_dev2(struct uru4k_image *img)
|
|||||||
return res / IMAGE_WIDTH;
|
return res / IMAGE_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imaging_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void imaging_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
struct uru4k_image *img = urudev->img_data;
|
struct uru4k_image *img = urudev->img_data;
|
||||||
struct fp_img *fpimg;
|
struct fp_img *fpimg;
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
uint8_t flags, num_lines;
|
uint8_t flags, num_lines;
|
||||||
int i, r, to, dev2;
|
int i, r, to, dev2;
|
||||||
unsigned char buf[5];
|
char buf[5];
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case IMAGING_CAPTURE:
|
case IMAGING_CAPTURE:
|
||||||
urudev->img_lines_done = 0;
|
urudev->img_lines_done = 0;
|
||||||
urudev->img_block = 0;
|
urudev->img_block = 0;
|
||||||
r = fpi_usb_submit_transfer(urudev->img_transfer);
|
libusb_fill_bulk_transfer(urudev->img_transfer, fpi_imgdev_get_usb_dev(dev), EP_DATA,
|
||||||
if (r < 0) {
|
urudev->img_data, sizeof(struct uru4k_image), image_transfer_cb, ssm, 0);
|
||||||
urudev->img_transfer = NULL;
|
r = libusb_submit_transfer(urudev->img_transfer);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
if (r < 0)
|
||||||
}
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
break;
|
break;
|
||||||
case IMAGING_SEND_INDEX:
|
case IMAGING_SEND_INDEX:
|
||||||
fp_dbg("hw header lines %d", img->num_lines);
|
fp_dbg("hw header lines %d", img->num_lines);
|
||||||
|
|
||||||
if (img->num_lines >= IMAGE_HEIGHT ||
|
if (img->num_lines >= IMAGE_HEIGHT ||
|
||||||
urudev->img_data_actual_length < img->num_lines * IMAGE_WIDTH + 64) {
|
urudev->img_transfer->actual_length < img->num_lines * IMAGE_WIDTH + 64) {
|
||||||
fp_err("bad captured image (%d lines) or size mismatch %d < %d",
|
fp_err("bad captured image (%d lines) or size mismatch %d < %d",
|
||||||
img->num_lines,
|
img->num_lines,
|
||||||
urudev->img_data_actual_length,
|
urudev->img_transfer->actual_length,
|
||||||
img->num_lines * IMAGE_WIDTH + 64);
|
img->num_lines * IMAGE_WIDTH + 64);
|
||||||
fpi_ssm_jump_to_state(ssm, IMAGING_CAPTURE);
|
fpi_ssm_jump_to_state(ssm, IMAGING_CAPTURE);
|
||||||
return;
|
return;
|
||||||
@@ -748,10 +734,10 @@ static void imaging_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
buf[2] = urudev->img_enc_seed >> 8;
|
buf[2] = urudev->img_enc_seed >> 8;
|
||||||
buf[3] = urudev->img_enc_seed >> 16;
|
buf[3] = urudev->img_enc_seed >> 16;
|
||||||
buf[4] = urudev->img_enc_seed >> 24;
|
buf[4] = urudev->img_enc_seed >> 24;
|
||||||
sm_write_regs(ssm, dev, REG_SCRAMBLE_DATA_INDEX, 5, buf);
|
sm_write_regs(ssm, REG_SCRAMBLE_DATA_INDEX, 5, buf);
|
||||||
break;
|
break;
|
||||||
case IMAGING_READ_KEY:
|
case IMAGING_READ_KEY:
|
||||||
sm_read_regs(ssm, dev, REG_SCRAMBLE_DATA_KEY, 4);
|
sm_read_regs(ssm, REG_SCRAMBLE_DATA_KEY, 4);
|
||||||
break;
|
break;
|
||||||
case IMAGING_DECODE:
|
case IMAGING_DECODE:
|
||||||
key = urudev->last_reg_rd[0];
|
key = urudev->last_reg_rd[0];
|
||||||
@@ -824,10 +810,10 @@ static void imaging_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imaging_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void imaging_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
|
|
||||||
@@ -837,12 +823,11 @@ static void imaging_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
if (r)
|
if (r)
|
||||||
fpi_imgdev_session_error(dev, r);
|
fpi_imgdev_session_error(dev, r);
|
||||||
|
|
||||||
/* Freed by callback or cancellation */
|
|
||||||
urudev->img_transfer = NULL;
|
|
||||||
|
|
||||||
g_free(urudev->img_data);
|
g_free(urudev->img_data);
|
||||||
urudev->img_data = NULL;
|
urudev->img_data = NULL;
|
||||||
urudev->img_data_actual_length = 0;
|
|
||||||
|
libusb_free_transfer(urudev->img_transfer);
|
||||||
|
urudev->img_transfer = NULL;
|
||||||
|
|
||||||
r = execute_state_change(dev);
|
r = execute_state_change(dev);
|
||||||
if (r)
|
if (r)
|
||||||
@@ -855,7 +840,7 @@ static void imaging_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
* confused state and returns hwstat 0x85. On next app run, we don't get the
|
* confused state and returns hwstat 0x85. On next app run, we don't get the
|
||||||
* 56aa interrupt. This is the best way I've found to fix it: mess around
|
* 56aa interrupt. This is the best way I've found to fix it: mess around
|
||||||
* with hwstat until it starts returning more recognisable values. This
|
* with hwstat until it starts returning more recognisable values. This
|
||||||
* doesn't happen on my other devices: uru4000, uru4000b, ms fp rdr v2
|
* doesn't happen on my other devices: uru4000, uru4000b, ms fp rdr v2
|
||||||
*
|
*
|
||||||
* The windows driver copes with this OK, but then again it uploads firmware
|
* The windows driver copes with this OK, but then again it uploads firmware
|
||||||
* right after reading the 0x85 hwstat, allowing some time to pass before it
|
* right after reading the 0x85 hwstat, allowing some time to pass before it
|
||||||
@@ -875,33 +860,32 @@ enum rebootpwr_states {
|
|||||||
REBOOTPWR_NUM_STATES,
|
REBOOTPWR_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void rebootpwr_pause_cb(void *data)
|
||||||
rebootpwr_pause_cb(struct fp_dev *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = data;
|
struct fpi_ssm *ssm = data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (!--urudev->rebootpwr_ctr) {
|
if (!--urudev->rebootpwr_ctr) {
|
||||||
fp_err("could not reboot device power");
|
fp_err("could not reboot device power");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_jump_to_state(ssm, REBOOTPWR_GET_HWSTAT);
|
fpi_ssm_jump_to_state(ssm, REBOOTPWR_GET_HWSTAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rebootpwr_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void rebootpwr_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case REBOOTPWR_SET_HWSTAT:
|
case REBOOTPWR_SET_HWSTAT:
|
||||||
urudev->rebootpwr_ctr = 100;
|
urudev->rebootpwr_ctr = 100;
|
||||||
sm_set_hwstat(ssm, dev, urudev->last_hwstat & 0xf);
|
sm_set_hwstat(ssm, urudev->last_hwstat & 0xf);
|
||||||
break;
|
break;
|
||||||
case REBOOTPWR_GET_HWSTAT:
|
case REBOOTPWR_GET_HWSTAT:
|
||||||
sm_read_reg(ssm, dev, REG_HWSTAT);
|
sm_read_reg(ssm, REG_HWSTAT);
|
||||||
break;
|
break;
|
||||||
case REBOOTPWR_CHECK_HWSTAT:
|
case REBOOTPWR_CHECK_HWSTAT:
|
||||||
urudev->last_hwstat = urudev->last_reg_rd[0];
|
urudev->last_hwstat = urudev->last_reg_rd[0];
|
||||||
@@ -911,16 +895,16 @@ static void rebootpwr_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case REBOOTPWR_PAUSE:
|
case REBOOTPWR_PAUSE:
|
||||||
if (fpi_timeout_add(10, rebootpwr_pause_cb, _dev, ssm) == NULL)
|
if (fpi_timeout_add(10, rebootpwr_pause_cb, ssm) == NULL)
|
||||||
fpi_ssm_mark_failed(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After messing with the device firmware in its low-power state, we have to
|
/* After messing with the device firmware in it's low-power state, we have to
|
||||||
* power it back up and wait for interrupt notification. It's not quite as easy
|
* power it back up and wait for interrupt notification. It's not quite as easy
|
||||||
* as that: the combination of both modifying firmware *and* doing C-R auth on
|
* as that: the combination of both modifying firmware *and* doing C-R auth on
|
||||||
* my ms fp v2 device causes us not to get the 56aa interrupt and
|
* my ms fp v2 device causes us not to get to get the 56aa interrupt and
|
||||||
* for the hwstat write not to take effect. We have to loop a few times,
|
* for the hwstat write not to take effect. We have to loop a few times,
|
||||||
* authenticating each time, until the device wakes up.
|
* authenticating each time, until the device wakes up.
|
||||||
*
|
*
|
||||||
@@ -953,16 +937,15 @@ enum powerup_states {
|
|||||||
POWERUP_NUM_STATES,
|
POWERUP_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void powerup_pause_cb(void *data)
|
||||||
powerup_pause_cb(struct fp_dev *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = data;
|
struct fpi_ssm *ssm = data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (!--urudev->powerup_ctr) {
|
if (!--urudev->powerup_ctr) {
|
||||||
fp_err("could not power device up");
|
fp_err("could not power device up");
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
} else if (!urudev->profile->auth_cr) {
|
} else if (!urudev->profile->auth_cr) {
|
||||||
fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT);
|
fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT);
|
||||||
} else {
|
} else {
|
||||||
@@ -970,10 +953,10 @@ powerup_pause_cb(struct fp_dev *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void powerup_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void powerup_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case POWERUP_INIT:
|
case POWERUP_INIT:
|
||||||
@@ -982,10 +965,10 @@ static void powerup_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case POWERUP_SET_HWSTAT:
|
case POWERUP_SET_HWSTAT:
|
||||||
sm_set_hwstat(ssm, dev, urudev->powerup_hwstat);
|
sm_set_hwstat(ssm, urudev->powerup_hwstat);
|
||||||
break;
|
break;
|
||||||
case POWERUP_GET_HWSTAT:
|
case POWERUP_GET_HWSTAT:
|
||||||
sm_read_reg(ssm, dev, REG_HWSTAT);
|
sm_read_reg(ssm, REG_HWSTAT);
|
||||||
break;
|
break;
|
||||||
case POWERUP_CHECK_HWSTAT:
|
case POWERUP_CHECK_HWSTAT:
|
||||||
urudev->last_hwstat = urudev->last_reg_rd[0];
|
urudev->last_hwstat = urudev->last_reg_rd[0];
|
||||||
@@ -995,11 +978,11 @@ static void powerup_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case POWERUP_PAUSE:
|
case POWERUP_PAUSE:
|
||||||
if (fpi_timeout_add(10, powerup_pause_cb, _dev, ssm) == NULL)
|
if (fpi_timeout_add(10, powerup_pause_cb, ssm) == NULL)
|
||||||
fpi_ssm_mark_failed(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
break;
|
break;
|
||||||
case POWERUP_CHALLENGE_RESPONSE:
|
case POWERUP_CHALLENGE_RESPONSE:
|
||||||
sm_do_challenge_response(ssm, dev);
|
sm_do_challenge_response(ssm);
|
||||||
break;
|
break;
|
||||||
case POWERUP_CHALLENGE_RESPONSE_SUCCESS:
|
case POWERUP_CHALLENGE_RESPONSE_SUCCESS:
|
||||||
fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT);
|
fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT);
|
||||||
@@ -1041,11 +1024,11 @@ enum init_states {
|
|||||||
static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status,
|
static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status,
|
||||||
uint16_t type, void *user_data)
|
uint16_t type, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
fpi_ssm_mark_failed(ssm, status);
|
fpi_ssm_mark_aborted(ssm, status);
|
||||||
else if (type != IRQDATA_SCANPWR_ON)
|
else if (type != IRQDATA_SCANPWR_ON)
|
||||||
fp_dbg("ignoring interrupt");
|
fp_dbg("ignoring interrupt");
|
||||||
else if (fpi_ssm_get_cur_state(ssm) != INIT_AWAIT_SCAN_POWER) {
|
else if (fpi_ssm_get_cur_state(ssm) != INIT_AWAIT_SCAN_POWER) {
|
||||||
@@ -1057,12 +1040,11 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void init_scanpwr_timeout(void *user_data)
|
||||||
init_scanpwr_timeout(struct fp_dev *dev,
|
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(dev);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
fp_warn("powerup timed out");
|
fp_warn("powerup timed out");
|
||||||
urudev->irq_cb = NULL;
|
urudev->irq_cb = NULL;
|
||||||
@@ -1070,20 +1052,20 @@ init_scanpwr_timeout(struct fp_dev *dev,
|
|||||||
|
|
||||||
if (++urudev->scanpwr_irq_timeouts >= 3) {
|
if (++urudev->scanpwr_irq_timeouts >= 3) {
|
||||||
fp_err("powerup timed out 3 times, giving up");
|
fp_err("powerup timed out 3 times, giving up");
|
||||||
fpi_ssm_mark_failed(ssm, -ETIMEDOUT);
|
fpi_ssm_mark_aborted(ssm, -ETIMEDOUT);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_jump_to_state(ssm, INIT_GET_HWSTAT);
|
fpi_ssm_jump_to_state(ssm, INIT_GET_HWSTAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void init_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(_dev);
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case INIT_GET_HWSTAT:
|
case INIT_GET_HWSTAT:
|
||||||
sm_read_reg(ssm, dev, REG_HWSTAT);
|
sm_read_reg(ssm, REG_HWSTAT);
|
||||||
break;
|
break;
|
||||||
case INIT_CHECK_HWSTAT_REBOOT:
|
case INIT_CHECK_HWSTAT_REBOOT:
|
||||||
urudev->last_hwstat = urudev->last_reg_rd[0];
|
urudev->last_hwstat = urudev->last_reg_rd[0];
|
||||||
@@ -1093,26 +1075,28 @@ static void init_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
fpi_ssm_jump_to_state(ssm, INIT_CHECK_HWSTAT_POWERDOWN);
|
fpi_ssm_jump_to_state(ssm, INIT_CHECK_HWSTAT_POWERDOWN);
|
||||||
break;
|
break;
|
||||||
case INIT_REBOOT_POWER: ;
|
case INIT_REBOOT_POWER: ;
|
||||||
fpi_ssm *rebootsm = fpi_ssm_new(FP_DEV(dev), rebootpwr_run_state,
|
struct fpi_ssm *rebootsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), rebootpwr_run_state,
|
||||||
REBOOTPWR_NUM_STATES, dev);
|
REBOOTPWR_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(rebootsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, rebootsm);
|
fpi_ssm_start_subsm(ssm, rebootsm);
|
||||||
break;
|
break;
|
||||||
case INIT_CHECK_HWSTAT_POWERDOWN:
|
case INIT_CHECK_HWSTAT_POWERDOWN:
|
||||||
if ((urudev->last_hwstat & 0x80) == 0)
|
if ((urudev->last_hwstat & 0x80) == 0)
|
||||||
sm_set_hwstat(ssm, dev, urudev->last_hwstat | 0x80);
|
sm_set_hwstat(ssm, urudev->last_hwstat | 0x80);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case INIT_POWERUP: ;
|
case INIT_POWERUP: ;
|
||||||
if (!IRQ_HANDLER_IS_RUNNING(urudev)) {
|
if (!IRQ_HANDLER_IS_RUNNING(urudev)) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
urudev->irq_cb_data = ssm;
|
urudev->irq_cb_data = ssm;
|
||||||
urudev->irq_cb = init_scanpwr_irq_cb;
|
urudev->irq_cb = init_scanpwr_irq_cb;
|
||||||
|
|
||||||
fpi_ssm *powerupsm = fpi_ssm_new(FP_DEV(dev), powerup_run_state,
|
struct fpi_ssm *powerupsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), powerup_run_state,
|
||||||
POWERUP_NUM_STATES, dev);
|
POWERUP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(powerupsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, powerupsm);
|
fpi_ssm_start_subsm(ssm, powerupsm);
|
||||||
break;
|
break;
|
||||||
case INIT_AWAIT_SCAN_POWER:
|
case INIT_AWAIT_SCAN_POWER:
|
||||||
@@ -1125,10 +1109,9 @@ static void init_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
* so we include this timeout loop to retry the whole process 3 times
|
* so we include this timeout loop to retry the whole process 3 times
|
||||||
* if we don't get an irq any time soon. */
|
* if we don't get an irq any time soon. */
|
||||||
urudev->scanpwr_irq_timeout = fpi_timeout_add(300,
|
urudev->scanpwr_irq_timeout = fpi_timeout_add(300,
|
||||||
init_scanpwr_timeout,
|
init_scanpwr_timeout, ssm);
|
||||||
_dev, ssm);
|
|
||||||
if (!urudev->scanpwr_irq_timeout) {
|
if (!urudev->scanpwr_irq_timeout) {
|
||||||
fpi_ssm_mark_failed(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1142,7 +1125,7 @@ static void init_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case INIT_GET_VERSION:
|
case INIT_GET_VERSION:
|
||||||
sm_read_regs(ssm, dev, REG_DEVICE_INFO, 16);
|
sm_read_regs(ssm, REG_DEVICE_INFO, 16);
|
||||||
break;
|
break;
|
||||||
case INIT_REPORT_VERSION:
|
case INIT_REPORT_VERSION:
|
||||||
/* Likely hardware revision, and firmware version.
|
/* Likely hardware revision, and firmware version.
|
||||||
@@ -1155,9 +1138,9 @@ static void init_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_initsm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
|
|
||||||
@@ -1176,8 +1159,8 @@ static void activate_initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *us
|
|||||||
* call. */
|
* call. */
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = start_irq_handler(dev);
|
r = start_irq_handler(dev);
|
||||||
@@ -1186,7 +1169,8 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
urudev->scanpwr_irq_timeouts = 0;
|
urudev->scanpwr_irq_timeouts = 0;
|
||||||
urudev->activate_state = state;
|
urudev->activate_state = state;
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), init_run_state, INIT_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), init_run_state, INIT_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, activate_initsm_complete);
|
fpi_ssm_start(ssm, activate_initsm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1211,9 +1195,8 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
|
|
||||||
static int execute_state_change(struct fp_img_dev *dev)
|
static int execute_state_change(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
void *img_data;
|
|
||||||
|
|
||||||
switch (urudev->activate_state) {
|
switch (urudev->activate_state) {
|
||||||
case IMGDEV_STATE_INACTIVE:
|
case IMGDEV_STATE_INACTIVE:
|
||||||
@@ -1236,18 +1219,12 @@ static int execute_state_change(struct fp_img_dev *dev)
|
|||||||
fp_dbg("starting capture");
|
fp_dbg("starting capture");
|
||||||
urudev->irq_cb = NULL;
|
urudev->irq_cb = NULL;
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), imaging_run_state, IMAGING_NUM_STATES, dev);
|
urudev->img_transfer = libusb_alloc_transfer(0);
|
||||||
img_data = g_malloc(sizeof(struct uru4k_image));
|
urudev->img_data = g_malloc(sizeof(struct uru4k_image));
|
||||||
urudev->img_enc_seed = rand();
|
urudev->img_enc_seed = rand();
|
||||||
urudev->img_transfer = fpi_usb_fill_bulk_transfer(FP_DEV(dev),
|
|
||||||
ssm,
|
|
||||||
EP_DATA,
|
|
||||||
img_data,
|
|
||||||
sizeof(struct uru4k_image),
|
|
||||||
image_transfer_cb,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), imaging_run_state, IMAGING_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, imaging_complete);
|
fpi_ssm_start(ssm, imaging_complete);
|
||||||
|
|
||||||
return write_reg(dev, REG_MODE, MODE_CAPTURE,
|
return write_reg(dev, REG_MODE, MODE_CAPTURE,
|
||||||
@@ -1280,7 +1257,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Find fingerprint interface */
|
/* Find fingerprint interface */
|
||||||
r = libusb_get_config_descriptor(libusb_get_device(fpi_dev_get_usb_dev(FP_DEV(dev))), 0, &config);
|
r = libusb_get_config_descriptor(libusb_get_device(fpi_imgdev_get_usb_dev(dev)), 0, &config);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("Failed to get config descriptor");
|
fp_err("Failed to get config descriptor");
|
||||||
return r;
|
return r;
|
||||||
@@ -1334,15 +1311,12 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
/* Device looks like a supported reader */
|
/* Device looks like a supported reader */
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), iface_desc->bInterfaceNumber);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), iface_desc->bInterfaceNumber);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fp_err("interface claim failed: %s", libusb_error_name(r));
|
fp_err("interface claim failed: %s", libusb_error_name(r));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable loading p11-kit's user configuration */
|
|
||||||
g_setenv ("P11_KIT_NO_USER_CONFIG", "1", TRUE);
|
|
||||||
|
|
||||||
/* Initialise NSS early */
|
/* Initialise NSS early */
|
||||||
rv = NSS_NoDB_Init(".");
|
rv = NSS_NoDB_Init(".");
|
||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
@@ -1351,8 +1325,6 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
urudev = g_malloc0(sizeof(*urudev));
|
urudev = g_malloc0(sizeof(*urudev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), urudev);
|
|
||||||
|
|
||||||
urudev->profile = &uru4k_dev_info[driver_data];
|
urudev->profile = &uru4k_dev_info[driver_data];
|
||||||
urudev->interface = iface_desc->bInterfaceNumber;
|
urudev->interface = iface_desc->bInterfaceNumber;
|
||||||
|
|
||||||
@@ -1379,6 +1351,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
}
|
}
|
||||||
urudev->param = PK11_ParamFromIV(urudev->cipher, NULL);
|
urudev->param = PK11_ParamFromIV(urudev->cipher, NULL);
|
||||||
|
|
||||||
|
fpi_imgdev_set_user_data(dev, urudev);
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1388,14 +1361,14 @@ out:
|
|||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev);
|
||||||
if (urudev->symkey)
|
if (urudev->symkey)
|
||||||
PK11_FreeSymKey (urudev->symkey);
|
PK11_FreeSymKey (urudev->symkey);
|
||||||
if (urudev->param)
|
if (urudev->param)
|
||||||
SECITEM_FreeItem(urudev->param, PR_TRUE);
|
SECITEM_FreeItem(urudev->param, PR_TRUE);
|
||||||
if (urudev->slot)
|
if (urudev->slot)
|
||||||
PK11_FreeSlot(urudev->slot);
|
PK11_FreeSlot(urudev->slot);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), urudev->interface);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), urudev->interface);
|
||||||
g_free(urudev);
|
g_free(urudev);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ enum v5s_cmd {
|
|||||||
|
|
||||||
static void sm_write_reg_cb(struct libusb_transfer *transfer)
|
static void sm_write_reg_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
||||||
@@ -85,35 +85,38 @@ static void sm_write_reg_cb(struct libusb_transfer *transfer)
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg,
|
||||||
sm_write_reg(fpi_ssm *ssm,
|
unsigned char value)
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned char reg,
|
|
||||||
unsigned char value)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("set %02x=%02x", reg, value);
|
fp_dbg("set %02x=%02x", reg, value);
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
|
||||||
libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0);
|
libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), data, sm_write_reg_cb,
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, sm_write_reg_cb,
|
||||||
ssm, CTRL_TIMEOUT);
|
ssm, CTRL_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm_exec_cmd_cb(struct libusb_transfer *transfer)
|
static void sm_exec_cmd_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
||||||
@@ -121,26 +124,29 @@ static void sm_exec_cmd_cb(struct libusb_transfer *transfer)
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd,
|
||||||
sm_exec_cmd(fpi_ssm *ssm,
|
unsigned char param)
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned char cmd,
|
|
||||||
unsigned char param)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("cmd %02x param %02x", cmd, param);
|
fp_dbg("cmd %02x param %02x", cmd, param);
|
||||||
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
|
data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
|
||||||
libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0);
|
libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0);
|
||||||
libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), data, sm_exec_cmd_cb,
|
libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, sm_exec_cmd_cb,
|
||||||
ssm, CTRL_TIMEOUT);
|
ssm, CTRL_TIMEOUT);
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
g_free(data);
|
g_free(data);
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,16 +187,16 @@ static gboolean finger_is_present(unsigned char *data)
|
|||||||
|
|
||||||
/***** IMAGE ACQUISITION *****/
|
/***** IMAGE ACQUISITION *****/
|
||||||
|
|
||||||
static void capture_iterate(fpi_ssm *ssm, struct fp_img_dev *dev);
|
static void capture_iterate(struct fpi_ssm *ssm);
|
||||||
|
|
||||||
static void capture_cb(struct libusb_transfer *transfer)
|
static void capture_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,44 +211,47 @@ static void capture_cb(struct libusb_transfer *transfer)
|
|||||||
fpi_imgdev_image_captured(dev, img);
|
fpi_imgdev_image_captured(dev, img);
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
} else {
|
} else {
|
||||||
capture_iterate(ssm, dev);
|
capture_iterate(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void capture_iterate(struct fpi_ssm *ssm)
|
||||||
capture_iterate(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
int iteration = vdev->capture_iteration;
|
int iteration = vdev->capture_iteration;
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN,
|
if (!transfer) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN,
|
||||||
vdev->capture_img->data + (RQ_SIZE * iteration), RQ_SIZE,
|
vdev->capture_img->data + (RQ_SIZE * iteration), RQ_SIZE,
|
||||||
capture_cb, ssm, CTRL_TIMEOUT);
|
capture_cb, ssm, CTRL_TIMEOUT);
|
||||||
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK;
|
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK;
|
||||||
r = libusb_submit_transfer(transfer);
|
r = libusb_submit_transfer(transfer);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void sm_do_capture(struct fpi_ssm *ssm)
|
||||||
sm_do_capture(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
vdev->capture_img = fpi_img_new_for_imgdev(dev);
|
vdev->capture_img = fpi_img_new_for_imgdev(dev);
|
||||||
vdev->capture_iteration = 0;
|
vdev->capture_iteration = 0;
|
||||||
capture_iterate(ssm, dev);
|
capture_iterate(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** CAPTURE LOOP *****/
|
/***** CAPTURE LOOP *****/
|
||||||
@@ -256,27 +265,27 @@ enum loop_states {
|
|||||||
LOOP_NUM_STATES,
|
LOOP_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void loop_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void loop_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(_dev);
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case LOOP_SET_CONTRAST:
|
case LOOP_SET_CONTRAST:
|
||||||
sm_write_reg(ssm, dev, REG_CONTRAST, 0x01);
|
sm_write_reg(ssm, REG_CONTRAST, 0x01);
|
||||||
break;
|
break;
|
||||||
case LOOP_SET_GAIN:
|
case LOOP_SET_GAIN:
|
||||||
sm_write_reg(ssm, dev, REG_GAIN, 0x29);
|
sm_write_reg(ssm, REG_GAIN, 0x29);
|
||||||
break;
|
break;
|
||||||
case LOOP_CMD_SCAN:
|
case LOOP_CMD_SCAN:
|
||||||
if (vdev->deactivating) {
|
if (vdev->deactivating) {
|
||||||
fp_dbg("deactivating, marking completed");
|
fp_dbg("deactivating, marking completed");
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else
|
} else
|
||||||
sm_exec_cmd(ssm, dev, CMD_SCAN, 0x00);
|
sm_exec_cmd(ssm, CMD_SCAN, 0x00);
|
||||||
break;
|
break;
|
||||||
case LOOP_CAPTURE:
|
case LOOP_CAPTURE:
|
||||||
sm_do_capture(ssm, dev);
|
sm_do_capture(ssm);
|
||||||
break;
|
break;
|
||||||
case LOOP_CAPTURE_DONE:
|
case LOOP_CAPTURE_DONE:
|
||||||
fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
|
fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
|
||||||
@@ -284,10 +293,10 @@ static void loop_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void loopsm_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(_dev);
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -304,9 +313,10 @@ static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), loop_run_state,
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), loop_run_state,
|
||||||
LOOP_NUM_STATES, dev);
|
LOOP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
vdev->deactivating = FALSE;
|
vdev->deactivating = FALSE;
|
||||||
fpi_ssm_start(ssm, loopsm_complete);
|
fpi_ssm_start(ssm, loopsm_complete);
|
||||||
vdev->loop_running = TRUE;
|
vdev->loop_running = TRUE;
|
||||||
@@ -316,7 +326,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
if (vdev->loop_running)
|
if (vdev->loop_running)
|
||||||
vdev->deactivating = TRUE;
|
vdev->deactivating = TRUE;
|
||||||
else
|
else
|
||||||
@@ -329,9 +339,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
struct v5s_dev *v5s_dev;
|
struct v5s_dev *v5s_dev;
|
||||||
|
|
||||||
v5s_dev = g_malloc0(sizeof(struct v5s_dev));
|
v5s_dev = g_malloc0(sizeof(struct v5s_dev));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), v5s_dev);
|
fpi_imgdev_set_user_data(dev, v5s_dev);
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
|
|
||||||
@@ -344,9 +354,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
static void dev_deinit(struct fp_img_dev *dev)
|
static void dev_deinit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct v5s_dev *v5s_dev;
|
struct v5s_dev *v5s_dev;
|
||||||
v5s_dev = FP_INSTANCE_DATA(FP_DEV(dev));
|
v5s_dev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(v5s_dev);
|
g_free(v5s_dev);
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
/* Callback for async_write */
|
/* Callback for async_write */
|
||||||
static void async_write_callback(struct libusb_transfer *transfer)
|
static void async_write_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
int transferred = transfer->actual_length, error =
|
int transferred = transfer->actual_length, error =
|
||||||
@@ -36,14 +36,14 @@ static void async_write_callback(struct libusb_transfer *transfer)
|
|||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
fp_err("USB write transfer: %s", libusb_error_name(error));
|
fp_err("USB write transfer: %s", libusb_error_name(error));
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transferred != len) {
|
if (transferred != len) {
|
||||||
fp_err("Written only %d of %d bytes", transferred, len);
|
fp_err("Written only %d of %d bytes", transferred, len);
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,16 +51,13 @@ static void async_write_callback(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send data to EP1, the only out endpoint */
|
/* Send data to EP1, the only out endpoint */
|
||||||
static void
|
static void async_write(struct fpi_ssm *ssm, void *data, int len)
|
||||||
async_write(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
void *data,
|
|
||||||
int len)
|
|
||||||
{
|
{
|
||||||
struct libusb_device_handle *usb_dev = fpi_dev_get_usb_dev(FP_DEV(dev));
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev);
|
||||||
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x01, data, len,
|
libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x01, data, len,
|
||||||
async_write_callback, ssm, VFS_USB_TIMEOUT);
|
async_write_callback, ssm, VFS_USB_TIMEOUT);
|
||||||
@@ -70,7 +67,7 @@ async_write(fpi_ssm *ssm,
|
|||||||
/* Callback for async_read */
|
/* Callback for async_read */
|
||||||
static void async_read_callback(struct libusb_transfer *transfer)
|
static void async_read_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
int transferred = transfer->actual_length, error =
|
int transferred = transfer->actual_length, error =
|
||||||
@@ -81,14 +78,14 @@ static void async_read_callback(struct libusb_transfer *transfer)
|
|||||||
fp_err("USB read transfer on endpoint %d: %s", ep - 0x80,
|
fp_err("USB read transfer on endpoint %d: %s", ep - 0x80,
|
||||||
libusb_error_name(error));
|
libusb_error_name(error));
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transferred != len) {
|
if (transferred != len) {
|
||||||
fp_err("Received %d instead of %d bytes", transferred, len);
|
fp_err("Received %d instead of %d bytes", transferred, len);
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,20 +93,15 @@ static void async_read_callback(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Receive data from the given ep and compare with expected */
|
/* Receive data from the given ep and compare with expected */
|
||||||
static void
|
static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len)
|
||||||
async_read(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
int ep,
|
|
||||||
void *data,
|
|
||||||
int len)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct libusb_device_handle *usb_dev = fpi_dev_get_usb_dev(FP_DEV(idev));
|
struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
ep |= LIBUSB_ENDPOINT_IN;
|
ep |= LIBUSB_ENDPOINT_IN;
|
||||||
|
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
|
|
||||||
/* 0x83 is the only interrupt endpoint */
|
/* 0x83 is the only interrupt endpoint */
|
||||||
@@ -127,7 +119,7 @@ async_read(fpi_ssm *ssm,
|
|||||||
/* Callback for async_read */
|
/* Callback for async_read */
|
||||||
static void async_abort_callback(struct libusb_transfer *transfer)
|
static void async_abort_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
int transferred = transfer->actual_length, error = transfer->status;
|
int transferred = transfer->actual_length, error = transfer->status;
|
||||||
@@ -142,7 +134,7 @@ static void async_abort_callback(struct libusb_transfer *transfer)
|
|||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
fp_err("USB write transfer: %s", libusb_error_name(error));
|
fp_err("USB write transfer: %s", libusb_error_name(error));
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,18 +147,18 @@ static void async_abort_callback(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Receive data from the given ep and compare with expected */
|
/* Receive data from the given ep and compare with expected */
|
||||||
static void async_abort(fpi_ssm *ssm, int ep)
|
static void async_abort(struct fpi_ssm *ssm, int ep)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct libusb_device_handle *usb_dev = fpi_dev_get_usb_dev(FP_DEV(idev));
|
struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
int len = VFS_USB_BUFFER_SIZE;
|
int len = VFS_USB_BUFFER_SIZE;
|
||||||
unsigned char *data = g_malloc(VFS_USB_BUFFER_SIZE);
|
unsigned char *data = g_malloc(VFS_USB_BUFFER_SIZE);
|
||||||
|
|
||||||
ep |= LIBUSB_ENDPOINT_IN;
|
ep |= LIBUSB_ENDPOINT_IN;
|
||||||
|
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
vdev->transfer->flags |=
|
vdev->transfer->flags |=
|
||||||
LIBUSB_TRANSFER_FREE_TRANSFER | LIBUSB_TRANSFER_FREE_BUFFER;
|
LIBUSB_TRANSFER_FREE_TRANSFER | LIBUSB_TRANSFER_FREE_BUFFER;
|
||||||
|
|
||||||
@@ -267,7 +259,7 @@ static struct fp_img *prepare_image(struct vfs_dev_t *vdev)
|
|||||||
/* Processes and submits image after fingerprint received */
|
/* Processes and submits image after fingerprint received */
|
||||||
static void submit_image(struct fp_img_dev *idev)
|
static void submit_image(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
/* We were not asked to submit image actually */
|
/* We were not asked to submit image actually */
|
||||||
if (!vdev->active)
|
if (!vdev->active)
|
||||||
@@ -287,21 +279,20 @@ static void submit_image(struct fp_img_dev *idev)
|
|||||||
/* Proto functions */
|
/* Proto functions */
|
||||||
|
|
||||||
/* SSM loop for clear_ep2 */
|
/* SSM loop for clear_ep2 */
|
||||||
static void
|
static void clear_ep2_ssm(struct fpi_ssm *ssm)
|
||||||
clear_ep2_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
|
||||||
short result;
|
short result;
|
||||||
char command04 = 0x04;
|
char command04 = 0x04;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case SUBSM1_COMMAND_04:
|
case SUBSM1_COMMAND_04:
|
||||||
async_write(ssm, idev, &command04, sizeof(command04));
|
async_write(ssm, &command04, sizeof(command04));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM1_RETURN_CODE:
|
case SUBSM1_RETURN_CODE:
|
||||||
async_read(ssm, idev, 1, &result, sizeof(result));
|
async_read(ssm, 1, &result, sizeof(result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM1_ABORT_2:
|
case SUBSM1_ABORT_2:
|
||||||
@@ -311,35 +302,36 @@ clear_ep2_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
default:
|
default:
|
||||||
fp_err("Unknown SUBSM1 state");
|
fp_err("Unknown SUBSM1 state");
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send command to clear EP2 */
|
/* Send command to clear EP2 */
|
||||||
static void
|
static void clear_ep2(struct fpi_ssm *ssm)
|
||||||
clear_ep2(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *idev)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *subsm =
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
fpi_ssm_new(FP_DEV(idev), clear_ep2_ssm, SUBSM1_STATES, idev);
|
|
||||||
|
struct fpi_ssm *subsm =
|
||||||
|
fpi_ssm_new(fpi_imgdev_get_dev(idev), clear_ep2_ssm, SUBSM1_STATES);
|
||||||
|
fpi_ssm_set_user_data(subsm, idev);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
fpi_ssm_start_subsm(ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_control_packet_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void send_control_packet_ssm(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(_dev);
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
short result;
|
short result;
|
||||||
unsigned char *commit_result = NULL;
|
unsigned char *commit_result = NULL;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case SUBSM2_SEND_CONTROL:
|
case SUBSM2_SEND_CONTROL:
|
||||||
async_write(ssm, idev, vdev->control_packet, VFS_CONTROL_PACKET_SIZE);
|
async_write(ssm, vdev->control_packet, VFS_CONTROL_PACKET_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_RETURN_CODE:
|
case SUBSM2_RETURN_CODE:
|
||||||
async_read(ssm, idev, 1, &result, sizeof(result));
|
async_read(ssm, 1, &result, sizeof(result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_SEND_COMMIT:
|
case SUBSM2_SEND_COMMIT:
|
||||||
@@ -350,19 +342,19 @@ static void send_control_packet_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *use
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* commit_out in Windows differs in each commit, but I send the same each time */
|
/* commit_out in Windows differs in each commit, but I send the same each time */
|
||||||
async_write(ssm, idev, commit_out, sizeof(commit_out));
|
async_write(ssm, commit_out, sizeof(commit_out));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_COMMIT_RESPONSE:
|
case SUBSM2_COMMIT_RESPONSE:
|
||||||
commit_result = g_malloc(VFS_COMMIT_RESPONSE_SIZE);
|
commit_result = g_malloc(VFS_COMMIT_RESPONSE_SIZE);
|
||||||
async_read(ssm, idev, 1, commit_result, VFS_COMMIT_RESPONSE_SIZE);
|
async_read(ssm, 1, commit_result, VFS_COMMIT_RESPONSE_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_READ_EMPTY_INTERRUPT:
|
case SUBSM2_READ_EMPTY_INTERRUPT:
|
||||||
/* I don't know how to check result, it could be different */
|
/* I don't know how to check result, it could be different */
|
||||||
g_free(commit_result);
|
g_free(commit_result);
|
||||||
|
|
||||||
async_read(ssm, idev, 3, vdev->interrupt, VFS_INTERRUPT_SIZE);
|
async_read(ssm, 3, vdev->interrupt, VFS_INTERRUPT_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_ABORT_3:
|
case SUBSM2_ABORT_3:
|
||||||
@@ -371,7 +363,7 @@ static void send_control_packet_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *use
|
|||||||
(vdev->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE)) {
|
(vdev->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE)) {
|
||||||
fp_err("Unknown SUBSM2 state");
|
fp_err("Unknown SUBSM2 state");
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
async_abort(ssm, 3);
|
async_abort(ssm, 3);
|
||||||
@@ -380,7 +372,7 @@ static void send_control_packet_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *use
|
|||||||
case SUBSM2_CLEAR_EP2:
|
case SUBSM2_CLEAR_EP2:
|
||||||
/* After turn_on Windows doesn't clear EP2 */
|
/* After turn_on Windows doesn't clear EP2 */
|
||||||
if (vdev->control_packet != turn_on)
|
if (vdev->control_packet != turn_on)
|
||||||
clear_ep2(ssm, idev);
|
clear_ep2(ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
@@ -388,17 +380,18 @@ static void send_control_packet_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *use
|
|||||||
default:
|
default:
|
||||||
fp_err("Unknown SUBSM2 state");
|
fp_err("Unknown SUBSM2 state");
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send device state control packet */
|
/* Send device state control packet */
|
||||||
static void
|
static void send_control_packet(struct fpi_ssm *ssm)
|
||||||
send_control_packet(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *idev)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *subsm =
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
fpi_ssm_new(FP_DEV(idev), send_control_packet_ssm, SUBSM2_STATES, idev);
|
|
||||||
|
struct fpi_ssm *subsm =
|
||||||
|
fpi_ssm_new(fpi_imgdev_get_dev(idev), send_control_packet_ssm, SUBSM2_STATES);
|
||||||
|
fpi_ssm_set_user_data(subsm, idev);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
fpi_ssm_start_subsm(ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,9 +406,9 @@ static void clear_data(struct vfs_dev_t *vdev)
|
|||||||
/* After receiving interrupt from EP3 */
|
/* After receiving interrupt from EP3 */
|
||||||
static void interrupt_callback(struct libusb_transfer *transfer)
|
static void interrupt_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
char *interrupt = vdev->interrupt;
|
char *interrupt = vdev->interrupt;
|
||||||
int error = transfer->status, transferred = transfer->actual_length;
|
int error = transfer->status, transferred = transfer->actual_length;
|
||||||
@@ -430,7 +423,7 @@ static void interrupt_callback(struct libusb_transfer *transfer)
|
|||||||
fp_err("USB read interrupt transfer: %s",
|
fp_err("USB read interrupt transfer: %s",
|
||||||
libusb_error_name(error));
|
libusb_error_name(error));
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +432,7 @@ static void interrupt_callback(struct libusb_transfer *transfer)
|
|||||||
fp_err("Unknown interrupt size %d", transferred);
|
fp_err("Unknown interrupt size %d", transferred);
|
||||||
/* Abort ssm */
|
/* Abort ssm */
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,14 +461,14 @@ static void interrupt_callback(struct libusb_transfer *transfer)
|
|||||||
|
|
||||||
/* Abort ssm */
|
/* Abort ssm */
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_callback(struct libusb_transfer *transfer)
|
static void receive_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
int transferred = transfer->actual_length, error = transfer->status;
|
int transferred = transfer->actual_length, error = transfer->status;
|
||||||
|
|
||||||
@@ -483,7 +476,7 @@ static void receive_callback(struct libusb_transfer *transfer)
|
|||||||
fp_err("USB read transfer: %s", libusb_error_name(error));
|
fp_err("USB read transfer: %s", libusb_error_name(error));
|
||||||
|
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,12 +492,11 @@ static void receive_callback(struct libusb_transfer *transfer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Stub to keep SSM alive when waiting an interrupt */
|
/* Stub to keep SSM alive when waiting an interrupt */
|
||||||
static void
|
static void wait_interrupt(void *data)
|
||||||
wait_interrupt(struct fp_dev *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = data;
|
struct fpi_ssm *ssm = data;
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(dev);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
/* Keep sleeping while this flag is on */
|
/* Keep sleeping while this flag is on */
|
||||||
if (vdev->wait_interrupt)
|
if (vdev->wait_interrupt)
|
||||||
@@ -512,20 +504,25 @@ wait_interrupt(struct fp_dev *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SSM stub to prepare device to another scan after orange light was on */
|
/* SSM stub to prepare device to another scan after orange light was on */
|
||||||
static void
|
static void another_scan(void *data)
|
||||||
another_scan(struct fp_dev *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = data;
|
struct fpi_ssm *ssm = data;
|
||||||
fpi_ssm_jump_to_state(ssm, SSM_TURN_ON);
|
fpi_ssm_jump_to_state(ssm, SSM_TURN_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main SSM loop */
|
/* Another SSM stub to continue after waiting for probable vdev->active changes */
|
||||||
static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void scan_completed(void *data)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *idev = user_data;
|
struct fpi_ssm *ssm = data;
|
||||||
struct libusb_device_handle *usb_dev = fpi_dev_get_usb_dev(FP_DEV(idev));
|
fpi_ssm_next_state(ssm);
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(_dev);
|
}
|
||||||
|
|
||||||
|
/* Main SSM loop */
|
||||||
|
static void activate_ssm(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev);
|
||||||
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case SSM_INITIAL_ABORT_1:
|
case SSM_INITIAL_ABORT_1:
|
||||||
@@ -541,14 +538,14 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_CLEAR_EP2:
|
case SSM_CLEAR_EP2:
|
||||||
clear_ep2(ssm, idev);
|
clear_ep2(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_TURN_OFF:
|
case SSM_TURN_OFF:
|
||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
vdev->control_packet = turn_off;
|
vdev->control_packet = turn_off;
|
||||||
|
|
||||||
send_control_packet(ssm, idev);
|
send_control_packet(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_TURN_ON:
|
case SSM_TURN_ON:
|
||||||
@@ -565,7 +562,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
vdev->control_packet = turn_on;
|
vdev->control_packet = turn_on;
|
||||||
|
|
||||||
send_control_packet(ssm, idev);
|
send_control_packet(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_ASK_INTERRUPT:
|
case SSM_ASK_INTERRUPT:
|
||||||
@@ -578,7 +575,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Asyncronously enquire an interrupt */
|
/* Asyncronously enquire an interrupt */
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, 0x83,
|
libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, 0x83,
|
||||||
vdev->interrupt,
|
vdev->interrupt,
|
||||||
@@ -604,7 +601,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vdev->wait_interrupt)
|
if (vdev->wait_interrupt)
|
||||||
fpi_timeout_add(VFS_SSM_TIMEOUT, wait_interrupt, _dev, ssm);
|
fpi_timeout_add(VFS_SSM_TIMEOUT, wait_interrupt, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_RECEIVE_FINGER:
|
case SSM_RECEIVE_FINGER:
|
||||||
@@ -628,7 +625,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Receive chunk of data */
|
/* Receive chunk of data */
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x82,
|
libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x82,
|
||||||
(void *)vdev->lines_buffer +
|
(void *)vdev->lines_buffer +
|
||||||
@@ -643,7 +640,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
clear_data(vdev);
|
clear_data(vdev);
|
||||||
|
|
||||||
/* Wait for probable vdev->active changing */
|
/* Wait for probable vdev->active changing */
|
||||||
fpi_timeout_add(VFS_SSM_TIMEOUT, fpi_ssm_next_state_timeout_cb, _dev, ssm);
|
fpi_timeout_add(VFS_SSM_TIMEOUT, scan_completed, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_NEXT_RECEIVE:
|
case SSM_NEXT_RECEIVE:
|
||||||
@@ -656,27 +653,28 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
vdev->control_packet = next_receive_1;
|
vdev->control_packet = next_receive_1;
|
||||||
|
|
||||||
send_control_packet(ssm, idev);
|
send_control_packet(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_WAIT_ANOTHER_SCAN:
|
case SSM_WAIT_ANOTHER_SCAN:
|
||||||
/* Orange light is on now */
|
/* Orange light is on now */
|
||||||
fpi_timeout_add(VFS_SSM_ORANGE_TIMEOUT, another_scan, _dev, ssm);
|
fpi_timeout_add(VFS_SSM_ORANGE_TIMEOUT, another_scan, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Unknown state");
|
fp_err("Unknown state");
|
||||||
fpi_imgdev_session_error(idev, -EIO);
|
fpi_imgdev_session_error(idev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Driver functions */
|
/* Driver functions */
|
||||||
|
|
||||||
/* Callback for dev_activate ssm */
|
/* Callback for dev_activate ssm */
|
||||||
static void dev_activate_callback(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void dev_activate_callback(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(_dev);
|
struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
vdev->ssm_active = 0;
|
vdev->ssm_active = 0;
|
||||||
|
|
||||||
@@ -686,14 +684,15 @@ static void dev_activate_callback(fpi_ssm *ssm, struct fp_dev *_dev, void *user_
|
|||||||
/* Activate device */
|
/* Activate device */
|
||||||
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
/* Initialize flags */
|
/* Initialize flags */
|
||||||
vdev->active = 1;
|
vdev->active = 1;
|
||||||
vdev->need_report = 1;
|
vdev->need_report = 1;
|
||||||
vdev->ssm_active = 1;
|
vdev->ssm_active = 1;
|
||||||
|
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(idev), activate_ssm, SSM_STATES, idev);
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), activate_ssm, SSM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, idev);
|
||||||
fpi_ssm_start(ssm, dev_activate_callback);
|
fpi_ssm_start(ssm, dev_activate_callback);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -701,7 +700,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
|||||||
/* Deactivate device */
|
/* Deactivate device */
|
||||||
static void dev_deactivate(struct fp_img_dev *idev)
|
static void dev_deactivate(struct fp_img_dev *idev)
|
||||||
{
|
{
|
||||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev);
|
||||||
|
|
||||||
if (!vdev->ssm_active) {
|
if (!vdev->ssm_active) {
|
||||||
fpi_imgdev_deactivate_complete(idev);
|
fpi_imgdev_deactivate_complete(idev);
|
||||||
@@ -714,10 +713,10 @@ static void dev_deactivate(struct fp_img_dev *idev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for dev_open ssm */
|
/* Callback for dev_open ssm */
|
||||||
static void dev_open_callback(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void dev_open_callback(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
/* Notify open complete */
|
/* Notify open complete */
|
||||||
fpi_imgdev_open_complete(user_data, 0);
|
fpi_imgdev_open_complete(fpi_ssm_get_user_data(ssm), 0);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,7 +726,7 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
|||||||
struct vfs_dev_t *vdev;
|
struct vfs_dev_t *vdev;
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
int error = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(idev)), 0);
|
int error = libusb_claim_interface(fpi_imgdev_get_usb_dev(idev), 0);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
/* Interface not claimed, return error */
|
/* Interface not claimed, return error */
|
||||||
fp_err("could not claim interface 0");
|
fp_err("could not claim interface 0");
|
||||||
@@ -736,10 +735,11 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
|
|||||||
|
|
||||||
/* Initialize private structure */
|
/* Initialize private structure */
|
||||||
vdev = g_malloc0(sizeof(struct vfs_dev_t));
|
vdev = g_malloc0(sizeof(struct vfs_dev_t));
|
||||||
fp_dev_set_instance_data(FP_DEV(idev), vdev);
|
fpi_imgdev_set_user_data(idev, vdev);
|
||||||
|
|
||||||
/* Clearing previous device state */
|
/* Clearing previous device state */
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(idev), activate_ssm, SSM_STATES, idev);
|
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), activate_ssm, SSM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, idev);
|
||||||
fpi_ssm_start(ssm, dev_open_callback);
|
fpi_ssm_start(ssm, dev_open_callback);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -750,11 +750,11 @@ static void dev_close(struct fp_img_dev *idev)
|
|||||||
struct vfs_dev_t *vdev;
|
struct vfs_dev_t *vdev;
|
||||||
|
|
||||||
/* Release private structure */
|
/* Release private structure */
|
||||||
vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
vdev = fpi_imgdev_get_user_data(idev);
|
||||||
g_free(vdev);
|
g_free(vdev);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(idev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(idev), 0);
|
||||||
|
|
||||||
/* Notify close complete */
|
/* Notify close complete */
|
||||||
fpi_imgdev_close_complete(idev);
|
fpi_imgdev_close_complete(idev);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
#define VFS_IMG_MIN_IMAGE_LEVEL 144
|
#define VFS_IMG_MIN_IMAGE_LEVEL 144
|
||||||
|
|
||||||
/* Best image contrast */
|
/* Best image contrast */
|
||||||
#define VFS_IMG_BEST_CONTRAST 128
|
#define VFS_IMG_BEST_CONRAST 128
|
||||||
|
|
||||||
/* Device parameters address */
|
/* Device parameters address */
|
||||||
#define VFS_PAR_000E 0x000e
|
#define VFS_PAR_000E 0x000e
|
||||||
@@ -105,6 +105,9 @@ struct vfs101_dev
|
|||||||
/* Ignore usb error */
|
/* Ignore usb error */
|
||||||
int ignore_error;
|
int ignore_error;
|
||||||
|
|
||||||
|
/* Timeout */
|
||||||
|
struct fpi_timeout *timeout;
|
||||||
|
|
||||||
/* Loop counter */
|
/* Loop counter */
|
||||||
int counter;
|
int counter;
|
||||||
|
|
||||||
@@ -196,9 +199,9 @@ static int result_code(struct fp_img_dev *dev, int result)
|
|||||||
/* Callback of asynchronous send */
|
/* Callback of asynchronous send */
|
||||||
static void async_send_cb(struct libusb_transfer *transfer)
|
static void async_send_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Cleanup transfer */
|
/* Cleanup transfer */
|
||||||
vdev->transfer = NULL;
|
vdev->transfer = NULL;
|
||||||
@@ -211,7 +214,7 @@ static void async_send_cb(struct libusb_transfer *transfer)
|
|||||||
/* Transfer not completed, return IO error */
|
/* Transfer not completed, return IO error */
|
||||||
fp_err("transfer not completed, status = %d", transfer->status);
|
fp_err("transfer not completed, status = %d", transfer->status);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +224,7 @@ static void async_send_cb(struct libusb_transfer *transfer)
|
|||||||
fp_err("length mismatch, got %d, expected %d",
|
fp_err("length mismatch, got %d, expected %d",
|
||||||
transfer->actual_length, transfer->length);
|
transfer->actual_length, transfer->length);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,15 +242,22 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Submit asynchronous send */
|
/* Submit asynchronous send */
|
||||||
static void
|
static void async_send(struct fpi_ssm *ssm)
|
||||||
async_send(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Allocation of transfer */
|
/* Allocation of transfer */
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!vdev->transfer)
|
||||||
|
{
|
||||||
|
/* Allocation transfer failed, return no memory error */
|
||||||
|
fp_err("allocation of usb transfer failed");
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Put sequential number into the buffer */
|
/* Put sequential number into the buffer */
|
||||||
vdev->seqnum++;
|
vdev->seqnum++;
|
||||||
@@ -255,7 +265,7 @@ async_send(fpi_ssm *ssm,
|
|||||||
vdev->buffer[1] = byte(1, vdev->seqnum);
|
vdev->buffer[1] = byte(1, vdev->seqnum);
|
||||||
|
|
||||||
/* Prepare bulk transfer */
|
/* Prepare bulk transfer */
|
||||||
libusb_fill_bulk_transfer(vdev->transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT(1), vdev->buffer, vdev->length, async_send_cb, ssm, BULK_TIMEOUT);
|
libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT(1), vdev->buffer, vdev->length, async_send_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
/* Submit transfer */
|
/* Submit transfer */
|
||||||
r = libusb_submit_transfer(vdev->transfer);
|
r = libusb_submit_transfer(vdev->transfer);
|
||||||
@@ -265,7 +275,7 @@ async_send(fpi_ssm *ssm,
|
|||||||
libusb_free_transfer(vdev->transfer);
|
libusb_free_transfer(vdev->transfer);
|
||||||
fp_err("submit of usb transfer failed");
|
fp_err("submit of usb transfer failed");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,9 +283,9 @@ async_send(fpi_ssm *ssm,
|
|||||||
/* Callback of asynchronous recv */
|
/* Callback of asynchronous recv */
|
||||||
static void async_recv_cb(struct libusb_transfer *transfer)
|
static void async_recv_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Cleanup transfer */
|
/* Cleanup transfer */
|
||||||
vdev->transfer = NULL;
|
vdev->transfer = NULL;
|
||||||
@@ -288,7 +298,7 @@ static void async_recv_cb(struct libusb_transfer *transfer)
|
|||||||
/* Transfer not completed, return IO error */
|
/* Transfer not completed, return IO error */
|
||||||
fp_err("transfer not completed, status = %d", transfer->status);
|
fp_err("transfer not completed, status = %d", transfer->status);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +308,7 @@ static void async_recv_cb(struct libusb_transfer *transfer)
|
|||||||
fp_err("seqnum mismatch, got %04x, expected %04x",
|
fp_err("seqnum mismatch, got %04x, expected %04x",
|
||||||
get_seqnum(vdev->buffer[1], vdev->buffer[0]), vdev->seqnum);
|
get_seqnum(vdev->buffer[1], vdev->buffer[0]), vdev->seqnum);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,18 +329,25 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Submit asynchronous recv */
|
/* Submit asynchronous recv */
|
||||||
static void
|
static void async_recv(struct fpi_ssm *ssm)
|
||||||
async_recv(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Allocation of transfer */
|
/* Allocation of transfer */
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!vdev->transfer)
|
||||||
|
{
|
||||||
|
/* Allocation transfer failed, return no memory error */
|
||||||
|
fp_err("allocation of usb transfer failed");
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare bulk transfer */
|
/* Prepare bulk transfer */
|
||||||
libusb_fill_bulk_transfer(vdev->transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN(1), vdev->buffer, 0x0f, async_recv_cb, ssm, BULK_TIMEOUT);
|
libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_IN(1), vdev->buffer, 0x0f, async_recv_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
/* Submit transfer */
|
/* Submit transfer */
|
||||||
r = libusb_submit_transfer(vdev->transfer);
|
r = libusb_submit_transfer(vdev->transfer);
|
||||||
@@ -340,19 +357,19 @@ async_recv(fpi_ssm *ssm,
|
|||||||
libusb_free_transfer(vdev->transfer);
|
libusb_free_transfer(vdev->transfer);
|
||||||
fp_err("submit of usb transfer failed");
|
fp_err("submit of usb transfer failed");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void async_load(fpi_ssm *ssm, struct fp_img_dev *dev);
|
static void async_load(struct fpi_ssm *ssm);
|
||||||
|
|
||||||
/* Callback of asynchronous load */
|
/* Callback of asynchronous load */
|
||||||
static void async_load_cb(struct libusb_transfer *transfer)
|
static void async_load_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Cleanup transfer */
|
/* Cleanup transfer */
|
||||||
vdev->transfer = NULL;
|
vdev->transfer = NULL;
|
||||||
@@ -365,7 +382,7 @@ static void async_load_cb(struct libusb_transfer *transfer)
|
|||||||
/* Transfer not completed */
|
/* Transfer not completed */
|
||||||
fp_err("transfer not completed, status = %d, length = %d", transfer->status, vdev->length);
|
fp_err("transfer not completed, status = %d, length = %d", transfer->status, vdev->length);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +391,7 @@ static void async_load_cb(struct libusb_transfer *transfer)
|
|||||||
/* Received incomplete frame, return protocol error */
|
/* Received incomplete frame, return protocol error */
|
||||||
fp_err("received incomplete frame");
|
fp_err("received incomplete frame");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,12 +406,12 @@ static void async_load_cb(struct libusb_transfer *transfer)
|
|||||||
/* Buffer full, image too large, return no memory error */
|
/* Buffer full, image too large, return no memory error */
|
||||||
fp_err("buffer full, image too large");
|
fp_err("buffer full, image too large");
|
||||||
fpi_imgdev_session_error(dev, -ENOMEM);
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Image load not completed, submit another asynchronous load */
|
/* Image load not completed, submit another asynchronous load */
|
||||||
async_load(ssm, dev);
|
async_load(ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -413,22 +430,29 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Submit asynchronous load */
|
/* Submit asynchronous load */
|
||||||
static void
|
static void async_load(struct fpi_ssm *ssm)
|
||||||
async_load(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Allocation of transfer */
|
/* Allocation of transfer */
|
||||||
vdev->transfer = fpi_usb_alloc();
|
vdev->transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!vdev->transfer)
|
||||||
|
{
|
||||||
|
/* Allocation transfer failed, return no memory error */
|
||||||
|
fp_err("allocation of usb transfer failed");
|
||||||
|
fpi_imgdev_session_error(dev, -ENOMEM);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Append new data into the buffer */
|
/* Append new data into the buffer */
|
||||||
buffer = vdev->buffer + vdev->length;
|
buffer = vdev->buffer + vdev->length;
|
||||||
|
|
||||||
/* Prepare bulk transfer */
|
/* Prepare bulk transfer */
|
||||||
libusb_fill_bulk_transfer(vdev->transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN(2), buffer, VFS_BLOCK_SIZE, async_load_cb, ssm, BULK_TIMEOUT);
|
libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_IN(2), buffer, VFS_BLOCK_SIZE, async_load_cb, ssm, BULK_TIMEOUT);
|
||||||
|
|
||||||
/* Submit transfer */
|
/* Submit transfer */
|
||||||
r = libusb_submit_transfer(vdev->transfer);
|
r = libusb_submit_transfer(vdev->transfer);
|
||||||
@@ -438,23 +462,39 @@ async_load(fpi_ssm *ssm,
|
|||||||
libusb_free_transfer(vdev->transfer);
|
libusb_free_transfer(vdev->transfer);
|
||||||
fp_err("submit of usb transfer failed");
|
fp_err("submit of usb transfer failed");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Submit asynchronous sleep */
|
/* Callback of asynchronous sleep */
|
||||||
static void
|
static void async_sleep_cb(void *data)
|
||||||
async_sleep(unsigned int msec,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
if (fpi_timeout_add(msec, fpi_ssm_next_state_timeout_cb, FP_DEV(dev), ssm) == NULL)
|
struct fpi_ssm *ssm = data;
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
|
/* Cleanup timeout */
|
||||||
|
vdev->timeout = NULL;
|
||||||
|
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Submit asynchronous sleep */
|
||||||
|
static void async_sleep(unsigned int msec, struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
|
/* Add timeout */
|
||||||
|
vdev->timeout = fpi_timeout_add(msec, async_sleep_cb, ssm);
|
||||||
|
|
||||||
|
if (vdev->timeout == NULL)
|
||||||
{
|
{
|
||||||
/* Failed to add timeout */
|
/* Failed to add timeout */
|
||||||
fp_err("failed to add timeout");
|
fp_err("failed to add timeout");
|
||||||
fpi_imgdev_session_error(dev, -ETIME);
|
fpi_imgdev_session_error(dev, -ETIME);
|
||||||
fpi_ssm_mark_failed(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,31 +507,28 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Exec swap sequential state machine */
|
/* Exec swap sequential state machine */
|
||||||
static void m_swap_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_swap_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm))
|
switch (fpi_ssm_get_cur_state(ssm))
|
||||||
{
|
{
|
||||||
case M_SWAP_SEND:
|
case M_SWAP_SEND:
|
||||||
/* Send data */
|
/* Send data */
|
||||||
async_send(ssm, user_data);
|
async_send(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_SWAP_RECV:
|
case M_SWAP_RECV:
|
||||||
/* Recv response */
|
/* Recv response */
|
||||||
async_recv(ssm, user_data);
|
async_recv(ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start swap sequential state machine */
|
/* Start swap sequential state machine */
|
||||||
static void
|
static void m_swap(struct fpi_ssm *ssm, unsigned char *data, size_t length)
|
||||||
m_swap(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned char *data,
|
|
||||||
size_t length)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fpi_ssm *subsm;
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
struct fpi_ssm *subsm;
|
||||||
|
|
||||||
/* Prepare data for sending */
|
/* Prepare data for sending */
|
||||||
memcpy(vdev->buffer, data, length);
|
memcpy(vdev->buffer, data, length);
|
||||||
@@ -499,16 +536,13 @@ m_swap(fpi_ssm *ssm,
|
|||||||
vdev->length = length;
|
vdev->length = length;
|
||||||
|
|
||||||
/* Start swap ssm */
|
/* Start swap ssm */
|
||||||
subsm = fpi_ssm_new(FP_DEV(dev), m_swap_state, M_SWAP_NUM_STATES, dev);
|
subsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_swap_state, M_SWAP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(subsm, dev);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
fpi_ssm_start_subsm(ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve fingerprint image */
|
/* Retrieve fingerprint image */
|
||||||
static void
|
static void vfs_get_print(struct fpi_ssm *ssm, unsigned int param, int type)
|
||||||
vfs_get_print(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned int param,
|
|
||||||
int type)
|
|
||||||
{
|
{
|
||||||
unsigned char data[2][0x0e] = {
|
unsigned char data[2][0x0e] = {
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||||
@@ -524,15 +558,11 @@ vfs_get_print(fpi_ssm *ssm,
|
|||||||
data[type][7] = byte(1, param);
|
data[type][7] = byte(1, param);
|
||||||
|
|
||||||
/* Run swap sequential state machine */
|
/* Run swap sequential state machine */
|
||||||
m_swap(ssm, dev, data[type], 0x0e);
|
m_swap(ssm, data[type], 0x0e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a parameter value on the device */
|
/* Set a parameter value on the device */
|
||||||
static void
|
static void vfs_set_param(struct fpi_ssm *ssm, unsigned int param, unsigned int value)
|
||||||
vfs_set_param(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned int param,
|
|
||||||
unsigned int value)
|
|
||||||
{
|
{
|
||||||
unsigned char data[0x0a] = { 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
unsigned char data[0x0a] = { 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
@@ -545,29 +575,22 @@ vfs_set_param(fpi_ssm *ssm,
|
|||||||
data[9] = byte(1, value);
|
data[9] = byte(1, value);
|
||||||
|
|
||||||
/* Run swap sequential state machine */
|
/* Run swap sequential state machine */
|
||||||
m_swap(ssm, dev, data, 0x0a);
|
m_swap(ssm, data, 0x0a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Abort previous print */
|
/* Abort previous print */
|
||||||
static void
|
static void vfs_abort_print(struct fpi_ssm *ssm)
|
||||||
vfs_abort_print(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00 };
|
unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00 };
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
/* Run swap sequential state machine */
|
/* Run swap sequential state machine */
|
||||||
m_swap (ssm, dev, data, 0x06);
|
m_swap (ssm, data, 0x06);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Poke a value on a region */
|
/* Poke a value on a region */
|
||||||
static void
|
static void vfs_poke(struct fpi_ssm *ssm, unsigned int addr, unsigned int value, unsigned int size)
|
||||||
vfs_poke(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev,
|
|
||||||
unsigned int addr,
|
|
||||||
unsigned int value,
|
|
||||||
unsigned int size)
|
|
||||||
{
|
{
|
||||||
unsigned char data[0x0f] = { 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
unsigned char data[0x0f] = { 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
@@ -585,28 +608,25 @@ vfs_poke(fpi_ssm *ssm,
|
|||||||
data[14] = byte(0, size);
|
data[14] = byte(0, size);
|
||||||
|
|
||||||
/* Run swap sequential state machine */
|
/* Run swap sequential state machine */
|
||||||
m_swap(ssm, dev, data, 0x0f);
|
m_swap(ssm, data, 0x0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get current finger state */
|
/* Get current finger state */
|
||||||
static void
|
static void vfs_get_finger_state(struct fpi_ssm *ssm)
|
||||||
vfs_get_finger_state(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x16, 0x00 };
|
unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x16, 0x00 };
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
/* Run swap sequential state machine */
|
/* Run swap sequential state machine */
|
||||||
m_swap (ssm, dev, data, 0x06);
|
m_swap (ssm, data, 0x06);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load raw image from reader */
|
/* Load raw image from reader */
|
||||||
static void
|
static void vfs_img_load(struct fpi_ssm *ssm)
|
||||||
vfs_img_load(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
@@ -618,16 +638,16 @@ vfs_img_load(fpi_ssm *ssm,
|
|||||||
vdev->height = -1;
|
vdev->height = -1;
|
||||||
|
|
||||||
/* Asynchronous load */
|
/* Asynchronous load */
|
||||||
async_load(ssm, dev);
|
async_load(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if action is completed */
|
/* Check if action is completed */
|
||||||
static int action_completed(struct fp_img_dev *dev)
|
static int action_completed(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if ((fpi_imgdev_get_action(dev) == IMG_ACTION_ENROLL) &&
|
if ((fpi_imgdev_get_action(dev) == IMG_ACTION_ENROLL) &&
|
||||||
(vdev->enroll_stage < fp_dev_get_nr_enroll_stages(FP_DEV(dev))))
|
(vdev->enroll_stage < fpi_dev_get_nr_enroll_stages(fpi_imgdev_get_dev(dev))))
|
||||||
/* Enroll not completed, return false */
|
/* Enroll not completed, return false */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -734,11 +754,10 @@ static void img_copy(struct vfs101_dev *vdev, struct fp_img *img)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract fingerpint image from raw data */
|
/* Extract fingerpint image from raw data */
|
||||||
static void
|
static void img_extract(struct fpi_ssm *ssm)
|
||||||
img_extract(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
/* Screen image to remove noise and find top and bottom line */
|
/* Screen image to remove noise and find top and bottom line */
|
||||||
@@ -767,11 +786,6 @@ img_extract(fpi_ssm *ssm,
|
|||||||
/* Notify image captured */
|
/* Notify image captured */
|
||||||
fpi_imgdev_image_captured(dev, img);
|
fpi_imgdev_image_captured(dev, img);
|
||||||
|
|
||||||
/* FIXME
|
|
||||||
* What is this for? The action result, and the enroll stages should
|
|
||||||
* already be handled in fpi_imgdev_image_captured()
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Check captured result */
|
/* Check captured result */
|
||||||
if (fpi_imgdev_get_action_result(dev) >= 0 &&
|
if (fpi_imgdev_get_action_result(dev) >= 0 &&
|
||||||
fpi_imgdev_get_action_result(dev) != FP_ENROLL_RETRY &&
|
fpi_imgdev_get_action_result(dev) != FP_ENROLL_RETRY &&
|
||||||
@@ -856,7 +870,7 @@ static void vfs_check_contrast(struct vfs101_dev *vdev)
|
|||||||
|
|
||||||
fp_dbg("contrast = %d, level = %ld", vdev->contrast, count);
|
fp_dbg("contrast = %d, level = %ld", vdev->contrast, count);
|
||||||
|
|
||||||
if (labs(count - VFS_IMG_BEST_CONTRAST) < abs(vdev->best_clevel - VFS_IMG_BEST_CONTRAST))
|
if (abs(count - VFS_IMG_BEST_CONRAST) < abs(vdev->best_clevel - VFS_IMG_BEST_CONRAST))
|
||||||
{
|
{
|
||||||
/* Better contrast found, use it */
|
/* Better contrast found, use it */
|
||||||
vdev->best_contrast = vdev->contrast;
|
vdev->best_contrast = vdev->contrast;
|
||||||
@@ -898,10 +912,10 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Exec loop sequential state machine */
|
/* Exec loop sequential state machine */
|
||||||
static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_loop_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(_dev);
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Check action state */
|
/* Check action state */
|
||||||
if (!vdev->active)
|
if (!vdev->active)
|
||||||
@@ -915,17 +929,17 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
{
|
{
|
||||||
case M_LOOP_0_GET_PRINT:
|
case M_LOOP_0_GET_PRINT:
|
||||||
/* Send get print command to the reader */
|
/* Send get print command to the reader */
|
||||||
vfs_get_print(ssm, dev, VFS_BUFFER_HEIGHT, 1);
|
vfs_get_print(ssm, VFS_BUFFER_HEIGHT, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_SLEEP:
|
case M_LOOP_0_SLEEP:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(50, ssm, dev);
|
async_sleep(50, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_GET_STATE:
|
case M_LOOP_0_GET_STATE:
|
||||||
/* Get finger state */
|
/* Get finger state */
|
||||||
vfs_get_finger_state(ssm, dev);
|
vfs_get_finger_state(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_LOAD_IMAGE:
|
case M_LOOP_0_LOAD_IMAGE:
|
||||||
@@ -940,14 +954,14 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
case VFS_FINGER_PRESENT:
|
case VFS_FINGER_PRESENT:
|
||||||
/* Load image from reader */
|
/* Load image from reader */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Unknown state */
|
/* Unknown state */
|
||||||
fp_err("unknown device state 0x%02x", vdev->buffer[0x0a]);
|
fp_err("unknown device state 0x%02x", vdev->buffer[0x0a]);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -956,10 +970,10 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
/* Check if image is loaded */
|
/* Check if image is loaded */
|
||||||
if (vdev->height > 0)
|
if (vdev->height > 0)
|
||||||
/* Fingerprint is loaded, extract image from raw data */
|
/* Fingerprint is loaded, extract image from raw data */
|
||||||
img_extract(ssm, dev);
|
img_extract(ssm);
|
||||||
|
|
||||||
/* Wait handling image */
|
/* Wait handling image */
|
||||||
async_sleep(10, ssm, dev);
|
async_sleep(10, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_CHECK_ACTION:
|
case M_LOOP_0_CHECK_ACTION:
|
||||||
@@ -979,7 +993,7 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_LOOP_1_GET_STATE:
|
case M_LOOP_1_GET_STATE:
|
||||||
/* Get finger state */
|
/* Get finger state */
|
||||||
vfs_get_finger_state(ssm, dev);
|
vfs_get_finger_state(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_1_CHECK_STATE:
|
case M_LOOP_1_CHECK_STATE:
|
||||||
@@ -997,14 +1011,14 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
/* Wait removing finger */
|
/* Wait removing finger */
|
||||||
vdev->counter++;
|
vdev->counter++;
|
||||||
async_sleep(250, ssm, dev);
|
async_sleep(250, ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* reach max loop counter, return protocol error */
|
/* reach max loop counter, return protocol error */
|
||||||
fp_err("finger not removed from the scanner");
|
fp_err("finger not removed from the scanner");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1035,13 +1049,13 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_LOOP_1_GET_PRINT:
|
case M_LOOP_1_GET_PRINT:
|
||||||
/* Send get print command to the reader */
|
/* Send get print command to the reader */
|
||||||
vfs_get_print(ssm, dev, VFS_BUFFER_HEIGHT, 1);
|
vfs_get_print(ssm, VFS_BUFFER_HEIGHT, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_1_LOAD_IMAGE:
|
case M_LOOP_1_LOAD_IMAGE:
|
||||||
/* Load image */
|
/* Load image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_1_LOOP:
|
case M_LOOP_1_LOOP:
|
||||||
@@ -1051,29 +1065,29 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_LOOP_1_SLEEP:
|
case M_LOOP_1_SLEEP:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(10, ssm, dev);
|
async_sleep(10, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_2_ABORT_PRINT:
|
case M_LOOP_2_ABORT_PRINT:
|
||||||
/* Abort print command */
|
/* Abort print command */
|
||||||
vfs_abort_print(ssm, dev);
|
vfs_abort_print(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_2_LOAD_IMAGE:
|
case M_LOOP_2_LOAD_IMAGE:
|
||||||
/* Load abort image */
|
/* Load abort image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_3_GET_PRINT:
|
case M_LOOP_3_GET_PRINT:
|
||||||
/* Get empty image */
|
/* Get empty image */
|
||||||
vfs_get_print(ssm, dev, 0x000a, 0);
|
vfs_get_print(ssm, 0x000a, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_3_LOAD_IMAGE:
|
case M_LOOP_3_LOAD_IMAGE:
|
||||||
/* Load abort image */
|
/* Load abort image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_3_CHECK_IMAGE:
|
case M_LOOP_3_CHECK_IMAGE:
|
||||||
@@ -1087,14 +1101,14 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
{
|
{
|
||||||
/* Wait aborting */
|
/* Wait aborting */
|
||||||
vdev->counter++;
|
vdev->counter++;
|
||||||
async_sleep(100, ssm, dev);
|
async_sleep(100, ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* reach max loop counter, return protocol error */
|
/* reach max loop counter, return protocol error */
|
||||||
fp_err("waiting abort reach max loop counter");
|
fp_err("waiting abort reach max loop counter");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1106,7 +1120,7 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Complete loop sequential state machine */
|
/* Complete loop sequential state machine */
|
||||||
static void m_loop_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_loop_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
/* Free sequential state machine */
|
/* Free sequential state machine */
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -1162,10 +1176,10 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Exec init sequential state machine */
|
/* Exec init sequential state machine */
|
||||||
static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(_dev);
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Check action state */
|
/* Check action state */
|
||||||
if (!vdev->active)
|
if (!vdev->active)
|
||||||
@@ -1180,29 +1194,29 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
case M_INIT_0_RECV_DIRTY:
|
case M_INIT_0_RECV_DIRTY:
|
||||||
/* Recv eventualy dirty data */
|
/* Recv eventualy dirty data */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
async_recv(ssm, dev);
|
async_recv(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_0_ABORT_PRINT:
|
case M_INIT_0_ABORT_PRINT:
|
||||||
/* Abort print command */
|
/* Abort print command */
|
||||||
vfs_abort_print(ssm, dev);
|
vfs_abort_print(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_0_LOAD_IMAGE:
|
case M_INIT_0_LOAD_IMAGE:
|
||||||
/* Load abort image */
|
/* Load abort image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_1_GET_PRINT:
|
case M_INIT_1_GET_PRINT:
|
||||||
/* Get empty image */
|
/* Get empty image */
|
||||||
vfs_get_print(ssm, dev, 0x000a, 0);
|
vfs_get_print(ssm, 0x000a, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_1_LOAD_IMAGE:
|
case M_INIT_1_LOAD_IMAGE:
|
||||||
/* Load abort image */
|
/* Load abort image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_1_CHECK_IMAGE:
|
case M_INIT_1_CHECK_IMAGE:
|
||||||
@@ -1216,14 +1230,14 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
{
|
{
|
||||||
/* Wait aborting */
|
/* Wait aborting */
|
||||||
vdev->counter++;
|
vdev->counter++;
|
||||||
async_sleep(100, ssm, dev);
|
async_sleep(100, ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* reach max loop counter, return protocol error */
|
/* reach max loop counter, return protocol error */
|
||||||
fp_err("waiting abort reach max loop counter");
|
fp_err("waiting abort reach max loop counter");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1234,7 +1248,7 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_INIT_2_GET_STATE:
|
case M_INIT_2_GET_STATE:
|
||||||
/* Get finger state */
|
/* Get finger state */
|
||||||
vfs_get_finger_state(ssm, dev);
|
vfs_get_finger_state(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_2_CHECK_STATE:
|
case M_INIT_2_CHECK_STATE:
|
||||||
@@ -1252,14 +1266,14 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
/* Wait removing finger */
|
/* Wait removing finger */
|
||||||
vdev->counter++;
|
vdev->counter++;
|
||||||
async_sleep(250, ssm, dev);
|
async_sleep(250, ssm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* reach max loop counter, return protocol error */
|
/* reach max loop counter, return protocol error */
|
||||||
fp_err("finger not removed from the scanner");
|
fp_err("finger not removed from the scanner");
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
fpi_imgdev_session_error(dev, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1279,13 +1293,13 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_INIT_2_GET_PRINT:
|
case M_INIT_2_GET_PRINT:
|
||||||
/* Send get print command to the reader */
|
/* Send get print command to the reader */
|
||||||
vfs_get_print(ssm, dev, VFS_BUFFER_HEIGHT, 1);
|
vfs_get_print(ssm, VFS_BUFFER_HEIGHT, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_2_LOAD_IMAGE:
|
case M_INIT_2_LOAD_IMAGE:
|
||||||
/* Load unexpected image */
|
/* Load unexpected image */
|
||||||
vdev->ignore_error = TRUE;
|
vdev->ignore_error = TRUE;
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_2_LOOP:
|
case M_INIT_2_LOOP:
|
||||||
@@ -1295,68 +1309,68 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_INIT_3_SET_000E:
|
case M_INIT_3_SET_000E:
|
||||||
/* Set param 0x000e, required for take image */
|
/* Set param 0x000e, required for take image */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_000E, VFS_VAL_000E);
|
vfs_set_param(ssm, VFS_PAR_000E, VFS_VAL_000E);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_0011:
|
case M_INIT_3_SET_0011:
|
||||||
/* Set param 0x0011, required for take image */
|
/* Set param 0x0011, required for take image */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_0011, VFS_VAL_0011);
|
vfs_set_param(ssm, VFS_PAR_0011, VFS_VAL_0011);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_0076:
|
case M_INIT_3_SET_0076:
|
||||||
/* Set param 0x0076, required for use info line */
|
/* Set param 0x0076, required for use info line */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_0076, VFS_VAL_0076);
|
vfs_set_param(ssm, VFS_PAR_0076, VFS_VAL_0076);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_0078:
|
case M_INIT_3_SET_0078:
|
||||||
/* Set param 0x0078, required for use info line */
|
/* Set param 0x0078, required for use info line */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_0078, VFS_VAL_0078);
|
vfs_set_param(ssm, VFS_PAR_0078, VFS_VAL_0078);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_THRESHOLD:
|
case M_INIT_3_SET_THRESHOLD:
|
||||||
/* Set threshold */
|
/* Set threshold */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_THRESHOLD, VFS_VAL_THRESHOLD);
|
vfs_set_param(ssm, VFS_PAR_THRESHOLD, VFS_VAL_THRESHOLD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_STATE3_COUNT:
|
case M_INIT_3_SET_STATE3_COUNT:
|
||||||
/* Set state 3 count */
|
/* Set state 3 count */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_STATE_3, VFS_VAL_STATE_3);
|
vfs_set_param(ssm, VFS_PAR_STATE_3, VFS_VAL_STATE_3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_STATE5_COUNT:
|
case M_INIT_3_SET_STATE5_COUNT:
|
||||||
/* Set state 5 count */
|
/* Set state 5 count */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_STATE_5, VFS_VAL_STATE_5);
|
vfs_set_param(ssm, VFS_PAR_STATE_5, VFS_VAL_STATE_5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_INFO_CONTRAST:
|
case M_INIT_3_SET_INFO_CONTRAST:
|
||||||
/* Set info line contrast */
|
/* Set info line contrast */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_INFO_CONTRAST, 10);
|
vfs_set_param(ssm, VFS_PAR_INFO_CONTRAST, 10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_3_SET_INFO_RATE:
|
case M_INIT_3_SET_INFO_RATE:
|
||||||
/* Set info line rate */
|
/* Set info line rate */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_INFO_RATE, 32);
|
vfs_set_param(ssm, VFS_PAR_INFO_RATE, 32);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_4_SET_EXPOSURE:
|
case M_INIT_4_SET_EXPOSURE:
|
||||||
/* Set exposure level of reader */
|
/* Set exposure level of reader */
|
||||||
vfs_poke(ssm, dev, VFS_REG_IMG_EXPOSURE, 0x4000, 0x02);
|
vfs_poke(ssm, VFS_REG_IMG_EXPOSURE, 0x4000, 0x02);
|
||||||
vdev->counter = 1;
|
vdev->counter = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_4_SET_CONTRAST:
|
case M_INIT_4_SET_CONTRAST:
|
||||||
/* Set contrast level of reader */
|
/* Set contrast level of reader */
|
||||||
vfs_poke(ssm, dev, VFS_REG_IMG_CONTRAST, vdev->contrast, 0x01);
|
vfs_poke(ssm, VFS_REG_IMG_CONTRAST, vdev->contrast, 0x01);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_4_GET_PRINT:
|
case M_INIT_4_GET_PRINT:
|
||||||
/* Get empty image */
|
/* Get empty image */
|
||||||
vfs_get_print(ssm, dev, 0x000a, 0);
|
vfs_get_print(ssm, 0x000a, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_4_LOAD_IMAGE:
|
case M_INIT_4_LOAD_IMAGE:
|
||||||
/* Load empty image */
|
/* Load empty image */
|
||||||
vfs_img_load(ssm, dev);
|
vfs_img_load(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_4_CHECK_CONTRAST:
|
case M_INIT_4_CHECK_CONTRAST:
|
||||||
@@ -1382,32 +1396,32 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_INIT_5_SET_EXPOSURE:
|
case M_INIT_5_SET_EXPOSURE:
|
||||||
/* Set exposure level of reader */
|
/* Set exposure level of reader */
|
||||||
vfs_poke(ssm, dev, VFS_REG_IMG_EXPOSURE, VFS_VAL_IMG_EXPOSURE, 0x02);
|
vfs_poke(ssm, VFS_REG_IMG_EXPOSURE, VFS_VAL_IMG_EXPOSURE, 0x02);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_5_SET_CONTRAST:
|
case M_INIT_5_SET_CONTRAST:
|
||||||
/* Set contrast level of reader */
|
/* Set contrast level of reader */
|
||||||
vfs_poke(ssm, dev, VFS_REG_IMG_CONTRAST, vdev->contrast, 0x01);
|
vfs_poke(ssm, VFS_REG_IMG_CONTRAST, vdev->contrast, 0x01);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_5_SET_INFO_CONTRAST:
|
case M_INIT_5_SET_INFO_CONTRAST:
|
||||||
/* Set info line contrast */
|
/* Set info line contrast */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_INFO_CONTRAST, vdev->contrast);
|
vfs_set_param(ssm, VFS_PAR_INFO_CONTRAST, vdev->contrast);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_INIT_5_SET_INFO_RATE:
|
case M_INIT_5_SET_INFO_RATE:
|
||||||
/* Set info line rate */
|
/* Set info line rate */
|
||||||
vfs_set_param(ssm, dev, VFS_PAR_INFO_RATE, VFS_VAL_INFO_RATE);
|
vfs_set_param(ssm, VFS_PAR_INFO_RATE, VFS_VAL_INFO_RATE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete init sequential state machine */
|
/* Complete init sequential state machine */
|
||||||
static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(_dev);
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm_loop;
|
struct fpi_ssm *ssm_loop;
|
||||||
|
|
||||||
if (!fpi_ssm_get_error(ssm) && vdev->active)
|
if (!fpi_ssm_get_error(ssm) && vdev->active)
|
||||||
{
|
{
|
||||||
@@ -1415,7 +1429,8 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
fpi_imgdev_activate_complete(dev, 0);
|
fpi_imgdev_activate_complete(dev, 0);
|
||||||
|
|
||||||
/* Start loop ssm */
|
/* Start loop ssm */
|
||||||
ssm_loop = fpi_ssm_new(FP_DEV(dev), m_loop_state, M_LOOP_NUM_STATES, dev);
|
ssm_loop = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_loop_state, M_LOOP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm_loop, dev);
|
||||||
fpi_ssm_start(ssm_loop, m_loop_complete);
|
fpi_ssm_start(ssm_loop, m_loop_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1426,8 +1441,8 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
/* Activate device */
|
/* Activate device */
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
/* Check if already active */
|
/* Check if already active */
|
||||||
if (vdev->active)
|
if (vdev->active)
|
||||||
@@ -1449,7 +1464,8 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
vdev->enroll_stage = 0;
|
vdev->enroll_stage = 0;
|
||||||
|
|
||||||
/* Start init ssm */
|
/* Start init ssm */
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), m_init_state, M_INIT_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_init_state, M_INIT_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, m_init_complete);
|
fpi_ssm_start(ssm, m_init_complete);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1458,13 +1474,13 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
/* Deactivate device */
|
/* Deactivate device */
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
/* Reset active state */
|
/* Reset active state */
|
||||||
vdev->active = FALSE;
|
vdev->active = FALSE;
|
||||||
|
|
||||||
/* Handle eventualy existing events */
|
/* Handle eventualy existing events */
|
||||||
while (vdev->transfer)
|
while (vdev->transfer || vdev->timeout)
|
||||||
fp_handle_events();
|
fp_handle_events();
|
||||||
|
|
||||||
/* Notify deactivate complete */
|
/* Notify deactivate complete */
|
||||||
@@ -1478,7 +1494,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
/* Interface not claimed, return error */
|
/* Interface not claimed, return error */
|
||||||
@@ -1489,7 +1505,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
/* Initialize private structure */
|
/* Initialize private structure */
|
||||||
vdev = g_malloc0(sizeof(struct vfs101_dev));
|
vdev = g_malloc0(sizeof(struct vfs101_dev));
|
||||||
vdev->seqnum = -1;
|
vdev->seqnum = -1;
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), vdev);
|
fpi_imgdev_set_user_data(dev, vdev);
|
||||||
|
|
||||||
/* Notify open complete */
|
/* Notify open complete */
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
@@ -1503,11 +1519,11 @@ static void dev_close(struct fp_img_dev *dev)
|
|||||||
struct vfs101_dev *vdev;
|
struct vfs101_dev *vdev;
|
||||||
|
|
||||||
/* Release private structure */
|
/* Release private structure */
|
||||||
vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
vdev = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(vdev);
|
g_free(vdev);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
|
|
||||||
/* Notify close complete */
|
/* Notify close complete */
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
|
|||||||
@@ -26,26 +26,35 @@
|
|||||||
|
|
||||||
/************************** GENERIC STUFF *************************************/
|
/************************** GENERIC STUFF *************************************/
|
||||||
|
|
||||||
/* Submit asynchronous sleep */
|
/* Callback of asynchronous sleep */
|
||||||
static void
|
static void async_sleep_cb(void *data)
|
||||||
async_sleep(unsigned int msec,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
|
struct fpi_ssm *ssm = data;
|
||||||
|
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Submit asynchronous sleep */
|
||||||
|
static void async_sleep(unsigned int msec, struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
struct fpi_timeout *timeout;
|
||||||
|
|
||||||
/* Add timeout */
|
/* Add timeout */
|
||||||
if (fpi_timeout_add(msec, fpi_ssm_next_state_timeout_cb, FP_DEV(dev), ssm) == NULL) {
|
timeout = fpi_timeout_add(msec, async_sleep_cb, ssm);
|
||||||
|
|
||||||
|
if (timeout == NULL) {
|
||||||
/* Failed to add timeout */
|
/* Failed to add timeout */
|
||||||
fp_err("failed to add timeout");
|
fp_err("failed to add timeout");
|
||||||
fpi_imgdev_session_error(dev, -ETIME);
|
fpi_imgdev_session_error(dev, -ETIME);
|
||||||
fpi_ssm_mark_failed(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int submit_image(struct fpi_ssm *ssm)
|
||||||
submit_image(fpi_ssm *ssm,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
vfs301_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
|
vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
int height;
|
int height;
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
@@ -71,7 +80,7 @@ submit_image(fpi_ssm *ssm,
|
|||||||
img->width = VFS301_FP_OUTPUT_WIDTH;
|
img->width = VFS301_FP_OUTPUT_WIDTH;
|
||||||
img->height = height;
|
img->height = height;
|
||||||
|
|
||||||
img = fpi_img_realloc(img, img->height * img->width);
|
img = fpi_img_resize(img, img->height * img->width);
|
||||||
fpi_imgdev_image_captured(dev, img);
|
fpi_imgdev_image_captured(dev, img);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -94,24 +103,24 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Exec loop sequential state machine */
|
/* Exec loop sequential state machine */
|
||||||
static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_loop_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
vfs301_dev_t *vdev = FP_INSTANCE_DATA(_dev);
|
vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case M_REQUEST_PRINT:
|
case M_REQUEST_PRINT:
|
||||||
vfs301_proto_request_fingerprint(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev);
|
vfs301_proto_request_fingerprint(fpi_imgdev_get_usb_dev(dev), vdev);
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_WAIT_PRINT:
|
case M_WAIT_PRINT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(200, ssm, dev);
|
async_sleep(200, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_CHECK_PRINT:
|
case M_CHECK_PRINT:
|
||||||
if (!vfs301_proto_peek_event(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev))
|
if (!vfs301_proto_peek_event(fpi_imgdev_get_usb_dev(dev), vdev))
|
||||||
fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT);
|
fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
@@ -119,18 +128,18 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case M_READ_PRINT_START:
|
case M_READ_PRINT_START:
|
||||||
fpi_imgdev_report_finger_status(dev, TRUE);
|
fpi_imgdev_report_finger_status(dev, TRUE);
|
||||||
vfs301_proto_process_event_start(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev);
|
vfs301_proto_process_event_start(fpi_imgdev_get_usb_dev(dev), vdev);
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_READ_PRINT_WAIT:
|
case M_READ_PRINT_WAIT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(200, ssm, dev);
|
async_sleep(200, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_READ_PRINT_POLL:
|
case M_READ_PRINT_POLL:
|
||||||
{
|
{
|
||||||
int rv = vfs301_proto_process_event_poll(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev);
|
int rv = vfs301_proto_process_event_poll(fpi_imgdev_get_usb_dev(dev), vdev);
|
||||||
g_assert(rv != VFS301_FAILURE);
|
g_assert(rv != VFS301_FAILURE);
|
||||||
if (rv == VFS301_ONGOING)
|
if (rv == VFS301_ONGOING)
|
||||||
fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT);
|
fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT);
|
||||||
@@ -140,7 +149,7 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case M_SUBMIT_PRINT:
|
case M_SUBMIT_PRINT:
|
||||||
if (submit_image(ssm, dev)) {
|
if (submit_image(ssm)) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
/* NOTE: finger off is expected only after submitting image... */
|
/* NOTE: finger off is expected only after submitting image... */
|
||||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
fpi_imgdev_report_finger_status(dev, FALSE);
|
||||||
@@ -152,37 +161,38 @@ static void m_loop_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Complete loop sequential state machine */
|
/* Complete loop sequential state machine */
|
||||||
static void m_loop_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_loop_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
/* Free sequential state machine */
|
/* Free sequential state machine */
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exec init sequential state machine */
|
/* Exec init sequential state machine */
|
||||||
static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
vfs301_dev_t *vdev = FP_INSTANCE_DATA(_dev);
|
vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
g_assert(fpi_ssm_get_cur_state(ssm) == 0);
|
g_assert(fpi_ssm_get_cur_state(ssm) == 0);
|
||||||
|
|
||||||
vfs301_proto_init(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev);
|
vfs301_proto_init(fpi_imgdev_get_usb_dev(dev), vdev);
|
||||||
|
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete init sequential state machine */
|
/* Complete init sequential state machine */
|
||||||
static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void m_init_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
fpi_ssm *ssm_loop;
|
struct fpi_ssm *ssm_loop;
|
||||||
|
|
||||||
if (!fpi_ssm_get_error(ssm)) {
|
if (!fpi_ssm_get_error(ssm)) {
|
||||||
/* Notify activate complete */
|
/* Notify activate complete */
|
||||||
fpi_imgdev_activate_complete(dev, 0);
|
fpi_imgdev_activate_complete(dev, 0);
|
||||||
|
|
||||||
/* Start loop ssm */
|
/* Start loop ssm */
|
||||||
ssm_loop = fpi_ssm_new(FP_DEV(dev), m_loop_state, M_LOOP_NUM_STATES, dev);
|
ssm_loop = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_loop_state, M_LOOP_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm_loop, dev);
|
||||||
fpi_ssm_start(ssm_loop, m_loop_complete);
|
fpi_ssm_start(ssm_loop, m_loop_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,10 +203,11 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
/* Activate device */
|
/* Activate device */
|
||||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
/* Start init ssm */
|
/* Start init ssm */
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), m_init_state, 1, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_init_state, 1);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, m_init_complete);
|
fpi_ssm_start(ssm, m_init_complete);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -205,10 +216,6 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
/* Deactivate device */
|
/* Deactivate device */
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
vfs301_dev_t *vdev;
|
|
||||||
|
|
||||||
vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
|
||||||
vfs301_proto_deinit(fpi_dev_get_usb_dev(FP_DEV(dev)), vdev);
|
|
||||||
fpi_imgdev_deactivate_complete(dev);
|
fpi_imgdev_deactivate_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +225,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
/* Interface not claimed, return error */
|
/* Interface not claimed, return error */
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||||
@@ -227,7 +234,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
/* Initialize private structure */
|
/* Initialize private structure */
|
||||||
vdev = g_malloc0(sizeof(vfs301_dev_t));
|
vdev = g_malloc0(sizeof(vfs301_dev_t));
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), vdev);
|
fpi_imgdev_set_user_data(dev, vdev);
|
||||||
|
|
||||||
vdev->scanline_buf = malloc(0);
|
vdev->scanline_buf = malloc(0);
|
||||||
vdev->scanline_count = 0;
|
vdev->scanline_count = 0;
|
||||||
@@ -243,12 +250,12 @@ static void dev_close(struct fp_img_dev *dev)
|
|||||||
vfs301_dev_t *vdev;
|
vfs301_dev_t *vdev;
|
||||||
|
|
||||||
/* Release private structure */
|
/* Release private structure */
|
||||||
vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
vdev = fpi_imgdev_get_user_data(dev);
|
||||||
free(vdev->scanline_buf);
|
free(vdev->scanline_buf);
|
||||||
g_free(vdev);
|
g_free(vdev);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
|
|
||||||
/* Notify close complete */
|
/* Notify close complete */
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_imgdev_close_complete(dev);
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <libusb-1.0/libusb.h>
|
||||||
|
|
||||||
#include "fpi-usb.h"
|
|
||||||
#include "vfs301_proto.h"
|
#include "vfs301_proto.h"
|
||||||
#include "vfs301_proto_fragments.h"
|
#include "vfs301_proto_fragments.h"
|
||||||
|
|
||||||
@@ -499,7 +499,12 @@ void vfs301_proto_process_event_start(
|
|||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 64);
|
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 64);
|
||||||
|
|
||||||
/* now read the fingerprint data, while there are some */
|
/* now read the fingerprint data, while there are some */
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
if (!transfer) {
|
||||||
|
dev->recv_progress = VFS301_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dev->recv_progress = VFS301_ONGOING;
|
dev->recv_progress = VFS301_ONGOING;
|
||||||
dev->recv_exp_amt = VFS301_FP_RECV_LEN_1;
|
dev->recv_exp_amt = VFS301_FP_RECV_LEN_1;
|
||||||
|
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ static void start_scan(struct fp_img_dev *dev);
|
|||||||
|
|
||||||
static void async_send_cb(struct libusb_transfer *transfer)
|
static void async_send_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct usbexchange_data *data = fpi_ssm_get_user_data(ssm);
|
struct usbexchange_data *data = fpi_ssm_get_user_data(ssm);
|
||||||
struct usb_action *action;
|
struct usb_action *action;
|
||||||
|
|
||||||
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
||||||
fp_err("Radiation detected!");
|
fp_err("Radiation detected!");
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ static void async_send_cb(struct libusb_transfer *transfer)
|
|||||||
if (action->type != ACTION_SEND) {
|
if (action->type != ACTION_SEND) {
|
||||||
fp_err("Radiation detected!");
|
fp_err("Radiation detected!");
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ static void async_send_cb(struct libusb_transfer *transfer)
|
|||||||
/* Transfer not completed, return IO error */
|
/* Transfer not completed, return IO error */
|
||||||
fp_err("transfer not completed, status = %d", transfer->status);
|
fp_err("transfer not completed, status = %d", transfer->status);
|
||||||
fpi_imgdev_session_error(data->device, -EIO);
|
fpi_imgdev_session_error(data->device, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (transfer->length != transfer->actual_length) {
|
if (transfer->length != transfer->actual_length) {
|
||||||
@@ -106,7 +106,7 @@ static void async_send_cb(struct libusb_transfer *transfer)
|
|||||||
fp_err("length mismatch, got %d, expected %d",
|
fp_err("length mismatch, got %d, expected %d",
|
||||||
transfer->actual_length, transfer->length);
|
transfer->actual_length, transfer->length);
|
||||||
fpi_imgdev_session_error(data->device, -EIO);
|
fpi_imgdev_session_error(data->device, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ out:
|
|||||||
|
|
||||||
static void async_recv_cb(struct libusb_transfer *transfer)
|
static void async_recv_cb(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
struct fpi_ssm *ssm = transfer->user_data;
|
||||||
struct usbexchange_data *data = fpi_ssm_get_user_data(ssm);
|
struct usbexchange_data *data = fpi_ssm_get_user_data(ssm);
|
||||||
struct usb_action *action;
|
struct usb_action *action;
|
||||||
|
|
||||||
@@ -127,14 +127,14 @@ static void async_recv_cb(struct libusb_transfer *transfer)
|
|||||||
/* Transfer not completed, return IO error */
|
/* Transfer not completed, return IO error */
|
||||||
fp_err("transfer not completed, status = %d", transfer->status);
|
fp_err("transfer not completed, status = %d", transfer->status);
|
||||||
fpi_imgdev_session_error(data->device, -EIO);
|
fpi_imgdev_session_error(data->device, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
||||||
fp_err("Radiation detected!");
|
fp_err("Radiation detected!");
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ static void async_recv_cb(struct libusb_transfer *transfer)
|
|||||||
if (action->type != ACTION_RECEIVE) {
|
if (action->type != ACTION_RECEIVE) {
|
||||||
fp_err("Radiation detected!");
|
fp_err("Radiation detected!");
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,14 +152,14 @@ static void async_recv_cb(struct libusb_transfer *transfer)
|
|||||||
transfer->actual_length,
|
transfer->actual_length,
|
||||||
action->correct_reply_size);
|
action->correct_reply_size);
|
||||||
fpi_imgdev_session_error(data->device, -EIO);
|
fpi_imgdev_session_error(data->device, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (memcmp(transfer->buffer, action->data,
|
if (memcmp(transfer->buffer, action->data,
|
||||||
action->correct_reply_size) != 0) {
|
action->correct_reply_size) != 0) {
|
||||||
fp_dbg("Wrong reply:");
|
fp_dbg("Wrong reply:");
|
||||||
fpi_imgdev_session_error(data->device, -EIO);
|
fpi_imgdev_session_error(data->device, -EIO);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -171,14 +171,14 @@ out:
|
|||||||
libusb_free_transfer(transfer);
|
libusb_free_transfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usbexchange_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void usbexchange_loop(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct usbexchange_data *data = user_data;
|
struct usbexchange_data *data = fpi_ssm_get_user_data(ssm);
|
||||||
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) {
|
||||||
fp_err("Bug detected: state %d out of range, only %d steps",
|
fp_err("Bug detected: state %d out of range, only %d steps",
|
||||||
fpi_ssm_get_cur_state(ssm), data->stepcount);
|
fpi_ssm_get_cur_state(ssm), data->stepcount);
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,8 +189,14 @@ static void usbexchange_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
switch (action->type) {
|
switch (action->type) {
|
||||||
case ACTION_SEND:
|
case ACTION_SEND:
|
||||||
fp_dbg("Sending %s", action->name);
|
fp_dbg("Sending %s", action->name);
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(data->device)),
|
if (transfer == NULL) {
|
||||||
|
fp_err("Failed to allocate transfer");
|
||||||
|
fpi_imgdev_session_error(data->device, -ENOMEM);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(data->device),
|
||||||
action->endpoint, action->data,
|
action->endpoint, action->data,
|
||||||
action->size, async_send_cb, ssm,
|
action->size, async_send_cb, ssm,
|
||||||
data->timeout);
|
data->timeout);
|
||||||
@@ -199,8 +205,14 @@ static void usbexchange_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
|
|
||||||
case ACTION_RECEIVE:
|
case ACTION_RECEIVE:
|
||||||
fp_dbg("Receiving %d bytes", action->size);
|
fp_dbg("Receiving %d bytes", action->size);
|
||||||
transfer = fpi_usb_alloc();
|
transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(data->device)),
|
if (transfer == NULL) {
|
||||||
|
fp_err("Failed to allocate transfer");
|
||||||
|
fpi_imgdev_session_error(data->device, -ENOMEM);
|
||||||
|
fpi_ssm_mark_aborted(ssm, -ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(data->device),
|
||||||
action->endpoint, data->receive_buf,
|
action->endpoint, data->receive_buf,
|
||||||
action->size, async_recv_cb, ssm,
|
action->size, async_recv_cb, ssm,
|
||||||
data->timeout);
|
data->timeout);
|
||||||
@@ -210,24 +222,24 @@ static void usbexchange_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
default:
|
default:
|
||||||
fp_err("Bug detected: invalid action %d", action->type);
|
fp_err("Bug detected: invalid action %d", action->type);
|
||||||
fpi_imgdev_session_error(data->device, -EINVAL);
|
fpi_imgdev_session_error(data->device, -EINVAL);
|
||||||
fpi_ssm_mark_failed(ssm, -EINVAL);
|
fpi_ssm_mark_aborted(ssm, -EINVAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fp_err("USB transfer error: %s", strerror(ret));
|
fp_err("USB transfer error: %s", strerror(ret));
|
||||||
fpi_imgdev_session_error(data->device, ret);
|
fpi_imgdev_session_error(data->device, ret);
|
||||||
fpi_ssm_mark_failed(ssm, ret);
|
fpi_ssm_mark_aborted(ssm, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_exchange_async(fpi_ssm *ssm,
|
static void usb_exchange_async(struct fpi_ssm *ssm,
|
||||||
struct usbexchange_data *data)
|
struct usbexchange_data *data)
|
||||||
{
|
{
|
||||||
fpi_ssm *subsm = fpi_ssm_new(FP_DEV(data->device),
|
struct fpi_ssm *subsm = fpi_ssm_new(fpi_imgdev_get_dev(data->device),
|
||||||
usbexchange_loop,
|
usbexchange_loop,
|
||||||
data->stepcount,
|
data->stepcount);
|
||||||
data);
|
fpi_ssm_set_user_data(subsm, data);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
fpi_ssm_start_subsm(ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,11 +395,9 @@ static int process_chunk(struct vfs5011_data *data, int transferred)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data)
|
||||||
submit_image(fpi_ssm *ssm,
|
|
||||||
struct vfs5011_data *data,
|
|
||||||
struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct fp_img *img;
|
struct fp_img *img;
|
||||||
|
|
||||||
if (data->lines_recorded == 0) {
|
if (data->lines_recorded == 0) {
|
||||||
@@ -412,11 +422,11 @@ submit_image(fpi_ssm *ssm,
|
|||||||
|
|
||||||
static void chunk_capture_callback(struct libusb_transfer *transfer)
|
static void chunk_capture_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = (fpi_ssm *)transfer->user_data;
|
struct fpi_ssm *ssm = (struct fpi_ssm *)transfer->user_data;
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(FP_DEV(dev));
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) ||
|
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) ||
|
||||||
(transfer->status == LIBUSB_TRANSFER_TIMED_OUT)) {
|
(transfer->status == LIBUSB_TRANSFER_TIMED_OUT)) {
|
||||||
@@ -431,7 +441,7 @@ static void chunk_capture_callback(struct libusb_transfer *transfer)
|
|||||||
} else {
|
} else {
|
||||||
if (!data->deactivating) {
|
if (!data->deactivating) {
|
||||||
fp_err("Failed to capture data");
|
fp_err("Failed to capture data");
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
}
|
}
|
||||||
@@ -442,7 +452,7 @@ static void chunk_capture_callback(struct libusb_transfer *transfer)
|
|||||||
|
|
||||||
static int capture_chunk_async(struct vfs5011_data *data,
|
static int capture_chunk_async(struct vfs5011_data *data,
|
||||||
libusb_device_handle *handle, int nline,
|
libusb_device_handle *handle, int nline,
|
||||||
int timeout, fpi_ssm *ssm)
|
int timeout, struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
fp_dbg("capture_chunk_async: capture %d lines, already have %d",
|
fp_dbg("capture_chunk_async: capture %d lines, already have %d",
|
||||||
nline, data->lines_recorded);
|
nline, data->lines_recorded);
|
||||||
@@ -452,7 +462,7 @@ static int capture_chunk_async(struct vfs5011_data *data,
|
|||||||
STOP_CHECK_LINES = 50
|
STOP_CHECK_LINES = 50
|
||||||
};
|
};
|
||||||
|
|
||||||
data->flying_transfer = fpi_usb_alloc();
|
data->flying_transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(data->flying_transfer, handle, VFS5011_IN_ENDPOINT_DATA,
|
libusb_fill_bulk_transfer(data->flying_transfer, handle, VFS5011_IN_ENDPOINT_DATA,
|
||||||
data->capture_buffer,
|
data->capture_buffer,
|
||||||
nline * VFS5011_LINE_SIZE,
|
nline * VFS5011_LINE_SIZE,
|
||||||
@@ -460,6 +470,13 @@ static int capture_chunk_async(struct vfs5011_data *data,
|
|||||||
return libusb_submit_transfer(data->flying_transfer);
|
return libusb_submit_transfer(data->flying_transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void async_sleep_cb(void *data)
|
||||||
|
{
|
||||||
|
struct fpi_ssm *ssm = data;
|
||||||
|
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device initialization. Windows driver only does it when the device is
|
* Device initialization. Windows driver only does it when the device is
|
||||||
* plugged in, but it doesn't harm to do this every time before scanning the
|
* plugged in, but it doesn't harm to do this every time before scanning the
|
||||||
@@ -648,16 +665,16 @@ struct usb_action vfs5011_initiate_capture[] = {
|
|||||||
|
|
||||||
/* ====================== lifprint interface ======================= */
|
/* ====================== lifprint interface ======================= */
|
||||||
|
|
||||||
static void activate_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_loop(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
enum {READ_TIMEOUT = 0};
|
enum {READ_TIMEOUT = 0};
|
||||||
|
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
int r;
|
int r;
|
||||||
fpi_timeout *timeout;
|
struct fpi_timeout *timeout;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(_dev);
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
fp_dbg("main_loop: state %d", fpi_ssm_get_cur_state(ssm));
|
fp_dbg("main_loop: state %d", fpi_ssm_get_cur_state(ssm));
|
||||||
|
|
||||||
@@ -690,23 +707,23 @@ static void activate_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_ACTIVATE_READ_DATA:
|
case DEV_ACTIVATE_READ_DATA:
|
||||||
r = capture_chunk_async(data, fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_LINES,
|
r = capture_chunk_async(data, fpi_imgdev_get_usb_dev(dev), CAPTURE_LINES,
|
||||||
READ_TIMEOUT, ssm);
|
READ_TIMEOUT, ssm);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
fp_err("Failed to capture data");
|
fp_err("Failed to capture data");
|
||||||
fpi_imgdev_session_error(dev, r);
|
fpi_imgdev_session_error(dev, r);
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
fpi_ssm_mark_aborted(ssm, r);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_ACTIVATE_DATA_COMPLETE:
|
case DEV_ACTIVATE_DATA_COMPLETE:
|
||||||
timeout = fpi_timeout_add(1, fpi_ssm_next_state_timeout_cb, _dev, ssm);
|
timeout = fpi_timeout_add(1, async_sleep_cb, ssm);
|
||||||
|
|
||||||
if (timeout == NULL) {
|
if (timeout == NULL) {
|
||||||
/* Failed to add timeout */
|
/* Failed to add timeout */
|
||||||
fp_err("failed to add timeout");
|
fp_err("failed to add timeout");
|
||||||
fpi_imgdev_session_error(dev, -1);
|
fpi_imgdev_session_error(dev, -1);
|
||||||
fpi_ssm_mark_failed(ssm, -1);
|
fpi_ssm_mark_aborted(ssm, -1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -725,20 +742,20 @@ static void activate_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_loop_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_loop_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
int r = fpi_ssm_get_error(ssm);
|
int r = fpi_ssm_get_error(ssm);
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(_dev);
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
fp_dbg("finishing");
|
fp_dbg("finishing");
|
||||||
if (data->init_sequence.receive_buf != NULL)
|
if (data->init_sequence.receive_buf != NULL)
|
||||||
g_free(data->init_sequence.receive_buf);
|
g_free(data->init_sequence.receive_buf);
|
||||||
data->init_sequence.receive_buf = NULL;
|
data->init_sequence.receive_buf = NULL;
|
||||||
if (!data->deactivating && !r) {
|
if (!data->deactivating && !r) {
|
||||||
submit_image(ssm, data, dev);
|
submit_image(ssm, data);
|
||||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
fpi_imgdev_report_finger_status(dev, FALSE);
|
||||||
}
|
}
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
@@ -755,12 +772,12 @@ static void activate_loop_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void open_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void open_loop(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(_dev);
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case DEV_OPEN_START:
|
case DEV_OPEN_START:
|
||||||
@@ -776,12 +793,12 @@ static void open_loop(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_loop_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void open_loop_complete(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(_dev);
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
g_free(data->init_sequence.receive_buf);
|
g_free(data->init_sequence.receive_buf);
|
||||||
data->init_sequence.receive_buf = NULL;
|
data->init_sequence.receive_buf = NULL;
|
||||||
|
|
||||||
@@ -798,22 +815,23 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
data = (struct vfs5011_data *)g_malloc0(sizeof(*data));
|
data = (struct vfs5011_data *)g_malloc0(sizeof(*data));
|
||||||
data->capture_buffer =
|
data->capture_buffer =
|
||||||
(unsigned char *)g_malloc0(CAPTURE_LINES * VFS5011_LINE_SIZE);
|
(unsigned char *)g_malloc0(CAPTURE_LINES * VFS5011_LINE_SIZE);
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), data);
|
fpi_imgdev_set_user_data(dev, data);
|
||||||
|
|
||||||
r = libusb_reset_device(fpi_dev_get_usb_dev(FP_DEV(dev)));
|
r = libusb_reset_device(fpi_imgdev_get_usb_dev(dev));
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
fp_err("Failed to reset the device");
|
fp_err("Failed to reset the device");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
fp_err("Failed to claim interface: %s", libusb_error_name(r));
|
fp_err("Failed to claim interface: %s", libusb_error_name(r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), open_loop, DEV_OPEN_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), open_loop, DEV_OPEN_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fpi_ssm_start(ssm, open_loop_complete);
|
fpi_ssm_start(ssm, open_loop_complete);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -821,9 +839,9 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
|
|||||||
|
|
||||||
static void dev_close(struct fp_img_dev *dev)
|
static void dev_close(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0);
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
data = FP_INSTANCE_DATA(FP_DEV(dev));
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
g_free(data->capture_buffer);
|
g_free(data->capture_buffer);
|
||||||
g_slist_free_full(data->rows, g_free);
|
g_slist_free_full(data->rows, g_free);
|
||||||
@@ -835,12 +853,13 @@ static void dev_close(struct fp_img_dev *dev)
|
|||||||
static void start_scan(struct fp_img_dev *dev)
|
static void start_scan(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
fpi_ssm *ssm;
|
struct fpi_ssm *ssm;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(FP_DEV(dev));
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
data->loop_running = TRUE;
|
data->loop_running = TRUE;
|
||||||
fp_dbg("creating ssm");
|
fp_dbg("creating ssm");
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), activate_loop, DEV_ACTIVATE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_loop, DEV_ACTIVATE_NUM_STATES);
|
||||||
|
fpi_ssm_set_user_data(ssm, dev);
|
||||||
fp_dbg("starting ssm");
|
fp_dbg("starting ssm");
|
||||||
fpi_ssm_start(ssm, activate_loop_complete);
|
fpi_ssm_start(ssm, activate_loop_complete);
|
||||||
fp_dbg("ssm done, getting out");
|
fp_dbg("ssm done, getting out");
|
||||||
@@ -850,7 +869,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||||||
{
|
{
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(FP_DEV(dev));
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
fp_dbg("device initialized");
|
fp_dbg("device initialized");
|
||||||
data->deactivating = FALSE;
|
data->deactivating = FALSE;
|
||||||
|
|
||||||
@@ -864,7 +883,7 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
int r;
|
int r;
|
||||||
struct vfs5011_data *data;
|
struct vfs5011_data *data;
|
||||||
|
|
||||||
data = FP_INSTANCE_DATA(FP_DEV(dev));
|
data = fpi_imgdev_get_user_data(dev);
|
||||||
if (data->loop_running) {
|
if (data->loop_running) {
|
||||||
data->deactivating = TRUE;
|
data->deactivating = TRUE;
|
||||||
if (data->flying_transfer) {
|
if (data->flying_transfer) {
|
||||||
@@ -879,7 +898,6 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
|||||||
static const struct usb_id id_table[] = {
|
static const struct usb_id id_table[] = {
|
||||||
{ .vendor = 0x138a, .product = 0x0010 /* Validity device from some Toshiba laptops */ },
|
{ .vendor = 0x138a, .product = 0x0010 /* Validity device from some Toshiba laptops */ },
|
||||||
{ .vendor = 0x138a, .product = 0x0011 /* vfs5011 */ },
|
{ .vendor = 0x138a, .product = 0x0011 /* vfs5011 */ },
|
||||||
{ .vendor = 0x138a, .product = 0x0015 /* Validity device from Lenovo Preferred Pro USB Fingerprint Keyboard KUF1256 */ },
|
|
||||||
{ .vendor = 0x138a, .product = 0x0017 /* Validity device from Lenovo T440 laptops */ },
|
{ .vendor = 0x138a, .product = 0x0017 /* Validity device from Lenovo T440 laptops */ },
|
||||||
{ .vendor = 0x138a, .product = 0x0018 /* one more Validity device */ },
|
{ .vendor = 0x138a, .product = 0x0018 /* one more Validity device */ },
|
||||||
{ 0, 0, 0, },
|
{ 0, 0, 0, },
|
||||||
|
|||||||
@@ -23,17 +23,282 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef FP_COMPONENT
|
||||||
|
#undef G_LOG_DOMAIN
|
||||||
|
#define G_LOG_DOMAIN "libfprint-"FP_COMPONENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <libusb.h>
|
||||||
|
|
||||||
#include "fprint.h"
|
#include "fprint.h"
|
||||||
#include "fpi-log.h"
|
#include "assembling.h"
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-dev-img.h"
|
|
||||||
#include "fpi-core.h"
|
|
||||||
#include "fpi-ssm.h"
|
|
||||||
#include "fpi-poll.h"
|
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-usb.h"
|
|
||||||
#include "fpi-img.h"
|
|
||||||
#include "fpi-assembling.h"
|
|
||||||
#include "drivers/driver_ids.h"
|
#include "drivers/driver_ids.h"
|
||||||
|
|
||||||
|
#define fp_dbg g_debug
|
||||||
|
#define fp_info g_debug
|
||||||
|
#define fp_warn g_warning
|
||||||
|
#define fp_err g_error
|
||||||
|
|
||||||
|
#define BUG_ON(condition) g_assert(!(condition))
|
||||||
|
#define BUG() g_assert_not_reached()
|
||||||
|
|
||||||
|
enum fp_dev_state {
|
||||||
|
DEV_STATE_INITIAL = 0,
|
||||||
|
DEV_STATE_ERROR,
|
||||||
|
DEV_STATE_INITIALIZING,
|
||||||
|
DEV_STATE_INITIALIZED,
|
||||||
|
DEV_STATE_DEINITIALIZING,
|
||||||
|
DEV_STATE_DEINITIALIZED,
|
||||||
|
DEV_STATE_ENROLL_STARTING,
|
||||||
|
DEV_STATE_ENROLLING,
|
||||||
|
DEV_STATE_ENROLL_STOPPING,
|
||||||
|
DEV_STATE_VERIFY_STARTING,
|
||||||
|
DEV_STATE_VERIFYING,
|
||||||
|
DEV_STATE_VERIFY_DONE,
|
||||||
|
DEV_STATE_VERIFY_STOPPING,
|
||||||
|
DEV_STATE_IDENTIFY_STARTING,
|
||||||
|
DEV_STATE_IDENTIFYING,
|
||||||
|
DEV_STATE_IDENTIFY_DONE,
|
||||||
|
DEV_STATE_IDENTIFY_STOPPING,
|
||||||
|
DEV_STATE_CAPTURE_STARTING,
|
||||||
|
DEV_STATE_CAPTURING,
|
||||||
|
DEV_STATE_CAPTURE_DONE,
|
||||||
|
DEV_STATE_CAPTURE_STOPPING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_dev;
|
||||||
|
libusb_device_handle *fpi_dev_get_usb_dev(struct fp_dev *dev);
|
||||||
|
void *fpi_dev_get_user_data (struct fp_dev *dev);
|
||||||
|
void fpi_dev_set_user_data (struct fp_dev *dev, void *user_data);
|
||||||
|
int fpi_dev_get_nr_enroll_stages(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);
|
||||||
|
enum fp_dev_state fpi_dev_get_dev_state(struct fp_dev *dev);
|
||||||
|
|
||||||
|
enum fp_imgdev_state {
|
||||||
|
IMGDEV_STATE_INACTIVE,
|
||||||
|
IMGDEV_STATE_AWAIT_FINGER_ON,
|
||||||
|
IMGDEV_STATE_CAPTURE,
|
||||||
|
IMGDEV_STATE_AWAIT_FINGER_OFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_action {
|
||||||
|
IMG_ACTION_NONE = 0,
|
||||||
|
IMG_ACTION_ENROLL,
|
||||||
|
IMG_ACTION_VERIFY,
|
||||||
|
IMG_ACTION_IDENTIFY,
|
||||||
|
IMG_ACTION_CAPTURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_enroll_state {
|
||||||
|
IMG_ACQUIRE_STATE_NONE = 0,
|
||||||
|
IMG_ACQUIRE_STATE_ACTIVATING,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_FINGER_ON,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_IMAGE,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF,
|
||||||
|
IMG_ACQUIRE_STATE_DONE,
|
||||||
|
IMG_ACQUIRE_STATE_DEACTIVATING,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_verify_state {
|
||||||
|
IMG_VERIFY_STATE_NONE = 0,
|
||||||
|
IMG_VERIFY_STATE_ACTIVATING
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_img_dev;
|
||||||
|
libusb_device_handle *fpi_imgdev_get_usb_dev(struct fp_img_dev *dev);
|
||||||
|
void fpi_imgdev_set_user_data(struct fp_img_dev *imgdev,
|
||||||
|
void *user_data);
|
||||||
|
void *fpi_imgdev_get_user_data(struct fp_img_dev *imgdev);
|
||||||
|
struct fp_dev *fpi_imgdev_get_dev(struct fp_img_dev *imgdev);
|
||||||
|
enum fp_imgdev_enroll_state fpi_imgdev_get_action_state(struct fp_img_dev *imgdev);
|
||||||
|
enum fp_imgdev_action fpi_imgdev_get_action(struct fp_img_dev *imgdev);
|
||||||
|
int fpi_imgdev_get_action_result(struct fp_img_dev *imgdev);
|
||||||
|
void fpi_imgdev_set_action_result(struct fp_img_dev *imgdev, int action_result);
|
||||||
|
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev);
|
||||||
|
int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev);
|
||||||
|
|
||||||
|
struct usb_id {
|
||||||
|
uint16_t vendor;
|
||||||
|
uint16_t product;
|
||||||
|
unsigned long driver_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_driver_type {
|
||||||
|
DRIVER_PRIMITIVE = 0,
|
||||||
|
DRIVER_IMAGING = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_driver {
|
||||||
|
const uint16_t id;
|
||||||
|
const char *name;
|
||||||
|
const char *full_name;
|
||||||
|
const struct usb_id * const id_table;
|
||||||
|
enum fp_driver_type type;
|
||||||
|
enum fp_scan_type scan_type;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
|
|
||||||
|
/* Device operations */
|
||||||
|
int (*discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype);
|
||||||
|
int (*open)(struct fp_dev *dev, unsigned long driver_data);
|
||||||
|
void (*close)(struct fp_dev *dev);
|
||||||
|
int (*enroll_start)(struct fp_dev *dev);
|
||||||
|
int (*enroll_stop)(struct fp_dev *dev);
|
||||||
|
int (*verify_start)(struct fp_dev *dev);
|
||||||
|
int (*verify_stop)(struct fp_dev *dev, gboolean iterating);
|
||||||
|
int (*identify_start)(struct fp_dev *dev);
|
||||||
|
int (*identify_stop)(struct fp_dev *dev, gboolean iterating);
|
||||||
|
int (*capture_start)(struct fp_dev *dev);
|
||||||
|
int (*capture_stop)(struct fp_dev *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* flags for fp_img_driver.flags */
|
||||||
|
#define FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE (1 << 0)
|
||||||
|
|
||||||
|
struct fp_img_driver {
|
||||||
|
struct fp_driver driver;
|
||||||
|
uint16_t flags;
|
||||||
|
int img_width;
|
||||||
|
int img_height;
|
||||||
|
int bz3_threshold;
|
||||||
|
|
||||||
|
/* Device operations */
|
||||||
|
int (*open)(struct fp_img_dev *dev, unsigned long driver_data);
|
||||||
|
void (*close)(struct fp_img_dev *dev);
|
||||||
|
int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||||
|
int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||||
|
void (*deactivate)(struct fp_img_dev *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_print_data_type {
|
||||||
|
PRINT_DATA_RAW = 0, /* memset-imposed default */
|
||||||
|
PRINT_DATA_NBIS_MINUTIAE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_print_data_item {
|
||||||
|
size_t length;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_print_data {
|
||||||
|
uint16_t driver_id;
|
||||||
|
uint32_t devtype;
|
||||||
|
enum fp_print_data_type type;
|
||||||
|
GSList *prints;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev);
|
||||||
|
struct fp_print_data_item *fpi_print_data_item_new(size_t length);
|
||||||
|
gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
|
||||||
|
enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
|
||||||
|
enum fp_print_data_type type2);
|
||||||
|
|
||||||
|
struct fp_minutiae;
|
||||||
|
|
||||||
|
/* bit values for fp_img.flags */
|
||||||
|
#define FP_IMG_V_FLIPPED (1<<0)
|
||||||
|
#define FP_IMG_H_FLIPPED (1<<1)
|
||||||
|
#define FP_IMG_COLORS_INVERTED (1<<2)
|
||||||
|
#define FP_IMG_BINARIZED_FORM (1<<3)
|
||||||
|
#define FP_IMG_PARTIAL (1<<4)
|
||||||
|
|
||||||
|
#define FP_IMG_STANDARDIZATION_FLAGS (FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED \
|
||||||
|
| FP_IMG_COLORS_INVERTED)
|
||||||
|
|
||||||
|
struct fp_img {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
size_t length;
|
||||||
|
uint16_t flags;
|
||||||
|
struct fp_minutiae *minutiae;
|
||||||
|
unsigned char *binarized;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_img *fpi_img_new(size_t length);
|
||||||
|
struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev);
|
||||||
|
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize);
|
||||||
|
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor);
|
||||||
|
|
||||||
|
/* polling and timeouts */
|
||||||
|
|
||||||
|
typedef void (*fpi_timeout_fn)(void *data);
|
||||||
|
|
||||||
|
struct fpi_timeout;
|
||||||
|
struct fpi_timeout *fpi_timeout_add(unsigned int msec, fpi_timeout_fn callback,
|
||||||
|
void *data);
|
||||||
|
void fpi_timeout_cancel(struct fpi_timeout *timeout);
|
||||||
|
|
||||||
|
/* async drv <--> lib comms */
|
||||||
|
|
||||||
|
struct fpi_ssm;
|
||||||
|
typedef void (*ssm_completed_fn)(struct fpi_ssm *ssm);
|
||||||
|
typedef void (*ssm_handler_fn)(struct fpi_ssm *ssm);
|
||||||
|
|
||||||
|
/* sequential state machine: state machine that iterates sequentially over
|
||||||
|
* a predefined series of states. can be aborted by either completion or
|
||||||
|
* abortion error conditions. */
|
||||||
|
|
||||||
|
/* for library and drivers */
|
||||||
|
struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler,
|
||||||
|
int nr_states);
|
||||||
|
void fpi_ssm_free(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback);
|
||||||
|
void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child);
|
||||||
|
|
||||||
|
/* for drivers */
|
||||||
|
void fpi_ssm_next_state(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state);
|
||||||
|
void fpi_ssm_mark_completed(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error);
|
||||||
|
struct fp_dev *fpi_ssm_get_dev(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_set_user_data(struct fpi_ssm *machine,
|
||||||
|
void *user_data);
|
||||||
|
void *fpi_ssm_get_user_data(struct fpi_ssm *machine);
|
||||||
|
int fpi_ssm_get_error(struct fpi_ssm *machine);
|
||||||
|
int fpi_ssm_get_cur_state(struct fpi_ssm *machine);
|
||||||
|
|
||||||
|
void fpi_drvcb_open_complete(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_close_complete(struct fp_dev *dev);
|
||||||
|
|
||||||
|
void fpi_drvcb_enroll_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
|
||||||
|
struct fp_print_data *data, struct fp_img *img);
|
||||||
|
void fpi_drvcb_enroll_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
|
void fpi_drvcb_verify_started(struct fp_dev *dev, int status);
|
||||||
|
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_identify_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
||||||
|
size_t match_offset, struct fp_img *img);
|
||||||
|
void fpi_drvcb_identify_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
|
void fpi_drvcb_capture_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result,
|
||||||
|
struct fp_img *img);
|
||||||
|
void fpi_drvcb_capture_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
|
/* for image drivers */
|
||||||
|
void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status);
|
||||||
|
void fpi_imgdev_close_complete(struct fp_img_dev *imgdev);
|
||||||
|
void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status);
|
||||||
|
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev);
|
||||||
|
void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
||||||
|
gboolean present);
|
||||||
|
void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img);
|
||||||
|
void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result);
|
||||||
|
void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error);
|
||||||
|
|
||||||
|
/* utils */
|
||||||
|
int fpi_std_sq_dev(const unsigned char *buf, int size);
|
||||||
|
int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
199
libfprint/drv.c
Normal file
199
libfprint/drv.c
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Functions to assist with asynchronous driver <---> library communications
|
||||||
|
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
||||||
|
*
|
||||||
|
* 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 "drv"
|
||||||
|
|
||||||
|
#include "fp_internal.h"
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* next state, you never jump or go backwards. The SSM functions help you
|
||||||
|
* implement such a machine.
|
||||||
|
*
|
||||||
|
* e.g. S1 --> S2 --> S3 --> S4
|
||||||
|
* S1 is the start state
|
||||||
|
* There is also an implicit error state and an implicit accepting state
|
||||||
|
* (both with implicit edges from every state).
|
||||||
|
*
|
||||||
|
* You can also jump to any arbitrary state (while marking completion of the
|
||||||
|
* current state) while the machine is running. In other words there are
|
||||||
|
* implicit edges linking one state to every other state. OK, we're stretching
|
||||||
|
* the "state machine" description at this point.
|
||||||
|
*
|
||||||
|
* To create a ssm, you pass a state handler function and the total number of
|
||||||
|
* states (4 in the above example).
|
||||||
|
*
|
||||||
|
* To start a ssm, you pass in a completion callback function which gets
|
||||||
|
* called when the ssm completes (both on error and on failure).
|
||||||
|
*
|
||||||
|
* To iterate to the next state, call fpi_ssm_next_state(). It is legal to
|
||||||
|
* attempt to iterate beyond the final state - this is equivalent to marking
|
||||||
|
* the ssm as successfully completed.
|
||||||
|
*
|
||||||
|
* To mark successful completion of a SSM, either iterate beyond the final
|
||||||
|
* state or call fpi_ssm_mark_completed() from any state.
|
||||||
|
*
|
||||||
|
* To mark failed completion of a SSM, call fpi_ssm_mark_aborted() from any
|
||||||
|
* state. You must pass a non-zero error code.
|
||||||
|
*
|
||||||
|
* Your state handling function looks at ssm->cur_state in order to determine
|
||||||
|
* the current state and hence which operations to perform (a switch statement
|
||||||
|
* is appropriate).
|
||||||
|
* Typically, the state handling function fires off an asynchronous libusb
|
||||||
|
* transfer, and the callback function iterates the machine to the next state
|
||||||
|
* upon success (or aborts the machine on transfer failure).
|
||||||
|
*
|
||||||
|
* Your completion callback should examine ssm->error in order to determine
|
||||||
|
* whether the ssm completed or failed. An error code of zero indicates
|
||||||
|
* successful completion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Allocate a new ssm */
|
||||||
|
struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler,
|
||||||
|
int nr_states)
|
||||||
|
{
|
||||||
|
struct fpi_ssm *machine;
|
||||||
|
BUG_ON(nr_states < 1);
|
||||||
|
|
||||||
|
machine = g_malloc0(sizeof(*machine));
|
||||||
|
machine->handler = handler;
|
||||||
|
machine->nr_states = nr_states;
|
||||||
|
machine->dev = dev;
|
||||||
|
machine->completed = TRUE;
|
||||||
|
return machine;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fp_dev *
|
||||||
|
fpi_ssm_get_dev(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
return machine->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fpi_ssm_set_user_data(struct fpi_ssm *machine,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
machine->priv = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
fpi_ssm_get_user_data(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
return machine->priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a ssm */
|
||||||
|
void fpi_ssm_free(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
if (!machine)
|
||||||
|
return;
|
||||||
|
g_free(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invoke the state handler */
|
||||||
|
static void __ssm_call_handler(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
fp_dbg("%p entering state %d", machine, machine->cur_state);
|
||||||
|
machine->handler(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start a ssm. You can also restart a completed or aborted ssm. */
|
||||||
|
void fpi_ssm_start(struct fpi_ssm *ssm, ssm_completed_fn callback)
|
||||||
|
{
|
||||||
|
BUG_ON(!ssm->completed);
|
||||||
|
ssm->callback = callback;
|
||||||
|
ssm->cur_state = 0;
|
||||||
|
ssm->completed = FALSE;
|
||||||
|
ssm->error = 0;
|
||||||
|
__ssm_call_handler(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __subsm_complete(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fpi_ssm *parent = ssm->parentsm;
|
||||||
|
BUG_ON(!parent);
|
||||||
|
if (ssm->error)
|
||||||
|
fpi_ssm_mark_aborted(parent, ssm->error);
|
||||||
|
else
|
||||||
|
fpi_ssm_next_state(parent);
|
||||||
|
fpi_ssm_free(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start a SSM as a child of another. if the child completes successfully, the
|
||||||
|
* parent will be advanced to the next state. if the child aborts, the parent
|
||||||
|
* will be aborted with the same error code. the child will be automatically
|
||||||
|
* freed upon completion/abortion. */
|
||||||
|
void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child)
|
||||||
|
{
|
||||||
|
child->parentsm = parent;
|
||||||
|
fpi_ssm_start(child, __subsm_complete);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark a ssm as completed successfully. */
|
||||||
|
void fpi_ssm_mark_completed(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
BUG_ON(machine->completed);
|
||||||
|
machine->completed = TRUE;
|
||||||
|
fp_dbg("%p completed with status %d", machine, machine->error);
|
||||||
|
if (machine->callback)
|
||||||
|
machine->callback(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark a ssm as aborted with error. */
|
||||||
|
void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error)
|
||||||
|
{
|
||||||
|
fp_dbg("error %d from state %d", error, machine->cur_state);
|
||||||
|
BUG_ON(error == 0);
|
||||||
|
machine->error = error;
|
||||||
|
fpi_ssm_mark_completed(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate to next state of a ssm */
|
||||||
|
void fpi_ssm_next_state(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
BUG_ON(machine->completed);
|
||||||
|
machine->cur_state++;
|
||||||
|
if (machine->cur_state == machine->nr_states) {
|
||||||
|
fpi_ssm_mark_completed(machine);
|
||||||
|
} else {
|
||||||
|
__ssm_call_handler(machine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state)
|
||||||
|
{
|
||||||
|
BUG_ON(machine->completed);
|
||||||
|
BUG_ON(state >= machine->nr_states);
|
||||||
|
machine->cur_state = state;
|
||||||
|
__ssm_call_handler(machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fpi_ssm_get_cur_state(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
return machine->cur_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fpi_ssm_get_error(struct fpi_ssm *machine)
|
||||||
|
{
|
||||||
|
return machine->error;
|
||||||
|
}
|
||||||
@@ -22,39 +22,31 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef FP_COMPONENT
|
||||||
|
#undef G_LOG_DOMAIN
|
||||||
|
#define G_LOG_DOMAIN "libfprint-"FP_COMPONENT
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
#include "nbis-helpers.h"
|
|
||||||
#include "fprint.h"
|
#include "fprint.h"
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-core.h"
|
|
||||||
#include "fpi-log.h"
|
|
||||||
#include "fpi-dev-img.h"
|
|
||||||
#include "fpi-data.h"
|
|
||||||
#include "fpi-img.h"
|
|
||||||
#include "drivers/driver_ids.h"
|
#include "drivers/driver_ids.h"
|
||||||
|
|
||||||
/* Global variables */
|
#define container_of(ptr, type, member) ({ \
|
||||||
extern libusb_context *fpi_usb_ctx;
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
extern GSList *opened_devices;
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
/* fp_print_data structure definition */
|
#define fp_dbg g_debug
|
||||||
enum fp_print_data_type {
|
#define fp_info g_debug
|
||||||
PRINT_DATA_RAW = 0, /* memset-imposed default */
|
#define fp_warn g_warning
|
||||||
PRINT_DATA_NBIS_MINUTIAE
|
#define fp_err g_error
|
||||||
};
|
|
||||||
|
|
||||||
struct fp_print_data {
|
#define BUG_ON(condition) g_assert(!(condition))
|
||||||
uint16_t driver_id;
|
#define BUG() g_assert_not_reached()
|
||||||
uint32_t devtype;
|
|
||||||
enum fp_print_data_type type;
|
|
||||||
GSList *prints;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* fp_dev structure definition */
|
|
||||||
enum fp_dev_state {
|
enum fp_dev_state {
|
||||||
DEV_STATE_INITIAL = 0,
|
DEV_STATE_INITIAL = 0,
|
||||||
DEV_STATE_ERROR,
|
DEV_STATE_ERROR,
|
||||||
@@ -77,31 +69,21 @@ enum fp_dev_state {
|
|||||||
DEV_STATE_CAPTURING,
|
DEV_STATE_CAPTURING,
|
||||||
DEV_STATE_CAPTURE_DONE,
|
DEV_STATE_CAPTURE_DONE,
|
||||||
DEV_STATE_CAPTURE_STOPPING,
|
DEV_STATE_CAPTURE_STOPPING,
|
||||||
DEV_STATE_DELETING,
|
|
||||||
DEV_STATE_DELETE_DONE,
|
|
||||||
DEV_STATE_DELETE_STOPPING,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fp_driver **fprint_get_drivers (void);
|
||||||
|
|
||||||
struct fp_dev {
|
struct fp_dev {
|
||||||
struct fp_driver *drv;
|
struct fp_driver *drv;
|
||||||
|
libusb_device_handle *udev;
|
||||||
uint32_t devtype;
|
uint32_t devtype;
|
||||||
|
void *priv;
|
||||||
/* only valid if drv->type == DRIVER_IMAGING */
|
|
||||||
struct fp_img_dev *img_dev;
|
|
||||||
/* Link to the instance specific struct */
|
|
||||||
void *instance_data;
|
|
||||||
|
|
||||||
int nr_enroll_stages;
|
int nr_enroll_stages;
|
||||||
|
|
||||||
/* FIXME: This will eventually have a bus type */
|
|
||||||
libusb_device_handle *udev;
|
|
||||||
|
|
||||||
/* read-only to drivers */
|
/* read-only to drivers */
|
||||||
struct fp_print_data *verify_data;
|
struct fp_print_data *verify_data;
|
||||||
|
|
||||||
|
|
||||||
struct fp_print_data *delete_data;
|
|
||||||
|
|
||||||
/* drivers should not mess with any of the below */
|
/* drivers should not mess with any of the below */
|
||||||
enum fp_dev_state state;
|
enum fp_dev_state state;
|
||||||
int __enroll_stage;
|
int __enroll_stage;
|
||||||
@@ -129,17 +111,44 @@ struct fp_dev {
|
|||||||
void *capture_cb_data;
|
void *capture_cb_data;
|
||||||
fp_operation_stop_cb capture_stop_cb;
|
fp_operation_stop_cb capture_stop_cb;
|
||||||
void *capture_stop_cb_data;
|
void *capture_stop_cb_data;
|
||||||
fp_delete_cb delete_cb;
|
|
||||||
void *delete_cb_data;
|
|
||||||
|
|
||||||
/* FIXME: better place to put this? */
|
/* FIXME: better place to put this? */
|
||||||
struct fp_print_data **identify_gallery;
|
struct fp_print_data **identify_gallery;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_img_dev structure definition */
|
enum fp_imgdev_state {
|
||||||
struct fp_img_dev {
|
IMGDEV_STATE_INACTIVE,
|
||||||
struct fp_dev *parent;
|
IMGDEV_STATE_AWAIT_FINGER_ON,
|
||||||
|
IMGDEV_STATE_CAPTURE,
|
||||||
|
IMGDEV_STATE_AWAIT_FINGER_OFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_action {
|
||||||
|
IMG_ACTION_NONE = 0,
|
||||||
|
IMG_ACTION_ENROLL,
|
||||||
|
IMG_ACTION_VERIFY,
|
||||||
|
IMG_ACTION_IDENTIFY,
|
||||||
|
IMG_ACTION_CAPTURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_enroll_state {
|
||||||
|
IMG_ACQUIRE_STATE_NONE = 0,
|
||||||
|
IMG_ACQUIRE_STATE_ACTIVATING,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_FINGER_ON,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_IMAGE,
|
||||||
|
IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF,
|
||||||
|
IMG_ACQUIRE_STATE_DONE,
|
||||||
|
IMG_ACQUIRE_STATE_DEACTIVATING,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_imgdev_verify_state {
|
||||||
|
IMG_VERIFY_STATE_NONE = 0,
|
||||||
|
IMG_VERIFY_STATE_ACTIVATING
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_img_dev {
|
||||||
|
struct fp_dev *dev;
|
||||||
|
libusb_device_handle *udev;
|
||||||
enum fp_imgdev_action action;
|
enum fp_imgdev_action action;
|
||||||
int action_state;
|
int action_state;
|
||||||
|
|
||||||
@@ -151,18 +160,78 @@ struct fp_img_dev {
|
|||||||
|
|
||||||
/* FIXME: better place to put this? */
|
/* FIXME: better place to put this? */
|
||||||
size_t identify_match_offset;
|
size_t identify_match_offset;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_driver structure definition */
|
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev);
|
||||||
|
int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev);
|
||||||
|
|
||||||
|
struct usb_id {
|
||||||
|
uint16_t vendor;
|
||||||
|
uint16_t product;
|
||||||
|
unsigned long driver_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_driver_type {
|
||||||
|
DRIVER_PRIMITIVE = 0,
|
||||||
|
DRIVER_IMAGING = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_driver {
|
||||||
|
const uint16_t id;
|
||||||
|
const char *name;
|
||||||
|
const char *full_name;
|
||||||
|
const struct usb_id * const id_table;
|
||||||
|
enum fp_driver_type type;
|
||||||
|
enum fp_scan_type scan_type;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
|
|
||||||
|
/* Device operations */
|
||||||
|
int (*discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype);
|
||||||
|
int (*open)(struct fp_dev *dev, unsigned long driver_data);
|
||||||
|
void (*close)(struct fp_dev *dev);
|
||||||
|
int (*enroll_start)(struct fp_dev *dev);
|
||||||
|
int (*enroll_stop)(struct fp_dev *dev);
|
||||||
|
int (*verify_start)(struct fp_dev *dev);
|
||||||
|
int (*verify_stop)(struct fp_dev *dev, gboolean iterating);
|
||||||
|
int (*identify_start)(struct fp_dev *dev);
|
||||||
|
int (*identify_stop)(struct fp_dev *dev, gboolean iterating);
|
||||||
|
int (*capture_start)(struct fp_dev *dev);
|
||||||
|
int (*capture_stop)(struct fp_dev *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv);
|
||||||
|
|
||||||
|
/* flags for fp_img_driver.flags */
|
||||||
|
#define FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE (1 << 0)
|
||||||
|
|
||||||
|
struct fp_img_driver {
|
||||||
|
struct fp_driver driver;
|
||||||
|
uint16_t flags;
|
||||||
|
int img_width;
|
||||||
|
int img_height;
|
||||||
|
int bz3_threshold;
|
||||||
|
|
||||||
|
/* Device operations */
|
||||||
|
int (*open)(struct fp_img_dev *dev, unsigned long driver_data);
|
||||||
|
void (*close)(struct fp_img_dev *dev);
|
||||||
|
int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||||
|
int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||||
|
void (*deactivate)(struct fp_img_dev *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "drivers_definitions.h"
|
||||||
|
|
||||||
|
extern libusb_context *fpi_usb_ctx;
|
||||||
|
extern GSList *opened_devices;
|
||||||
|
|
||||||
|
void fpi_img_driver_setup(struct fp_img_driver *idriver);
|
||||||
|
|
||||||
/* fp_img_driver structure definition */
|
|
||||||
#define container_of(ptr, type, member) ({ \
|
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
||||||
#define fpi_driver_to_img_driver(drv) \
|
#define fpi_driver_to_img_driver(drv) \
|
||||||
container_of((drv), struct fp_img_driver, driver)
|
container_of((drv), struct fp_img_driver, driver)
|
||||||
|
|
||||||
/* fp_dscv_dev structure definition */
|
|
||||||
struct fp_dscv_dev {
|
struct fp_dscv_dev {
|
||||||
struct libusb_device *udev;
|
struct libusb_device *udev;
|
||||||
struct fp_driver *drv;
|
struct fp_driver *drv;
|
||||||
@@ -170,7 +239,6 @@ struct fp_dscv_dev {
|
|||||||
uint32_t devtype;
|
uint32_t devtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_dscv_print structure definition */
|
|
||||||
struct fp_dscv_print {
|
struct fp_dscv_print {
|
||||||
uint16_t driver_id;
|
uint16_t driver_id;
|
||||||
uint32_t devtype;
|
uint32_t devtype;
|
||||||
@@ -178,7 +246,43 @@ struct fp_dscv_print {
|
|||||||
char *path;
|
char *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_minutia structure definition */
|
enum fp_print_data_type {
|
||||||
|
PRINT_DATA_RAW = 0, /* memset-imposed default */
|
||||||
|
PRINT_DATA_NBIS_MINUTIAE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_print_data_item {
|
||||||
|
size_t length;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fp_print_data {
|
||||||
|
uint16_t driver_id;
|
||||||
|
uint32_t devtype;
|
||||||
|
enum fp_print_data_type type;
|
||||||
|
GSList *prints;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fpi_print_data_fp2 {
|
||||||
|
char prefix[3];
|
||||||
|
uint16_t driver_id;
|
||||||
|
uint32_t devtype;
|
||||||
|
unsigned char data_type;
|
||||||
|
unsigned char data[0];
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
struct fpi_print_data_item_fp2 {
|
||||||
|
uint32_t length;
|
||||||
|
unsigned char data[0];
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
void fpi_data_exit(void);
|
||||||
|
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev);
|
||||||
|
struct fp_print_data_item *fpi_print_data_item_new(size_t length);
|
||||||
|
gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
|
||||||
|
enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
|
||||||
|
enum fp_print_data_type type2);
|
||||||
|
|
||||||
struct fp_minutia {
|
struct fp_minutia {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
@@ -194,32 +298,34 @@ struct fp_minutia {
|
|||||||
int num_nbrs;
|
int num_nbrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_minutiae structure definition */
|
|
||||||
struct fp_minutiae {
|
struct fp_minutiae {
|
||||||
int alloc;
|
int alloc;
|
||||||
int num;
|
int num;
|
||||||
struct fp_minutia **list;
|
struct fp_minutia **list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Defined in fpi-dev-img.c */
|
/* bit values for fp_img.flags */
|
||||||
void fpi_img_driver_setup(struct fp_img_driver *idriver);
|
#define FP_IMG_V_FLIPPED (1<<0)
|
||||||
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev);
|
#define FP_IMG_H_FLIPPED (1<<1)
|
||||||
int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev);
|
#define FP_IMG_COLORS_INVERTED (1<<2)
|
||||||
|
#define FP_IMG_BINARIZED_FORM (1<<3)
|
||||||
|
#define FP_IMG_PARTIAL (1<<4)
|
||||||
|
|
||||||
/* Exported for use in command-line tools
|
#define FP_IMG_STANDARDIZATION_FLAGS (FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED \
|
||||||
* Defined in fpi-core.c */
|
| FP_IMG_COLORS_INVERTED)
|
||||||
struct fp_driver **fprint_get_drivers (void);
|
|
||||||
|
|
||||||
/* Defined in fpi-core.c */
|
struct fp_img {
|
||||||
enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv);
|
int width;
|
||||||
|
int height;
|
||||||
|
size_t length;
|
||||||
|
uint16_t flags;
|
||||||
|
struct fp_minutiae *minutiae;
|
||||||
|
unsigned char *binarized;
|
||||||
|
unsigned char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
/* Defined in fpi-data.c */
|
struct fp_img *fpi_img_new(size_t length);
|
||||||
void fpi_data_exit(void);
|
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize);
|
||||||
gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
|
|
||||||
enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
|
|
||||||
enum fp_print_data_type type2);
|
|
||||||
|
|
||||||
/* Defined in fpi-img.c */
|
|
||||||
gboolean fpi_img_is_sane(struct fp_img *img);
|
gboolean fpi_img_is_sane(struct fp_img *img);
|
||||||
int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
||||||
struct fp_print_data **ret);
|
struct fp_print_data **ret);
|
||||||
@@ -227,23 +333,71 @@ int fpi_img_compare_print_data(struct fp_print_data *enrolled_print,
|
|||||||
struct fp_print_data *new_print);
|
struct fp_print_data *new_print);
|
||||||
int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print,
|
int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print,
|
||||||
struct fp_print_data **gallery, int match_threshold, size_t *match_offset);
|
struct fp_print_data **gallery, int match_threshold, size_t *match_offset);
|
||||||
|
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor);
|
||||||
|
|
||||||
|
/* polling and timeouts */
|
||||||
|
|
||||||
/* Defined in fpi-poll.c */
|
|
||||||
void fpi_timeout_cancel_all_for_dev(struct fp_dev *dev);
|
|
||||||
void fpi_poll_init(void);
|
void fpi_poll_init(void);
|
||||||
void fpi_poll_exit(void);
|
void fpi_poll_exit(void);
|
||||||
|
|
||||||
/* Defined in fpi-async.c */
|
typedef void (*fpi_timeout_fn)(void *data);
|
||||||
void fpi_drvcb_capture_started(struct fp_dev *dev, int status);
|
|
||||||
void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result,
|
/* async drv <--> lib comms */
|
||||||
|
|
||||||
|
struct fpi_ssm;
|
||||||
|
typedef void (*ssm_completed_fn)(struct fpi_ssm *ssm);
|
||||||
|
typedef void (*ssm_handler_fn)(struct fpi_ssm *ssm);
|
||||||
|
|
||||||
|
/* sequential state machine: state machine that iterates sequentially over
|
||||||
|
* a predefined series of states. can be aborted by either completion or
|
||||||
|
* abortion error conditions. */
|
||||||
|
struct fpi_ssm {
|
||||||
|
struct fp_dev *dev;
|
||||||
|
struct fpi_ssm *parentsm;
|
||||||
|
void *priv;
|
||||||
|
int nr_states;
|
||||||
|
int cur_state;
|
||||||
|
gboolean completed;
|
||||||
|
int error;
|
||||||
|
ssm_completed_fn callback;
|
||||||
|
ssm_handler_fn handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* for library and drivers */
|
||||||
|
struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler,
|
||||||
|
int nr_states);
|
||||||
|
void fpi_ssm_free(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback);
|
||||||
|
|
||||||
|
/* for drivers */
|
||||||
|
void fpi_ssm_next_state(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state);
|
||||||
|
void fpi_ssm_mark_completed(struct fpi_ssm *machine);
|
||||||
|
void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error);
|
||||||
|
|
||||||
|
void fpi_drvcb_open_complete(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_close_complete(struct fp_dev *dev);
|
||||||
|
|
||||||
|
void fpi_drvcb_enroll_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
|
||||||
|
struct fp_print_data *data, struct fp_img *img);
|
||||||
|
void fpi_drvcb_enroll_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
|
void fpi_drvcb_verify_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result,
|
||||||
struct fp_img *img);
|
struct fp_img *img);
|
||||||
void fpi_drvcb_capture_stopped(struct fp_dev *dev);
|
void fpi_drvcb_verify_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
void fpi_drvcb_identify_started(struct fp_dev *dev, int status);
|
void fpi_drvcb_identify_started(struct fp_dev *dev, int status);
|
||||||
void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result,
|
||||||
size_t match_offset, struct fp_img *img);
|
size_t match_offset, struct fp_img *img);
|
||||||
void fpi_drvcb_identify_stopped(struct fp_dev *dev);
|
void fpi_drvcb_identify_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
#include "drivers_definitions.h"
|
void fpi_drvcb_capture_started(struct fp_dev *dev, int status);
|
||||||
|
void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result,
|
||||||
|
struct fp_img *img);
|
||||||
|
void fpi_drvcb_capture_stopped(struct fp_dev *dev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2015 Vasily Khoruzhick <anarsoul@gmail.com>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_ASSEMBLING_H__
|
|
||||||
#define __FPI_ASSEMBLING_H__
|
|
||||||
|
|
||||||
#include <fprint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_frame:
|
|
||||||
* @delta_x: X offset of the frame
|
|
||||||
* @delta_y: Y offset of the frame
|
|
||||||
* @data: bitmap
|
|
||||||
*
|
|
||||||
* #fpi_frame is used to store frames for swipe sensors. Drivers should
|
|
||||||
* populate delta_x and delta_y if the device supports hardware movement
|
|
||||||
* estimation.
|
|
||||||
*/
|
|
||||||
struct fpi_frame {
|
|
||||||
int delta_x;
|
|
||||||
int delta_y;
|
|
||||||
unsigned char data[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_frame_asmbl_ctx:
|
|
||||||
* @frame_width: width of the frame
|
|
||||||
* @frame_height: height of the frame
|
|
||||||
* @image_width: resulting image width
|
|
||||||
* @get_pixel: pixel accessor, returns pixel brightness at x,y of frame
|
|
||||||
*
|
|
||||||
* #fpi_frame_asmbl_ctx is a structure holding the context for frame
|
|
||||||
* assembling routines.
|
|
||||||
*
|
|
||||||
* Drivers should define their own #fpi_frame_asmbl_ctx depending on
|
|
||||||
* hardware parameters of scanner. @image_width is usually 25% wider than
|
|
||||||
* @frame_width to take horizontal movement into account.
|
|
||||||
*/
|
|
||||||
struct fpi_frame_asmbl_ctx {
|
|
||||||
unsigned int frame_width;
|
|
||||||
unsigned int frame_height;
|
|
||||||
unsigned int image_width;
|
|
||||||
unsigned char (*get_pixel)(struct fpi_frame_asmbl_ctx *ctx,
|
|
||||||
struct fpi_frame *frame,
|
|
||||||
unsigned int x,
|
|
||||||
unsigned int y);
|
|
||||||
};
|
|
||||||
|
|
||||||
void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx,
|
|
||||||
GSList *stripes, size_t num_stripes);
|
|
||||||
|
|
||||||
struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx,
|
|
||||||
GSList *stripes, size_t num_stripes);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_line_asmbl_ctx:
|
|
||||||
* @line_width: width of line
|
|
||||||
* @max_height: maximal height of assembled image
|
|
||||||
* @resolution: scale factor used for line assembling routines.
|
|
||||||
* @median_filter_size: size of median filter for movement estimation
|
|
||||||
* @max_search_offset: the number of lines to search for the next line
|
|
||||||
* @get_deviation: pointer to a function that returns the numerical difference
|
|
||||||
* between two lines
|
|
||||||
* @get_pixel: pixel accessor, returns pixel brightness at x of line
|
|
||||||
*
|
|
||||||
* #fpi_line_asmbl_ctx is a structure holding the context for line assembling
|
|
||||||
* routines.
|
|
||||||
*
|
|
||||||
* Drivers should define their own #fpi_line_asmbl_ctx depending on
|
|
||||||
* the hardware parameters of the scanner. Swipe scanners of this type usually
|
|
||||||
* return two lines, the second line is often narrower than first and is used
|
|
||||||
* for movement estimation.
|
|
||||||
*
|
|
||||||
* The @max_search_offset value indicates how many lines forward the assembling
|
|
||||||
* routines should look while searching for next line. This value depends on
|
|
||||||
* how fast the hardware sends frames.
|
|
||||||
*
|
|
||||||
* The function pointed to by @get_deviation should return the numerical difference
|
|
||||||
* between two lines. Higher values means lines are more different. If the reader
|
|
||||||
* returns two lines at a time, this function should be used to estimate the
|
|
||||||
* difference between pairs of lines.
|
|
||||||
*/
|
|
||||||
struct fpi_line_asmbl_ctx {
|
|
||||||
unsigned int line_width;
|
|
||||||
unsigned int max_height;
|
|
||||||
unsigned int resolution;
|
|
||||||
unsigned int median_filter_size;
|
|
||||||
unsigned int max_search_offset;
|
|
||||||
int (*get_deviation)(struct fpi_line_asmbl_ctx *ctx,
|
|
||||||
GSList *line1, GSList *line2);
|
|
||||||
unsigned char (*get_pixel)(struct fpi_line_asmbl_ctx *ctx,
|
|
||||||
GSList *line,
|
|
||||||
unsigned int x);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx,
|
|
||||||
GSList *lines, size_t num_lines);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_ASYNC_H__
|
|
||||||
#define __FPI_ASYNC_H__
|
|
||||||
|
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-data.h"
|
|
||||||
|
|
||||||
void fpi_drvcb_open_complete(struct fp_dev *dev, int status);
|
|
||||||
void fpi_drvcb_close_complete(struct fp_dev *dev);
|
|
||||||
|
|
||||||
void fpi_drvcb_enroll_started(struct fp_dev *dev, int status);
|
|
||||||
void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result,
|
|
||||||
struct fp_print_data *data, struct fp_img *img);
|
|
||||||
void fpi_drvcb_enroll_stopped(struct fp_dev *dev);
|
|
||||||
|
|
||||||
void fpi_drvcb_verify_started(struct fp_dev *dev, int status);
|
|
||||||
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
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_CORE_H__
|
|
||||||
#define __FPI_CORE_H__
|
|
||||||
|
|
||||||
#include <fprint.h>
|
|
||||||
#include "fpi-dev-img.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* usb_id:
|
|
||||||
* @vendor: the USB vendor ID
|
|
||||||
* @product: the USB product ID
|
|
||||||
* @driver_data: data to differentiate devices of different
|
|
||||||
* vendor and product IDs.
|
|
||||||
*
|
|
||||||
* The struct #usb_id is used to declare devices supported by a
|
|
||||||
* particular driver. The @driver_data information is used to
|
|
||||||
* differentiate different models of devices which only need
|
|
||||||
* small changes compared to the default driver behaviour to function.
|
|
||||||
*
|
|
||||||
* For example, a device might have a different initialisation from
|
|
||||||
* the stock device, so the driver could do:
|
|
||||||
*
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* if (driver_data == MY_DIFFERENT_DEVICE_QUIRK) {
|
|
||||||
* ...
|
|
||||||
* } else {
|
|
||||||
* ...
|
|
||||||
* }
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* The default value is zero, so the @driver_data needs to be a
|
|
||||||
* non-zero to be useful.
|
|
||||||
*/
|
|
||||||
struct usb_id {
|
|
||||||
uint16_t vendor;
|
|
||||||
uint16_t product;
|
|
||||||
unsigned long driver_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_driver_type:
|
|
||||||
* @DRIVER_PRIMITIVE: primitive, non-imaging, driver
|
|
||||||
* @DRIVER_IMAGING: imaging driver
|
|
||||||
*
|
|
||||||
* The type of device the driver supports.
|
|
||||||
*/
|
|
||||||
enum fp_driver_type {
|
|
||||||
DRIVER_PRIMITIVE = 0,
|
|
||||||
DRIVER_IMAGING = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fp_driver {
|
|
||||||
const uint16_t id;
|
|
||||||
const char *name;
|
|
||||||
const char *full_name;
|
|
||||||
const struct usb_id * const id_table;
|
|
||||||
enum fp_driver_type type;
|
|
||||||
enum fp_scan_type scan_type;
|
|
||||||
|
|
||||||
/* Device operations */
|
|
||||||
int (*discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype);
|
|
||||||
int (*open)(struct fp_dev *dev, unsigned long driver_data);
|
|
||||||
void (*close)(struct fp_dev *dev);
|
|
||||||
int (*enroll_start)(struct fp_dev *dev);
|
|
||||||
int (*enroll_stop)(struct fp_dev *dev);
|
|
||||||
int (*verify_start)(struct fp_dev *dev);
|
|
||||||
int (*verify_stop)(struct fp_dev *dev, gboolean iterating);
|
|
||||||
int (*identify_start)(struct fp_dev *dev);
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FpiImgDriverFlags:
|
|
||||||
* @FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE: Whether the driver supports
|
|
||||||
* unconditional image capture. No driver currently does.
|
|
||||||
*
|
|
||||||
* Flags used in the #fp_img_driver to advertise the capabilities of drivers.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE = 1 << 0
|
|
||||||
} FpiImgDriverFlags;
|
|
||||||
|
|
||||||
struct fp_img_driver {
|
|
||||||
struct fp_driver driver;
|
|
||||||
FpiImgDriverFlags flags;
|
|
||||||
int img_width;
|
|
||||||
int img_height;
|
|
||||||
int bz3_threshold;
|
|
||||||
|
|
||||||
/* Device operations */
|
|
||||||
int (*open)(struct fp_img_dev *dev, unsigned long driver_data);
|
|
||||||
void (*close)(struct fp_img_dev *dev);
|
|
||||||
int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
|
||||||
int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
|
||||||
void (*deactivate)(struct fp_img_dev *dev);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_DATA_H__
|
|
||||||
#define __FPI_DATA_H__
|
|
||||||
|
|
||||||
struct fp_print_data;
|
|
||||||
struct fp_print_data_item {
|
|
||||||
size_t length;
|
|
||||||
unsigned char data[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev);
|
|
||||||
struct fp_print_data_item *fpi_print_data_item_new(size_t length);
|
|
||||||
struct fp_print_data_item *fpi_print_data_get_item(struct fp_print_data *data);
|
|
||||||
void fpi_print_data_add_item(struct fp_print_data *data, struct fp_print_data_item *item);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_DEV_IMG_H__
|
|
||||||
#define __FPI_DEV_IMG_H__
|
|
||||||
|
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-img.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_imgdev_action:
|
|
||||||
* @IMG_ACTION_NONE: no action
|
|
||||||
* @IMG_ACTION_ENROLL: device action is enrolling
|
|
||||||
* @IMG_ACTION_VERIFY: device action is verifying
|
|
||||||
* @IMG_ACTION_IDENTIFY: device action is identifying
|
|
||||||
* @IMG_ACTION_CAPTURE: device action is capturing
|
|
||||||
*
|
|
||||||
* The current action being performed by an imaging device. The current
|
|
||||||
* action can be gathered inside the driver using fpi_imgdev_get_action().
|
|
||||||
*/
|
|
||||||
enum fp_imgdev_action {
|
|
||||||
IMG_ACTION_NONE = 0,
|
|
||||||
IMG_ACTION_ENROLL,
|
|
||||||
IMG_ACTION_VERIFY,
|
|
||||||
IMG_ACTION_IDENTIFY,
|
|
||||||
IMG_ACTION_CAPTURE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_imgdev_state:
|
|
||||||
* @IMGDEV_STATE_INACTIVE: inactive
|
|
||||||
* @IMGDEV_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
|
|
||||||
* @IMGDEV_STATE_CAPTURE: capturing an image
|
|
||||||
* @IMGDEV_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
|
|
||||||
*
|
|
||||||
* The state of an imaging device while doing a capture. The state is
|
|
||||||
* passed through to the driver using the ::activate() or ::change_state() vfuncs.
|
|
||||||
*/
|
|
||||||
enum fp_imgdev_state {
|
|
||||||
IMGDEV_STATE_INACTIVE,
|
|
||||||
IMGDEV_STATE_AWAIT_FINGER_ON,
|
|
||||||
IMGDEV_STATE_CAPTURE,
|
|
||||||
IMGDEV_STATE_AWAIT_FINGER_OFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_imgdev_enroll_state:
|
|
||||||
* @IMG_ACQUIRE_STATE_NONE: doing nothing
|
|
||||||
* @IMG_ACQUIRE_STATE_ACTIVATING: activating the device
|
|
||||||
* @IMG_ACQUIRE_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
|
|
||||||
* @IMG_ACQUIRE_STATE_AWAIT_IMAGE: waiting for the image to be captured
|
|
||||||
* @IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
|
|
||||||
* @IMG_ACQUIRE_STATE_DONE: enrollment has all the images it needs
|
|
||||||
* @IMG_ACQUIRE_STATE_DEACTIVATING: deactivating the device
|
|
||||||
*
|
|
||||||
* The state of an imaging device while enrolling a fingerprint. Given that enrollment
|
|
||||||
* requires multiple captures, a number of those states will be repeated before
|
|
||||||
* the state is @IMG_ACQUIRE_STATE_DONE.
|
|
||||||
*/
|
|
||||||
enum fp_imgdev_enroll_state {
|
|
||||||
IMG_ACQUIRE_STATE_NONE = 0,
|
|
||||||
IMG_ACQUIRE_STATE_ACTIVATING,
|
|
||||||
IMG_ACQUIRE_STATE_AWAIT_FINGER_ON,
|
|
||||||
IMG_ACQUIRE_STATE_AWAIT_IMAGE,
|
|
||||||
IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF,
|
|
||||||
IMG_ACQUIRE_STATE_DONE,
|
|
||||||
IMG_ACQUIRE_STATE_DEACTIVATING,
|
|
||||||
};
|
|
||||||
|
|
||||||
void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status);
|
|
||||||
void fpi_imgdev_close_complete(struct fp_img_dev *imgdev);
|
|
||||||
void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status);
|
|
||||||
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev);
|
|
||||||
void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
|
||||||
gboolean present);
|
|
||||||
void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img);
|
|
||||||
void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result);
|
|
||||||
void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error);
|
|
||||||
|
|
||||||
enum fp_imgdev_enroll_state fpi_imgdev_get_action_state(struct fp_img_dev *imgdev);
|
|
||||||
enum fp_imgdev_action fpi_imgdev_get_action(struct fp_img_dev *imgdev);
|
|
||||||
int fpi_imgdev_get_action_result(struct fp_img_dev *imgdev);
|
|
||||||
void fpi_imgdev_set_action_result(struct fp_img_dev *imgdev, int action_result);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* fp_dev types manipulation
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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 "fp_internal.h"
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-dev
|
|
||||||
* @title: Device operations
|
|
||||||
* @short_description: Device operation functions
|
|
||||||
*
|
|
||||||
* Those macros and functions will help get access to and from struct #fp_dev,
|
|
||||||
* and struct #fp_img_dev types, as well as get and set the instance struct
|
|
||||||
* data, eg. the structure containing the data specific to each driver.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FP_DEV:
|
|
||||||
* @dev: a struct #fp_img_dev
|
|
||||||
*
|
|
||||||
* Returns the struct #fp_dev associated with @dev, or %NULL on failure.
|
|
||||||
*
|
|
||||||
* Returns: a struct #fp_dev or %NULL
|
|
||||||
*/
|
|
||||||
struct fp_dev *
|
|
||||||
FP_DEV(struct fp_img_dev *dev)
|
|
||||||
{
|
|
||||||
struct fp_img_dev *imgdev;
|
|
||||||
|
|
||||||
g_return_val_if_fail (dev, NULL);
|
|
||||||
imgdev = (struct fp_img_dev *) dev;
|
|
||||||
return imgdev->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FP_IMG_DEV:
|
|
||||||
* @dev: a struct #fp_dev representing an imaging device.
|
|
||||||
*
|
|
||||||
* Returns a struct #fp_img_dev associated with @dev, or %NULL on failure.
|
|
||||||
*
|
|
||||||
* Returns: a struct #fp_img_dev or %NULL
|
|
||||||
*/
|
|
||||||
struct fp_img_dev *
|
|
||||||
FP_IMG_DEV(struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (dev, NULL);
|
|
||||||
g_return_val_if_fail (dev->drv, NULL);
|
|
||||||
g_return_val_if_fail (dev->drv->type == DRIVER_IMAGING, NULL);
|
|
||||||
return dev->img_dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_dev_set_instance_data:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
* @instance_data: a pointer to the instance data
|
|
||||||
*
|
|
||||||
* Set the instance data for a struct #fp_dev. This is usually a structure
|
|
||||||
* private to the driver used to keep state and pass it as user_data to
|
|
||||||
* asynchronous functions.
|
|
||||||
*
|
|
||||||
* The core does not do any memory management for this data, so the driver
|
|
||||||
* itself will have to create and free its own structure when appropriate.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fp_dev_set_instance_data (struct fp_dev *dev,
|
|
||||||
void *instance_data)
|
|
||||||
{
|
|
||||||
g_return_if_fail (dev);
|
|
||||||
g_return_if_fail (instance_data != NULL);
|
|
||||||
g_return_if_fail (dev->instance_data == NULL);
|
|
||||||
|
|
||||||
dev->instance_data = instance_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FP_INSTANCE_DATA:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
*
|
|
||||||
* Returns the instance data set using fp_dev_set_instance_data().
|
|
||||||
*/
|
|
||||||
void *
|
|
||||||
FP_INSTANCE_DATA (struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (dev, NULL);
|
|
||||||
|
|
||||||
return dev->instance_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_dev_get_usb_dev:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
*
|
|
||||||
* Returns the #libusb_device_handle associated with @dev or %NULL
|
|
||||||
* if none are associated.
|
|
||||||
*
|
|
||||||
* Returns: a #libusb_device_handle pointer or %NULL
|
|
||||||
*/
|
|
||||||
libusb_device_handle *
|
|
||||||
fpi_dev_get_usb_dev(struct fp_dev *dev)
|
|
||||||
{
|
|
||||||
return dev->udev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_dev_set_nr_enroll_stages:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
* @nr_enroll_stages: the number of enroll stages
|
|
||||||
*
|
|
||||||
* Sets the number of enroll stages that this device uses. This is
|
|
||||||
* usually only necessary for primitive devices which have a hard-coded
|
|
||||||
* number of enroll stages baked into their protocol.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fpi_dev_set_nr_enroll_stages(struct fp_dev *dev,
|
|
||||||
int nr_enroll_stages)
|
|
||||||
{
|
|
||||||
dev->nr_enroll_stages = nr_enroll_stages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_dev_get_verify_data:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
*
|
|
||||||
* Returns the verify data associated with @dev.
|
|
||||||
* This is usually only necessary for primitive devices which need to
|
|
||||||
* have access to the raw verify data as it might have been stored on disk.
|
|
||||||
*
|
|
||||||
* Returns: a struct #fp_print_data pointer or %NULL
|
|
||||||
*/
|
|
||||||
struct fp_print_data *
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_DEV_H__
|
|
||||||
#define __FPI_DEV_H__
|
|
||||||
|
|
||||||
#include <libusb.h>
|
|
||||||
#include <fprint.h>
|
|
||||||
|
|
||||||
struct fp_dev;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_img_dev:
|
|
||||||
*
|
|
||||||
* #fp_img_dev is an opaque structure type. You must access it using the
|
|
||||||
* appropriate functions.
|
|
||||||
*/
|
|
||||||
struct fp_img_dev;
|
|
||||||
|
|
||||||
struct fp_dev *FP_DEV (struct fp_img_dev *dev);
|
|
||||||
struct fp_img_dev *FP_IMG_DEV (struct fp_dev *dev);
|
|
||||||
|
|
||||||
void fp_dev_set_instance_data (struct fp_dev *dev,
|
|
||||||
void *instance_data);
|
|
||||||
void *FP_INSTANCE_DATA (struct fp_dev *dev);
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_IMG_H__
|
|
||||||
#define __FPI_IMG_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct fp_minutiae;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FpiImgFlags:
|
|
||||||
* @FP_IMG_V_FLIPPED: the image is vertically flipped
|
|
||||||
* @FP_IMG_H_FLIPPED: the image is horizontally flipped
|
|
||||||
* @FP_IMG_COLORS_INVERTED: the colours are inverted
|
|
||||||
* @FP_IMG_BINARIZED_FORM: binarised image, see fp_img_binarize()
|
|
||||||
* @FP_IMG_PARTIAL: the image is partial, useful for driver to keep track
|
|
||||||
* of incomplete captures
|
|
||||||
*
|
|
||||||
* Flags used in the #fp_img structure to describe the image contained
|
|
||||||
* into the structure. Note that a number of functions will refuse to
|
|
||||||
* handle images which haven't been standardised through fp_img_standardize()
|
|
||||||
* (meaning the @FP_IMG_V_FLIPPED, @FP_IMG_H_FLIPPED and @FP_IMG_COLORS_INVERTED
|
|
||||||
* should all be unset when the image needs to be analysed).
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
FP_IMG_V_FLIPPED = 1 << 0,
|
|
||||||
FP_IMG_H_FLIPPED = 1 << 1,
|
|
||||||
FP_IMG_COLORS_INVERTED = 1 << 2,
|
|
||||||
FP_IMG_BINARIZED_FORM = 1 << 3,
|
|
||||||
FP_IMG_PARTIAL = 1 << 4
|
|
||||||
} FpiImgFlags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_img:
|
|
||||||
* @width: the width of the image
|
|
||||||
* @height: the height of the image
|
|
||||||
* @length: the length of the data associated with the image
|
|
||||||
* @flags: @FpiImgFlags flags describing the image contained in the structure
|
|
||||||
* @minutiae: an opaque structure representing the detected minutiae
|
|
||||||
* @binarized: the binarized image data
|
|
||||||
* @data: the start of the image data, which will be of @length size.
|
|
||||||
*
|
|
||||||
* A structure representing a captured, or processed image. The @flags member
|
|
||||||
* will show its current state, including whether whether the binarized form
|
|
||||||
* if present, whether it is complete, and whether it needs particular changes
|
|
||||||
* before being processed.
|
|
||||||
*/
|
|
||||||
struct fp_img {
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
size_t length;
|
|
||||||
FpiImgFlags flags;
|
|
||||||
/*< private >*/
|
|
||||||
struct fp_minutiae *minutiae;
|
|
||||||
/*< public >*/
|
|
||||||
unsigned char *binarized;
|
|
||||||
unsigned char data[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fp_img *fpi_img_new(size_t length);
|
|
||||||
struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *imgdev);
|
|
||||||
struct fp_img *fpi_img_realloc(struct fp_img *img, size_t newsize);
|
|
||||||
struct fp_img *fpi_img_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor);
|
|
||||||
|
|
||||||
int fpi_std_sq_dev(const unsigned char *buf, int size);
|
|
||||||
int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_LOG_H__
|
|
||||||
#define __FPI_LOG_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-log
|
|
||||||
* @title: Logging
|
|
||||||
* @short_description: Logging functions
|
|
||||||
*
|
|
||||||
* Logging in libfprint is handled through GLib's logging system, and behave the same
|
|
||||||
* way as in the GLib [Message Output and Debugging Functions](https://developer.gnome.org/glib/stable/glib-Message-Logging.html)
|
|
||||||
* documentation.
|
|
||||||
*
|
|
||||||
* You should include `fpi-log.h` as early as possible in your sources, just after
|
|
||||||
* setting the `FP_COMPONENT` define to a string unique to your sources. This will
|
|
||||||
* set the suffix of the `G_LOG_DOMAIN` used for printing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef FP_COMPONENT
|
|
||||||
#undef G_LOG_DOMAIN
|
|
||||||
#ifndef __GTK_DOC_IGNORE__
|
|
||||||
#define G_LOG_DOMAIN "libfprint-"FP_COMPONENT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_dbg:
|
|
||||||
*
|
|
||||||
* Same as g_debug().
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define fp_dbg g_debug
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_info:
|
|
||||||
*
|
|
||||||
* Same as g_debug().
|
|
||||||
*/
|
|
||||||
#define fp_info g_debug
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_warn:
|
|
||||||
*
|
|
||||||
* Same as g_warning().
|
|
||||||
*/
|
|
||||||
#define fp_warn g_warning
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fp_err:
|
|
||||||
*
|
|
||||||
* Same as g_warning(). In the future, this might be changed to a
|
|
||||||
* g_assert() instead, so bear this in mind when adding those calls
|
|
||||||
* to your driver.
|
|
||||||
*/
|
|
||||||
#define fp_err g_warning
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BUG_ON:
|
|
||||||
* @condition: the condition to check
|
|
||||||
*
|
|
||||||
* Uses fp_err() to print an error if the @condition is true.
|
|
||||||
*/
|
|
||||||
#define BUG_ON(condition) G_STMT_START \
|
|
||||||
if (condition) { \
|
|
||||||
char *s; \
|
|
||||||
s = g_strconcat ("BUG: (", #condition, ")", NULL); \
|
|
||||||
fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \
|
|
||||||
g_free (s); \
|
|
||||||
} G_STMT_END
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BUG:
|
|
||||||
*
|
|
||||||
* Same as BUG_ON() but is always true.
|
|
||||||
*/
|
|
||||||
#define BUG() BUG_ON(1)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_POLL_H__
|
|
||||||
#define __FPI_POLL_H__
|
|
||||||
|
|
||||||
#include "fprint.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_timeout_fn:
|
|
||||||
* @dev: the struct #fp_dev passed to fpi_timeout_add()
|
|
||||||
* @data: the data passed to fpi_timeout_add()
|
|
||||||
*
|
|
||||||
* The prototype of the callback function for fpi_timeout_add().
|
|
||||||
* Note that after the callback is called, the #fpi_timeout structure will
|
|
||||||
* be freed.
|
|
||||||
*/
|
|
||||||
typedef void (*fpi_timeout_fn)(struct fp_dev *dev, void *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_timeout:
|
|
||||||
*
|
|
||||||
* An opaque structure representing a scheduled function call, created with
|
|
||||||
* fpi_timeout_add().
|
|
||||||
*/
|
|
||||||
typedef struct fpi_timeout fpi_timeout;
|
|
||||||
fpi_timeout *fpi_timeout_add(unsigned int msec,
|
|
||||||
fpi_timeout_fn callback,
|
|
||||||
struct fp_dev *dev,
|
|
||||||
void *data);
|
|
||||||
void fpi_timeout_set_name(fpi_timeout *timeout,
|
|
||||||
const char *name);
|
|
||||||
void fpi_timeout_cancel(fpi_timeout *timeout);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,317 +0,0 @@
|
|||||||
/*
|
|
||||||
* Functions to assist with asynchronous driver <---> library communications
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
*
|
|
||||||
* 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 "drv"
|
|
||||||
|
|
||||||
#include "fp_internal.h"
|
|
||||||
#include "fpi-ssm.h"
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-ssm
|
|
||||||
* @title: Sequential state machine
|
|
||||||
* @short_description: State machine helpers
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* next state, you never jump or go backwards. The #fpi_ssm functions help you
|
|
||||||
* implement such a machine.
|
|
||||||
*
|
|
||||||
* e.g. `S1` ↦ `S2` ↦ `S3` ↦ `S4`
|
|
||||||
*
|
|
||||||
* `S1` is the start state
|
|
||||||
* There is also an implicit error state and an implicit accepting state
|
|
||||||
* (both with implicit edges from every state).
|
|
||||||
*
|
|
||||||
* You can also jump to any arbitrary state (while marking completion of the
|
|
||||||
* current state) while the machine is running. In other words there are
|
|
||||||
* implicit edges linking one state to every other state.
|
|
||||||
*
|
|
||||||
* To create an #fpi_ssm, you pass a state handler function and the total number of
|
|
||||||
* states (4 in the above example) to fpi_ssm_new(). Note that the state numbers
|
|
||||||
* start at zero, making them match the first value in a C enumeration.
|
|
||||||
*
|
|
||||||
* To start a ssm, you pass in a completion callback function to fpi_ssm_start()
|
|
||||||
* which gets called when the ssm completes (both on error and on failure).
|
|
||||||
*
|
|
||||||
* To iterate to the next state, call fpi_ssm_next_state(). It is legal to
|
|
||||||
* attempt to iterate beyond the final state - this is equivalent to marking
|
|
||||||
* the ssm as successfully completed.
|
|
||||||
*
|
|
||||||
* To mark successful completion of a SSM, either iterate beyond the final
|
|
||||||
* state or call fpi_ssm_mark_completed() from any state.
|
|
||||||
*
|
|
||||||
* To mark failed completion of a SSM, call fpi_ssm_mark_failed() from any
|
|
||||||
* state. You must pass a non-zero error code.
|
|
||||||
*
|
|
||||||
* Your state handling function looks at the return value of
|
|
||||||
* fpi_ssm_get_cur_state() in order to determine the current state and hence
|
|
||||||
* which operations to perform (a switch statement is appropriate).
|
|
||||||
*
|
|
||||||
* Typically, the state handling function fires off an asynchronous
|
|
||||||
* communication with the device (such as a libsub transfer), and the
|
|
||||||
* callback function iterates the machine to the next state
|
|
||||||
* upon success (or fails).
|
|
||||||
*
|
|
||||||
* Your completion callback should examine the return value of
|
|
||||||
* fpi_ssm_get_error() in order to determine whether the #fpi_ssm completed or
|
|
||||||
* failed. An error code of zero indicates successful completion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct fpi_ssm {
|
|
||||||
struct fp_dev *dev;
|
|
||||||
fpi_ssm *parentsm;
|
|
||||||
void *user_data;
|
|
||||||
int nr_states;
|
|
||||||
int cur_state;
|
|
||||||
gboolean completed;
|
|
||||||
int error;
|
|
||||||
ssm_completed_fn callback;
|
|
||||||
ssm_handler_fn handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_new:
|
|
||||||
* @dev: a #fp_dev fingerprint device
|
|
||||||
* @handler: the callback function
|
|
||||||
* @nr_states: the number of states
|
|
||||||
* @user_data: the user data to pass to callbacks
|
|
||||||
*
|
|
||||||
* Allocate a new ssm, with @nr_states states. The @handler callback
|
|
||||||
* will be called after each state transition.
|
|
||||||
*
|
|
||||||
* Returns: a new #fpi_ssm state machine
|
|
||||||
*/
|
|
||||||
fpi_ssm *fpi_ssm_new(struct fp_dev *dev,
|
|
||||||
ssm_handler_fn handler,
|
|
||||||
int nr_states,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
fpi_ssm *machine;
|
|
||||||
BUG_ON(nr_states < 1);
|
|
||||||
|
|
||||||
machine = g_malloc0(sizeof(*machine));
|
|
||||||
machine->handler = handler;
|
|
||||||
machine->nr_states = nr_states;
|
|
||||||
machine->dev = dev;
|
|
||||||
machine->completed = TRUE;
|
|
||||||
machine->user_data = user_data;
|
|
||||||
return machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_get_user_data:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Retrieve the pointer to user data set when fpi_ssm_new()
|
|
||||||
* is called.
|
|
||||||
*
|
|
||||||
* Returns: a pointer
|
|
||||||
*/
|
|
||||||
void *
|
|
||||||
fpi_ssm_get_user_data(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
return machine->user_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_free:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Frees a state machine. This does not call any error or success
|
|
||||||
* callbacks, so you need to do this yourself.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_free(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
if (!machine)
|
|
||||||
return;
|
|
||||||
g_free(machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Invoke the state handler */
|
|
||||||
static void __ssm_call_handler(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
fp_dbg("%p entering state %d", machine, machine->cur_state);
|
|
||||||
machine->handler(machine, machine->dev, machine->user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_start:
|
|
||||||
* @ssm: an #fpi_ssm state machine
|
|
||||||
* @callback: the #ssm_completed_fn callback to call on completion
|
|
||||||
*
|
|
||||||
* Starts a state machine. You can also use this function to restart
|
|
||||||
* a completed or failed state machine. The @callback will be called
|
|
||||||
* on completion.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_start(fpi_ssm *ssm, ssm_completed_fn callback)
|
|
||||||
{
|
|
||||||
BUG_ON(!ssm->completed);
|
|
||||||
ssm->callback = callback;
|
|
||||||
ssm->cur_state = 0;
|
|
||||||
ssm->completed = FALSE;
|
|
||||||
ssm->error = 0;
|
|
||||||
__ssm_call_handler(ssm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __subsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
|
||||||
{
|
|
||||||
fpi_ssm *parent = ssm->parentsm;
|
|
||||||
BUG_ON(!parent);
|
|
||||||
if (ssm->error)
|
|
||||||
fpi_ssm_mark_failed(parent, ssm->error);
|
|
||||||
else
|
|
||||||
fpi_ssm_next_state(parent);
|
|
||||||
fpi_ssm_free(ssm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_start_subsm:
|
|
||||||
* @parent: an #fpi_ssm state machine
|
|
||||||
* @child: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Starts a state machine as a child of another. if the child completes
|
|
||||||
* successfully, the parent will be advanced to the next state. if the
|
|
||||||
* child fails, the parent will be marked as failed with the same error code.
|
|
||||||
*
|
|
||||||
* The child will be automatically freed upon completion or failure.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_start_subsm(fpi_ssm *parent, fpi_ssm *child)
|
|
||||||
{
|
|
||||||
child->parentsm = parent;
|
|
||||||
fpi_ssm_start(child, __subsm_complete);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_mark_completed:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Mark a ssm as completed successfully. The callback set when creating
|
|
||||||
* the state machine with fpi_ssm_new() will be called synchronously.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_mark_completed(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
BUG_ON(machine->completed);
|
|
||||||
machine->completed = TRUE;
|
|
||||||
fp_dbg("%p completed with status %d", machine, machine->error);
|
|
||||||
if (machine->callback)
|
|
||||||
machine->callback(machine, machine->dev, machine->user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_mark_failed:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
* @error: the error code
|
|
||||||
*
|
|
||||||
* Mark a state machine as failed with @error as the error code.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_mark_failed(fpi_ssm *machine, int error)
|
|
||||||
{
|
|
||||||
fp_dbg("error %d from state %d", error, machine->cur_state);
|
|
||||||
BUG_ON(error == 0);
|
|
||||||
machine->error = error;
|
|
||||||
fpi_ssm_mark_completed(machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_next_state:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Iterate to next state of a state machine. If the current state is the
|
|
||||||
* last state, then the state machine will be marked as completed, as
|
|
||||||
* if calling fpi_ssm_mark_completed().
|
|
||||||
*/
|
|
||||||
void fpi_ssm_next_state(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
g_return_if_fail (machine != NULL);
|
|
||||||
|
|
||||||
BUG_ON(machine->completed);
|
|
||||||
machine->cur_state++;
|
|
||||||
if (machine->cur_state == machine->nr_states) {
|
|
||||||
fpi_ssm_mark_completed(machine);
|
|
||||||
} else {
|
|
||||||
__ssm_call_handler(machine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_next_state_timeout_cb:
|
|
||||||
* @dev: a struct #fp_dev
|
|
||||||
* @data: a pointer to an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Same as fpi_ssm_next_state(), but to be used as a callback
|
|
||||||
* for an fpi_timeout_add() callback, when the state change needs
|
|
||||||
* to happen after a timeout.
|
|
||||||
*
|
|
||||||
* Make sure to pass the #fpi_ssm as the `user_data` argument
|
|
||||||
* for that fpi_timeout_add() call.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fpi_ssm_next_state_timeout_cb(struct fp_dev *dev,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
g_return_if_fail (dev != NULL);
|
|
||||||
g_return_if_fail (data != NULL);
|
|
||||||
|
|
||||||
fpi_ssm_next_state(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_jump_to_state:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
* @state: the state to jump to
|
|
||||||
*
|
|
||||||
* Jump to the @state state, bypassing intermediary states.
|
|
||||||
*/
|
|
||||||
void fpi_ssm_jump_to_state(fpi_ssm *machine, int state)
|
|
||||||
{
|
|
||||||
BUG_ON(machine->completed);
|
|
||||||
BUG_ON(state >= machine->nr_states);
|
|
||||||
machine->cur_state = state;
|
|
||||||
__ssm_call_handler(machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_get_cur_state:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Returns the value of the current state. Note that states are
|
|
||||||
* 0-indexed, so a value of 0 means “the first state”.
|
|
||||||
*
|
|
||||||
* Returns: the current state.
|
|
||||||
*/
|
|
||||||
int fpi_ssm_get_cur_state(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
return machine->cur_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm_get_error:
|
|
||||||
* @machine: an #fpi_ssm state machine
|
|
||||||
*
|
|
||||||
* Returns the error code set by fpi_ssm_mark_failed().
|
|
||||||
*
|
|
||||||
* Returns: a error code
|
|
||||||
*/
|
|
||||||
int fpi_ssm_get_error(fpi_ssm *machine)
|
|
||||||
{
|
|
||||||
return machine->error;
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_SSM_H__
|
|
||||||
#define __FPI_SSM_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <libusb.h>
|
|
||||||
|
|
||||||
/* async drv <--> lib comms */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_ssm:
|
|
||||||
*
|
|
||||||
* Sequential state machine that iterates sequentially over
|
|
||||||
* a predefined series of states. Can be terminated by either completion or
|
|
||||||
* failure error conditions.
|
|
||||||
*/
|
|
||||||
typedef struct fpi_ssm fpi_ssm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ssm_completed_fn:
|
|
||||||
* @ssm: a #fpi_ssm state machine
|
|
||||||
* @dev: the #fp_dev fingerprint device
|
|
||||||
* @user_data: the user data passed to fpi_ssm_new()
|
|
||||||
*
|
|
||||||
* The callback called when a state machine completes successfully,
|
|
||||||
* as set when calling fpi_ssm_start().
|
|
||||||
*/
|
|
||||||
typedef void (*ssm_completed_fn)(fpi_ssm *ssm,
|
|
||||||
struct fp_dev *dev,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ssm_handler_fn:
|
|
||||||
* @ssm: a #fpi_ssm state machine
|
|
||||||
* @dev: the #fp_dev fingerprint device
|
|
||||||
* @user_data: the user data passed to fpi_ssm_new()
|
|
||||||
*
|
|
||||||
* The callback called when a state machine transitions from one
|
|
||||||
* state to the next, as set when calling fpi_ssm_new().
|
|
||||||
*/
|
|
||||||
typedef void (*ssm_handler_fn)(fpi_ssm *ssm,
|
|
||||||
struct fp_dev *dev,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
/* for library and drivers */
|
|
||||||
fpi_ssm *fpi_ssm_new(struct fp_dev *dev,
|
|
||||||
ssm_handler_fn handler,
|
|
||||||
int nr_states,
|
|
||||||
void *user_data);
|
|
||||||
void fpi_ssm_free(fpi_ssm *machine);
|
|
||||||
void fpi_ssm_start(fpi_ssm *ssm, ssm_completed_fn callback);
|
|
||||||
void fpi_ssm_start_subsm(fpi_ssm *parent, fpi_ssm *child);
|
|
||||||
|
|
||||||
/* for drivers */
|
|
||||||
void fpi_ssm_next_state(fpi_ssm *machine);
|
|
||||||
void fpi_ssm_next_state_timeout_cb(struct fp_dev *dev, void *data);
|
|
||||||
void fpi_ssm_jump_to_state(fpi_ssm *machine, int state);
|
|
||||||
void fpi_ssm_mark_completed(fpi_ssm *machine);
|
|
||||||
void fpi_ssm_mark_failed(fpi_ssm *machine, int error);
|
|
||||||
void *fpi_ssm_get_user_data(fpi_ssm *machine);
|
|
||||||
int fpi_ssm_get_error(fpi_ssm *machine);
|
|
||||||
int fpi_ssm_get_cur_state(fpi_ssm *machine);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
/*
|
|
||||||
* Driver API definitions
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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 "fpi-usb.h"
|
|
||||||
#include "drivers_api.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-usb
|
|
||||||
* @title: Helpers for libusb
|
|
||||||
* @short_description: libusb-related helpers
|
|
||||||
*
|
|
||||||
* A collection of [libusb helpers](http://libusb.sourceforge.net/api-1.0/group__poll.html#details)
|
|
||||||
* to make driver development easier. Please refer to the libusb API documentation for more
|
|
||||||
* information about the original API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Helpers from glib */
|
|
||||||
#include <glib.h>
|
|
||||||
#include <glib/gprintf.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* special helpers to avoid gmessage.c dependency */
|
|
||||||
static void mem_error (const char *format, ...) G_GNUC_PRINTF (1,2);
|
|
||||||
#define mem_assert(cond) do { if (G_LIKELY (cond)) ; else mem_error ("assertion failed: %s", #cond); } while (0)
|
|
||||||
|
|
||||||
static void
|
|
||||||
mem_error (const char *format,
|
|
||||||
...)
|
|
||||||
{
|
|
||||||
const char *pname;
|
|
||||||
va_list args;
|
|
||||||
/* at least, put out "MEMORY-ERROR", in case we segfault during the rest of the function */
|
|
||||||
fputs ("\n***MEMORY-ERROR***: ", stderr);
|
|
||||||
pname = g_get_prgname();
|
|
||||||
g_fprintf (stderr, "%s[%ld]: ", pname ? pname : "", (long)getpid());
|
|
||||||
va_start (args, format);
|
|
||||||
g_vfprintf (stderr, format, args);
|
|
||||||
va_end (args);
|
|
||||||
fputs ("\n", stderr);
|
|
||||||
abort();
|
|
||||||
_exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fpi_usb_transfer {
|
|
||||||
struct libusb_transfer *transfer;
|
|
||||||
fpi_ssm *ssm;
|
|
||||||
struct fp_dev *dev;
|
|
||||||
fpi_usb_transfer_cb_fn callback;
|
|
||||||
void *user_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_alloc:
|
|
||||||
*
|
|
||||||
* Returns a struct libusb_transfer, similar to calling
|
|
||||||
* `libusb_alloc_transfer(0)`[[1](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga13cc69ea40c702181c430c950121c000)]. As libfprint uses GLib internally,
|
|
||||||
* and [memory allocation failures will make applications fail](https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html#glib-Memory-Allocation.description),
|
|
||||||
* this helper will assert when the libusb call fails.
|
|
||||||
*/
|
|
||||||
struct libusb_transfer *
|
|
||||||
fpi_usb_alloc(void)
|
|
||||||
{
|
|
||||||
struct libusb_transfer *transfer;
|
|
||||||
|
|
||||||
transfer = libusb_alloc_transfer(0);
|
|
||||||
mem_assert(transfer);
|
|
||||||
|
|
||||||
return transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fpi_usb_transfer *
|
|
||||||
fpi_usb_transfer_new(struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
fpi_usb_transfer_cb_fn callback,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
fpi_usb_transfer *transfer;
|
|
||||||
|
|
||||||
transfer = g_new0(fpi_usb_transfer, 1);
|
|
||||||
transfer->transfer = fpi_usb_alloc();
|
|
||||||
transfer->dev = dev;
|
|
||||||
transfer->ssm = ssm;
|
|
||||||
transfer->callback = callback;
|
|
||||||
transfer->user_data = user_data;
|
|
||||||
|
|
||||||
return transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fpi_usb_transfer_free(fpi_usb_transfer *transfer)
|
|
||||||
{
|
|
||||||
if (transfer == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_free(transfer->transfer->buffer);
|
|
||||||
libusb_free_transfer(transfer->transfer);
|
|
||||||
g_free(transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fpi_usb_transfer_cb (struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
fpi_usb_transfer *t;
|
|
||||||
|
|
||||||
g_assert(transfer);
|
|
||||||
g_assert(transfer->user_data);
|
|
||||||
|
|
||||||
t = transfer->user_data;
|
|
||||||
BUG_ON(transfer->callback == NULL);
|
|
||||||
(t->callback) (transfer, t->dev, t->ssm, t->user_data);
|
|
||||||
fpi_usb_transfer_free(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_fill_bulk_transfer:
|
|
||||||
* @dev: a struct #fp_dev fingerprint device
|
|
||||||
* @ssm: the current #fpi_ssm state machine
|
|
||||||
* @endpoint: the USB end point
|
|
||||||
* @buffer: a buffer allocated with g_malloc() or another GLib function.
|
|
||||||
* Note that the returned #fpi_usb_transfer will own this buffer, so it
|
|
||||||
* should not be freed manually.
|
|
||||||
* @length: the size of @buffer
|
|
||||||
* @callback: the callback function that will be called once the fpi_usb_submit_transfer()
|
|
||||||
* call finishes.
|
|
||||||
* @user_data: a user data pointer to pass to the callback
|
|
||||||
* @timeout: timeout for the transfer in milliseconds, or 0 for no timeout
|
|
||||||
*
|
|
||||||
* This function is similar to calling [`libusb_alloc_transfer(0)`](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga13cc69ea40c702181c430c950121c000)]
|
|
||||||
* followed by calling [`libusb_fill_bulk_transfer()`](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#gad4ddb1a5c6c7fefc979a44d7300b95d7).
|
|
||||||
* The #fpi_usb_transfer_cb_fn callback will however provide more arguments
|
|
||||||
* relevant to libfprint drivers, making it a good replacement for the raw libusb
|
|
||||||
* calls.
|
|
||||||
*
|
|
||||||
* Returns: a #fpi_usb_transfer transfer struct, to be passed to
|
|
||||||
* fpi_usb_submit_transfer().
|
|
||||||
*/
|
|
||||||
fpi_usb_transfer *
|
|
||||||
fpi_usb_fill_bulk_transfer (struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
unsigned char endpoint,
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length,
|
|
||||||
fpi_usb_transfer_cb_fn callback,
|
|
||||||
void *user_data,
|
|
||||||
unsigned int timeout)
|
|
||||||
{
|
|
||||||
fpi_usb_transfer *transfer;
|
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, NULL);
|
|
||||||
g_return_val_if_fail (callback != NULL, NULL);
|
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(dev,
|
|
||||||
ssm,
|
|
||||||
callback,
|
|
||||||
user_data);
|
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer->transfer,
|
|
||||||
fpi_dev_get_usb_dev(dev),
|
|
||||||
endpoint,
|
|
||||||
buffer,
|
|
||||||
length,
|
|
||||||
fpi_usb_transfer_cb,
|
|
||||||
transfer,
|
|
||||||
timeout);
|
|
||||||
|
|
||||||
return transfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_submit_transfer:
|
|
||||||
* @transfer: a #fpi_usb_transfer struct
|
|
||||||
*
|
|
||||||
* Start a transfer to the device with the provided #fpi_usb_transfer.
|
|
||||||
* On error, the #fpi_usb_transfer struct will be freed, otherwise it will
|
|
||||||
* be freed once the callback provided to fpi_usb_fill_bulk_transfer() has
|
|
||||||
* been called.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, or the same errors as [libusb_submit_transfer](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#gabb0932601f2c7dad2fee4b27962848ce)
|
|
||||||
* on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
fpi_usb_submit_transfer(fpi_usb_transfer *transfer)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
g_return_val_if_fail (transfer != NULL, LIBUSB_ERROR_INVALID_PARAM);
|
|
||||||
|
|
||||||
r = libusb_submit_transfer(transfer->transfer);
|
|
||||||
if (r < 0)
|
|
||||||
fpi_usb_transfer_free(transfer);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_cancel_transfer:
|
|
||||||
* @transfer: a #fpi_usb_transfer struct
|
|
||||||
*
|
|
||||||
* Cancel a transfer to the device with the provided #fpi_usb_transfer.
|
|
||||||
* Note that this will not complete the cancellation, as your transfer
|
|
||||||
* callback will be called with the `LIBUSB_TRANSFER_CANCELLED` status,
|
|
||||||
* as [libusb_cancel_transfer](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga685eb7731f9a0593f75beb99727bbe54)
|
|
||||||
* would.
|
|
||||||
*
|
|
||||||
* You should not access anything but the given struct #libusb_transfer
|
|
||||||
* in the callback before checking whether `LIBUSB_TRANSFER_CANCELLED` has
|
|
||||||
* been called, as that might cause memory access violations.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, or the same errors as [libusb_cancel_transfer](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga685eb7731f9a0593f75beb99727bbe54)
|
|
||||||
* on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
fpi_usb_cancel_transfer(fpi_usb_transfer *transfer)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (transfer != NULL, LIBUSB_ERROR_NOT_FOUND);
|
|
||||||
|
|
||||||
return libusb_cancel_transfer(transfer->transfer);
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FPI_USB_H__
|
|
||||||
#define __FPI_USB_H__
|
|
||||||
|
|
||||||
#include <libusb.h>
|
|
||||||
#include "fpi-dev.h"
|
|
||||||
#include "fpi-ssm.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_transfer:
|
|
||||||
*
|
|
||||||
* A structure containing the arguments passed to fpi_usb_fill_bulk_transfer()
|
|
||||||
* to be used with fpi_usb_submit_transfer().
|
|
||||||
*/
|
|
||||||
typedef struct fpi_usb_transfer fpi_usb_transfer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_usb_transfer_cb_fn:
|
|
||||||
* @transfer: a struct #libusb_transfer
|
|
||||||
* @dev: the struct #fp_dev on which the operation was performed
|
|
||||||
* @ssm: the #fpi_ssm state machine
|
|
||||||
* @user_data: the user data passed to fpi_usb_fill_bulk_transfer()
|
|
||||||
*
|
|
||||||
* This callback will be called in response to a libusb bulk transfer
|
|
||||||
* triggered via fpi_usb_fill_bulk_transfer() finishing. Note that the
|
|
||||||
* struct #libusb_transfer does not need to be freed, as it will be
|
|
||||||
* freed after the callback returns, similarly to
|
|
||||||
* the [LIBUSB_TRANSFER_FREE_TRANSFER flag](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#gga1fb47dd0f7c209b60a3609ff0c03d56dacf3f064997b283a14097c9f4d6f8ccc1).
|
|
||||||
*
|
|
||||||
* Note that the cancelled status of the transfer should be checked
|
|
||||||
* first thing, as the @dev, @ssm and @user_data pointers might not
|
|
||||||
* be pointing to valid values anymore. See fpi_usb_cancel_transfer()
|
|
||||||
* for more information.
|
|
||||||
*/
|
|
||||||
typedef void(*fpi_usb_transfer_cb_fn) (struct libusb_transfer *transfer,
|
|
||||||
struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
struct libusb_transfer *fpi_usb_alloc(void) __attribute__((returns_nonnull));
|
|
||||||
|
|
||||||
fpi_usb_transfer *fpi_usb_fill_bulk_transfer (struct fp_dev *dev,
|
|
||||||
fpi_ssm *ssm,
|
|
||||||
unsigned char endpoint,
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length,
|
|
||||||
fpi_usb_transfer_cb_fn callback,
|
|
||||||
void *user_data,
|
|
||||||
unsigned int timeout);
|
|
||||||
int fpi_usb_submit_transfer (fpi_usb_transfer *transfer);
|
|
||||||
int fpi_usb_cancel_transfer (fpi_usb_transfer *transfer);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -24,6 +24,10 @@
|
|||||||
#include "fp_internal.h"
|
#include "fp_internal.h"
|
||||||
|
|
||||||
static const struct usb_id whitelist_id_table[] = {
|
static const struct usb_id whitelist_id_table[] = {
|
||||||
|
/* Unsupported (for now) Elantech finger print readers */
|
||||||
|
{ .vendor = 0x04f3, .product = 0x0c03 },
|
||||||
|
{ .vendor = 0x04f3, .product = 0x0c16 },
|
||||||
|
{ .vendor = 0x04f3, .product = 0x0c26 },
|
||||||
/* Unsupported (for now) Validity Sensors finger print readers */
|
/* Unsupported (for now) Validity Sensors finger print readers */
|
||||||
{ .vendor = 0x138a, .product = 0x0090 }, /* Found on e.g. Lenovo T460s */
|
{ .vendor = 0x138a, .product = 0x0090 }, /* Found on e.g. Lenovo T460s */
|
||||||
{ .vendor = 0x138a, .product = 0x0091 },
|
{ .vendor = 0x138a, .product = 0x0091 },
|
||||||
|
|||||||
@@ -25,24 +25,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* LIBFPRINT_DEPRECATED:
|
|
||||||
*
|
|
||||||
* Expands to the GNU C deprecated attribute if the compiler is `gcc`. When
|
|
||||||
* called with the `-Wdeprecated-declarations` option, `gcc` will generate warnings
|
|
||||||
* when deprecated interfaces are used.
|
|
||||||
*/
|
|
||||||
#define LIBFPRINT_DEPRECATED __attribute__((__deprecated__))
|
#define LIBFPRINT_DEPRECATED __attribute__((__deprecated__))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dscv_dev:
|
* fp_dscv_dev:
|
||||||
*
|
*
|
||||||
* #fp_dscv_dev is an opaque structure type. You must access it using the
|
* #fp_dscv_dev is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_dscv_dev;
|
struct fp_dscv_dev;
|
||||||
|
|
||||||
@@ -50,7 +41,7 @@ struct fp_dscv_dev;
|
|||||||
* fp_dscv_print:
|
* fp_dscv_print:
|
||||||
*
|
*
|
||||||
* #fp_dscv_print is an opaque structure type. You must access it using the
|
* #fp_dscv_print is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_dscv_print;
|
struct fp_dscv_print;
|
||||||
|
|
||||||
@@ -58,7 +49,7 @@ struct fp_dscv_print;
|
|||||||
* fp_dev:
|
* fp_dev:
|
||||||
*
|
*
|
||||||
* #fp_dev is an opaque structure type. You must access it using the
|
* #fp_dev is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_dev;
|
struct fp_dev;
|
||||||
|
|
||||||
@@ -66,7 +57,7 @@ struct fp_dev;
|
|||||||
* fp_driver:
|
* fp_driver:
|
||||||
*
|
*
|
||||||
* #fp_driver is an opaque structure type. You must access it using the
|
* #fp_driver is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_driver;
|
struct fp_driver;
|
||||||
|
|
||||||
@@ -74,7 +65,7 @@ struct fp_driver;
|
|||||||
* fp_print_data:
|
* fp_print_data:
|
||||||
*
|
*
|
||||||
* #fp_print_data is an opaque structure type. You must access it using the
|
* #fp_print_data is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_print_data;
|
struct fp_print_data;
|
||||||
|
|
||||||
@@ -82,7 +73,7 @@ struct fp_print_data;
|
|||||||
* fp_img:
|
* fp_img:
|
||||||
*
|
*
|
||||||
* #fp_img is an opaque structure type. You must access it using the
|
* #fp_img is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_img;
|
struct fp_img;
|
||||||
|
|
||||||
@@ -137,7 +128,6 @@ const char *fp_driver_get_name(struct fp_driver *drv);
|
|||||||
const char *fp_driver_get_full_name(struct fp_driver *drv);
|
const char *fp_driver_get_full_name(struct fp_driver *drv);
|
||||||
uint16_t fp_driver_get_driver_id(struct fp_driver *drv);
|
uint16_t fp_driver_get_driver_id(struct fp_driver *drv);
|
||||||
enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv);
|
enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv);
|
||||||
int fp_driver_supports_imaging(struct fp_driver *drv);
|
|
||||||
|
|
||||||
/* Device discovery */
|
/* Device discovery */
|
||||||
struct fp_dscv_dev **fp_discover_devs(void);
|
struct fp_dscv_dev **fp_discover_devs(void);
|
||||||
@@ -173,10 +163,11 @@ int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_capture_result:
|
* fp_capture_result:
|
||||||
|
* Whether a capture failed or completed.
|
||||||
|
*
|
||||||
* @FP_CAPTURE_COMPLETE: Capture completed successfully, the capture data has been returned to the caller.
|
* @FP_CAPTURE_COMPLETE: Capture completed successfully, the capture data has been returned to the caller.
|
||||||
* @FP_CAPTURE_FAIL: Capture failed
|
* @FP_CAPTURE_FAIL: Capture failed
|
||||||
*
|
*
|
||||||
* Whether a capture failed or completed.
|
|
||||||
*/
|
*/
|
||||||
enum fp_capture_result {
|
enum fp_capture_result {
|
||||||
FP_CAPTURE_COMPLETE = 0,
|
FP_CAPTURE_COMPLETE = 0,
|
||||||
@@ -267,26 +258,19 @@ int fp_verify_finger(struct fp_dev *dev,
|
|||||||
struct fp_print_data *enrolled_print);
|
struct fp_print_data *enrolled_print);
|
||||||
|
|
||||||
int fp_dev_supports_identification(struct fp_dev *dev);
|
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,
|
int fp_identify_finger_img(struct fp_dev *dev,
|
||||||
struct fp_print_data **print_gallery, size_t *match_offset,
|
struct fp_print_data **print_gallery, size_t *match_offset,
|
||||||
struct fp_img **img);
|
struct fp_img **img);
|
||||||
int fp_identify_finger(struct fp_dev *dev,
|
int fp_identify_finger(struct fp_dev *dev,
|
||||||
struct fp_print_data **print_gallery, size_t *match_offset);
|
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 */
|
/* Data handling */
|
||||||
int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger,
|
int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger,
|
||||||
struct fp_print_data **data) LIBFPRINT_DEPRECATED;
|
struct fp_print_data **data);
|
||||||
int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
|
int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
|
||||||
struct fp_print_data **data) LIBFPRINT_DEPRECATED;
|
struct fp_print_data **data) LIBFPRINT_DEPRECATED;
|
||||||
int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger)
|
int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger);
|
||||||
LIBFPRINT_DEPRECATED;
|
int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger);
|
||||||
int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger)
|
|
||||||
LIBFPRINT_DEPRECATED;
|
|
||||||
void fp_print_data_free(struct fp_print_data *data);
|
void fp_print_data_free(struct fp_print_data *data);
|
||||||
size_t fp_print_data_get_data(struct fp_print_data *data, unsigned char **ret);
|
size_t fp_print_data_get_data(struct fp_print_data *data, unsigned char **ret);
|
||||||
struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
|
struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
|
||||||
@@ -300,7 +284,7 @@ uint32_t fp_print_data_get_devtype(struct fp_print_data *data);
|
|||||||
* fp_minutia:
|
* fp_minutia:
|
||||||
*
|
*
|
||||||
* #fp_minutia is an opaque structure type. You must access it using the
|
* #fp_minutia is an opaque structure type. You must access it using the
|
||||||
* functions in this section.
|
* functions below.
|
||||||
*/
|
*/
|
||||||
struct fp_minutia;
|
struct fp_minutia;
|
||||||
|
|
||||||
@@ -311,7 +295,6 @@ int fp_img_save_to_file(struct fp_img *img, char *path);
|
|||||||
void fp_img_standardize(struct fp_img *img);
|
void fp_img_standardize(struct fp_img *img);
|
||||||
struct fp_img *fp_img_binarize(struct fp_img *img);
|
struct fp_img *fp_img_binarize(struct fp_img *img);
|
||||||
struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, int *nr_minutiae);
|
struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, int *nr_minutiae);
|
||||||
int fp_minutia_get_coords(struct fp_minutia *minutia, int *coord_x, int *coord_y);
|
|
||||||
void fp_img_free(struct fp_img *img);
|
void fp_img_free(struct fp_img *img);
|
||||||
|
|
||||||
/* Polling and timing */
|
/* Polling and timing */
|
||||||
@@ -321,17 +304,17 @@ void fp_img_free(struct fp_img *img);
|
|||||||
* @fd: a file descriptor
|
* @fd: a file descriptor
|
||||||
* @events: Event flags to poll for from `<poll.h>`
|
* @events: Event flags to poll for from `<poll.h>`
|
||||||
*
|
*
|
||||||
* A structure representing a file descriptor and the @events to poll
|
* A structure representing a file descriptor and the events to poll
|
||||||
* for, as returned by fp_get_pollfds().
|
* for, as returned by fp_get_pollfds().
|
||||||
*/
|
*/
|
||||||
struct fp_pollfd {
|
struct fp_pollfd {
|
||||||
int fd;
|
int fd;
|
||||||
short int events;
|
short events;
|
||||||
};
|
};
|
||||||
|
|
||||||
int fp_handle_events_timeout(struct timeval *timeout);
|
int fp_handle_events_timeout(struct timeval *timeout);
|
||||||
int fp_handle_events(void);
|
int fp_handle_events(void);
|
||||||
ssize_t fp_get_pollfds(struct fp_pollfd **pollfds);
|
size_t fp_get_pollfds(struct fp_pollfd **pollfds);
|
||||||
int fp_get_next_timeout(struct timeval *tv);
|
int fp_get_next_timeout(struct timeval *tv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -343,7 +326,7 @@ int fp_get_next_timeout(struct timeval *tv);
|
|||||||
* event source is added. The @events argument is a flag as defined in
|
* event source is added. The @events argument is a flag as defined in
|
||||||
* `<poll.h>` such as `POLLIN`, or `POLLOUT`. See fp_set_pollfd_notifiers().
|
* `<poll.h>` such as `POLLIN`, or `POLLOUT`. See fp_set_pollfd_notifiers().
|
||||||
*/
|
*/
|
||||||
typedef void (*fp_pollfd_added_cb)(int fd, short int events);
|
typedef void (*fp_pollfd_added_cb)(int fd, short events);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_pollfd_removed_cb:
|
* fp_pollfd_removed_cb:
|
||||||
@@ -365,7 +348,7 @@ void fp_set_debug(int level) LIBFPRINT_DEPRECATED;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_operation_stop_cb:
|
* fp_operation_stop_cb:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the #fp_dev device
|
||||||
* @user_data: user data passed to the callback
|
* @user_data: user data passed to the callback
|
||||||
*
|
*
|
||||||
* Type definition for a function that will be called when fp_async_dev_close(),
|
* Type definition for a function that will be called when fp_async_dev_close(),
|
||||||
@@ -376,7 +359,7 @@ typedef void (*fp_operation_stop_cb)(struct fp_dev *dev, void *user_data);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_img_operation_cb:
|
* fp_img_operation_cb:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the #fp_dev device
|
||||||
* @result: an #fp_verify_result for fp_async_verify_start(), or an #fp_capture_result
|
* @result: an #fp_verify_result for fp_async_verify_start(), or an #fp_capture_result
|
||||||
* for fp_async_capture_start(), or a negative value on error
|
* for fp_async_capture_start(), or a negative value on error
|
||||||
* @img: the captured #fp_img if capture or verification was successful
|
* @img: the captured #fp_img if capture or verification was successful
|
||||||
@@ -390,7 +373,7 @@ typedef void (*fp_img_operation_cb)(struct fp_dev *dev, int result,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_dev_open_cb:
|
* fp_dev_open_cb:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the #fp_dev device
|
||||||
* @status: 0 on success, or a negative value on error
|
* @status: 0 on success, or a negative value on error
|
||||||
* @user_data: user data passed to the callback
|
* @user_data: user data passed to the callback
|
||||||
*
|
*
|
||||||
@@ -407,15 +390,14 @@ void fp_async_dev_close(struct fp_dev *dev, fp_operation_stop_cb callback,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_enroll_stage_cb:
|
* fp_enroll_stage_cb:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the #fp_dev device
|
||||||
* @result: a #fp_enroll_result on success, or a negative value on failure
|
* @result: a #fp_enroll_result on success, or a negative value on failure
|
||||||
* @print: the enrollment data from the final stage
|
* @print: the enrollment data from the final stage
|
||||||
* @img: an #fp_img to free with fp_img_free()
|
* @img: an #fp_img to free with fp_img_free()
|
||||||
* @user_data: user data passed to the callback
|
* @user_data: user data passed to the callback
|
||||||
*
|
*
|
||||||
* Type definition for a function that will be called when
|
* Type definition for a function that will be called when
|
||||||
* fp_async_enroll_start() finishes. See fp_enroll_finger_img() for
|
* fp_async_enroll_start() finishes.
|
||||||
* the expected behaviour of your program based on the @result.
|
|
||||||
*/
|
*/
|
||||||
typedef void (*fp_enroll_stage_cb)(struct fp_dev *dev, int result,
|
typedef void (*fp_enroll_stage_cb)(struct fp_dev *dev, int result,
|
||||||
struct fp_print_data *print, struct fp_img *img, void *user_data);
|
struct fp_print_data *print, struct fp_img *img, void *user_data);
|
||||||
@@ -434,7 +416,7 @@ int fp_async_verify_stop(struct fp_dev *dev, fp_operation_stop_cb callback,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_identify_cb:
|
* fp_identify_cb:
|
||||||
* @dev: the struct #fp_dev device
|
* @dev: the #fp_dev device
|
||||||
* @result: a #fp_verify_result on success, or a negative value on error.
|
* @result: a #fp_verify_result on success, or a negative value on error.
|
||||||
* @match_offset: the array index of the matched gallery print (if any was found).
|
* @match_offset: the array index of the matched gallery print (if any was found).
|
||||||
* Only valid if %FP_VERIFY_MATCH was returned.
|
* Only valid if %FP_VERIFY_MATCH was returned.
|
||||||
@@ -456,22 +438,6 @@ 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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
/**
|
/**
|
||||||
* SECTION:img
|
* SECTION:img
|
||||||
* @title: Image operations
|
* @title: Image operations
|
||||||
* @short_description: Image operation functions
|
|
||||||
*
|
*
|
||||||
* libfprint offers several ways of retrieving images from imaging devices,
|
* libfprint offers several ways of retrieving images from imaging devices,
|
||||||
* one example being the fp_dev_img_capture() function. The functions
|
* one example being the fp_dev_img_capture() function. The functions
|
||||||
@@ -49,25 +48,6 @@
|
|||||||
* natural upright orientation.
|
* natural upright orientation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-img
|
|
||||||
* @title: Driver Image operations
|
|
||||||
* @short_description: Driver image operation functions
|
|
||||||
*
|
|
||||||
* Those are the driver-specific helpers for #fp_img manipulation. See #fp_img's
|
|
||||||
* documentation for more information about data formats, and their uses in
|
|
||||||
* front-end applications.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_img_new:
|
|
||||||
* @length: the length of data to allocate
|
|
||||||
*
|
|
||||||
* Creates a new #fp_img structure with @length bytes of data allocated
|
|
||||||
* to hold the image.
|
|
||||||
*
|
|
||||||
* Returns: a new #fp_img to free with fp_img_free()
|
|
||||||
*/
|
|
||||||
struct fp_img *fpi_img_new(size_t length)
|
struct fp_img *fpi_img_new(size_t length)
|
||||||
{
|
{
|
||||||
struct fp_img *img = g_malloc0(sizeof(*img) + length);
|
struct fp_img *img = g_malloc0(sizeof(*img) + length);
|
||||||
@@ -76,19 +56,9 @@ struct fp_img *fpi_img_new(size_t length)
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_img_new_for_imgdev:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Creates a new #fp_img structure, like fpi_img_new(), but uses the
|
|
||||||
* driver's advertised height and width to calculate the size of the
|
|
||||||
* length of data to allocate.
|
|
||||||
*
|
|
||||||
* Returns: a new #fp_img to free with fp_img_free()
|
|
||||||
*/
|
|
||||||
struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *imgdev)
|
struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(FP_DEV(imgdev)->drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(imgdev->dev->drv);
|
||||||
int width = imgdrv->img_width;
|
int width = imgdrv->img_width;
|
||||||
int height = imgdrv->img_height;
|
int height = imgdrv->img_height;
|
||||||
struct fp_img *img = fpi_img_new(width * height);
|
struct fp_img *img = fpi_img_new(width * height);
|
||||||
@@ -97,53 +67,27 @@ struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *imgdev)
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_img_is_sane:
|
|
||||||
* @img: a #fp_img image
|
|
||||||
*
|
|
||||||
* Checks whether an #fp_img structure passes some basic checks, such
|
|
||||||
* as length, width and height being non-zero, and the buffer being
|
|
||||||
* big enough to hold the image of said size.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the image is sane, %FALSE otherwise
|
|
||||||
*/
|
|
||||||
gboolean fpi_img_is_sane(struct fp_img *img)
|
gboolean fpi_img_is_sane(struct fp_img *img)
|
||||||
{
|
{
|
||||||
guint len;
|
|
||||||
|
|
||||||
/* basic checks */
|
/* basic checks */
|
||||||
if (!img->length || img->width <= 0 || img->height <= 0)
|
if (!img->length || !img->width || !img->height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Are width and height just too big? */
|
/* buffer is big enough? */
|
||||||
if (!g_uint_checked_mul(&len, img->width, img->height) ||
|
if ((img->length * img->height) < img->length)
|
||||||
len > G_MAXINT)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* buffer big enough? */
|
|
||||||
if (len > img->length)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize)
|
||||||
* fpi_img_realloc:
|
|
||||||
* @img: an #fp_img image
|
|
||||||
* @newsize: the new length of the image
|
|
||||||
*
|
|
||||||
* Changes the size of the data part of the #fp_img.
|
|
||||||
*
|
|
||||||
* Returns: the modified #fp_img, the same as the first argument to this function
|
|
||||||
*/
|
|
||||||
struct fp_img *fpi_img_realloc(struct fp_img *img, size_t newsize)
|
|
||||||
{
|
{
|
||||||
return g_realloc(img, sizeof(*img) + newsize);
|
return g_realloc(img, sizeof(*img) + newsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fp_img_free:
|
* fp_img_free:
|
||||||
* @img: the image to destroy. If %NULL, function simply returns.
|
* @img: the image to destroy. If NULL, function simply returns.
|
||||||
*
|
*
|
||||||
* Frees an image. Must be called when you are finished working with an image.
|
* Frees an image. Must be called when you are finished working with an image.
|
||||||
*/
|
*/
|
||||||
@@ -318,8 +262,9 @@ static void minutiae_to_xyt(struct fp_minutiae *minutiae, int bwidth,
|
|||||||
struct minutiae_struct c[MAX_FILE_MINUTIAE];
|
struct minutiae_struct c[MAX_FILE_MINUTIAE];
|
||||||
struct xyt_struct *xyt = (struct xyt_struct *) buf;
|
struct xyt_struct *xyt = (struct xyt_struct *) buf;
|
||||||
|
|
||||||
/* struct xyt_struct uses arrays of MAX_BOZORTH_MINUTIAE (200) */
|
/* FIXME: only considers first 150 minutiae (MAX_FILE_MINUTIAE) */
|
||||||
int nmin = min(minutiae->num, MAX_BOZORTH_MINUTIAE);
|
/* nist does weird stuff with 150 vs 1000 limits */
|
||||||
|
int nmin = min(minutiae->num, MAX_FILE_MINUTIAE);
|
||||||
|
|
||||||
for (i = 0; i < nmin; i++){
|
for (i = 0; i < nmin; i++){
|
||||||
minutia = minutiae->list[i];
|
minutia = minutiae->list[i];
|
||||||
@@ -343,9 +288,6 @@ static void minutiae_to_xyt(struct fp_minutiae *minutiae, int bwidth,
|
|||||||
xyt->nrows = nmin;
|
xyt->nrows = nmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FP_IMG_STANDARDIZATION_FLAGS (FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED \
|
|
||||||
| FP_IMG_COLORS_INVERTED)
|
|
||||||
|
|
||||||
static int fpi_img_detect_minutiae(struct fp_img *img)
|
static int fpi_img_detect_minutiae(struct fp_img *img)
|
||||||
{
|
{
|
||||||
struct fp_minutiae *minutiae;
|
struct fp_minutiae *minutiae;
|
||||||
@@ -358,10 +300,13 @@ static int fpi_img_detect_minutiae(struct fp_img *img)
|
|||||||
GTimer *timer;
|
GTimer *timer;
|
||||||
|
|
||||||
if (img->flags & FP_IMG_STANDARDIZATION_FLAGS) {
|
if (img->flags & FP_IMG_STANDARDIZATION_FLAGS) {
|
||||||
fp_err("Cannot detect minutiae for non-standardized images");
|
fp_err("cant detect minutiae for non-standardized image");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove perimeter points from partial image */
|
||||||
|
g_lfsparms_V2.remove_perimeter_pts = img->flags & FP_IMG_PARTIAL ? TRUE : FALSE;
|
||||||
|
|
||||||
/* 25.4 mm per inch */
|
/* 25.4 mm per inch */
|
||||||
timer = g_timer_new();
|
timer = g_timer_new();
|
||||||
r = get_minutiae(&minutiae, &quality_map, &direction_map,
|
r = get_minutiae(&minutiae, &quality_map, &direction_map,
|
||||||
@@ -407,7 +352,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
|||||||
|
|
||||||
/* FIXME: space is wasted if we dont hit the max minutiae count. would
|
/* FIXME: space is wasted if we dont hit the max minutiae count. would
|
||||||
* be good to make this dynamic. */
|
* be good to make this dynamic. */
|
||||||
print = fpi_print_data_new(FP_DEV(imgdev));
|
print = fpi_print_data_new(imgdev->dev);
|
||||||
item = fpi_print_data_item_new(sizeof(struct xyt_struct));
|
item = fpi_print_data_item_new(sizeof(struct xyt_struct));
|
||||||
print->type = PRINT_DATA_NBIS_MINUTIAE;
|
print->type = PRINT_DATA_NBIS_MINUTIAE;
|
||||||
minutiae_to_xyt(img->minutiae, img->width, img->height, item->data);
|
minutiae_to_xyt(img->minutiae, img->width, img->height, item->data);
|
||||||
@@ -591,46 +536,57 @@ API_EXPORTED struct fp_minutia **fp_img_get_minutiae(struct fp_img *img,
|
|||||||
return img->minutiae->list;
|
return img->minutiae->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
libusb_device_handle *
|
||||||
* fp_minutia_get_coords:
|
fpi_imgdev_get_usb_dev(struct fp_img_dev *dev)
|
||||||
* @minutia: a struct #fp_minutia
|
|
||||||
* @coord_x: the return variable for the X coordinate of the minutia
|
|
||||||
* @coord_y: the return variable for the Y coordinate of the minutia
|
|
||||||
*
|
|
||||||
* Sets @coord_x and @coord_y to be the coordinates of the detected minutia, so it
|
|
||||||
* can be presented in a more verbose user interface. This is usually only
|
|
||||||
* used for debugging purposes.
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error.
|
|
||||||
*/
|
|
||||||
API_EXPORTED int fp_minutia_get_coords(struct fp_minutia *minutia, int *coord_x, int *coord_y)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (minutia != NULL, -1);
|
return dev->udev;
|
||||||
g_return_val_if_fail (coord_x != NULL, -1);
|
|
||||||
g_return_val_if_fail (coord_y != NULL, -1);
|
|
||||||
|
|
||||||
*coord_x = minutia->x;
|
|
||||||
*coord_y = minutia->y;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void
|
||||||
* fpi_std_sq_dev:
|
fpi_imgdev_set_user_data(struct fp_img_dev *imgdev,
|
||||||
* @buf: buffer (usually bitmap, one byte per pixel)
|
void *user_data)
|
||||||
* @size: size of @buffer
|
{
|
||||||
*
|
imgdev->priv = user_data;
|
||||||
* Calculates the squared standard deviation of the individual
|
}
|
||||||
* pixels in the buffer, as per the following formula:
|
|
||||||
* |[<!-- -->
|
void *
|
||||||
* mean = sum (buf[0..size]) / size
|
fpi_imgdev_get_user_data(struct fp_img_dev *imgdev)
|
||||||
* sq_dev = sum ((buf[0.size] - mean) ^ 2)
|
{
|
||||||
* ]|
|
return imgdev->priv;
|
||||||
* This function is usually used to determine whether image
|
}
|
||||||
* is empty.
|
|
||||||
*
|
struct fp_dev *
|
||||||
* Returns: the squared standard deviation for @buffer
|
fpi_imgdev_get_dev(struct fp_img_dev *imgdev)
|
||||||
*/
|
{
|
||||||
|
return imgdev->dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fp_imgdev_enroll_state
|
||||||
|
fpi_imgdev_get_action_state(struct fp_img_dev *imgdev)
|
||||||
|
{
|
||||||
|
return imgdev->action_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fp_imgdev_action
|
||||||
|
fpi_imgdev_get_action(struct fp_img_dev *imgdev)
|
||||||
|
{
|
||||||
|
return imgdev->action;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fpi_imgdev_get_action_result(struct fp_img_dev *imgdev)
|
||||||
|
{
|
||||||
|
return imgdev->action_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fpi_imgdev_set_action_result(struct fp_img_dev *imgdev,
|
||||||
|
int action_result)
|
||||||
|
{
|
||||||
|
imgdev->action_result = action_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate squared standand deviation */
|
||||||
int fpi_std_sq_dev(const unsigned char *buf, int size)
|
int fpi_std_sq_dev(const unsigned char *buf, int size)
|
||||||
{
|
{
|
||||||
int res = 0, mean = 0, i;
|
int res = 0, mean = 0, i;
|
||||||
@@ -653,23 +609,7 @@ int fpi_std_sq_dev(const unsigned char *buf, int size)
|
|||||||
return res / size;
|
return res / size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Calculate normalized mean square difference of two lines */
|
||||||
* fpi_mean_sq_diff_norm:
|
|
||||||
* @buf1: buffer (usually bitmap, one byte per pixel)
|
|
||||||
* @buf2: buffer (usually bitmap, one byte per pixel)
|
|
||||||
* @size: buffer size of smallest buffer
|
|
||||||
*
|
|
||||||
* This function calculates the normalized mean square difference of
|
|
||||||
* two buffers, usually two lines, as per the following formula:
|
|
||||||
* |[<!-- -->
|
|
||||||
* sq_diff = sum ((buf1[0..size] - buf2[0..size]) ^ 2) / size
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* This functions is usually used to get numerical difference
|
|
||||||
* between two images.
|
|
||||||
*
|
|
||||||
* Returns: the normalized mean squared difference between @buf1 and @buf2
|
|
||||||
*/
|
|
||||||
int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size)
|
int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size)
|
||||||
{
|
{
|
||||||
int res = 0, i;
|
int res = 0, i;
|
||||||
@@ -21,94 +21,26 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "fpi-dev-img.h"
|
|
||||||
#include "fpi-async.h"
|
|
||||||
#include "fp_internal.h"
|
#include "fp_internal.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:fpi-dev-img
|
|
||||||
* @title: Image device operations
|
|
||||||
* @short_description: Image device operation functions
|
|
||||||
*
|
|
||||||
* As drivers work through different operations, they need to report back
|
|
||||||
* to the core as to their internal state, so errors and successes can be
|
|
||||||
* reported back to front-ends.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MIN_ACCEPTABLE_MINUTIAE 10
|
#define MIN_ACCEPTABLE_MINUTIAE 10
|
||||||
#define BOZORTH3_DEFAULT_THRESHOLD 40
|
#define BOZORTH3_DEFAULT_THRESHOLD 40
|
||||||
#define IMG_ENROLL_STAGES 5
|
#define IMG_ENROLL_STAGES 5
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_get_action_state:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Returns the state of an imaging device while enrolling a fingerprint.
|
|
||||||
*
|
|
||||||
* Returns: a enum #fp_imgdev_enroll_state
|
|
||||||
*/
|
|
||||||
enum fp_imgdev_enroll_state
|
|
||||||
fpi_imgdev_get_action_state(struct fp_img_dev *imgdev)
|
|
||||||
{
|
|
||||||
return imgdev->action_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_get_action:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Returns the current action being performed by an imaging device.
|
|
||||||
*
|
|
||||||
* Returns: a enum #fp_imgdev_action
|
|
||||||
*/
|
|
||||||
enum fp_imgdev_action
|
|
||||||
fpi_imgdev_get_action(struct fp_img_dev *imgdev)
|
|
||||||
{
|
|
||||||
return imgdev->action;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_get_action_result:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Returns an integer representing the result of an action. Which enum
|
|
||||||
* the result code is taken from depends on the current action being performed.
|
|
||||||
* See #fp_capture_result, #fp_enroll_result and #fp_verify_result.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
fpi_imgdev_get_action_result(struct fp_img_dev *imgdev)
|
|
||||||
{
|
|
||||||
return imgdev->action_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_set_action_result:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @action_result: an action result
|
|
||||||
*
|
|
||||||
* Drivers should use fpi_imgdev_image_captured() instead. This function
|
|
||||||
* should not be used, and will be removed soon.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fpi_imgdev_set_action_result(struct fp_img_dev *imgdev,
|
|
||||||
int action_result)
|
|
||||||
{
|
|
||||||
imgdev->action_result = action_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int img_dev_open(struct fp_dev *dev, unsigned long driver_data)
|
static int img_dev_open(struct fp_dev *dev, unsigned long driver_data)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = g_malloc0(sizeof(*imgdev));
|
struct fp_img_dev *imgdev = g_malloc0(sizeof(*imgdev));
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
/* Set up back pointers */
|
imgdev->dev = dev;
|
||||||
dev->img_dev = imgdev;
|
|
||||||
imgdev->parent = dev;
|
|
||||||
|
|
||||||
imgdev->enroll_stage = 0;
|
imgdev->enroll_stage = 0;
|
||||||
|
dev->priv = imgdev;
|
||||||
dev->nr_enroll_stages = IMG_ENROLL_STAGES;
|
dev->nr_enroll_stages = IMG_ENROLL_STAGES;
|
||||||
|
|
||||||
|
/* for consistency in driver code, allow udev access through imgdev */
|
||||||
|
imgdev->udev = dev->udev;
|
||||||
|
|
||||||
if (imgdrv->open) {
|
if (imgdrv->open) {
|
||||||
r = imgdrv->open(imgdev, driver_data);
|
r = imgdrv->open(imgdev, driver_data);
|
||||||
if (r)
|
if (r)
|
||||||
@@ -123,45 +55,32 @@ err:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_open_complete:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @status: an error code
|
|
||||||
*
|
|
||||||
* Function to call when the device has been opened, whether
|
|
||||||
* successfully of not.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status)
|
void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status)
|
||||||
{
|
{
|
||||||
fpi_drvcb_open_complete(FP_DEV(imgdev), status);
|
fpi_drvcb_open_complete(imgdev->dev, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void img_dev_close(struct fp_dev *dev)
|
static void img_dev_close(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv);
|
||||||
|
|
||||||
if (imgdrv->close)
|
if (imgdrv->close)
|
||||||
imgdrv->close(dev->img_dev);
|
imgdrv->close(imgdev);
|
||||||
else
|
else
|
||||||
fpi_drvcb_close_complete(dev);
|
fpi_drvcb_close_complete(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_close_complete:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Function to call when the device has been closed.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_close_complete(struct fp_img_dev *imgdev)
|
void fpi_imgdev_close_complete(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
fpi_drvcb_close_complete(FP_DEV(imgdev));
|
fpi_drvcb_close_complete(imgdev->dev);
|
||||||
g_free(imgdev);
|
g_free(imgdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_change_state(struct fp_img_dev *imgdev,
|
static int dev_change_state(struct fp_img_dev *imgdev,
|
||||||
enum fp_imgdev_state state)
|
enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
|
|
||||||
if (!imgdrv->change_state)
|
if (!imgdrv->change_state)
|
||||||
@@ -173,7 +92,7 @@ static int dev_change_state(struct fp_img_dev *imgdev,
|
|||||||
* image after freeing the old one. */
|
* image after freeing the old one. */
|
||||||
static int sanitize_image(struct fp_img_dev *imgdev, struct fp_img **_img)
|
static int sanitize_image(struct fp_img_dev *imgdev, struct fp_img **_img)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
struct fp_img *img = *_img;
|
struct fp_img *img = *_img;
|
||||||
|
|
||||||
@@ -199,14 +118,6 @@ static int sanitize_image(struct fp_img_dev *imgdev, struct fp_img **_img)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_report_finger_status:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @present: whether the finger is present on the sensor
|
|
||||||
*
|
|
||||||
* Reports from the driver whether the user's finger is on
|
|
||||||
* the sensor.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
||||||
gboolean present)
|
gboolean present)
|
||||||
{
|
{
|
||||||
@@ -239,7 +150,7 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
|||||||
if (r == FP_ENROLL_COMPLETE) {
|
if (r == FP_ENROLL_COMPLETE) {
|
||||||
imgdev->enroll_data = NULL;
|
imgdev->enroll_data = NULL;
|
||||||
}
|
}
|
||||||
fpi_drvcb_enroll_stage_completed(FP_DEV(imgdev), r,
|
fpi_drvcb_enroll_stage_completed(imgdev->dev, r,
|
||||||
r == FP_ENROLL_COMPLETE ? data : NULL,
|
r == FP_ENROLL_COMPLETE ? data : NULL,
|
||||||
img);
|
img);
|
||||||
/* the callback can cancel enrollment, so recheck current
|
/* the callback can cancel enrollment, so recheck current
|
||||||
@@ -252,18 +163,18 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_VERIFY:
|
case IMG_ACTION_VERIFY:
|
||||||
fpi_drvcb_report_verify_result(FP_DEV(imgdev), r, img);
|
fpi_drvcb_report_verify_result(imgdev->dev, r, img);
|
||||||
imgdev->action_result = 0;
|
imgdev->action_result = 0;
|
||||||
fp_print_data_free(data);
|
fp_print_data_free(data);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_IDENTIFY:
|
case IMG_ACTION_IDENTIFY:
|
||||||
fpi_drvcb_report_identify_result(FP_DEV(imgdev), r,
|
fpi_drvcb_report_identify_result(imgdev->dev, r,
|
||||||
imgdev->identify_match_offset, img);
|
imgdev->identify_match_offset, img);
|
||||||
imgdev->action_result = 0;
|
imgdev->action_result = 0;
|
||||||
fp_print_data_free(data);
|
fp_print_data_free(data);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_CAPTURE:
|
case IMG_ACTION_CAPTURE:
|
||||||
fpi_drvcb_report_capture_result(FP_DEV(imgdev), r, img);
|
fpi_drvcb_report_capture_result(imgdev->dev, r, img);
|
||||||
imgdev->action_result = 0;
|
imgdev->action_result = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -274,14 +185,14 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
|||||||
|
|
||||||
static void verify_process_img(struct fp_img_dev *imgdev)
|
static void verify_process_img(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(FP_DEV(imgdev)->drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(imgdev->dev->drv);
|
||||||
int match_score = imgdrv->bz3_threshold;
|
int match_score = imgdrv->bz3_threshold;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (match_score == 0)
|
if (match_score == 0)
|
||||||
match_score = BOZORTH3_DEFAULT_THRESHOLD;
|
match_score = BOZORTH3_DEFAULT_THRESHOLD;
|
||||||
|
|
||||||
r = fpi_img_compare_print_data(FP_DEV(imgdev)->verify_data,
|
r = fpi_img_compare_print_data(imgdev->dev->verify_data,
|
||||||
imgdev->acquire_data);
|
imgdev->acquire_data);
|
||||||
|
|
||||||
if (r >= match_score)
|
if (r >= match_score)
|
||||||
@@ -294,7 +205,7 @@ static void verify_process_img(struct fp_img_dev *imgdev)
|
|||||||
|
|
||||||
static void identify_process_img(struct fp_img_dev *imgdev)
|
static void identify_process_img(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(FP_DEV(imgdev)->drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(imgdev->dev->drv);
|
||||||
int match_score = imgdrv->bz3_threshold;
|
int match_score = imgdrv->bz3_threshold;
|
||||||
size_t match_offset;
|
size_t match_offset;
|
||||||
int r;
|
int r;
|
||||||
@@ -303,20 +214,12 @@ static void identify_process_img(struct fp_img_dev *imgdev)
|
|||||||
match_score = BOZORTH3_DEFAULT_THRESHOLD;
|
match_score = BOZORTH3_DEFAULT_THRESHOLD;
|
||||||
|
|
||||||
r = fpi_img_compare_print_data_to_gallery(imgdev->acquire_data,
|
r = fpi_img_compare_print_data_to_gallery(imgdev->acquire_data,
|
||||||
FP_DEV(imgdev)->identify_gallery, match_score, &match_offset);
|
imgdev->dev->identify_gallery, match_score, &match_offset);
|
||||||
|
|
||||||
imgdev->action_result = r;
|
imgdev->action_result = r;
|
||||||
imgdev->identify_match_offset = match_offset;
|
imgdev->identify_match_offset = match_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_abort_scan:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @result: the scan result
|
|
||||||
*
|
|
||||||
* Aborts a scan after an error, and set the action result. See
|
|
||||||
* fpi_imgdev_get_action_result() for possible values.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result)
|
void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result)
|
||||||
{
|
{
|
||||||
imgdev->action_result = result;
|
imgdev->action_result = result;
|
||||||
@@ -324,16 +227,9 @@ void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result)
|
|||||||
dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF);
|
dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_image_captured:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @img: an #fp_img image
|
|
||||||
*
|
|
||||||
* Report to the core that the driver captured this image from the sensor.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
|
void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
|
||||||
{
|
{
|
||||||
struct fp_print_data *print = NULL;
|
struct fp_print_data *print;
|
||||||
int r;
|
int r;
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
@@ -376,7 +272,7 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
|
|||||||
switch (imgdev->action) {
|
switch (imgdev->action) {
|
||||||
case IMG_ACTION_ENROLL:
|
case IMG_ACTION_ENROLL:
|
||||||
if (!imgdev->enroll_data) {
|
if (!imgdev->enroll_data) {
|
||||||
imgdev->enroll_data = fpi_print_data_new(FP_DEV(imgdev));
|
imgdev->enroll_data = fpi_print_data_new(imgdev->dev);
|
||||||
}
|
}
|
||||||
BUG_ON(g_slist_length(print->prints) != 1);
|
BUG_ON(g_slist_length(print->prints) != 1);
|
||||||
/* Move print data from acquire data into enroll_data */
|
/* Move print data from acquire data into enroll_data */
|
||||||
@@ -387,7 +283,7 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
|
|||||||
fp_print_data_free(imgdev->acquire_data);
|
fp_print_data_free(imgdev->acquire_data);
|
||||||
imgdev->acquire_data = NULL;
|
imgdev->acquire_data = NULL;
|
||||||
imgdev->enroll_stage++;
|
imgdev->enroll_stage++;
|
||||||
if (imgdev->enroll_stage == FP_DEV(imgdev)->nr_enroll_stages)
|
if (imgdev->enroll_stage == imgdev->dev->nr_enroll_stages)
|
||||||
imgdev->action_result = FP_ENROLL_COMPLETE;
|
imgdev->action_result = FP_ENROLL_COMPLETE;
|
||||||
else
|
else
|
||||||
imgdev->action_result = FP_ENROLL_PASS;
|
imgdev->action_result = FP_ENROLL_PASS;
|
||||||
@@ -411,29 +307,22 @@ next_state:
|
|||||||
dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF);
|
dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_session_error:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @error: an error code
|
|
||||||
*
|
|
||||||
* Report an error that occurred in the driver.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error)
|
void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error)
|
||||||
{
|
{
|
||||||
fp_dbg("error %d", error);
|
fp_dbg("error %d", error);
|
||||||
BUG_ON(error == 0);
|
BUG_ON(error == 0);
|
||||||
switch (imgdev->action) {
|
switch (imgdev->action) {
|
||||||
case IMG_ACTION_ENROLL:
|
case IMG_ACTION_ENROLL:
|
||||||
fpi_drvcb_enroll_stage_completed(FP_DEV(imgdev), error, NULL, NULL);
|
fpi_drvcb_enroll_stage_completed(imgdev->dev, error, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_VERIFY:
|
case IMG_ACTION_VERIFY:
|
||||||
fpi_drvcb_report_verify_result(FP_DEV(imgdev), error, NULL);
|
fpi_drvcb_report_verify_result(imgdev->dev, error, NULL);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_IDENTIFY:
|
case IMG_ACTION_IDENTIFY:
|
||||||
fpi_drvcb_report_identify_result(FP_DEV(imgdev), error, 0, NULL);
|
fpi_drvcb_report_identify_result(imgdev->dev, error, 0, NULL);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_CAPTURE:
|
case IMG_ACTION_CAPTURE:
|
||||||
fpi_drvcb_report_capture_result(FP_DEV(imgdev), error, NULL);
|
fpi_drvcb_report_capture_result(imgdev->dev, error, NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_err("unhandled action %d", imgdev->action);
|
fp_err("unhandled action %d", imgdev->action);
|
||||||
@@ -441,30 +330,22 @@ void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_activate_complete:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
* @status: the activation result
|
|
||||||
*
|
|
||||||
* Marks an activation as complete, whether successful or not.
|
|
||||||
* See fpi_imgdev_get_action_result() for possible values.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status)
|
void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status)
|
||||||
{
|
{
|
||||||
fp_dbg("status %d", status);
|
fp_dbg("status %d", status);
|
||||||
|
|
||||||
switch (imgdev->action) {
|
switch (imgdev->action) {
|
||||||
case IMG_ACTION_ENROLL:
|
case IMG_ACTION_ENROLL:
|
||||||
fpi_drvcb_enroll_started(FP_DEV(imgdev), status);
|
fpi_drvcb_enroll_started(imgdev->dev, status);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_VERIFY:
|
case IMG_ACTION_VERIFY:
|
||||||
fpi_drvcb_verify_started(FP_DEV(imgdev), status);
|
fpi_drvcb_verify_started(imgdev->dev, status);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_IDENTIFY:
|
case IMG_ACTION_IDENTIFY:
|
||||||
fpi_drvcb_identify_started(FP_DEV(imgdev), status);
|
fpi_drvcb_identify_started(imgdev->dev, status);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_CAPTURE:
|
case IMG_ACTION_CAPTURE:
|
||||||
fpi_drvcb_capture_started(FP_DEV(imgdev), status);
|
fpi_drvcb_capture_started(imgdev->dev, status);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_err("unhandled action %d", imgdev->action);
|
fp_err("unhandled action %d", imgdev->action);
|
||||||
@@ -477,28 +358,22 @@ void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fpi_imgdev_deactivate_complete:
|
|
||||||
* @imgdev: a #fp_img_dev imaging fingerprint device
|
|
||||||
*
|
|
||||||
* Marks a deactivation as complete.
|
|
||||||
*/
|
|
||||||
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
|
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
switch (imgdev->action) {
|
switch (imgdev->action) {
|
||||||
case IMG_ACTION_ENROLL:
|
case IMG_ACTION_ENROLL:
|
||||||
fpi_drvcb_enroll_stopped(FP_DEV(imgdev));
|
fpi_drvcb_enroll_stopped(imgdev->dev);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_VERIFY:
|
case IMG_ACTION_VERIFY:
|
||||||
fpi_drvcb_verify_stopped(FP_DEV(imgdev));
|
fpi_drvcb_verify_stopped(imgdev->dev);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_IDENTIFY:
|
case IMG_ACTION_IDENTIFY:
|
||||||
fpi_drvcb_identify_stopped(FP_DEV(imgdev));
|
fpi_drvcb_identify_stopped(imgdev->dev);
|
||||||
break;
|
break;
|
||||||
case IMG_ACTION_CAPTURE:
|
case IMG_ACTION_CAPTURE:
|
||||||
fpi_drvcb_capture_stopped(FP_DEV(imgdev));
|
fpi_drvcb_capture_stopped(imgdev->dev);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_err("unhandled action %d", imgdev->action);
|
fp_err("unhandled action %d", imgdev->action);
|
||||||
@@ -511,7 +386,7 @@ void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
|
|||||||
|
|
||||||
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev)
|
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
int width = imgdrv->img_width;
|
int width = imgdrv->img_width;
|
||||||
|
|
||||||
@@ -523,7 +398,7 @@ int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev)
|
|||||||
|
|
||||||
int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev)
|
int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
int height = imgdrv->img_height;
|
int height = imgdrv->img_height;
|
||||||
|
|
||||||
@@ -535,7 +410,7 @@ int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev)
|
|||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state)
|
static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
|
|
||||||
if (!imgdrv->activate)
|
if (!imgdrv->activate)
|
||||||
@@ -545,7 +420,7 @@ static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state)
|
|||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *imgdev)
|
static void dev_deactivate(struct fp_img_dev *imgdev)
|
||||||
{
|
{
|
||||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
struct fp_driver *drv = imgdev->dev->drv;
|
||||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||||
|
|
||||||
if (!imgdrv->deactivate)
|
if (!imgdrv->deactivate)
|
||||||
@@ -555,7 +430,7 @@ static void dev_deactivate(struct fp_img_dev *imgdev)
|
|||||||
|
|
||||||
static int generic_acquire_start(struct fp_dev *dev, int action)
|
static int generic_acquire_start(struct fp_dev *dev, int action)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = dev->img_dev;
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
int r;
|
int r;
|
||||||
fp_dbg("action %d", action);
|
fp_dbg("action %d", action);
|
||||||
imgdev->action = action;
|
imgdev->action = action;
|
||||||
@@ -609,7 +484,7 @@ static int img_dev_capture_start(struct fp_dev *dev)
|
|||||||
|
|
||||||
static int img_dev_enroll_stop(struct fp_dev *dev)
|
static int img_dev_enroll_stop(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = dev->img_dev;
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
BUG_ON(imgdev->action != IMG_ACTION_ENROLL);
|
BUG_ON(imgdev->action != IMG_ACTION_ENROLL);
|
||||||
generic_acquire_stop(imgdev);
|
generic_acquire_stop(imgdev);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -617,7 +492,7 @@ static int img_dev_enroll_stop(struct fp_dev *dev)
|
|||||||
|
|
||||||
static int img_dev_verify_stop(struct fp_dev *dev, gboolean iterating)
|
static int img_dev_verify_stop(struct fp_dev *dev, gboolean iterating)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = dev->img_dev;
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
BUG_ON(imgdev->action != IMG_ACTION_VERIFY);
|
BUG_ON(imgdev->action != IMG_ACTION_VERIFY);
|
||||||
generic_acquire_stop(imgdev);
|
generic_acquire_stop(imgdev);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -625,7 +500,7 @@ static int img_dev_verify_stop(struct fp_dev *dev, gboolean iterating)
|
|||||||
|
|
||||||
static int img_dev_identify_stop(struct fp_dev *dev, gboolean iterating)
|
static int img_dev_identify_stop(struct fp_dev *dev, gboolean iterating)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = dev->img_dev;
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
BUG_ON(imgdev->action != IMG_ACTION_IDENTIFY);
|
BUG_ON(imgdev->action != IMG_ACTION_IDENTIFY);
|
||||||
generic_acquire_stop(imgdev);
|
generic_acquire_stop(imgdev);
|
||||||
imgdev->identify_match_offset = 0;
|
imgdev->identify_match_offset = 0;
|
||||||
@@ -634,7 +509,7 @@ static int img_dev_identify_stop(struct fp_dev *dev, gboolean iterating)
|
|||||||
|
|
||||||
static int img_dev_capture_stop(struct fp_dev *dev)
|
static int img_dev_capture_stop(struct fp_dev *dev)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *imgdev = dev->img_dev;
|
struct fp_img_dev *imgdev = dev->priv;
|
||||||
BUG_ON(imgdev->action != IMG_ACTION_CAPTURE);
|
BUG_ON(imgdev->action != IMG_ACTION_CAPTURE);
|
||||||
generic_acquire_stop(imgdev);
|
generic_acquire_stop(imgdev);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1,29 +1,16 @@
|
|||||||
libfprint_sources = [
|
libfprint_sources = [
|
||||||
'fp_internal.h',
|
'fp_internal.h',
|
||||||
'nbis-helpers.h',
|
|
||||||
'drivers_api.h',
|
'drivers_api.h',
|
||||||
'fpi-async.c',
|
'async.c',
|
||||||
'fpi-async.h',
|
'core.c',
|
||||||
'fpi-assembling.c',
|
'data.c',
|
||||||
'fpi-assembling.h',
|
'drv.c',
|
||||||
'fpi-core.c',
|
'img.c',
|
||||||
'fpi-core.h',
|
'imgdev.c',
|
||||||
'fpi-data.c',
|
'poll.c',
|
||||||
'fpi-data.h',
|
'sync.c',
|
||||||
'fpi-dev.c',
|
'assembling.c',
|
||||||
'fpi-dev.h',
|
'assembling.h',
|
||||||
'fpi-dev-img.c',
|
|
||||||
'fpi-dev-img.h',
|
|
||||||
'fpi-img.c',
|
|
||||||
'fpi-img.h',
|
|
||||||
'fpi-log.h',
|
|
||||||
'fpi-ssm.c',
|
|
||||||
'fpi-ssm.h',
|
|
||||||
'fpi-sync.c',
|
|
||||||
'fpi-poll.h',
|
|
||||||
'fpi-poll.c',
|
|
||||||
'fpi-usb.h',
|
|
||||||
'fpi-usb.c',
|
|
||||||
'drivers/driver_ids.h',
|
'drivers/driver_ids.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -43,17 +30,14 @@ nbis_sources = [
|
|||||||
'nbis/bozorth3/bz_sort.c',
|
'nbis/bozorth3/bz_sort.c',
|
||||||
'nbis/mindtct/binar.c',
|
'nbis/mindtct/binar.c',
|
||||||
'nbis/mindtct/block.c',
|
'nbis/mindtct/block.c',
|
||||||
'nbis/mindtct/chaincod.c',
|
|
||||||
'nbis/mindtct/contour.c',
|
'nbis/mindtct/contour.c',
|
||||||
'nbis/mindtct/detect.c',
|
'nbis/mindtct/detect.c',
|
||||||
'nbis/mindtct/dft.c',
|
'nbis/mindtct/dft.c',
|
||||||
'nbis/mindtct/free.c',
|
'nbis/mindtct/free.c',
|
||||||
'nbis/mindtct/getmin.c',
|
|
||||||
'nbis/mindtct/globals.c',
|
'nbis/mindtct/globals.c',
|
||||||
'nbis/mindtct/imgutil.c',
|
'nbis/mindtct/imgutil.c',
|
||||||
'nbis/mindtct/init.c',
|
'nbis/mindtct/init.c',
|
||||||
'nbis/mindtct/line.c',
|
'nbis/mindtct/line.c',
|
||||||
'nbis/mindtct/link.c',
|
|
||||||
'nbis/mindtct/log.c',
|
'nbis/mindtct/log.c',
|
||||||
'nbis/mindtct/loop.c',
|
'nbis/mindtct/loop.c',
|
||||||
'nbis/mindtct/maps.c',
|
'nbis/mindtct/maps.c',
|
||||||
@@ -66,7 +50,6 @@ nbis_sources = [
|
|||||||
'nbis/mindtct/shape.c',
|
'nbis/mindtct/shape.c',
|
||||||
'nbis/mindtct/sort.c',
|
'nbis/mindtct/sort.c',
|
||||||
'nbis/mindtct/util.c',
|
'nbis/mindtct/util.c',
|
||||||
'nbis/mindtct/xytreps.c',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
aeslib = false
|
aeslib = false
|
||||||
@@ -74,13 +57,12 @@ aesx660 = false
|
|||||||
aes3k = false
|
aes3k = false
|
||||||
drivers_sources = []
|
drivers_sources = []
|
||||||
drivers_cflags = []
|
drivers_cflags = []
|
||||||
|
|
||||||
foreach driver: drivers
|
foreach driver: drivers
|
||||||
if driver == 'upekts'
|
if driver == 'upekts'
|
||||||
drivers_sources += [ 'drivers/upekts.c' ]
|
drivers_sources += [ 'drivers/upekts.c' ]
|
||||||
endif
|
endif
|
||||||
if driver == 'upektc'
|
if driver == 'upektc'
|
||||||
drivers_sources += [ 'drivers/upektc.c', 'drivers/upektc.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ]
|
drivers_sources += [ 'drivers/upektc.c', 'drivers/upektc.h' ]
|
||||||
endif
|
endif
|
||||||
if driver == 'upeksonly'
|
if driver == 'upeksonly'
|
||||||
drivers_sources += [ 'drivers/upeksonly.c', 'drivers/upeksonly.h' ]
|
drivers_sources += [ 'drivers/upeksonly.c', 'drivers/upeksonly.h' ]
|
||||||
@@ -136,7 +118,7 @@ foreach driver: drivers
|
|||||||
drivers_sources += [ 'drivers/vfs5011.c', 'drivers/vfs5011_proto.h' ]
|
drivers_sources += [ 'drivers/vfs5011.c', 'drivers/vfs5011_proto.h' ]
|
||||||
endif
|
endif
|
||||||
if driver == 'upektc_img'
|
if driver == 'upektc_img'
|
||||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upektc_img.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ]
|
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upektc_img.h' ]
|
||||||
endif
|
endif
|
||||||
if driver == 'etes603'
|
if driver == 'etes603'
|
||||||
drivers_sources += [ 'drivers/etes603.c' ]
|
drivers_sources += [ 'drivers/etes603.c' ]
|
||||||
@@ -147,20 +129,10 @@ foreach driver: drivers
|
|||||||
if driver == 'elan'
|
if driver == 'elan'
|
||||||
drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ]
|
drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ]
|
||||||
endif
|
endif
|
||||||
if driver == 'synaptics'
|
|
||||||
drivers_sources += [
|
|
||||||
'drivers/synaptics/synaptics.c',
|
|
||||||
'drivers/synaptics/bmkt.c',
|
|
||||||
'drivers/synaptics/util.c',
|
|
||||||
'drivers/synaptics/bmkt_message.c',
|
|
||||||
'drivers/synaptics/sensor.c',
|
|
||||||
'drivers/synaptics/usb_transport.c',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
if aeslib
|
if aeslib
|
||||||
drivers_sources += [ 'drivers/aeslib.c', 'drivers/aeslib.h' ]
|
drivers_sources += [ 'aeslib.c', 'aeslib.h' ]
|
||||||
endif
|
endif
|
||||||
if aesx660
|
if aesx660
|
||||||
drivers_sources += ['drivers/aesx660.c', 'drivers/aesx660.h' ]
|
drivers_sources += ['drivers/aesx660.c', 'drivers/aesx660.h' ]
|
||||||
@@ -171,7 +143,7 @@ endif
|
|||||||
|
|
||||||
other_sources = []
|
other_sources = []
|
||||||
if imaging_dep.found()
|
if imaging_dep.found()
|
||||||
other_sources += [ 'fpi-img-pixman.c' ]
|
other_sources += [ 'pixman.c' ]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libfprint_sources += configure_file(input: 'empty_file',
|
libfprint_sources += configure_file(input: 'empty_file',
|
||||||
@@ -191,7 +163,6 @@ libfprint_sources += configure_file(input: 'empty_file',
|
|||||||
])
|
])
|
||||||
|
|
||||||
deps = [ mathlib_dep, glib_dep, libusb_dep, nss_dep, imaging_dep ]
|
deps = [ mathlib_dep, glib_dep, libusb_dep, nss_dep, imaging_dep ]
|
||||||
|
|
||||||
libfprint = library('fprint',
|
libfprint = library('fprint',
|
||||||
libfprint_sources + drivers_sources + nbis_sources + other_sources,
|
libfprint_sources + drivers_sources + nbis_sources + other_sources,
|
||||||
soversion: soversion,
|
soversion: soversion,
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Helpers to use within the NBIS copy/paste library
|
|
||||||
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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 <glib.h>
|
|
||||||
|
|
||||||
#define ASSERT_SIZE_MUL(a,b) \
|
|
||||||
{ \
|
|
||||||
gsize dest; \
|
|
||||||
g_assert(g_size_checked_mul(&dest, a, b)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ASSERT_INT_MUL(a, b) \
|
|
||||||
{ \
|
|
||||||
gsize dest; \
|
|
||||||
g_assert(g_size_checked_mul(&dest, a, b)); \
|
|
||||||
g_assert(dest < G_MAXINT); \
|
|
||||||
}
|
|
||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -81,6 +89,9 @@ of the software.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
|
static const int verbose_bozorth = 0;
|
||||||
|
static const int m1_xyt = 0;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void bz_comp(
|
void bz_comp(
|
||||||
int npoints, /* INPUT: # of points */
|
int npoints, /* INPUT: # of points */
|
||||||
@@ -149,7 +160,7 @@ for ( k = 0; k < npoints - 1; k++ ) {
|
|||||||
else {
|
else {
|
||||||
double dz;
|
double dz;
|
||||||
|
|
||||||
if ( 0 )
|
if ( m1_xyt )
|
||||||
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) -dy / (float) dx );
|
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) -dy / (float) dx );
|
||||||
else
|
else
|
||||||
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) dy / (float) dx );
|
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) dy / (float) dx );
|
||||||
@@ -250,7 +261,7 @@ for ( k = 0; k < npoints - 1; k++ ) {
|
|||||||
|
|
||||||
if ( table_index == 19999 ) {
|
if ( table_index == 19999 ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
printf( "bz_comp(): breaking loop to avoid table overflow\n" );
|
printf( "bz_comp(): breaking loop to avoid table overflow\n" );
|
||||||
#endif
|
#endif
|
||||||
goto COMP_END;
|
goto COMP_END;
|
||||||
@@ -381,7 +392,7 @@ static int * rtp[ ROT_SIZE_1 ];
|
|||||||
/* extern int * scolpt[ SCOLPT_SIZE ]; INPUT */
|
/* extern int * scolpt[ SCOLPT_SIZE ]; INPUT */
|
||||||
/* extern int * fcolpt[ FCOLPT_SIZE ]; INPUT */
|
/* extern int * fcolpt[ FCOLPT_SIZE ]; INPUT */
|
||||||
/* extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; OUTPUT */
|
/* extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; OUTPUT */
|
||||||
/* extern int 0; */
|
/* extern int verbose_bozorth; */
|
||||||
/* extern FILE * stderr; */
|
/* extern FILE * stderr; */
|
||||||
/* extern char * get_progname( void ); */
|
/* extern char * get_progname( void ); */
|
||||||
/* extern char * get_probe_filename( void ); */
|
/* extern char * get_probe_filename( void ); */
|
||||||
@@ -390,7 +401,6 @@ static int * rtp[ ROT_SIZE_1 ];
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
st = 1;
|
st = 1;
|
||||||
edge_pair_index = 0;
|
edge_pair_index = 0;
|
||||||
rotptr = &rot[0][0];
|
rotptr = &rot[0][0];
|
||||||
@@ -560,7 +570,7 @@ for ( k = 1; k < probe_ptrlist_len; k++ ) {
|
|||||||
|
|
||||||
if ( edge_pair_index == 19999 ) {
|
if ( edge_pair_index == 19999 ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
fprintf( stderr, "%s: bz_match(): WARNING: list is full, breaking loop early [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match(): WARNING: list is full, breaking loop early [p=%s; g=%s]\n",
|
||||||
get_progname(), get_probe_filename(), get_gallery_filename() );
|
get_progname(), get_probe_filename(), get_gallery_filename() );
|
||||||
#endif
|
#endif
|
||||||
@@ -642,13 +652,13 @@ int avv[ AVV_SIZE_1 ][ AVV_SIZE_2 ];
|
|||||||
if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
fprintf( stderr, "%s: bz_match_score(): both probe and gallery file have too few minutiae (%d,%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): both probe and gallery file have too few minutiae (%d,%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
pstruct->nrows, gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
pstruct->nrows, gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
get_probe_filename(), get_gallery_filename() );
|
get_probe_filename(), get_gallery_filename() );
|
||||||
} else {
|
} else {
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
fprintf( stderr, "%s: bz_match_score(): probe file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): probe file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
pstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
pstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
@@ -662,7 +672,7 @@ if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
|||||||
|
|
||||||
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
fprintf( stderr, "%s: bz_match_score(): gallery file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): gallery file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
@@ -701,6 +711,7 @@ tp = 0;
|
|||||||
p1 = 0;
|
p1 = 0;
|
||||||
tot = 0;
|
tot = 0;
|
||||||
ftt = 0;
|
ftt = 0;
|
||||||
|
kx = 0;
|
||||||
match_score = 0;
|
match_score = 0;
|
||||||
|
|
||||||
for ( k = 0; k < np - 1; k++ ) {
|
for ( k = 0; k < np - 1; k++ ) {
|
||||||
@@ -754,7 +765,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 )
|
if ( verbose_bozorth )
|
||||||
printf( "x1 %d %d %d %d %d %d\n", kx, colp[kx][0], colp[kx][1], colp[kx][2], colp[kx][3], colp[kx][4] );
|
printf( "x1 %d %d %d %d %d %d\n", kx, colp[kx][0], colp[kx][1], colp[kx][2], colp[kx][3], colp[kx][4] );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -816,6 +827,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
l = 1;
|
||||||
t = np + 1;
|
t = np + 1;
|
||||||
b = kq;
|
b = kq;
|
||||||
|
|
||||||
@@ -1155,7 +1167,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
|
|
||||||
if ( ll ) {
|
if ( ll ) {
|
||||||
|
|
||||||
if ( 0 )
|
if ( m1_xyt )
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -jj / (float) ll );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -jj / (float) ll );
|
||||||
else
|
else
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) jj / (float) ll );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) jj / (float) ll );
|
||||||
@@ -1175,7 +1187,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
jj += 360;
|
jj += 360;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( 0 ) {
|
if ( m1_xyt ) {
|
||||||
if ( jj > 0 )
|
if ( jj > 0 )
|
||||||
jj = -90;
|
jj = -90;
|
||||||
else
|
else
|
||||||
@@ -1192,7 +1204,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
|
|
||||||
if ( kk ) {
|
if ( kk ) {
|
||||||
|
|
||||||
if ( 0 )
|
if ( m1_xyt )
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -j / (float) kk );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -j / (float) kk );
|
||||||
else
|
else
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) j / (float) kk );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) j / (float) kk );
|
||||||
@@ -1212,7 +1224,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
|||||||
j += 360;
|
j += 360;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( 0 ) {
|
if ( m1_xyt ) {
|
||||||
if ( j > 0 )
|
if ( j > 0 )
|
||||||
j = -90;
|
j = -90;
|
||||||
else
|
else
|
||||||
@@ -1599,7 +1611,7 @@ if ( n ) {
|
|||||||
notfound = 1;
|
notfound = 1;
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 ) {
|
if ( verbose_bozorth ) {
|
||||||
int * llptr = lptr;
|
int * llptr = lptr;
|
||||||
printf( "bz_sift(): n: looking for l=%d in [", l );
|
printf( "bz_sift(): n: looking for l=%d in [", l );
|
||||||
for ( i = 0; i < lim; i++ ) {
|
for ( i = 0; i < lim; i++ ) {
|
||||||
@@ -1645,7 +1657,7 @@ if ( t ) {
|
|||||||
notfound = 1;
|
notfound = 1;
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( 0 ) {
|
if ( verbose_bozorth ) {
|
||||||
int * llptr = lptr;
|
int * llptr = lptr;
|
||||||
printf( "bz_sift(): t: looking for kz=%d in [", kz );
|
printf( "bz_sift(): t: looking for kz=%d in [", kz );
|
||||||
for ( i = 0; i < lim; i++ ) {
|
for ( i = 0; i < lim; i++ ) {
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -69,6 +77,43 @@ of the software.
|
|||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
char * malloc_or_exit( int nbytes, const char * what )
|
||||||
|
{
|
||||||
|
char * p;
|
||||||
|
|
||||||
|
/* These are now externally defined in bozorth.h */
|
||||||
|
/* extern FILE * stderr; */
|
||||||
|
/* extern char * get_progname( void ); */
|
||||||
|
|
||||||
|
|
||||||
|
p = malloc( (size_t) nbytes );
|
||||||
|
if ( p == CNULL ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n",
|
||||||
|
get_progname(),
|
||||||
|
nbytes,
|
||||||
|
what,
|
||||||
|
strerror( errno )
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* returns CNULL on error */
|
/* returns CNULL on error */
|
||||||
|
char * malloc_or_return_error( int nbytes, const char * what )
|
||||||
|
{
|
||||||
|
char * p;
|
||||||
|
|
||||||
|
p = malloc( (size_t) nbytes );
|
||||||
|
if ( p == CNULL ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n",
|
||||||
|
get_progname(),
|
||||||
|
nbytes,
|
||||||
|
what,
|
||||||
|
strerror( errno )
|
||||||
|
);
|
||||||
|
return(CNULL);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -169,3 +177,47 @@ return bz_match_score( np, pstruct, gstruct );
|
|||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
|
int bozorth_main(
|
||||||
|
struct xyt_struct * pstruct,
|
||||||
|
struct xyt_struct * gstruct
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ms;
|
||||||
|
int np;
|
||||||
|
int probe_len;
|
||||||
|
int gallery_len;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "PROBE_INIT() called\n" );
|
||||||
|
#endif
|
||||||
|
probe_len = bozorth_probe_init( pstruct );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "GALLERY_INIT() called\n" );
|
||||||
|
#endif
|
||||||
|
gallery_len = bozorth_gallery_init( gstruct );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "BZ_MATCH() called\n" );
|
||||||
|
#endif
|
||||||
|
np = bz_match( probe_len, gallery_len );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "BZ_MATCH() returned %d edge pairs\n", np );
|
||||||
|
printf( "COMPUTE() called\n" );
|
||||||
|
#endif
|
||||||
|
ms = bz_match_score( np, pstruct, gstruct );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "COMPUTE() returned %d\n", ms );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -83,45 +91,23 @@ int yl[ YL_SIZE_1 ][ YL_SIZE_2 ];
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Globals used significantly by sift() */
|
/* Globals used significantly by sift() */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
#ifdef TARGET_OS
|
int rq[ RQ_SIZE ] = {};
|
||||||
int rq[ RQ_SIZE ];
|
int tq[ TQ_SIZE ] = {};
|
||||||
int tq[ TQ_SIZE ];
|
int zz[ ZZ_SIZE ] = {};
|
||||||
int zz[ ZZ_SIZE ];
|
|
||||||
|
|
||||||
int rx[ RX_SIZE ];
|
int rx[ RX_SIZE ] = {};
|
||||||
int mm[ MM_SIZE ];
|
int mm[ MM_SIZE ] = {};
|
||||||
int nn[ NN_SIZE ];
|
int nn[ NN_SIZE ] = {};
|
||||||
|
|
||||||
int qq[ QQ_SIZE ];
|
int qq[ QQ_SIZE ] = {};
|
||||||
|
|
||||||
int rk[ RK_SIZE ];
|
int rk[ RK_SIZE ] = {};
|
||||||
|
|
||||||
int cp[ CP_SIZE ];
|
int cp[ CP_SIZE ] = {};
|
||||||
int rp[ RP_SIZE ];
|
int rp[ RP_SIZE ] = {};
|
||||||
|
|
||||||
int rf[RF_SIZE_1][RF_SIZE_2];
|
int rf[RF_SIZE_1][RF_SIZE_2] = {};
|
||||||
int cf[CF_SIZE_1][CF_SIZE_2];
|
int cf[CF_SIZE_1][CF_SIZE_2] = {};
|
||||||
|
|
||||||
int y[20000];
|
int y[20000] = {};
|
||||||
#else
|
|
||||||
int rq[ RQ_SIZE ] = {};
|
|
||||||
int tq[ TQ_SIZE ] = {};
|
|
||||||
int zz[ ZZ_SIZE ] = {};
|
|
||||||
|
|
||||||
int rx[ RX_SIZE ] = {};
|
|
||||||
int mm[ MM_SIZE ] = {};
|
|
||||||
int nn[ NN_SIZE ] = {};
|
|
||||||
|
|
||||||
int qq[ QQ_SIZE ] = {};
|
|
||||||
|
|
||||||
int rk[ RK_SIZE ] = {};
|
|
||||||
|
|
||||||
int cp[ CP_SIZE ] = {};
|
|
||||||
int rp[ RP_SIZE ] = {};
|
|
||||||
|
|
||||||
int rf[RF_SIZE_1][RF_SIZE_2] = {};
|
|
||||||
int cf[CF_SIZE_1][CF_SIZE_2] = {};
|
|
||||||
|
|
||||||
int y[20000] = {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -49,9 +57,6 @@ of the software.
|
|||||||
MODIFICATIONS: Michael D. Garris (NIST)
|
MODIFICATIONS: Michael D. Garris (NIST)
|
||||||
Stan Janet (NIST)
|
Stan Janet (NIST)
|
||||||
DATE: 09/21/2004
|
DATE: 09/21/2004
|
||||||
UPDATED: 01/11/2012 by Kenneth Ko
|
|
||||||
UPDATED: 03/08/2012 by Kenneth Ko
|
|
||||||
UPDATED: 07/10/2014 by Kenneth Ko
|
|
||||||
|
|
||||||
Contains routines responsible for supporting command line
|
Contains routines responsible for supporting command line
|
||||||
processing, file and data input to, and output from the
|
processing, file and data input to, and output from the
|
||||||
@@ -95,7 +100,50 @@ of the software.
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
|
static const int verbose_load = 0;
|
||||||
|
static const int verbose_main = 0;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
int parse_line_range( const char * sb, int * begin, int * end )
|
||||||
|
{
|
||||||
|
int ib, ie;
|
||||||
|
char * se;
|
||||||
|
|
||||||
|
|
||||||
|
if ( ! isdigit(*sb) )
|
||||||
|
return -1;
|
||||||
|
ib = atoi( sb );
|
||||||
|
|
||||||
|
se = strchr( sb, '-' );
|
||||||
|
if ( se != (char *) NULL ) {
|
||||||
|
se++;
|
||||||
|
if ( ! isdigit(*se) )
|
||||||
|
return -2;
|
||||||
|
ie = atoi( se );
|
||||||
|
} else {
|
||||||
|
ie = ib;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ib <= 0 ) {
|
||||||
|
if ( ie <= 0 ) {
|
||||||
|
return -3;
|
||||||
|
} else {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ie <= 0 ) {
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ib > ie )
|
||||||
|
return -6;
|
||||||
|
|
||||||
|
*begin = ib;
|
||||||
|
*end = ie;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
@@ -105,10 +153,25 @@ static char * pfile;
|
|||||||
static char * gfile;
|
static char * gfile;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
void set_progname( int use_pid, char * basename, pid_t pid )
|
||||||
|
{
|
||||||
|
if ( use_pid )
|
||||||
|
sprintf( program_buffer, "%s pid %ld", basename, (long) pid );
|
||||||
|
else
|
||||||
|
sprintf( program_buffer, "%s", basename );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
void set_probe_filename( char * filename )
|
||||||
|
{
|
||||||
|
pfile = filename;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
void set_gallery_filename( char * filename )
|
||||||
|
{
|
||||||
|
gfile = filename;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char * get_progname( void )
|
char * get_progname( void )
|
||||||
@@ -129,15 +192,171 @@ return gfile;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
char * get_next_file(
|
||||||
|
char * fixed_file,
|
||||||
|
FILE * list_fp,
|
||||||
|
FILE * mates_fp,
|
||||||
|
int * done_now,
|
||||||
|
int * done_afterwards,
|
||||||
|
char * line,
|
||||||
|
int argc,
|
||||||
|
char ** argv,
|
||||||
|
int * optind,
|
||||||
|
|
||||||
|
int * lineno,
|
||||||
|
int begin,
|
||||||
|
int end
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char * p;
|
||||||
|
FILE * fp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( fixed_file != (char *) NULL ) {
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning fixed filename: %s\n", fixed_file );
|
||||||
|
return fixed_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fp = list_fp;
|
||||||
|
if ( fp == (FILE *) NULL )
|
||||||
|
fp = mates_fp;
|
||||||
|
if ( fp != (FILE *) NULL ) {
|
||||||
|
while (1) {
|
||||||
|
if ( fgets( line, MAX_LINE_LENGTH, fp ) == (char *) NULL ) {
|
||||||
|
*done_now = 1;
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning NULL -- reached EOF\n" );
|
||||||
|
return (char *) NULL;
|
||||||
|
}
|
||||||
|
++*lineno;
|
||||||
|
|
||||||
|
if ( begin <= 0 ) /* no line number range was specified */
|
||||||
|
break;
|
||||||
|
if ( *lineno > end ) {
|
||||||
|
*done_now = 1;
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning NULL -- current line (%d) > end line (%d)\n",
|
||||||
|
*lineno, end );
|
||||||
|
return (char *) NULL;
|
||||||
|
}
|
||||||
|
if ( *lineno >= begin ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Otherwise ( *lineno < begin ) so read another line */
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strchr( line, '\n' );
|
||||||
|
if ( p == (char *) NULL ) {
|
||||||
|
*done_now = 1;
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning NULL -- missing newline character\n" );
|
||||||
|
return (char *) NULL;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
p = line;
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning filename from next line: %s\n", p );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p = argv[*optind];
|
||||||
|
++*optind;
|
||||||
|
if ( *optind >= argc )
|
||||||
|
*done_afterwards = 1;
|
||||||
|
if ( verbose_main )
|
||||||
|
fprintf( stderr, "returning next argv: %s [done_afterwards=%d]\n", p, *done_afterwards );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* returns CNULL on error */
|
/* returns CNULL on error */
|
||||||
|
char * get_score_filename( const char * outdir, const char * listfile )
|
||||||
|
{
|
||||||
|
const char * basename;
|
||||||
|
int baselen;
|
||||||
|
int dirlen;
|
||||||
|
int extlen;
|
||||||
|
char * outfile;
|
||||||
|
|
||||||
|
/* These are now exteranlly defined in bozorth.h */
|
||||||
|
/* extern FILE * stderr; */
|
||||||
|
/* extern char * get_progname( void ); */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
basename = strrchr( listfile, '/' );
|
||||||
|
if ( basename == CNULL ) {
|
||||||
|
basename = listfile;
|
||||||
|
} else {
|
||||||
|
++basename;
|
||||||
|
}
|
||||||
|
baselen = strlen( basename );
|
||||||
|
if ( baselen == 0 ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: couldn't find basename of %s\n", get_progname(), listfile );
|
||||||
|
return(CNULL);
|
||||||
|
}
|
||||||
|
dirlen = strlen( outdir );
|
||||||
|
if ( dirlen == 0 ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: illegal output directory %s\n", get_progname(), outdir );
|
||||||
|
return(CNULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
extlen = strlen( SCOREFILE_EXTENSION );
|
||||||
|
outfile = malloc_or_return_error( dirlen + baselen + extlen + 2, "output filename" );
|
||||||
|
if ( outfile == CNULL)
|
||||||
|
return(CNULL);
|
||||||
|
|
||||||
|
sprintf( outfile, "%s/%s%s", outdir, basename, SCOREFILE_EXTENSION );
|
||||||
|
|
||||||
|
return outfile;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
char * get_score_line(
|
||||||
|
const char * probe_file,
|
||||||
|
const char * gallery_file,
|
||||||
|
int n,
|
||||||
|
int static_flag,
|
||||||
|
const char * fmt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int nchars;
|
||||||
|
char * bufptr;
|
||||||
|
static char linebuf[1024];
|
||||||
|
|
||||||
|
nchars = 0;
|
||||||
|
bufptr = &linebuf[0];
|
||||||
|
while ( *fmt ) {
|
||||||
|
if ( nchars++ > 0 )
|
||||||
|
*bufptr++ = ' ';
|
||||||
|
switch ( *fmt++ ) {
|
||||||
|
case 's':
|
||||||
|
sprintf( bufptr, "%d", n );
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
sprintf( bufptr, "%s", probe_file );
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
sprintf( bufptr, "%s", gallery_file );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (char *) NULL;
|
||||||
|
}
|
||||||
|
bufptr = strchr( bufptr, '\0' );
|
||||||
|
}
|
||||||
|
*bufptr++ = '\n';
|
||||||
|
*bufptr = '\0';
|
||||||
|
|
||||||
|
return static_flag ? &linebuf[0] : strdup( linebuf );
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Load a 3-4 column (X,Y,T[,Q]) set of minutiae from the specified file
|
Load a 3-4 column (X,Y,T[,Q]) set of minutiae from the specified file.
|
||||||
and return a XYT sturcture.
|
|
||||||
Row 3's value is an angle which is normalized to the interval (-180,180].
|
Row 3's value is an angle which is normalized to the interval (-180,180].
|
||||||
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
||||||
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
||||||
@@ -145,14 +364,241 @@ to be returned, the highest-quality minutiae are returned.
|
|||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
struct xyt_struct * bz_load( const char * xyt_file )
|
||||||
|
{
|
||||||
|
int nminutiae;
|
||||||
|
int j;
|
||||||
|
int m;
|
||||||
|
int nargs_expected;
|
||||||
|
FILE * fp;
|
||||||
|
struct xyt_struct * s;
|
||||||
|
int * xptr;
|
||||||
|
int * yptr;
|
||||||
|
int * tptr;
|
||||||
|
int * qptr;
|
||||||
|
struct minutiae_struct c[MAX_FILE_MINUTIAE];
|
||||||
|
int xvals_lng[MAX_FILE_MINUTIAE], /* Temporary lists to store all the minutaie from a file */
|
||||||
|
yvals_lng[MAX_FILE_MINUTIAE],
|
||||||
|
tvals_lng[MAX_FILE_MINUTIAE],
|
||||||
|
qvals_lng[MAX_FILE_MINUTIAE];
|
||||||
|
int order[MAX_FILE_MINUTIAE]; /* The ranked order, after sort, for each index */
|
||||||
|
int xvals[MAX_BOZORTH_MINUTIAE], /* Temporary lists to hold input coordinates */
|
||||||
|
yvals[MAX_BOZORTH_MINUTIAE],
|
||||||
|
tvals[MAX_BOZORTH_MINUTIAE],
|
||||||
|
qvals[MAX_BOZORTH_MINUTIAE];
|
||||||
|
char xyt_line[ MAX_LINE_LENGTH ];
|
||||||
|
|
||||||
/************************************************************************
|
/* This is now externally defined in bozorth.h */
|
||||||
Load a XYTQ structure and return a XYT struct.
|
/* extern FILE * stderr; */
|
||||||
Row 3's value is an angle which is normalized to the interval (-180,180].
|
|
||||||
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
|
||||||
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
|
||||||
to be returned, the highest-quality minutiae are returned.
|
#define C1 0
|
||||||
*************************************************************************/
|
#define C2 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fp = fopen( xyt_file, "r" );
|
||||||
|
if ( fp == (FILE *) NULL ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: fopen() of minutiae file \"%s\" failed: %s\n",
|
||||||
|
get_progname(), xyt_file, strerror(errno) );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nminutiae = 0;
|
||||||
|
nargs_expected = 0;
|
||||||
|
while ( fgets( xyt_line, sizeof xyt_line, fp ) != CNULL ) {
|
||||||
|
|
||||||
|
m = sscanf( xyt_line, "%d %d %d %d",
|
||||||
|
&xvals_lng[nminutiae],
|
||||||
|
&yvals_lng[nminutiae],
|
||||||
|
&tvals_lng[nminutiae],
|
||||||
|
&qvals_lng[nminutiae] );
|
||||||
|
if ( nminutiae == 0 ) {
|
||||||
|
if ( m != 3 && m != 4 ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sscanf() failed on line %u in minutiae file \"%s\"\n",
|
||||||
|
get_progname(), nminutiae+1, xyt_file );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
nargs_expected = m;
|
||||||
|
} else {
|
||||||
|
if ( m != nargs_expected ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: inconsistent argument count on line %u of minutiae file \"%s\"\n",
|
||||||
|
get_progname(), nminutiae+1, xyt_file );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( m == 3 )
|
||||||
|
qvals_lng[nminutiae] = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( tvals_lng[nminutiae] > 180 )
|
||||||
|
tvals_lng[nminutiae] -= 360;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ( C1 ) {
|
||||||
|
c[nminutiae].col[0] = xvals_lng[nminutiae];
|
||||||
|
c[nminutiae].col[1] = yvals_lng[nminutiae];
|
||||||
|
c[nminutiae].col[2] = tvals_lng[nminutiae];
|
||||||
|
c[nminutiae].col[3] = qvals_lng[nminutiae];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
++nminutiae;
|
||||||
|
if ( nminutiae == MAX_FILE_MINUTIAE )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fclose(fp) != 0 ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: fclose() of minutiae file \"%s\" failed: %s\n",
|
||||||
|
get_progname(), xyt_file, strerror(errno) );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( nminutiae > DEFAULT_BOZORTH_MINUTIAE ) {
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "%s: WARNING: bz_load(): trimming minutiae to the %d of highest quality\n",
|
||||||
|
get_progname(), DEFAULT_BOZORTH_MINUTIAE );
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "Before quality sort:\n" );
|
||||||
|
if ( sort_order_decreasing( qvals_lng, nminutiae, order )) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sort failed and returned on error\n", get_progname());
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( j = 0; j < nminutiae; j++ ) {
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, " %3d: %3d %3d %3d ---> order = %3d\n",
|
||||||
|
j, xvals_lng[j], yvals_lng[j], qvals_lng[j], order[j] );
|
||||||
|
|
||||||
|
if ( j == 0 )
|
||||||
|
continue;
|
||||||
|
if ( qvals_lng[order[j]] > qvals_lng[order[j-1]] ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sort failed: j=%d; qvals_lng[%d] > qvals_lng[%d]\n",
|
||||||
|
get_progname(), j, order[j], order[j-1] );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "\nAfter quality sort:\n" );
|
||||||
|
for ( j = 0; j < DEFAULT_BOZORTH_MINUTIAE; j++ ) {
|
||||||
|
xvals[j] = xvals_lng[order[j]];
|
||||||
|
yvals[j] = yvals_lng[order[j]];
|
||||||
|
tvals[j] = tvals_lng[order[j]];
|
||||||
|
qvals[j] = qvals_lng[order[j]];
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, " %3d: %3d %3d %3d\n", j, xvals[j], yvals[j], qvals[j] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( C1 ) {
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "\nAfter qsort():\n" );
|
||||||
|
qsort( (void *) &c, (size_t) nminutiae, sizeof(struct minutiae_struct), sort_quality_decreasing );
|
||||||
|
for ( j = 0; j < nminutiae; j++ ) {
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "Q %3d: %3d %3d %3d\n",
|
||||||
|
j, c[j].col[0], c[j].col[1], c[j].col[3] );
|
||||||
|
|
||||||
|
if ( j > 0 && c[j].col[3] > c[j-1].col[3] ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[3] > c[%d].col[3]\n",
|
||||||
|
get_progname(), j, j-1 );
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "\n" );
|
||||||
|
|
||||||
|
xptr = xvals;
|
||||||
|
yptr = yvals;
|
||||||
|
tptr = tvals;
|
||||||
|
qptr = qvals;
|
||||||
|
|
||||||
|
nminutiae = DEFAULT_BOZORTH_MINUTIAE;
|
||||||
|
} else{
|
||||||
|
xptr = xvals_lng;
|
||||||
|
yptr = yvals_lng;
|
||||||
|
tptr = tvals_lng;
|
||||||
|
qptr = qvals_lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for ( j=0; j < nminutiae; j++ ) {
|
||||||
|
c[j].col[0] = xptr[j];
|
||||||
|
c[j].col[1] = yptr[j];
|
||||||
|
c[j].col[2] = tptr[j];
|
||||||
|
c[j].col[3] = qptr[j];
|
||||||
|
}
|
||||||
|
qsort( (void *) &c, (size_t) nminutiae, sizeof(struct minutiae_struct), sort_x_y );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( verbose_load ) {
|
||||||
|
fprintf( stderr, "\nSorted on increasing x, then increasing y\n" );
|
||||||
|
for ( j = 0; j < nminutiae; j++ ) {
|
||||||
|
fprintf( stderr, "%d : %3d, %3d, %3d, %3d\n", j, c[j].col[0], c[j].col[1], c[j].col[2], c[j].col[3] );
|
||||||
|
if ( j > 0 ) {
|
||||||
|
if ( c[j].col[0] < c[j-1].col[0] ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[0]=%d > c[%d].col[0]=%d\n",
|
||||||
|
get_progname(),
|
||||||
|
j, c[j].col[0], j-1, c[j-1].col[0]
|
||||||
|
);
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
if ( c[j].col[0] == c[j-1].col[0] && c[j].col[1] < c[j-1].col[1] ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[0]=%d == c[%d].col[0]=%d; c[%d].col[0]=%d == c[%d].col[0]=%d\n",
|
||||||
|
get_progname(),
|
||||||
|
j, c[j].col[0], j-1, c[j-1].col[0],
|
||||||
|
j, c[j].col[1], j-1, c[j-1].col[1]
|
||||||
|
);
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s = (struct xyt_struct *) malloc( sizeof( struct xyt_struct ) );
|
||||||
|
if ( s == XYT_NULL ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: malloc() failure while loading minutiae file \"%s\" failed: %s\n",
|
||||||
|
get_progname(),
|
||||||
|
xyt_file,
|
||||||
|
strerror(errno)
|
||||||
|
);
|
||||||
|
return XYT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for ( j = 0; j < nminutiae; j++ ) {
|
||||||
|
s->xcol[j] = c[j].col[0];
|
||||||
|
s->ycol[j] = c[j].col[1];
|
||||||
|
s->thetacol[j] = c[j].col[2];
|
||||||
|
}
|
||||||
|
s->nrows = nminutiae;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( verbose_load )
|
||||||
|
fprintf( stderr, "Loaded %s\n", xyt_file );
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#ifdef PARALLEL_SEARCH
|
#ifdef PARALLEL_SEARCH
|
||||||
@@ -171,13 +617,13 @@ tv.tv_usec = 0;
|
|||||||
retval = select( fd+1, &rfds, NULL, NULL, &tv );
|
retval = select( fd+1, &rfds, NULL, NULL, &tv );
|
||||||
|
|
||||||
if ( retval < 0 ) {
|
if ( retval < 0 ) {
|
||||||
perror( "select() failed" );
|
perror( "select() failed" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FD_ISSET( fd, &rfds ) ) {
|
if ( FD_ISSET( fd, &rfds ) ) {
|
||||||
/*fprintf( stderr, "data is available now.\n" );*/
|
/*fprintf( stderr, "data is available now.\n" );*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf( stderr, "no data is available\n" ); */
|
/* fprintf( stderr, "no data is available\n" ); */
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
This file is part of the Export Control subset of the United States NIST
|
||||||
|
Biometric Image Software (NBIS) distribution:
|
||||||
|
http://fingerprint.nist.gov/NBIS/index.html
|
||||||
|
|
||||||
|
It is our understanding that this falls within ECCN 3D980, which covers
|
||||||
|
software associated with the development, production or use of certain
|
||||||
|
equipment controlled in accordance with U.S. concerns about crime control
|
||||||
|
practices in specific countries.
|
||||||
|
|
||||||
|
Therefore, this file should not be exported, or made available on fileservers,
|
||||||
|
except as allowed by U.S. export control laws.
|
||||||
|
|
||||||
|
Do not remove this notice.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* NOTE: Despite the above notice (which I have not removed), this file is
|
||||||
|
* being legally distributed within libfprint; the U.S. Export Administration
|
||||||
|
* Regulations do not place export restrictions upon distribution of
|
||||||
|
* "publicly available technology and software", as stated in EAR section
|
||||||
|
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
||||||
|
* the definition in section 734.7(a)(1).
|
||||||
|
*
|
||||||
|
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
||||||
|
*/
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -70,10 +78,23 @@ of the software.
|
|||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
/* These are now externally defined in bozorth.h */
|
/* These are now externally defined in bozorth.h */
|
||||||
/* extern FILE * stderr; */
|
|
||||||
/* extern char * get_progname( void ); */
|
/* extern char * get_progname( void ); */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
int sort_quality_decreasing( const void * a, const void * b )
|
||||||
|
{
|
||||||
|
struct minutiae_struct * af;
|
||||||
|
struct minutiae_struct * bf;
|
||||||
|
|
||||||
|
af = (struct minutiae_struct *) a;
|
||||||
|
bf = (struct minutiae_struct *) b;
|
||||||
|
|
||||||
|
if ( af->col[3] > bf->col[3] )
|
||||||
|
return -1;
|
||||||
|
if ( af->col[3] < bf->col[3] )
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int sort_x_y( const void * a, const void * b )
|
int sort_x_y( const void * a, const void * b )
|
||||||
@@ -103,18 +124,67 @@ qsort_decreasing() - quicksort an array of integers in decreasing
|
|||||||
and Ted Zwiesler, 1986]
|
and Ted Zwiesler, 1986]
|
||||||
********************************************************/
|
********************************************************/
|
||||||
/* Used by custom quicksort code below */
|
/* Used by custom quicksort code below */
|
||||||
|
static int stack[BZ_STACKSIZE];
|
||||||
|
static int * stack_pointer = stack;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
|
static int popstack( int *popval )
|
||||||
|
{
|
||||||
|
if ( --stack_pointer < stack ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: popstack(): stack underflow\n", get_progname() );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*popval = *stack_pointer;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
|
static int pushstack( int position )
|
||||||
|
{
|
||||||
|
*stack_pointer++ = position;
|
||||||
|
if ( stack_pointer > ( stack + BZ_STACKSIZE ) ) {
|
||||||
|
fprintf( stderr, "%s: ERROR: pushstack(): stack overflow\n", get_progname() );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
select_pivot()
|
select_pivot()
|
||||||
selects a pivot from a list being sorted using the Singleton Method.
|
selects a pivot from a list being sorted using the Singleton Method.
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
static int select_pivot( struct cell v[], int left, int right )
|
||||||
|
{
|
||||||
|
int midpoint;
|
||||||
|
|
||||||
|
|
||||||
|
midpoint = ( left + right ) / 2;
|
||||||
|
if ( v[left].index <= v[midpoint].index ) {
|
||||||
|
if ( v[midpoint].index <= v[right].index ) {
|
||||||
|
return midpoint;
|
||||||
|
} else {
|
||||||
|
if ( v[right].index > v[left].index ) {
|
||||||
|
return right;
|
||||||
|
} else {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( v[left].index < v[right].index ) {
|
||||||
|
return left;
|
||||||
|
} else {
|
||||||
|
if ( v[right].index < v[midpoint].index ) {
|
||||||
|
return midpoint;
|
||||||
|
} else {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/********************************************************
|
/********************************************************
|
||||||
@@ -122,6 +192,41 @@ partition_dec()
|
|||||||
Inputs a pivot element making comparisons and swaps with other elements in a list,
|
Inputs a pivot element making comparisons and swaps with other elements in a list,
|
||||||
until pivot resides at its correct position in the list.
|
until pivot resides at its correct position in the list.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
static void partition_dec( struct cell v[], int *llen, int *rlen, int *ll, int *lr, int *rl, int *rr, int p, int l, int r )
|
||||||
|
{
|
||||||
|
#define iswap(a,b) { int itmp = (a); a = (b); b = itmp; }
|
||||||
|
|
||||||
|
*ll = l;
|
||||||
|
*rr = r;
|
||||||
|
while ( 1 ) {
|
||||||
|
if ( l < p ) {
|
||||||
|
if ( v[l].index < v[p].index ) {
|
||||||
|
iswap( v[l].index, v[p].index )
|
||||||
|
iswap( v[l].item, v[p].item )
|
||||||
|
p = l;
|
||||||
|
} else {
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( r > p ) {
|
||||||
|
if ( v[r].index > v[p].index ) {
|
||||||
|
iswap( v[r].index, v[p].index )
|
||||||
|
iswap( v[r].item, v[p].item )
|
||||||
|
p = r;
|
||||||
|
l++;
|
||||||
|
} else {
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*lr = p - 1;
|
||||||
|
*rl = p + 1;
|
||||||
|
*llen = *lr - *ll + 1;
|
||||||
|
*rlen = *rr - *rl + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/********************************************************
|
/********************************************************
|
||||||
@@ -131,6 +236,80 @@ sorted, a left subscript pointing to where the sort is to begin in the index ar
|
|||||||
subscript where to end. This module invokes a decreasing quick-sort sorting the index array from l to r.
|
subscript where to end. This module invokes a decreasing quick-sort sorting the index array from l to r.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
|
static int qsort_decreasing( struct cell v[], int left, int right )
|
||||||
|
{
|
||||||
|
int pivot;
|
||||||
|
int llen, rlen;
|
||||||
|
int lleft, lright, rleft, rright;
|
||||||
|
|
||||||
|
|
||||||
|
if ( pushstack( left ))
|
||||||
|
return 1;
|
||||||
|
if ( pushstack( right ))
|
||||||
|
return 2;
|
||||||
|
while ( stack_pointer != stack ) {
|
||||||
|
if (popstack(&right))
|
||||||
|
return 3;
|
||||||
|
if (popstack(&left ))
|
||||||
|
return 4;
|
||||||
|
if ( right - left > 0 ) {
|
||||||
|
pivot = select_pivot( v, left, right );
|
||||||
|
partition_dec( v, &llen, &rlen, &lleft, &lright, &rleft, &rright, pivot, left, right );
|
||||||
|
if ( llen > rlen ) {
|
||||||
|
if ( pushstack( lleft ))
|
||||||
|
return 5;
|
||||||
|
if ( pushstack( lright ))
|
||||||
|
return 6;
|
||||||
|
if ( pushstack( rleft ))
|
||||||
|
return 7;
|
||||||
|
if ( pushstack( rright ))
|
||||||
|
return 8;
|
||||||
|
} else{
|
||||||
|
if ( pushstack( rleft ))
|
||||||
|
return 9;
|
||||||
|
if ( pushstack( rright ))
|
||||||
|
return 10;
|
||||||
|
if ( pushstack( lleft ))
|
||||||
|
return 11;
|
||||||
|
if ( pushstack( lright ))
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
|
int sort_order_decreasing(
|
||||||
|
int values[], /* INPUT: the unsorted values themselves */
|
||||||
|
int num, /* INPUT: the number of values */
|
||||||
|
int order[] /* OUTPUT: the order for each of the values if sorted */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct cell * cells;
|
||||||
|
|
||||||
|
|
||||||
|
cells = (struct cell *) malloc( num * sizeof(struct cell) );
|
||||||
|
if ( cells == (struct cell *) NULL ){
|
||||||
|
fprintf( stderr, "%s: ERROR: malloc(): struct cell\n", get_progname() );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < num; i++ ) {
|
||||||
|
cells[i].index = values[i];
|
||||||
|
cells[i].item = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( qsort_decreasing( cells, 0, num-1 ) < 0)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
for( i = 0; i < num; i++ ) {
|
||||||
|
order[i] = cells[i].item;
|
||||||
|
}
|
||||||
|
|
||||||
|
free( (void *) cells );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,43 +1,23 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -183,7 +163,7 @@ struct cell {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* In BZ_IO : Supports the loading and manipulation of XYT and XYTQ data */
|
/* In BZ_IO : Supports the loading and manipulation of XYT data */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
#define MAX_FILE_MINUTIAE 1000 /* bz_load() */
|
#define MAX_FILE_MINUTIAE 1000 /* bz_load() */
|
||||||
|
|
||||||
@@ -194,17 +174,7 @@ struct xyt_struct {
|
|||||||
int thetacol[ MAX_BOZORTH_MINUTIAE ];
|
int thetacol[ MAX_BOZORTH_MINUTIAE ];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xytq_struct {
|
|
||||||
int nrows;
|
|
||||||
int xcol[ MAX_FILE_MINUTIAE ];
|
|
||||||
int ycol[ MAX_FILE_MINUTIAE ];
|
|
||||||
int thetacol[ MAX_FILE_MINUTIAE ];
|
|
||||||
int qualitycol[ MAX_FILE_MINUTIAE ];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */
|
#define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */
|
||||||
#define XYTQ_NULL ( (struct xytq_struct *) NULL ) /* bz_load() */
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
@@ -217,8 +187,6 @@ struct xytq_struct {
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Globals supporting command line options */
|
/* Globals supporting command line options */
|
||||||
extern int verbose_threshold;
|
extern int verbose_threshold;
|
||||||
/* Global supporting error reporting */
|
|
||||||
extern FILE *stderr;
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* In: BZ_GBLS.C */
|
/* In: BZ_GBLS.C */
|
||||||
@@ -279,7 +247,6 @@ extern char *get_next_file(char *, FILE *, FILE *, int *, int *, char *,
|
|||||||
extern char *get_score_filename(const char *, const char *);
|
extern char *get_score_filename(const char *, const char *);
|
||||||
extern char *get_score_line(const char *, const char *, int, int, const char *);
|
extern char *get_score_line(const char *, const char *, int, int, const char *);
|
||||||
extern struct xyt_struct *bz_load(const char *);
|
extern struct xyt_struct *bz_load(const char *);
|
||||||
extern struct xyt_struct *bz_prune(struct xytq_struct *, int);
|
|
||||||
extern int fd_readable(int);
|
extern int fd_readable(int);
|
||||||
/* In: BZ_SORT.C */
|
/* In: BZ_SORT.C */
|
||||||
extern int sort_quality_decreasing(const void *, const void *);
|
extern int sort_quality_decreasing(const void *, const void *);
|
||||||
|
|||||||
@@ -1,43 +1,23 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,23 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software and/or related materials was developed at the National Institute
|
This software was developed at the National Institute of Standards and
|
||||||
of Standards and Technology (NIST) by employees of the Federal Government
|
Technology (NIST) by employees of the Federal Government in the course
|
||||||
in the course of their official duties. Pursuant to title 17 Section 105
|
of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
of the United States Code, this software is not subject to copyright
|
United States Code, this software is not subject to copyright protection
|
||||||
protection and is in the public domain.
|
and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
about its quality, reliability, or any other characteristic.
|
||||||
|
|
||||||
This software and/or related materials have been determined to be not subject
|
Disclaimer:
|
||||||
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
This software was developed to promote biometric standards and biometric
|
||||||
a publicly available technology and software, and is freely distributed
|
technology testing for the Federal Government in accordance with the USA
|
||||||
to any interested party with no licensing requirements. Therefore, it is
|
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
||||||
permissible to distribute this software as a free download from the internet.
|
Specific hardware and software products identified in this software were used
|
||||||
|
in order to perform the software development. In no case does such
|
||||||
Disclaimer:
|
identification imply recommendation or endorsement by the National Institute
|
||||||
This software and/or related materials was developed to promote biometric
|
of Standards and Technology, nor does it imply that the products and equipment
|
||||||
standards and biometric technology testing for the Federal Government
|
identified are necessarily the best available for the purpose.
|
||||||
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
||||||
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
||||||
in this software were used in order to perform the software development.
|
|
||||||
In no case does such identification imply recommendation or endorsement
|
|
||||||
by the National Institute of Standards and Technology, nor does it imply that
|
|
||||||
the products and equipment identified are necessarily the best available
|
|
||||||
for the purpose.
|
|
||||||
|
|
||||||
This software and/or related materials are provided "AS-IS" without warranty
|
|
||||||
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
||||||
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
||||||
licensed product, however used. In no event shall NIST be liable for any
|
|
||||||
damages and/or costs, including but not limited to incidental or consequential
|
|
||||||
damages of any kind, including economic damage or injury to property and lost
|
|
||||||
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
||||||
or in fact shall know of the possibility.
|
|
||||||
|
|
||||||
By using this software, you agree to bear all risk relating to quality,
|
|
||||||
use and performance of the software and/or related materials. You agree
|
|
||||||
to hold the Government harmless from any claim arising from your use
|
|
||||||
of the software.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
@@ -73,6 +53,7 @@ of the software.
|
|||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
#define sround(x) ((int) (((x)<0) ? (x)-0.5 : (x)+0.5))
|
#define sround(x) ((int) (((x)<0) ? (x)-0.5 : (x)+0.5))
|
||||||
#define sround_uint(x) ((unsigned int) (((x)<0) ? (x)-0.5 : (x)+0.5))
|
#define sround_uint(x) ((unsigned int) (((x)<0) ? (x)-0.5 : (x)+0.5))
|
||||||
|
#define xor(a, b) (!(a && b) && (a || b))
|
||||||
#define align_to_16(_v_) ((((_v_)+15)>>4)<<4)
|
#define align_to_16(_v_) ((((_v_)+15)>>4)<<4)
|
||||||
#define align_to_32(_v_) ((((_v_)+31)>>5)<<5)
|
#define align_to_32(_v_) ((((_v_)+31)>>5)<<5)
|
||||||
#ifndef CHUNKS
|
#ifndef CHUNKS
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user