Uncrustify everything except for nbis
This commit is contained in:
parent
fd5f511b33
commit
d1fb1e26f3
60 changed files with 30386 additions and 28683 deletions
|
@ -22,35 +22,36 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
|
||||||
typedef GtkApplication LibfprintDemo;
|
typedef GtkApplication LibfprintDemo;
|
||||||
typedef GtkApplicationClass LibfprintDemoClass;
|
typedef GtkApplicationClass LibfprintDemoClass;
|
||||||
|
|
||||||
G_DEFINE_TYPE (LibfprintDemo, libfprint_demo, GTK_TYPE_APPLICATION)
|
G_DEFINE_TYPE (LibfprintDemo, libfprint_demo, GTK_TYPE_APPLICATION)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
IMAGE_DISPLAY_NONE = 0,
|
IMAGE_DISPLAY_NONE = 0,
|
||||||
IMAGE_DISPLAY_MINUTIAE = 1 << 0,
|
IMAGE_DISPLAY_MINUTIAE = 1 << 0,
|
||||||
IMAGE_DISPLAY_BINARY = 1 << 1
|
IMAGE_DISPLAY_BINARY = 1 << 1
|
||||||
} ImageDisplayFlags;
|
} ImageDisplayFlags;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
GtkApplicationWindow parent_instance;
|
{
|
||||||
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
GtkWidget *header_bar;
|
GtkWidget *header_bar;
|
||||||
GtkWidget *mode_stack;
|
GtkWidget *mode_stack;
|
||||||
GtkWidget *capture_button;
|
GtkWidget *capture_button;
|
||||||
GtkWidget *cancel_button;
|
GtkWidget *cancel_button;
|
||||||
GtkWidget *capture_image;
|
GtkWidget *capture_image;
|
||||||
GtkWidget *spinner;
|
GtkWidget *spinner;
|
||||||
GtkWidget *instructions;
|
GtkWidget *instructions;
|
||||||
|
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
gboolean opened;
|
gboolean opened;
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
|
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
ImageDisplayFlags img_flags;
|
ImageDisplayFlags img_flags;
|
||||||
} LibfprintDemoWindow;
|
} LibfprintDemoWindow;
|
||||||
|
|
||||||
typedef GtkApplicationWindowClass LibfprintDemoWindowClass;
|
typedef GtkApplicationWindowClass LibfprintDemoWindowClass;
|
||||||
|
@ -58,483 +59,506 @@ typedef GtkApplicationWindowClass LibfprintDemoWindowClass;
|
||||||
G_DEFINE_TYPE (LibfprintDemoWindow, libfprint_demo_window, GTK_TYPE_APPLICATION_WINDOW)
|
G_DEFINE_TYPE (LibfprintDemoWindow, libfprint_demo_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EMPTY_MODE,
|
EMPTY_MODE,
|
||||||
NOIMAGING_MODE,
|
NOIMAGING_MODE,
|
||||||
CAPTURE_MODE,
|
CAPTURE_MODE,
|
||||||
SPINNER_MODE,
|
SPINNER_MODE,
|
||||||
ERROR_MODE,
|
ERROR_MODE,
|
||||||
RETRY_MODE
|
RETRY_MODE
|
||||||
} LibfprintDemoMode;
|
} LibfprintDemoMode;
|
||||||
|
|
||||||
static void libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
static void libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
||||||
LibfprintDemoMode mode);
|
LibfprintDemoMode mode);
|
||||||
|
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
img_to_rgbdata (const guint8 *imgdata,
|
img_to_rgbdata (const guint8 *imgdata,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
int size = width * height;
|
int size = width * height;
|
||||||
guint8 *rgbdata = g_malloc (size * 3);
|
guint8 *rgbdata = g_malloc (size * 3);
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t rgb_offset = 0;
|
size_t rgb_offset = 0;
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++)
|
||||||
guint8 pixel = imgdata[i];
|
{
|
||||||
|
guint8 pixel = imgdata[i];
|
||||||
|
|
||||||
rgbdata[rgb_offset++] = pixel;
|
rgbdata[rgb_offset++] = pixel;
|
||||||
rgbdata[rgb_offset++] = pixel;
|
rgbdata[rgb_offset++] = pixel;
|
||||||
rgbdata[rgb_offset++] = pixel;
|
rgbdata[rgb_offset++] = pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rgbdata;
|
return rgbdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
plot_minutiae (unsigned char *rgbdata,
|
plot_minutiae (unsigned char *rgbdata,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
GPtrArray *minutiae)
|
GPtrArray *minutiae)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#define write_pixel(num) do { \
|
#define write_pixel(num) do { \
|
||||||
rgbdata[((num) * 3)] = 0xff; \
|
rgbdata[((num) * 3)] = 0xff; \
|
||||||
rgbdata[((num) * 3) + 1] = 0; \
|
rgbdata[((num) * 3) + 1] = 0; \
|
||||||
rgbdata[((num) * 3) + 2] = 0; \
|
rgbdata[((num) * 3) + 2] = 0; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
for (i = 0; i < minutiae->len; i++) {
|
for (i = 0; i < minutiae->len; i++)
|
||||||
struct fp_minutia *min = g_ptr_array_index (minutiae, i);
|
{
|
||||||
int x, y;
|
struct fp_minutia *min = g_ptr_array_index (minutiae, i);
|
||||||
size_t pixel_offset;
|
int x, y;
|
||||||
|
size_t pixel_offset;
|
||||||
|
|
||||||
fp_minutia_get_coords(min, &x, &y);
|
fp_minutia_get_coords (min, &x, &y);
|
||||||
pixel_offset = (y * width) + x;
|
pixel_offset = (y * width) + x;
|
||||||
write_pixel(pixel_offset - 2);
|
write_pixel (pixel_offset - 2);
|
||||||
write_pixel(pixel_offset - 1);
|
write_pixel (pixel_offset - 1);
|
||||||
write_pixel(pixel_offset);
|
write_pixel (pixel_offset);
|
||||||
write_pixel(pixel_offset + 1);
|
write_pixel (pixel_offset + 1);
|
||||||
write_pixel(pixel_offset + 2);
|
write_pixel (pixel_offset + 2);
|
||||||
|
|
||||||
write_pixel(pixel_offset - (width * 2));
|
write_pixel (pixel_offset - (width * 2));
|
||||||
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));
|
||||||
write_pixel(pixel_offset - (width * 1) + 1);
|
write_pixel (pixel_offset - (width * 1) + 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));
|
||||||
write_pixel(pixel_offset + (width * 1) + 1);
|
write_pixel (pixel_offset + (width * 1) + 1);
|
||||||
write_pixel(pixel_offset + (width * 2));
|
write_pixel (pixel_offset + (width * 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
img_to_pixbuf (FpImage *img,
|
img_to_pixbuf (FpImage *img,
|
||||||
ImageDisplayFlags flags)
|
ImageDisplayFlags flags)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
unsigned char *rgbdata;
|
unsigned char *rgbdata;
|
||||||
|
|
||||||
width = fp_image_get_width (img);
|
width = fp_image_get_width (img);
|
||||||
height = fp_image_get_height (img);
|
height = fp_image_get_height (img);
|
||||||
|
|
||||||
if (flags & IMAGE_DISPLAY_BINARY)
|
if (flags & IMAGE_DISPLAY_BINARY)
|
||||||
data = fp_image_get_binarized (img, NULL);
|
data = fp_image_get_binarized (img, NULL);
|
||||||
else
|
else
|
||||||
data = fp_image_get_data (img, NULL);
|
data = fp_image_get_data (img, NULL);
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rgbdata = img_to_rgbdata (data, width, height);
|
rgbdata = img_to_rgbdata (data, width, height);
|
||||||
|
|
||||||
if (flags & IMAGE_DISPLAY_MINUTIAE) {
|
if (flags & IMAGE_DISPLAY_MINUTIAE)
|
||||||
GPtrArray *minutiae;
|
{
|
||||||
|
GPtrArray *minutiae;
|
||||||
|
|
||||||
minutiae = fp_image_get_minutiae (img);
|
minutiae = fp_image_get_minutiae (img);
|
||||||
plot_minutiae (rgbdata, width, height, minutiae);
|
plot_minutiae (rgbdata, width, height, minutiae);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gdk_pixbuf_new_from_data (rgbdata, GDK_COLORSPACE_RGB,
|
return gdk_pixbuf_new_from_data (rgbdata, GDK_COLORSPACE_RGB,
|
||||||
FALSE, 8, width, height,
|
FALSE, 8, width, height,
|
||||||
width * 3, (GdkPixbufDestroyNotify) g_free,
|
width * 3, (GdkPixbufDestroyNotify) g_free,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_image (LibfprintDemoWindow *win)
|
update_image (LibfprintDemoWindow *win)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
if (win->img == NULL) {
|
if (win->img == NULL)
|
||||||
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
{
|
||||||
return;
|
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_debug ("Updating image, minutiae %s, binary mode %s",
|
g_debug ("Updating image, minutiae %s, binary mode %s",
|
||||||
win->img_flags & IMAGE_DISPLAY_MINUTIAE ? "shown" : "hidden",
|
win->img_flags & IMAGE_DISPLAY_MINUTIAE ? "shown" : "hidden",
|
||||||
win->img_flags & IMAGE_DISPLAY_BINARY ? "on" : "off");
|
win->img_flags & IMAGE_DISPLAY_BINARY ? "on" : "off");
|
||||||
pixbuf = img_to_pixbuf (win->img, win->img_flags);
|
pixbuf = img_to_pixbuf (win->img, win->img_flags);
|
||||||
gtk_image_set_from_pixbuf (GTK_IMAGE (win->capture_image), pixbuf);
|
gtk_image_set_from_pixbuf (GTK_IMAGE (win->capture_image), pixbuf);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_set_spinner_label (LibfprintDemoWindow *win,
|
libfprint_demo_set_spinner_label (LibfprintDemoWindow *win,
|
||||||
const char *message)
|
const char *message)
|
||||||
{
|
{
|
||||||
char *label;
|
char *label;
|
||||||
|
|
||||||
label = g_strdup_printf ("<b><span size=\"large\">%s</span></b>", message);
|
label = g_strdup_printf ("<b><span size=\"large\">%s</span></b>", message);
|
||||||
gtk_label_set_markup (GTK_LABEL (win->instructions), label);
|
gtk_label_set_markup (GTK_LABEL (win->instructions), label);
|
||||||
g_free (label);
|
g_free (label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
|
libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
|
||||||
{
|
{
|
||||||
FpScanType scan_type;
|
FpScanType scan_type;
|
||||||
const char *message;
|
const char *message;
|
||||||
|
|
||||||
scan_type = fp_device_get_scan_type(win->dev);
|
scan_type = fp_device_get_scan_type (win->dev);
|
||||||
|
|
||||||
switch (scan_type) {
|
switch (scan_type)
|
||||||
case FP_SCAN_TYPE_PRESS:
|
{
|
||||||
message = "Place your finger on the fingerprint reader";
|
case FP_SCAN_TYPE_PRESS:
|
||||||
break;
|
message = "Place your finger on the fingerprint reader";
|
||||||
case FP_SCAN_TYPE_SWIPE:
|
break;
|
||||||
message = "Swipe your finger across the fingerprint reader";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
|
|
||||||
libfprint_demo_set_spinner_label (win, message);
|
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
|
static void
|
||||||
dev_capture_start_cb (FpDevice *dev,
|
dev_capture_start_cb (FpDevice *dev,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
FpImage *image = NULL;
|
FpImage *image = NULL;
|
||||||
|
|
||||||
g_clear_object (&win->cancellable);
|
g_clear_object (&win->cancellable);
|
||||||
|
|
||||||
image = fp_device_capture_finish (dev, res, &error);
|
image = fp_device_capture_finish (dev, res, &error);
|
||||||
if (!image) {
|
if (!image)
|
||||||
g_warning ("Error capturing data: %s", error->message);
|
{
|
||||||
if (error->domain == FP_DEVICE_RETRY ||
|
g_warning ("Error capturing data: %s", error->message);
|
||||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
if (error->domain == FP_DEVICE_RETRY ||
|
||||||
libfprint_demo_set_mode (win, RETRY_MODE);
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
else
|
libfprint_demo_set_mode (win, RETRY_MODE);
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
else
|
||||||
return;
|
libfprint_demo_set_mode (win, ERROR_MODE);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_clear_object (&win->img);
|
g_clear_object (&win->img);
|
||||||
win->img = image;
|
win->img = image;
|
||||||
update_image (win);
|
update_image (win);
|
||||||
|
|
||||||
libfprint_demo_set_mode (win, CAPTURE_MODE);
|
libfprint_demo_set_mode (win, CAPTURE_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_start_capture (LibfprintDemoWindow *win)
|
dev_start_capture (LibfprintDemoWindow *win)
|
||||||
{
|
{
|
||||||
libfprint_demo_set_capture_label (win);
|
libfprint_demo_set_capture_label (win);
|
||||||
|
|
||||||
fp_device_capture (win->dev, TRUE, win->cancellable, (GAsyncReadyCallback) dev_capture_start_cb, win);
|
fp_device_capture (win->dev, TRUE, win->cancellable, (GAsyncReadyCallback) dev_capture_start_cb, win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_open_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
|
dev_open_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
g_autoptr(GError) error = NULL;
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_start_capture(win);
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
|
libfprint_demo_set_mode (win, ERROR_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_start_capture (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate_capture (GSimpleAction *action,
|
activate_capture (GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
|
|
||||||
libfprint_demo_set_mode (win, SPINNER_MODE);
|
libfprint_demo_set_mode (win, SPINNER_MODE);
|
||||||
g_clear_pointer (&win->img, g_object_unref);
|
g_clear_pointer (&win->img, g_object_unref);
|
||||||
|
|
||||||
g_clear_object (&win->cancellable);
|
g_clear_object (&win->cancellable);
|
||||||
win->cancellable = g_cancellable_new ();
|
win->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
if (win->opened) {
|
if (win->opened)
|
||||||
dev_start_capture (win);
|
{
|
||||||
return;
|
dev_start_capture (win);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
libfprint_demo_set_spinner_label (win, "Opening fingerprint reader");
|
libfprint_demo_set_spinner_label (win, "Opening fingerprint reader");
|
||||||
|
|
||||||
win->opened = TRUE;
|
win->opened = TRUE;
|
||||||
fp_device_open (win->dev, win->cancellable, (GAsyncReadyCallback) dev_open_cb, user_data);
|
fp_device_open (win->dev, win->cancellable, (GAsyncReadyCallback) dev_open_cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cancel_capture (GSimpleAction *action,
|
cancel_capture (GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
|
|
||||||
g_debug ("cancelling %p", win->cancellable);
|
g_debug ("cancelling %p", win->cancellable);
|
||||||
|
|
||||||
if (win->cancellable)
|
if (win->cancellable)
|
||||||
g_cancellable_cancel (win->cancellable);
|
g_cancellable_cancel (win->cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate_quit (GSimpleAction *action,
|
activate_quit (GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkApplication *app = user_data;
|
GtkApplication *app = user_data;
|
||||||
GtkWidget *win;
|
GtkWidget *win;
|
||||||
GList *list, *next;
|
GList *list, *next;
|
||||||
|
|
||||||
list = gtk_application_get_windows (app);
|
list = gtk_application_get_windows (app);
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
win = list->data;
|
win = list->data;
|
||||||
next = list->next;
|
next = list->next;
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (win));
|
gtk_widget_destroy (GTK_WIDGET (win));
|
||||||
|
|
||||||
list = next;
|
list = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate_show_minutiae (GSimpleAction *action,
|
activate_show_minutiae (GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
GVariant *state;
|
GVariant *state;
|
||||||
gboolean new_state;
|
gboolean new_state;
|
||||||
|
|
||||||
state = g_action_get_state (G_ACTION (action));
|
state = g_action_get_state (G_ACTION (action));
|
||||||
new_state = !g_variant_get_boolean (state);
|
new_state = !g_variant_get_boolean (state);
|
||||||
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
||||||
g_variant_unref (state);
|
g_variant_unref (state);
|
||||||
|
|
||||||
if (new_state)
|
if (new_state)
|
||||||
win->img_flags |= IMAGE_DISPLAY_MINUTIAE;
|
win->img_flags |= IMAGE_DISPLAY_MINUTIAE;
|
||||||
else
|
else
|
||||||
win->img_flags &= ~IMAGE_DISPLAY_MINUTIAE;
|
win->img_flags &= ~IMAGE_DISPLAY_MINUTIAE;
|
||||||
|
|
||||||
update_image (win);
|
update_image (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate_show_binary (GSimpleAction *action,
|
activate_show_binary (GSimpleAction *action,
|
||||||
GVariant *parameter,
|
GVariant *parameter,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *win = user_data;
|
LibfprintDemoWindow *win = user_data;
|
||||||
GVariant *state;
|
GVariant *state;
|
||||||
gboolean new_state;
|
gboolean new_state;
|
||||||
|
|
||||||
state = g_action_get_state (G_ACTION (action));
|
state = g_action_get_state (G_ACTION (action));
|
||||||
new_state = !g_variant_get_boolean (state);
|
new_state = !g_variant_get_boolean (state);
|
||||||
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
g_action_change_state (G_ACTION (action), g_variant_new_boolean (new_state));
|
||||||
g_variant_unref (state);
|
g_variant_unref (state);
|
||||||
|
|
||||||
if (new_state)
|
if (new_state)
|
||||||
win->img_flags |= IMAGE_DISPLAY_BINARY;
|
win->img_flags |= IMAGE_DISPLAY_BINARY;
|
||||||
else
|
else
|
||||||
win->img_flags &= ~IMAGE_DISPLAY_BINARY;
|
win->img_flags &= ~IMAGE_DISPLAY_BINARY;
|
||||||
|
|
||||||
update_image (win);
|
update_image (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
change_show_minutiae_state (GSimpleAction *action,
|
change_show_minutiae_state (GSimpleAction *action,
|
||||||
GVariant *state,
|
GVariant *state,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_simple_action_set_state (action, state);
|
g_simple_action_set_state (action, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
change_show_binary_state (GSimpleAction *action,
|
change_show_binary_state (GSimpleAction *action,
|
||||||
GVariant *state,
|
GVariant *state,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_simple_action_set_state (action, state);
|
g_simple_action_set_state (action, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GActionEntry app_entries[] = {
|
static GActionEntry app_entries[] = {
|
||||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
static GActionEntry win_entries[] = {
|
||||||
{ "show-minutiae", activate_show_minutiae, NULL, "false", change_show_minutiae_state },
|
{ "show-minutiae", activate_show_minutiae, NULL, "false", change_show_minutiae_state },
|
||||||
{ "show-binary", activate_show_binary, NULL, "false", change_show_binary_state },
|
{ "show-binary", activate_show_binary, NULL, "false", change_show_binary_state },
|
||||||
{ "capture", activate_capture, NULL, NULL, NULL },
|
{ "capture", activate_capture, NULL, NULL, NULL },
|
||||||
{ "cancel", cancel_capture, NULL, NULL, NULL }
|
{ "cancel", cancel_capture, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate (GApplication *app)
|
activate (GApplication *app)
|
||||||
{
|
{
|
||||||
LibfprintDemoWindow *window;
|
LibfprintDemoWindow *window;
|
||||||
|
|
||||||
window = g_object_new (libfprint_demo_window_get_type (),
|
window = g_object_new (libfprint_demo_window_get_type (),
|
||||||
"application", app,
|
"application", app,
|
||||||
NULL);
|
NULL);
|
||||||
gtk_widget_show (GTK_WIDGET (window));
|
gtk_widget_show (GTK_WIDGET (window));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
||||||
LibfprintDemoMode mode)
|
LibfprintDemoMode mode)
|
||||||
{
|
{
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode)
|
||||||
case EMPTY_MODE:
|
{
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
case EMPTY_MODE:
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
break;
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
case NOIMAGING_MODE:
|
break;
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
|
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_widget_set_sensitive (win->cancel_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);
|
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
|
||||||
|
|
||||||
title = g_strdup_printf ("%s Test", fp_device_get_name (win->dev));
|
case NOIMAGING_MODE:
|
||||||
gtk_header_bar_set_title (GTK_HEADER_BAR (win->header_bar), title);
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
|
||||||
g_free (title);
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
|
break;
|
||||||
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
case CAPTURE_MODE:
|
||||||
break;
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "capture-mode");
|
||||||
case SPINNER_MODE:
|
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
|
||||||
gtk_widget_set_sensitive (win->cancel_button, TRUE);
|
title = g_strdup_printf ("%s Test", fp_device_get_name (win->dev));
|
||||||
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
gtk_header_bar_set_title (GTK_HEADER_BAR (win->header_bar), title);
|
||||||
break;
|
g_free (title);
|
||||||
case ERROR_MODE:
|
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
break;
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
case SPINNER_MODE:
|
||||||
break;
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
||||||
case RETRY_MODE:
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "retry-mode");
|
gtk_widget_set_sensitive (win->cancel_button, TRUE);
|
||||||
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
break;
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
|
||||||
break;
|
case ERROR_MODE:
|
||||||
default:
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
||||||
g_assert_not_reached ();
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
}
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RETRY_MODE:
|
||||||
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "retry-mode");
|
||||||
|
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
||||||
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_init (LibfprintDemo *app)
|
libfprint_demo_init (LibfprintDemo *app)
|
||||||
{
|
{
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||||
app_entries, G_N_ELEMENTS (app_entries),
|
app_entries, G_N_ELEMENTS (app_entries),
|
||||||
app);
|
app);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_class_init (LibfprintDemoClass *class)
|
libfprint_demo_class_init (LibfprintDemoClass *class)
|
||||||
{
|
{
|
||||||
GApplicationClass *app_class = G_APPLICATION_CLASS (class);
|
GApplicationClass *app_class = G_APPLICATION_CLASS (class);
|
||||||
|
|
||||||
app_class->activate = activate;
|
app_class->activate = activate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_window_init (LibfprintDemoWindow *window)
|
libfprint_demo_window_init (LibfprintDemoWindow *window)
|
||||||
{
|
{
|
||||||
FpContext *ctx;
|
FpContext *ctx;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (window));
|
gtk_widget_init_template (GTK_WIDGET (window));
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 700, 500);
|
gtk_window_set_default_size (GTK_WINDOW (window), 700, 500);
|
||||||
|
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
||||||
win_entries, G_N_ELEMENTS (win_entries),
|
win_entries, G_N_ELEMENTS (win_entries),
|
||||||
window);
|
window);
|
||||||
|
|
||||||
ctx = fp_context_new ();
|
ctx = fp_context_new ();
|
||||||
|
|
||||||
devices = fp_context_get_devices(ctx);
|
devices = fp_context_get_devices (ctx);
|
||||||
if (!devices) {
|
if (!devices)
|
||||||
libfprint_demo_set_mode (window, ERROR_MODE);
|
{
|
||||||
return;
|
libfprint_demo_set_mode (window, ERROR_MODE);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Empty list? */
|
/* Empty list? */
|
||||||
if (devices->len == 0) {
|
if (devices->len == 0)
|
||||||
libfprint_demo_set_mode (window, EMPTY_MODE);
|
{
|
||||||
return;
|
libfprint_demo_set_mode (window, EMPTY_MODE);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fp_device_supports_capture(g_ptr_array_index (devices, 0))) {
|
if (!fp_device_supports_capture (g_ptr_array_index (devices, 0)))
|
||||||
libfprint_demo_set_mode (window, NOIMAGING_MODE);
|
{
|
||||||
return;
|
libfprint_demo_set_mode (window, NOIMAGING_MODE);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window->dev = g_object_ref (g_ptr_array_index (devices, 0));
|
window->dev = g_object_ref (g_ptr_array_index (devices, 0));
|
||||||
libfprint_demo_set_mode (window, CAPTURE_MODE);
|
libfprint_demo_set_mode (window, CAPTURE_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
|
libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
|
||||||
{
|
{
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (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_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, header_bar);
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, mode_stack);
|
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_button);
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, cancel_button);
|
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, cancel_button);
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, capture_image);
|
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, spinner);
|
||||||
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, instructions);
|
gtk_widget_class_bind_template_child (widget_class, LibfprintDemoWindow, instructions);
|
||||||
|
|
||||||
//FIXME setup dispose
|
//FIXME setup dispose
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GtkApplication *app;
|
GtkApplication *app;
|
||||||
|
|
||||||
app = GTK_APPLICATION (g_object_new (libfprint_demo_get_type (),
|
app = GTK_APPLICATION (g_object_new (libfprint_demo_get_type (),
|
||||||
"application-id", "org.freedesktop.libfprint.Demo",
|
"application-id", "org.freedesktop.libfprint.Demo",
|
||||||
"flags", G_APPLICATION_FLAGS_NONE,
|
"flags", G_APPLICATION_FLAGS_NONE,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
return g_application_run (G_APPLICATION (app), 0, NULL);
|
return g_application_run (G_APPLICATION (app), 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,155 +24,171 @@
|
||||||
|
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
typedef struct _EnrollData {
|
typedef struct _EnrollData
|
||||||
GMainLoop *loop;
|
{
|
||||||
int ret_value;
|
GMainLoop *loop;
|
||||||
|
int ret_value;
|
||||||
} EnrollData;
|
} EnrollData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enroll_data_free (EnrollData *enroll_data)
|
enroll_data_free (EnrollData *enroll_data)
|
||||||
{
|
{
|
||||||
g_main_loop_unref (enroll_data->loop);
|
g_main_loop_unref (enroll_data->loop);
|
||||||
g_free (enroll_data);
|
g_free (enroll_data);
|
||||||
}
|
}
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
|
||||||
|
|
||||||
FpDevice *discover_device (GPtrArray *devices)
|
FpDevice *discover_device (GPtrArray * devices)
|
||||||
{
|
{
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
if (!devices->len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dev = g_ptr_array_index (devices, 0);
|
if (!devices->len)
|
||||||
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
return NULL;
|
||||||
return dev;
|
|
||||||
|
dev = g_ptr_array_index (devices, 0);
|
||||||
|
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
EnrollData *enroll_data = user_data;
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
EnrollData *enroll_data = user_data;
|
||||||
|
|
||||||
fp_device_close_finish (dev, res, &error);
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (error)
|
fp_device_close_finish (dev, res, &error);
|
||||||
g_warning ("Failed closing device %s\n", error->message);
|
|
||||||
|
|
||||||
g_main_loop_quit (enroll_data->loop);
|
if (error)
|
||||||
|
g_warning ("Failed closing device %s\n", error->message);
|
||||||
|
|
||||||
|
g_main_loop_quit (enroll_data->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
EnrollData *enroll_data = user_data;
|
{
|
||||||
g_autoptr(FpPrint) print = NULL;
|
EnrollData *enroll_data = user_data;
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
print = fp_device_enroll_finish (dev, res, &error);
|
g_autoptr(FpPrint) print = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (!error) {
|
print = fp_device_enroll_finish (dev, res, &error);
|
||||||
enroll_data->ret_value = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
if (!fp_device_has_storage (dev)) {
|
if (!error)
|
||||||
g_debug("Device has not storage, saving locally");
|
{
|
||||||
int r = print_data_save(print, FP_FINGER_RIGHT_INDEX);
|
enroll_data->ret_value = EXIT_SUCCESS;
|
||||||
if (r < 0) {
|
|
||||||
g_warning("Data save failed, code %d", r);
|
|
||||||
enroll_data->ret_value = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_warning("Enroll failed with error %s\n", error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
if (!fp_device_has_storage (dev))
|
||||||
enroll_data);
|
{
|
||||||
|
g_debug ("Device has not storage, saving locally");
|
||||||
|
int r = print_data_save (print, FP_FINGER_RIGHT_INDEX);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
g_warning ("Data save failed, code %d", r);
|
||||||
|
enroll_data->ret_value = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Enroll failed with error %s\n", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||||
|
enroll_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_enroll_progress (FpDevice *device,
|
on_enroll_progress (FpDevice *device,
|
||||||
gint completed_stages,
|
gint completed_stages,
|
||||||
FpPrint *print,
|
FpPrint *print,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
g_warning ("Enroll stage %d of %d failed with error %s",
|
{
|
||||||
completed_stages,
|
g_warning ("Enroll stage %d of %d failed with error %s",
|
||||||
fp_device_get_nr_enroll_stages (device),
|
completed_stages,
|
||||||
error->message);
|
fp_device_get_nr_enroll_stages (device),
|
||||||
return;
|
error->message);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fp_device_supports_capture (device) &&
|
if (fp_device_supports_capture (device) &&
|
||||||
print_image_save (print, "enrolled.pgm")) {
|
print_image_save (print, "enrolled.pgm"))
|
||||||
printf ("Wrote scanned image to enrolled.pgm\n");
|
printf ("Wrote scanned image to enrolled.pgm\n");
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Enroll stage %d of %d passed. Yay!\n", completed_stages,
|
printf ("Enroll stage %d of %d passed. Yay!\n", completed_stages,
|
||||||
fp_device_get_nr_enroll_stages (device));
|
fp_device_get_nr_enroll_stages (device));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
{
|
{
|
||||||
EnrollData *enroll_data = user_data;
|
EnrollData *enroll_data = user_data;
|
||||||
FpPrint *print_template;
|
FpPrint *print_template;
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
g_autoptr(GError) error = NULL;
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
|
||||||
g_main_loop_quit (enroll_data->loop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Opened device. It's now time to enroll your finger.\n\n");
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
printf ("You will need to successfully scan your finger %d times to "
|
{
|
||||||
"complete the process.\n\n", fp_device_get_nr_enroll_stages (dev));
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
printf ("Scan your finger now.\n");
|
g_main_loop_quit (enroll_data->loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
print_template = print_create_template (dev, FP_FINGER_RIGHT_INDEX);
|
printf ("Opened device. It's now time to enroll your finger.\n\n");
|
||||||
fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
|
printf ("You will need to successfully scan your finger %d times to "
|
||||||
NULL, (GAsyncReadyCallback) on_enroll_completed,
|
"complete the process.\n\n", fp_device_get_nr_enroll_stages (dev));
|
||||||
enroll_data);
|
printf ("Scan your finger now.\n");
|
||||||
|
|
||||||
|
print_template = print_create_template (dev, FP_FINGER_RIGHT_INDEX);
|
||||||
|
fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
|
||||||
|
NULL, (GAsyncReadyCallback) on_enroll_completed,
|
||||||
|
enroll_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int
|
||||||
|
main (void)
|
||||||
{
|
{
|
||||||
g_autoptr (FpContext) ctx = NULL;
|
g_autoptr(FpContext) ctx = NULL;
|
||||||
g_autoptr (EnrollData) enroll_data = NULL;
|
g_autoptr(EnrollData) enroll_data = NULL;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
|
|
||||||
printf("This program will enroll your right index finger, "
|
printf ("This program will enroll your right index finger, "
|
||||||
"unconditionally overwriting any right-index print that was enrolled "
|
"unconditionally overwriting any right-index print that was enrolled "
|
||||||
"previously. If you want to continue, press enter, otherwise hit "
|
"previously. If you want to continue, press enter, otherwise hit "
|
||||||
"Ctrl+C\n");
|
"Ctrl+C\n");
|
||||||
getchar();
|
getchar ();
|
||||||
|
|
||||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||||
|
|
||||||
ctx = fp_context_new ();
|
ctx = fp_context_new ();
|
||||||
|
|
||||||
devices = fp_context_get_devices (ctx);
|
devices = fp_context_get_devices (ctx);
|
||||||
if (!devices) {
|
if (!devices)
|
||||||
g_warning("Impossible to get devices");
|
{
|
||||||
return EXIT_FAILURE;
|
g_warning ("Impossible to get devices");
|
||||||
}
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
dev = discover_device (devices);
|
dev = discover_device (devices);
|
||||||
if (!dev) {
|
if (!dev)
|
||||||
g_warning("No devices detected.");
|
{
|
||||||
return EXIT_FAILURE;
|
g_warning ("No devices detected.");
|
||||||
}
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
enroll_data = g_new0 (EnrollData, 1);
|
enroll_data = g_new0 (EnrollData, 1);
|
||||||
enroll_data->ret_value = EXIT_FAILURE;
|
enroll_data->ret_value = EXIT_FAILURE;
|
||||||
enroll_data->loop = g_main_loop_new (NULL, FALSE);
|
enroll_data->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
|
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
|
||||||
enroll_data);
|
enroll_data);
|
||||||
|
|
||||||
g_main_loop_run (enroll_data->loop);
|
g_main_loop_run (enroll_data->loop);
|
||||||
|
|
||||||
return enroll_data->ret_value;
|
return enroll_data->ret_value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,9 @@ delete_data_free (DeleteData *delete_data)
|
||||||
}
|
}
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DeleteData, delete_data_free);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DeleteData, delete_data_free);
|
||||||
|
|
||||||
static void
|
static void on_print_deleted (FpDevice *dev,
|
||||||
on_print_deleted (FpDevice *dev, GAsyncResult *res, gpointer user_data);
|
GAsyncResult *res,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_next_print (FpDevice *dev,
|
delete_next_print (FpDevice *dev,
|
||||||
|
@ -145,6 +146,7 @@ on_print_deleted (FpDevice *dev,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
ListData *list_data = user_data;
|
ListData *list_data = user_data;
|
||||||
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FpPrint) print = NULL;
|
g_autoptr(FpPrint) print = NULL;
|
||||||
GList *deleted_link;
|
GList *deleted_link;
|
||||||
|
@ -157,12 +159,14 @@ on_print_deleted (FpDevice *dev,
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
g_warning("Failed to remove print %s: %s",
|
g_warning ("Failed to remove print %s: %s",
|
||||||
fp_print_get_description (print), error->message);
|
fp_print_get_description (print), error->message);
|
||||||
list_data->any_failed = TRUE;
|
list_data->any_failed = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_debug ("Deleted print %s from device", fp_print_get_description (print));
|
{
|
||||||
|
g_debug ("Deleted print %s from device", fp_print_get_description (print));
|
||||||
|
}
|
||||||
|
|
||||||
if (list_data->to_delete != NULL)
|
if (list_data->to_delete != NULL)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +188,7 @@ on_list_completed (FpDevice *dev,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
ListData *list_data = user_data;
|
ListData *list_data = user_data;
|
||||||
|
|
||||||
g_autoptr(GPtrArray) prints = NULL;
|
g_autoptr(GPtrArray) prints = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
@ -198,7 +203,7 @@ on_list_completed (FpDevice *dev,
|
||||||
|
|
||||||
for (i = 0; i < prints->len; ++i)
|
for (i = 0; i < prints->len; ++i)
|
||||||
{
|
{
|
||||||
FpPrint* print = prints->pdata[i];
|
FpPrint * print = prints->pdata[i];
|
||||||
|
|
||||||
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d",
|
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d",
|
||||||
fp_print_get_enroll_date (print));
|
fp_print_get_enroll_date (print));
|
||||||
|
@ -247,10 +252,8 @@ on_list_completed (FpDevice *dev,
|
||||||
if (list_data->to_delete)
|
if (list_data->to_delete)
|
||||||
delete_next_print (dev, list_data);
|
delete_next_print (dev, list_data);
|
||||||
else
|
else
|
||||||
{
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
list_data);
|
||||||
list_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,183 +31,196 @@
|
||||||
static char *
|
static char *
|
||||||
get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
|
get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
const char *driver;
|
const char *driver;
|
||||||
const char *dev_id;
|
const char *dev_id;
|
||||||
|
|
||||||
if (print) {
|
if (print)
|
||||||
driver = fp_print_get_driver (print);
|
{
|
||||||
dev_id = fp_print_get_device_id (print);
|
driver = fp_print_get_driver (print);
|
||||||
} else {
|
dev_id = fp_print_get_device_id (print);
|
||||||
driver = fp_device_get_driver (dev);
|
}
|
||||||
dev_id = fp_device_get_device_id (dev);
|
else
|
||||||
}
|
{
|
||||||
|
driver = fp_device_get_driver (dev);
|
||||||
|
dev_id = fp_device_get_device_id (dev);
|
||||||
|
}
|
||||||
|
|
||||||
return g_strdup_printf("%s/%s/%x",
|
return g_strdup_printf ("%s/%s/%x",
|
||||||
driver,
|
driver,
|
||||||
dev_id,
|
dev_id,
|
||||||
finger);
|
finger);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GVariantDict *
|
static GVariantDict *
|
||||||
load_data(void)
|
load_data (void)
|
||||||
{
|
{
|
||||||
GVariantDict *res;
|
GVariantDict *res;
|
||||||
GVariant *var;
|
GVariant *var;
|
||||||
g_autofree gchar *contents = NULL;
|
g_autofree gchar *contents = NULL;
|
||||||
gssize length = 0;
|
gssize length = 0;
|
||||||
|
|
||||||
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL)) {
|
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL))
|
||||||
g_warning ("Error loading storage, assuming it is empty");
|
{
|
||||||
return g_variant_dict_new(NULL);
|
g_warning ("Error loading storage, assuming it is empty");
|
||||||
}
|
return g_variant_dict_new (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL);
|
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL);
|
||||||
|
|
||||||
res = g_variant_dict_new(var);
|
res = g_variant_dict_new (var);
|
||||||
g_variant_unref(var);
|
g_variant_unref (var);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
save_data(GVariant *data)
|
save_data (GVariant *data)
|
||||||
{
|
{
|
||||||
const gchar *contents = NULL;
|
const gchar *contents = NULL;
|
||||||
gsize length;
|
gsize length;
|
||||||
|
|
||||||
length = g_variant_get_size(data);
|
length = g_variant_get_size (data);
|
||||||
contents = (gchar*) g_variant_get_data (data);
|
contents = (gchar *) g_variant_get_data (data);
|
||||||
|
|
||||||
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL)) {
|
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL))
|
||||||
g_warning ("Error saving storage,!");
|
{
|
||||||
return -1;
|
g_warning ("Error saving storage,!");
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
g_variant_ref_sink(data);
|
g_variant_ref_sink (data);
|
||||||
g_variant_unref(data);
|
g_variant_unref (data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
print_data_save(FpPrint *print, FpFinger finger)
|
print_data_save (FpPrint *print, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
|
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
|
||||||
g_autoptr (GError) error = NULL;
|
|
||||||
g_autoptr (GVariantDict) dict = NULL;
|
|
||||||
g_autofree guchar *data = NULL;
|
|
||||||
GVariant *val;
|
|
||||||
gsize size;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
dict = load_data();
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
|
g_autofree guchar *data = NULL;
|
||||||
|
GVariant *val;
|
||||||
|
gsize size;
|
||||||
|
int res;
|
||||||
|
|
||||||
fp_print_serialize (print, &data, &size, &error);
|
dict = load_data ();
|
||||||
if (error) {
|
|
||||||
g_warning ("Error serializing data: %s", error->message);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
val = g_variant_new_fixed_array (G_VARIANT_TYPE("y"), data, size, 1);
|
|
||||||
g_variant_dict_insert_value (dict, descr, val);
|
|
||||||
|
|
||||||
res = save_data(g_variant_dict_end(dict));
|
fp_print_serialize (print, &data, &size, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("Error serializing data: %s", error->message);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val = g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), data, size, 1);
|
||||||
|
g_variant_dict_insert_value (dict, descr, val);
|
||||||
|
|
||||||
return res;
|
res = save_data (g_variant_dict_end (dict));
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
FpPrint *
|
FpPrint *
|
||||||
print_data_load(FpDevice *dev, FpFinger finger)
|
print_data_load (FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
|
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
|
||||||
g_autoptr (GVariant) val = NULL;
|
|
||||||
g_autoptr (GVariantDict) dict = NULL;
|
|
||||||
g_autofree guchar *stored_data = NULL;
|
|
||||||
gsize stored_len;
|
|
||||||
|
|
||||||
dict = load_data();
|
g_autoptr(GVariant) val = NULL;
|
||||||
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
|
g_autofree guchar *stored_data = NULL;
|
||||||
|
gsize stored_len;
|
||||||
|
|
||||||
if (val) {
|
dict = load_data ();
|
||||||
FpPrint *print;
|
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
||||||
g_autoptr (GError) error = NULL;
|
|
||||||
|
|
||||||
stored_data = (guchar*) g_variant_get_fixed_array (val, &stored_len, 1);
|
if (val)
|
||||||
print = fp_print_deserialize (stored_data, stored_len, &error);
|
{
|
||||||
|
FpPrint *print;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (error)
|
stored_data = (guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
|
||||||
g_warning ("Error deserializing data: %s", error->message);
|
print = fp_print_deserialize (stored_data, stored_len, &error);
|
||||||
|
|
||||||
return print;
|
if (error)
|
||||||
}
|
g_warning ("Error deserializing data: %s", error->message);
|
||||||
|
|
||||||
return NULL;
|
return print;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FpPrint *
|
FpPrint *
|
||||||
print_create_template (FpDevice *dev, FpFinger finger)
|
print_create_template (FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autoptr(GDateTime) datetime = NULL;
|
g_autoptr(GDateTime) datetime = NULL;
|
||||||
FpPrint *template = NULL;
|
FpPrint *template = NULL;
|
||||||
GDate *date = NULL;
|
GDate *date = NULL;
|
||||||
gint year, month, day;
|
gint year, month, day;
|
||||||
|
|
||||||
template = fp_print_new (dev);
|
template = fp_print_new (dev);
|
||||||
fp_print_set_finger (template, finger);
|
fp_print_set_finger (template, finger);
|
||||||
fp_print_set_username (template, g_get_user_name ());
|
fp_print_set_username (template, g_get_user_name ());
|
||||||
datetime = g_date_time_new_now_local ();
|
datetime = g_date_time_new_now_local ();
|
||||||
g_date_time_get_ymd (datetime, &year, &month, &day);
|
g_date_time_get_ymd (datetime, &year, &month, &day);
|
||||||
date = g_date_new_dmy (day, month, year);
|
date = g_date_new_dmy (day, month, year);
|
||||||
fp_print_set_enroll_date (template, date);
|
fp_print_set_enroll_date (template, date);
|
||||||
g_date_free (date);
|
g_date_free (date);
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
save_image_to_pgm (FpImage *img, const char *path)
|
save_image_to_pgm (FpImage *img, const char *path)
|
||||||
{
|
{
|
||||||
FILE *fd = fopen (path, "w");
|
FILE *fd = fopen (path, "w");
|
||||||
size_t write_size;
|
size_t write_size;
|
||||||
const guchar *data = fp_image_get_data (img, &write_size);
|
const guchar *data = fp_image_get_data (img, &write_size);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!fd) {
|
if (!fd)
|
||||||
g_warning("could not open '%s' for writing: %d", path, errno);
|
{
|
||||||
return FALSE;
|
g_warning ("could not open '%s' for writing: %d", path, errno);
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
r = fprintf (fd, "P5 %d %d 255\n",
|
r = fprintf (fd, "P5 %d %d 255\n",
|
||||||
fp_image_get_width (img), fp_image_get_height (img));
|
fp_image_get_width (img), fp_image_get_height (img));
|
||||||
if (r < 0) {
|
if (r < 0)
|
||||||
fclose(fd);
|
{
|
||||||
g_critical("pgm header write failed, error %d", r);
|
fclose (fd);
|
||||||
return FALSE;
|
g_critical ("pgm header write failed, error %d", r);
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
r = fwrite (data, 1, write_size, fd);
|
r = fwrite (data, 1, write_size, fd);
|
||||||
if (r < write_size) {
|
if (r < write_size)
|
||||||
fclose(fd);
|
{
|
||||||
g_critical("short write (%d)", r);
|
fclose (fd);
|
||||||
return FALSE;
|
g_critical ("short write (%d)", r);
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
fclose (fd);
|
fclose (fd);
|
||||||
g_debug ("written to '%s'", path);
|
g_debug ("written to '%s'", path);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean print_image_save (FpPrint *print, const char *path)
|
gboolean
|
||||||
|
print_image_save (FpPrint *print, const char *path)
|
||||||
{
|
{
|
||||||
g_autoptr(FpImage) img = NULL;
|
g_autoptr(FpImage) img = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_PRINT (print), FALSE);
|
g_return_val_if_fail (FP_IS_PRINT (print), FALSE);
|
||||||
g_return_val_if_fail (path != NULL, FALSE);
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
|
|
||||||
img = fp_print_get_image (print);
|
img = fp_print_get_image (print);
|
||||||
|
|
||||||
if (img)
|
if (img)
|
||||||
return save_image_to_pgm (img, path);
|
return save_image_to_pgm (img, path);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,13 @@
|
||||||
#define __STORAGE_H
|
#define __STORAGE_H
|
||||||
|
|
||||||
|
|
||||||
int print_data_save(FpPrint *print, FpFinger finger);
|
int print_data_save (FpPrint *print,
|
||||||
FpPrint * print_data_load(FpDevice *dev, FpFinger finger);
|
FpFinger finger);
|
||||||
FpPrint * print_create_template(FpDevice *dev, FpFinger finger);
|
FpPrint * print_data_load (FpDevice *dev,
|
||||||
gboolean print_image_save(FpPrint *print, const char *path);
|
FpFinger finger);
|
||||||
|
FpPrint * print_create_template (FpDevice *dev,
|
||||||
|
FpFinger finger);
|
||||||
|
gboolean print_image_save (FpPrint *print,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
#endif /* __STORAGE_H */
|
#endif /* __STORAGE_H */
|
||||||
|
|
|
@ -24,212 +24,236 @@
|
||||||
|
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
typedef struct _VerifyData {
|
typedef struct _VerifyData
|
||||||
GMainLoop *loop;
|
{
|
||||||
int ret_value;
|
GMainLoop *loop;
|
||||||
|
int ret_value;
|
||||||
} VerifyData;
|
} VerifyData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
verify_data_free (VerifyData *verify_data)
|
verify_data_free (VerifyData *verify_data)
|
||||||
{
|
{
|
||||||
g_main_loop_unref (verify_data->loop);
|
g_main_loop_unref (verify_data->loop);
|
||||||
g_free (verify_data);
|
g_free (verify_data);
|
||||||
}
|
}
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyData, verify_data_free)
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyData, verify_data_free)
|
||||||
|
|
||||||
FpDevice *discover_device (GPtrArray *devices)
|
FpDevice *discover_device (GPtrArray * devices)
|
||||||
{
|
{
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
if (!devices->len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dev = g_ptr_array_index (devices, 0);
|
if (!devices->len)
|
||||||
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
return NULL;
|
||||||
return dev;
|
|
||||||
|
dev = g_ptr_array_index (devices, 0);
|
||||||
|
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
VerifyData *verify_data = user_data;
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
VerifyData *verify_data = user_data;
|
||||||
|
|
||||||
fp_device_close_finish (dev, res, &error);
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (error)
|
fp_device_close_finish (dev, res, &error);
|
||||||
g_warning ("Failed closing device %s\n", error->message);
|
|
||||||
|
|
||||||
g_main_loop_quit (verify_data->loop);
|
if (error)
|
||||||
|
g_warning ("Failed closing device %s\n", error->message);
|
||||||
|
|
||||||
|
g_main_loop_quit (verify_data->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_verification (FpDevice *dev, VerifyData *verify_data);
|
static void start_verification (FpDevice *dev,
|
||||||
|
VerifyData *verify_data);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
{
|
{
|
||||||
VerifyData *verify_data = user_data;
|
VerifyData *verify_data = user_data;
|
||||||
g_autoptr(FpPrint) print = NULL;
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
char buffer[20];
|
|
||||||
gboolean match;
|
|
||||||
|
|
||||||
if (!fp_device_verify_finish (dev, res, &match, &print, &error)) {
|
g_autoptr(FpPrint) print = NULL;
|
||||||
g_warning ("Failed to verify print: %s", error->message);
|
g_autoptr(GError) error = NULL;
|
||||||
g_main_loop_quit (verify_data->loop);
|
char buffer[20];
|
||||||
return;
|
gboolean match;
|
||||||
}
|
|
||||||
|
|
||||||
if (match) {
|
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
|
||||||
g_print ("MATCH!\n");
|
{
|
||||||
if (fp_device_supports_capture (dev) &&
|
g_warning ("Failed to verify print: %s", error->message);
|
||||||
print_image_save (print, "verify.pgm")) {
|
g_main_loop_quit (verify_data->loop);
|
||||||
g_print("Print image saved as verify.pgm");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
verify_data->ret_value = EXIT_SUCCESS;
|
if (match)
|
||||||
} else {
|
{
|
||||||
g_print ("NO MATCH!\n");
|
g_print ("MATCH!\n");
|
||||||
verify_data->ret_value = EXIT_FAILURE;
|
if (fp_device_supports_capture (dev) &&
|
||||||
}
|
print_image_save (print, "verify.pgm"))
|
||||||
|
g_print ("Print image saved as verify.pgm");
|
||||||
|
|
||||||
g_print ("Verify again? [Y/n]? ");
|
verify_data->ret_value = EXIT_SUCCESS;
|
||||||
if (fgets (buffer, sizeof (buffer), stdin) &&
|
}
|
||||||
(buffer[0] == 'Y' || buffer[0] == 'y')) {
|
else
|
||||||
start_verification (dev, verify_data);
|
{
|
||||||
return;
|
g_print ("NO MATCH!\n");
|
||||||
}
|
verify_data->ret_value = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
g_print ("Verify again? [Y/n]? ");
|
||||||
verify_data);
|
if (fgets (buffer, sizeof (buffer), stdin) &&
|
||||||
|
(buffer[0] == 'Y' || buffer[0] == 'y'))
|
||||||
|
{
|
||||||
|
start_verification (dev, verify_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||||
|
verify_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
{
|
{
|
||||||
VerifyData *verify_data = user_data;
|
VerifyData *verify_data = user_data;
|
||||||
g_autoptr(GPtrArray) prints = NULL;
|
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
prints = fp_device_list_prints_finish (dev, res, &error);
|
g_autoptr(GPtrArray) prints = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (!error) {
|
prints = fp_device_list_prints_finish (dev, res, &error);
|
||||||
FpPrint *verify_print = NULL;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
if (!prints->len)
|
if (!error)
|
||||||
g_warning ("No prints saved on device");
|
{
|
||||||
|
FpPrint *verify_print = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < prints->len; ++i) {
|
if (!prints->len)
|
||||||
FpPrint *print = prints->pdata[i];
|
g_warning ("No prints saved on device");
|
||||||
|
|
||||||
if (fp_print_get_finger (print) == FP_FINGER_RIGHT_INDEX &&
|
for (i = 0; i < prints->len; ++i)
|
||||||
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0) {
|
{
|
||||||
if (!verify_print ||
|
FpPrint *print = prints->pdata[i];
|
||||||
(g_date_compare (fp_print_get_enroll_date (print),
|
|
||||||
fp_print_get_enroll_date (verify_print)) >= 0))
|
|
||||||
verify_print = print;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verify_print) {
|
if (fp_print_get_finger (print) == FP_FINGER_RIGHT_INDEX &&
|
||||||
g_warning ("Did you remember to enroll your right index "
|
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
|
||||||
"finger first?");
|
{
|
||||||
g_main_loop_quit (verify_data->loop);
|
if (!verify_print ||
|
||||||
return;
|
(g_date_compare (fp_print_get_enroll_date (print),
|
||||||
}
|
fp_print_get_enroll_date (verify_print)) >= 0))
|
||||||
|
verify_print = print;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_debug ("Comparing print with %s",
|
if (!verify_print)
|
||||||
fp_print_get_description (verify_print));
|
{
|
||||||
|
g_warning ("Did you remember to enroll your right index "
|
||||||
|
"finger first?");
|
||||||
|
g_main_loop_quit (verify_data->loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_print ("Print loaded. Time to verify!\n");
|
g_debug ("Comparing print with %s",
|
||||||
fp_device_verify (dev, verify_print, NULL,
|
fp_print_get_description (verify_print));
|
||||||
(GAsyncReadyCallback) on_verify_completed,
|
|
||||||
verify_data);
|
g_print ("Print loaded. Time to verify!\n");
|
||||||
} else {
|
fp_device_verify (dev, verify_print, NULL,
|
||||||
g_warning ("Loading prints failed with error %s", error->message);
|
(GAsyncReadyCallback) on_verify_completed,
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_data);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Loading prints failed with error %s", error->message);
|
||||||
|
g_main_loop_quit (verify_data->loop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
start_verification (FpDevice *dev, VerifyData *verify_data)
|
start_verification (FpDevice *dev, VerifyData *verify_data)
|
||||||
{
|
{
|
||||||
if (fp_device_has_storage (dev)) {
|
if (fp_device_has_storage (dev))
|
||||||
g_print ("Creating finger template, using device storage...\n");
|
{
|
||||||
fp_device_list_prints (dev, NULL,
|
g_print ("Creating finger template, using device storage...\n");
|
||||||
(GAsyncReadyCallback) on_list_completed,
|
fp_device_list_prints (dev, NULL,
|
||||||
verify_data);
|
(GAsyncReadyCallback) on_list_completed,
|
||||||
} else {
|
verify_data);
|
||||||
g_print ("Loading previously enrolled right index finger data...\n");
|
}
|
||||||
g_autoptr(FpPrint) verify_print;
|
else
|
||||||
|
{
|
||||||
|
g_print ("Loading previously enrolled right index finger data...\n");
|
||||||
|
g_autoptr(FpPrint) verify_print;
|
||||||
|
|
||||||
verify_print = print_data_load (dev, FP_FINGER_RIGHT_INDEX);
|
verify_print = print_data_load (dev, FP_FINGER_RIGHT_INDEX);
|
||||||
|
|
||||||
if (!verify_print) {
|
if (!verify_print)
|
||||||
g_warning ("Failed to load fingerprint data");
|
{
|
||||||
g_warning ("Did you remember to enroll your right index "
|
g_warning ("Failed to load fingerprint data");
|
||||||
"finger first?");
|
g_warning ("Did you remember to enroll your right index "
|
||||||
g_main_loop_quit (verify_data->loop);
|
"finger first?");
|
||||||
return;
|
g_main_loop_quit (verify_data->loop);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_print ("Print loaded. Time to verify!\n");
|
g_print ("Print loaded. Time to verify!\n");
|
||||||
fp_device_verify (dev, verify_print, NULL,
|
fp_device_verify (dev, verify_print, NULL,
|
||||||
(GAsyncReadyCallback) on_verify_completed,
|
(GAsyncReadyCallback) on_verify_completed,
|
||||||
verify_data);
|
verify_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
{
|
{
|
||||||
VerifyData *verify_data = user_data;
|
VerifyData *verify_data = user_data;
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
g_autoptr(GError) error = NULL;
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
|
||||||
g_main_loop_quit (verify_data->loop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_print ("Opened device. ");
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
|
g_main_loop_quit (verify_data->loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
start_verification (dev, verify_data);
|
g_print ("Opened device. ");
|
||||||
|
|
||||||
|
start_verification (dev, verify_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int
|
||||||
|
main (void)
|
||||||
{
|
{
|
||||||
g_autoptr (FpContext) ctx = NULL;
|
g_autoptr(FpContext) ctx = NULL;
|
||||||
g_autoptr (VerifyData) verify_data = NULL;
|
g_autoptr(VerifyData) verify_data = NULL;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
|
|
||||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||||
|
|
||||||
ctx = fp_context_new ();
|
ctx = fp_context_new ();
|
||||||
|
|
||||||
devices = fp_context_get_devices (ctx);
|
devices = fp_context_get_devices (ctx);
|
||||||
if (!devices) {
|
if (!devices)
|
||||||
g_warning("Impossible to get devices");
|
{
|
||||||
return EXIT_FAILURE;
|
g_warning ("Impossible to get devices");
|
||||||
}
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
dev = discover_device (devices);
|
dev = discover_device (devices);
|
||||||
if (!dev) {
|
if (!dev)
|
||||||
g_warning("No devices detected.");
|
{
|
||||||
return EXIT_FAILURE;
|
g_warning ("No devices detected.");
|
||||||
}
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
verify_data = g_new0 (VerifyData, 1);
|
verify_data = g_new0 (VerifyData, 1);
|
||||||
verify_data->ret_value = EXIT_FAILURE;
|
verify_data->ret_value = EXIT_FAILURE;
|
||||||
verify_data->loop = g_main_loop_new (NULL, FALSE);
|
verify_data->loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
|
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
|
||||||
verify_data);
|
verify_data);
|
||||||
|
|
||||||
g_main_loop_run (verify_data->loop);
|
g_main_loop_run (verify_data->loop);
|
||||||
|
|
||||||
return verify_data->ret_value;
|
return verify_data->ret_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,66 +25,71 @@
|
||||||
#include "aes1660.h"
|
#include "aes1660.h"
|
||||||
|
|
||||||
#define FRAME_WIDTH 128
|
#define FRAME_WIDTH 128
|
||||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||||
|
|
||||||
struct _FpiDeviceAes1660 {
|
struct _FpiDeviceAes1660
|
||||||
FpiDeviceAesX660 parent;
|
{
|
||||||
|
FpiDeviceAesX660 parent;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes1660, fpi_device_aes1660, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI,
|
||||||
DEVICE_AES1660, FpiDeviceAesX660);
|
DEVICE_AES1660, FpiDeviceAesX660);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes1660, fpi_device_aes1660, FPI_TYPE_DEVICE_AES_X660);
|
G_DEFINE_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI_TYPE_DEVICE_AES_X660);
|
||||||
|
|
||||||
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.frame_width = FRAME_WIDTH,
|
.frame_width = FRAME_WIDTH,
|
||||||
.frame_height = AESX660_FRAME_HEIGHT,
|
.frame_height = AESX660_FRAME_HEIGHT,
|
||||||
.image_width = IMAGE_WIDTH,
|
.image_width = IMAGE_WIDTH,
|
||||||
.get_pixel = aes_get_pixel,
|
.get_pixel = aes_get_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x08ff, .pid = 0x1660, },
|
{ .vid = 0x08ff, .pid = 0x1660, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1680, },
|
{ .vid = 0x08ff, .pid = 0x1680, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1681, },
|
{ .vid = 0x08ff, .pid = 0x1681, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1682, },
|
{ .vid = 0x08ff, .pid = 0x1682, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1683, },
|
{ .vid = 0x08ff, .pid = 0x1683, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1684, },
|
{ .vid = 0x08ff, .pid = 0x1684, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1685, },
|
{ .vid = 0x08ff, .pid = 0x1685, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1686, },
|
{ .vid = 0x08ff, .pid = 0x1686, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1687, },
|
{ .vid = 0x08ff, .pid = 0x1687, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1688, },
|
{ .vid = 0x08ff, .pid = 0x1688, },
|
||||||
{ .vid = 0x08ff, .pid = 0x1689, },
|
{ .vid = 0x08ff, .pid = 0x1689, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168a, },
|
{ .vid = 0x08ff, .pid = 0x168a, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168b, },
|
{ .vid = 0x08ff, .pid = 0x168b, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168c, },
|
{ .vid = 0x08ff, .pid = 0x168c, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168d, },
|
{ .vid = 0x08ff, .pid = 0x168d, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168e, },
|
{ .vid = 0x08ff, .pid = 0x168e, },
|
||||||
{ .vid = 0x08ff, .pid = 0x168f, },
|
{ .vid = 0x08ff, .pid = 0x168f, },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes1660_init(FpiDeviceAes1660 *self) {
|
static void
|
||||||
|
fpi_device_aes1660_init (FpiDeviceAes1660 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_aes1660_class_init(FpiDeviceAes1660Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes1660_class_init (FpiDeviceAes1660Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes1660";
|
dev_class->id = "aes1660";
|
||||||
dev_class->full_name = "AuthenTec AES1660";
|
dev_class->full_name = "AuthenTec AES1660";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
img_class->bz3_threshold = 20;
|
img_class->bz3_threshold = 20;
|
||||||
|
|
||||||
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
|
|
||||||
aes_class->init_seqs[0] = aes1660_init_1;
|
aes_class->init_seqs[0] = aes1660_init_1;
|
||||||
aes_class->init_seqs_len[0] = G_N_ELEMENTS(aes1660_init_1);
|
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes1660_init_1);
|
||||||
aes_class->init_seqs[1] = aes1660_init_2;
|
aes_class->init_seqs[1] = aes1660_init_2;
|
||||||
aes_class->init_seqs_len[1] = G_N_ELEMENTS(aes1660_init_2);
|
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes1660_init_2);
|
||||||
aes_class->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd;
|
aes_class->start_imaging_cmd = (unsigned char *) aes1660_start_imaging_cmd;
|
||||||
aes_class->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd);
|
aes_class->start_imaging_cmd_len = sizeof (aes1660_start_imaging_cmd);
|
||||||
aes_class->assembling_ctx = &assembling_ctx;
|
aes_class->assembling_ctx = &assembling_ctx;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -23,149 +23,149 @@
|
||||||
#define __AES2501_H
|
#define __AES2501_H
|
||||||
|
|
||||||
enum aes2501_regs {
|
enum aes2501_regs {
|
||||||
AES2501_REG_CTRL1 = 0x80,
|
AES2501_REG_CTRL1 = 0x80,
|
||||||
AES2501_REG_CTRL2 = 0x81,
|
AES2501_REG_CTRL2 = 0x81,
|
||||||
AES2501_REG_EXCITCTRL = 0x82, /* excitation control */
|
AES2501_REG_EXCITCTRL = 0x82, /* excitation control */
|
||||||
AES2501_REG_DETCTRL = 0x83, /* detect control */
|
AES2501_REG_DETCTRL = 0x83, /* detect control */
|
||||||
AES2501_REG_COLSCAN = 0x88, /* column scan rate register */
|
AES2501_REG_COLSCAN = 0x88, /* column scan rate register */
|
||||||
AES2501_REG_MEASDRV = 0x89, /* measure drive */
|
AES2501_REG_MEASDRV = 0x89, /* measure drive */
|
||||||
AES2501_REG_MEASFREQ = 0x8a, /* measure frequency */
|
AES2501_REG_MEASFREQ = 0x8a, /* measure frequency */
|
||||||
AES2501_REG_DEMODPHASE1 = 0x8d,
|
AES2501_REG_DEMODPHASE1 = 0x8d,
|
||||||
AES2501_REG_DEMODPHASE2 = 0x8c,
|
AES2501_REG_DEMODPHASE2 = 0x8c,
|
||||||
AES2501_REG_CHANGAIN = 0x8e, /* channel gain */
|
AES2501_REG_CHANGAIN = 0x8e, /* channel gain */
|
||||||
AES2501_REG_ADREFHI = 0x91, /* A/D reference high */
|
AES2501_REG_ADREFHI = 0x91, /* A/D reference high */
|
||||||
AES2501_REG_ADREFLO = 0x92, /* A/D reference low */
|
AES2501_REG_ADREFLO = 0x92, /* A/D reference low */
|
||||||
AES2501_REG_STRTROW = 0x93, /* start row */
|
AES2501_REG_STRTROW = 0x93, /* start row */
|
||||||
AES2501_REG_ENDROW = 0x94, /* end row */
|
AES2501_REG_ENDROW = 0x94, /* end row */
|
||||||
AES2501_REG_STRTCOL = 0x95, /* start column */
|
AES2501_REG_STRTCOL = 0x95, /* start column */
|
||||||
AES2501_REG_ENDCOL = 0x96, /* end column */
|
AES2501_REG_ENDCOL = 0x96, /* end column */
|
||||||
AES2501_REG_DATFMT = 0x97, /* data format */
|
AES2501_REG_DATFMT = 0x97, /* data format */
|
||||||
AES2501_REG_IMAGCTRL = 0x98, /* image data */
|
AES2501_REG_IMAGCTRL = 0x98, /* image data */
|
||||||
AES2501_REG_STAT = 0x9a,
|
AES2501_REG_STAT = 0x9a,
|
||||||
AES2501_REG_CHWORD1 = 0x9b, /* challenge word 1 */
|
AES2501_REG_CHWORD1 = 0x9b, /* challenge word 1 */
|
||||||
AES2501_REG_CHWORD2 = 0x9c,
|
AES2501_REG_CHWORD2 = 0x9c,
|
||||||
AES2501_REG_CHWORD3 = 0x9d,
|
AES2501_REG_CHWORD3 = 0x9d,
|
||||||
AES2501_REG_CHWORD4 = 0x9e,
|
AES2501_REG_CHWORD4 = 0x9e,
|
||||||
AES2501_REG_CHWORD5 = 0x9f,
|
AES2501_REG_CHWORD5 = 0x9f,
|
||||||
AES2501_REG_TREG1 = 0xa1, /* test register 1 */
|
AES2501_REG_TREG1 = 0xa1, /* test register 1 */
|
||||||
AES2501_REG_AUTOCALOFFSET = 0xa8,
|
AES2501_REG_AUTOCALOFFSET = 0xa8,
|
||||||
AES2501_REG_TREGC = 0xac,
|
AES2501_REG_TREGC = 0xac,
|
||||||
AES2501_REG_TREGD = 0xad,
|
AES2501_REG_TREGD = 0xad,
|
||||||
AES2501_REG_LPONT = 0xb4, /* low power oscillator on time */
|
AES2501_REG_LPONT = 0xb4, /* low power oscillator on time */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FIRST_AES2501_REG AES2501_REG_CTRL1
|
#define FIRST_AES2501_REG AES2501_REG_CTRL1
|
||||||
#define LAST_AES2501_REG AES2501_REG_CHWORD5
|
#define LAST_AES2501_REG AES2501_REG_CHWORD5
|
||||||
|
|
||||||
#define AES2501_CTRL1_MASTER_RESET (1<<0)
|
#define AES2501_CTRL1_MASTER_RESET (1 << 0)
|
||||||
#define AES2501_CTRL1_SCAN_RESET (1<<1) /* stop + restart scan sequencer */
|
#define AES2501_CTRL1_SCAN_RESET (1 << 1) /* stop + restart scan sequencer */
|
||||||
/* 1 = continuously updated, 0 = updated prior to starting a scan */
|
/* 1 = continuously updated, 0 = updated prior to starting a scan */
|
||||||
#define AES2501_CTRL1_REG_UPDATE (1<<2)
|
#define AES2501_CTRL1_REG_UPDATE (1 << 2)
|
||||||
|
|
||||||
/* 1 = continuous scans, 0 = single scans */
|
/* 1 = continuous scans, 0 = single scans */
|
||||||
#define AES2501_CTRL2_CONTINUOUS 0x01
|
#define AES2501_CTRL2_CONTINUOUS 0x01
|
||||||
#define AES2501_CTRL2_READ_REGS 0x02 /* dump registers */
|
#define AES2501_CTRL2_READ_REGS 0x02 /* dump registers */
|
||||||
#define AES2501_CTRL2_SET_ONE_SHOT 0x04
|
#define AES2501_CTRL2_SET_ONE_SHOT 0x04
|
||||||
#define AES2501_CTRL2_CLR_ONE_SHOT 0x08
|
#define AES2501_CTRL2_CLR_ONE_SHOT 0x08
|
||||||
#define AES2501_CTRL2_READ_ID 0x10
|
#define AES2501_CTRL2_READ_ID 0x10
|
||||||
|
|
||||||
enum aes2501_detection_rate {
|
enum aes2501_detection_rate {
|
||||||
/* rate of detection cycles: */
|
/* rate of detection cycles: */
|
||||||
AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* continuously */
|
AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* continuously */
|
||||||
AES2501_DETCTRL_DRATE_16_MS = 0x01, /* every 16.62ms */
|
AES2501_DETCTRL_DRATE_16_MS = 0x01, /* every 16.62ms */
|
||||||
AES2501_DETCTRL_DRATE_31_MS = 0x02, /* every 31.24ms */
|
AES2501_DETCTRL_DRATE_31_MS = 0x02, /* every 31.24ms */
|
||||||
AES2501_DETCTRL_DRATE_62_MS = 0x03, /* every 62.50ms */
|
AES2501_DETCTRL_DRATE_62_MS = 0x03, /* every 62.50ms */
|
||||||
AES2501_DETCTRL_DRATE_125_MS = 0x04, /* every 125.0ms */
|
AES2501_DETCTRL_DRATE_125_MS = 0x04, /* every 125.0ms */
|
||||||
AES2501_DETCTRL_DRATE_250_MS = 0x05, /* every 250.0ms */
|
AES2501_DETCTRL_DRATE_250_MS = 0x05, /* every 250.0ms */
|
||||||
AES2501_DETCTRL_DRATE_500_MS = 0x06, /* every 500.0ms */
|
AES2501_DETCTRL_DRATE_500_MS = 0x06, /* every 500.0ms */
|
||||||
AES2501_DETCTRL_DRATE_1_S = 0x07, /* every 1s */
|
AES2501_DETCTRL_DRATE_1_S = 0x07, /* every 1s */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum aes2501_settling_delay {
|
enum aes2501_settling_delay {
|
||||||
AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25ms */
|
AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25ms */
|
||||||
AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5ms */
|
AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5ms */
|
||||||
AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125ms */
|
AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125ms */
|
||||||
AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250ms */
|
AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250ms */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum aes2501_col_scan_rate {
|
enum aes2501_col_scan_rate {
|
||||||
AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32us */
|
AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32us */
|
||||||
AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64us */
|
AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64us */
|
||||||
AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128us */
|
AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128us */
|
||||||
AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256us */
|
AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256us */
|
||||||
AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512us */
|
AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512us */
|
||||||
AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024us */
|
AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024us */
|
||||||
AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048us */
|
AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048us */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum aes2501_mesure_drive {
|
enum aes2501_mesure_drive {
|
||||||
AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */
|
AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */
|
||||||
AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */
|
AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */
|
||||||
AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */
|
AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */
|
||||||
AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */
|
AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Select (1=square | 0=sine) wave drive during measure */
|
/* Select (1=square | 0=sine) wave drive during measure */
|
||||||
#define AES2501_MEASDRV_SQUARE 0x20
|
#define AES2501_MEASDRV_SQUARE 0x20
|
||||||
/* 0 = use measure drive setting, 1 = when sine wave is selected */
|
/* 0 = use measure drive setting, 1 = when sine wave is selected */
|
||||||
#define AES2501_MEASDRV_MEASURE_SQUARE 0x10
|
#define AES2501_MEASDRV_MEASURE_SQUARE 0x10
|
||||||
|
|
||||||
enum aes2501_measure_freq {
|
enum aes2501_measure_freq {
|
||||||
AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */
|
AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */
|
||||||
AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */
|
AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */
|
||||||
AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */
|
AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */
|
||||||
AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */
|
AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */
|
||||||
AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */
|
AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEMODPHASE_NONE 0x00
|
#define DEMODPHASE_NONE 0x00
|
||||||
#define DEMODPHASE_180_00 0x40 /* 180 degrees */
|
#define DEMODPHASE_180_00 0x40 /* 180 degrees */
|
||||||
#define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */
|
#define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */
|
||||||
|
|
||||||
#define AES2501_REG_DEMODPHASE1 0x8d
|
#define AES2501_REG_DEMODPHASE1 0x8d
|
||||||
#define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */
|
#define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */
|
||||||
#define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */
|
#define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */
|
||||||
|
|
||||||
enum aes2501_sensor_gain1 {
|
enum aes2501_sensor_gain1 {
|
||||||
AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */
|
AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */
|
||||||
AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */
|
AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */
|
||||||
AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */
|
AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */
|
||||||
AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */
|
AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum aes2501_sensor_gain2 {
|
enum aes2501_sensor_gain2 {
|
||||||
AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */
|
AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */
|
||||||
AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */
|
AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */
|
||||||
AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */
|
AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */
|
||||||
AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */
|
AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */
|
#define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */
|
||||||
#define AES2501_DATFMT_LOW_RES 0x20
|
#define AES2501_DATFMT_LOW_RES 0x20
|
||||||
#define AES2501_DATFMT_BIN_IMG 0x10
|
#define AES2501_DATFMT_BIN_IMG 0x10
|
||||||
|
|
||||||
/* don't send image or authentication messages when imaging */
|
/* don't send image or authentication messages when imaging */
|
||||||
#define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01
|
#define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01
|
||||||
/* send histogram when imaging */
|
/* send histogram when imaging */
|
||||||
#define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02
|
#define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02
|
||||||
/* send histogram at end of each row rather than each scan */
|
/* send histogram at end of each row rather than each scan */
|
||||||
#define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04
|
#define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04
|
||||||
/* send full image array rather than 64x64 center */
|
/* send full image array rather than 64x64 center */
|
||||||
#define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08
|
#define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08
|
||||||
/* return registers before data (rather than after) */
|
/* return registers before data (rather than after) */
|
||||||
#define AES2501_IMAGCTRL_REG_FIRST 0x10
|
#define AES2501_IMAGCTRL_REG_FIRST 0x10
|
||||||
/* return test registers with register dump */
|
/* return test registers with register dump */
|
||||||
#define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20
|
#define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20
|
||||||
|
|
||||||
#define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */
|
#define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */
|
||||||
|
|
||||||
/* Enable the reading of the register in TREGD */
|
/* Enable the reading of the register in TREGD */
|
||||||
#define AES2501_TREGC_ENABLE 0x01
|
#define AES2501_TREGC_ENABLE 0x01
|
||||||
|
|
||||||
#define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */
|
#define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */
|
||||||
#define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */
|
#define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */
|
||||||
|
|
||||||
#define AES2501_ADREFHI_MIN_VALUE 0x28
|
#define AES2501_ADREFHI_MIN_VALUE 0x28
|
||||||
#define AES2501_ADREFHI_MAX_VALUE 0x58
|
#define AES2501_ADREFHI_MAX_VALUE 0x58
|
||||||
|
@ -173,4 +173,4 @@ enum aes2501_sensor_gain2 {
|
||||||
#define AES2501_SUM_HIGH_THRESH 1000
|
#define AES2501_SUM_HIGH_THRESH 1000
|
||||||
#define AES2501_SUM_LOW_THRESH 700
|
#define AES2501_SUM_LOW_THRESH 700
|
||||||
|
|
||||||
#endif /* __AES2501_H */
|
#endif /* __AES2501_H */
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
#include "aes2550.h"
|
#include "aes2550.h"
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev);
|
static void start_capture (FpImageDevice *dev);
|
||||||
static void complete_deactivation(FpImageDevice *dev);
|
static void complete_deactivation (FpImageDevice *dev);
|
||||||
|
|
||||||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,528 +46,583 @@ static void complete_deactivation(FpImageDevice *dev);
|
||||||
* images returned from this driver vary in height.
|
* images returned from this driver vary in height.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FRAME_WIDTH 192
|
#define FRAME_WIDTH 192
|
||||||
#define FRAME_HEIGHT 8
|
#define FRAME_HEIGHT 8
|
||||||
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
||||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||||
|
|
||||||
struct _FpiDeviceAes2550 {
|
struct _FpiDeviceAes2550
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
GSList *strips;
|
GSList *strips;
|
||||||
size_t strips_len;
|
size_t strips_len;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
int heartbeat_cnt;
|
int heartbeat_cnt;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.frame_width = FRAME_WIDTH,
|
.frame_width = FRAME_WIDTH,
|
||||||
.frame_height = FRAME_HEIGHT,
|
.frame_height = FRAME_HEIGHT,
|
||||||
.image_width = IMAGE_WIDTH,
|
.image_width = IMAGE_WIDTH,
|
||||||
.get_pixel = aes_get_pixel,
|
.get_pixel = aes_get_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
/****** FINGER PRESENCE DETECTION ******/
|
/****** FINGER PRESENCE DETECTION ******/
|
||||||
|
|
||||||
static unsigned char finger_det_reqs[] = {
|
static unsigned char finger_det_reqs[] = {
|
||||||
0x80, AES2550_REG80_MASTER_RESET,
|
0x80, AES2550_REG80_MASTER_RESET,
|
||||||
0x95, (8 << AES2550_REG95_COL_SCANNED_OFS) | (1 << AES2550_REG95_EPIX_AVG_OFS),
|
0x95, (8 << AES2550_REG95_COL_SCANNED_OFS) | (1 << AES2550_REG95_EPIX_AVG_OFS),
|
||||||
0xad, 0x00,
|
0xad, 0x00,
|
||||||
0xbd, (0 << AES2550_REGBD_LPO_IN_15_8_OFS),
|
0xbd, (0 << AES2550_REGBD_LPO_IN_15_8_OFS),
|
||||||
0xbe, (0 << AES2550_REGBE_LPO_IN_7_0_OFS),
|
0xbe, (0 << AES2550_REGBE_LPO_IN_7_0_OFS),
|
||||||
0xcf, AES2550_REGCF_INTERFERENCE_CHK_EN,
|
0xcf, AES2550_REGCF_INTERFERENCE_CHK_EN,
|
||||||
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
|
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
|
||||||
AES2550_CMD_RUN_FD,
|
AES2550_CMD_RUN_FD,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void start_finger_detection(FpImageDevice *dev);
|
static void start_finger_detection (FpImageDevice *dev);
|
||||||
|
|
||||||
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_image_device_session_error(FP_IMAGE_DEVICE(device), error);
|
{
|
||||||
return;
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("transfer completed, len: %.4x, data: %.2x %.2x",
|
fp_dbg ("transfer completed, len: %.4x, data: %.2x %.2x",
|
||||||
(gint)transfer->actual_length, (int)data[0], (int)data[1]);
|
(gint) transfer->actual_length, (int) data[0], (int) data[1]);
|
||||||
|
|
||||||
/* Check if we got 2 bytes, reg address 0x83 and its value */
|
/* Check if we got 2 bytes, reg address 0x83 and its value */
|
||||||
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT)) {
|
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT))
|
||||||
/* finger present, start capturing */
|
{
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
/* finger present, start capturing */
|
||||||
start_capture(dev);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
} else {
|
start_capture (dev);
|
||||||
/* no finger, poll for a new histogram */
|
}
|
||||||
start_finger_detection(dev);
|
else
|
||||||
}
|
{
|
||||||
|
/* no finger, poll for a new histogram */
|
||||||
|
start_finger_detection (dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_image_device_session_error(dev, error);
|
{
|
||||||
return;
|
fpi_image_device_session_error (dev, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new (device);
|
transfer = fpi_usb_transfer_new (device);
|
||||||
/* 2 bytes of result */
|
/* 2 bytes of result */
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
finger_det_data_cb, NULL);
|
finger_det_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_finger_detection(FpImageDevice *dev)
|
static void
|
||||||
|
start_finger_detection (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
|
||||||
if (self->deactivating) {
|
G_DEBUG_HERE ();
|
||||||
complete_deactivation(dev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
if (self->deactivating)
|
||||||
transfer->short_is_error = TRUE;
|
{
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, finger_det_reqs,
|
complete_deactivation (dev);
|
||||||
sizeof(finger_det_reqs), NULL);
|
return;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
}
|
||||||
finger_det_reqs_cb, NULL);
|
|
||||||
fpi_usb_transfer_unref(transfer);
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, finger_det_reqs,
|
||||||
|
sizeof (finger_det_reqs), NULL);
|
||||||
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
|
finger_det_reqs_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
|
||||||
static unsigned char capture_reqs[] = {
|
static unsigned char capture_reqs[] = {
|
||||||
0x80, AES2550_REG80_MASTER_RESET,
|
0x80, AES2550_REG80_MASTER_RESET,
|
||||||
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_HGC_ENABLE),
|
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_HGC_ENABLE),
|
||||||
0x85, AES2550_REG85_FLUSH_PER_FRAME,
|
0x85, AES2550_REG85_FLUSH_PER_FRAME,
|
||||||
0x8f, AES2550_REG8F_AUTH_DISABLE | AES2550_REG8F_EHISTO_DISABLE,
|
0x8f, AES2550_REG8F_AUTH_DISABLE | AES2550_REG8F_EHISTO_DISABLE,
|
||||||
0xbf, AES2550_REGBF_RSR_DIR_UPDOWN_MOTION | AES2550_REGBF_RSR_LEVEL_SUPER_RSR,
|
0xbf, AES2550_REGBF_RSR_DIR_UPDOWN_MOTION | AES2550_REGBF_RSR_LEVEL_SUPER_RSR,
|
||||||
0xcf, (3 << AES2550_REGCF_INTERFERENCE_AVG_OFFS) | AES2550_REGCF_INTERFERENCE_AVG_EN,
|
0xcf, (3 << AES2550_REGCF_INTERFERENCE_AVG_OFFS) | AES2550_REGCF_INTERFERENCE_AVG_EN,
|
||||||
0xdc, (1 << AES2550_REGDC_BP_NUM_REF_SWEEP_OFS),
|
0xdc, (1 << AES2550_REGDC_BP_NUM_REF_SWEEP_OFS),
|
||||||
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x03, /* Heart beat cmd, 3 * 16 cycles without sending image */
|
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x03, /* Heart beat cmd, 3 * 16 cycles without sending image */
|
||||||
AES2550_CMD_GET_ENROLL_IMG,
|
AES2550_CMD_GET_ENROLL_IMG,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char capture_set_idle_reqs[] = {
|
static unsigned char capture_set_idle_reqs[] = {
|
||||||
0x80, AES2550_REG80_MASTER_RESET,
|
0x80, AES2550_REG80_MASTER_RESET,
|
||||||
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
|
AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */
|
||||||
AES2550_CMD_SET_IDLE_MODE,
|
AES2550_CMD_SET_IDLE_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum capture_states {
|
enum capture_states {
|
||||||
CAPTURE_WRITE_REQS,
|
CAPTURE_WRITE_REQS,
|
||||||
CAPTURE_READ_DATA,
|
CAPTURE_READ_DATA,
|
||||||
CAPTURE_SET_IDLE,
|
CAPTURE_SET_IDLE,
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
|
static gboolean
|
||||||
unsigned char *data)
|
process_strip_data (FpiSsm *ssm, FpImageDevice *dev,
|
||||||
|
unsigned char *data)
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
struct fpi_frame *stripe;
|
struct fpi_frame *stripe;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (data[0] != AES2550_EDATA_MAGIC) {
|
if (data[0] != AES2550_EDATA_MAGIC)
|
||||||
fp_dbg("Bogus magic: %.2x\n", (int)(data[0]));
|
{
|
||||||
return FALSE;
|
fp_dbg ("Bogus magic: %.2x\n", (int) (data[0]));
|
||||||
}
|
return FALSE;
|
||||||
len = data[1] * 256 + data[2];
|
}
|
||||||
if (len != (AES2550_STRIP_SIZE - 3)) {
|
len = data[1] * 256 + data[2];
|
||||||
fp_dbg("Bogus frame len: %.4x\n", len);
|
if (len != (AES2550_STRIP_SIZE - 3))
|
||||||
}
|
fp_dbg ("Bogus frame len: %.4x\n", len);
|
||||||
stripe = g_malloc0(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bits per pixel */
|
stripe = g_malloc0 (FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bits per pixel */
|
||||||
stripe->delta_x = (int8_t)data[6];
|
stripe->delta_x = (int8_t) data[6];
|
||||||
stripe->delta_y = -(int8_t)data[7];
|
stripe->delta_y = -(int8_t) data[7];
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
|
memcpy (stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
|
||||||
self->strips = g_slist_prepend(self->strips, stripe);
|
self->strips = g_slist_prepend (self->strips, stripe);
|
||||||
self->strips_len++;
|
self->strips_len++;
|
||||||
|
|
||||||
fp_dbg("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
|
fp_dbg ("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
capture_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_set_idle_reqs_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
FpDevice *device, gpointer user_data,
|
capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
|
||||||
GError *error)
|
FpDevice *device, gpointer user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
|
|
||||||
if (!error && self->strips_len) {
|
if (!error && self->strips_len)
|
||||||
FpImage *img;
|
{
|
||||||
|
FpImage *img;
|
||||||
|
|
||||||
self->strips = g_slist_reverse(self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
img = fpi_assemble_frames(&assembling_ctx, self->strips);
|
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||||
g_slist_free_full(self->strips, g_free);
|
g_slist_free_full (self->strips, g_free);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
fpi_image_device_image_captured(dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
fpi_image_device_report_finger_status(dev, FALSE);
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
/* marking machine complete will re-trigger finger detection loop */
|
/* marking machine complete will re-trigger finger detection loop */
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
} else {
|
}
|
||||||
if (error)
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
{
|
||||||
else
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
else
|
||||||
}
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
{
|
||||||
return;
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("request completed, len: %.4x", (gint)transfer->actual_length);
|
fp_dbg ("request completed, len: %.4x", (gint) transfer->actual_length);
|
||||||
if (transfer->actual_length >= 2)
|
if (transfer->actual_length >= 2)
|
||||||
fp_dbg("data: %.2x %.2x", (int)data[0], (int)data[1]);
|
fp_dbg ("data: %.2x %.2x", (int) data[0], (int) data[1]);
|
||||||
|
|
||||||
switch (transfer->actual_length) {
|
switch (transfer->actual_length)
|
||||||
case AES2550_STRIP_SIZE:
|
{
|
||||||
if (!process_strip_data(transfer->ssm, dev, data)) {
|
case AES2550_STRIP_SIZE:
|
||||||
fp_dbg("Processing strip data failed");
|
if (!process_strip_data (transfer->ssm, dev, data))
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
{
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fp_dbg ("Processing strip data failed");
|
||||||
return;
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
}
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
self->heartbeat_cnt = 0;
|
return;
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
}
|
||||||
break;
|
self->heartbeat_cnt = 0;
|
||||||
case AES2550_HEARTBEAT_SIZE:
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
if (data[0] == AES2550_HEARTBEAT_MAGIC) {
|
break;
|
||||||
/* No data for a long time => finger was removed or there's no movement */
|
|
||||||
self->heartbeat_cnt++;
|
case AES2550_HEARTBEAT_SIZE:
|
||||||
if (self->heartbeat_cnt == 3) {
|
if (data[0] == AES2550_HEARTBEAT_MAGIC)
|
||||||
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
{
|
||||||
* assemble image and submit it to the library */
|
/* No data for a long time => finger was removed or there's no movement */
|
||||||
fp_dbg("Got 3 heartbeats => finger removed");
|
self->heartbeat_cnt++;
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
if (self->heartbeat_cnt == 3)
|
||||||
} else {
|
{
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
||||||
CAPTURE_READ_DATA);
|
* assemble image and submit it to the library */
|
||||||
}
|
fp_dbg ("Got 3 heartbeats => finger removed");
|
||||||
}
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
break;
|
}
|
||||||
default:
|
else
|
||||||
fp_dbg("Short frame %d, skip",
|
{
|
||||||
(gint)transfer->actual_length);
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
CAPTURE_READ_DATA);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fp_dbg ("Short frame %d, skip",
|
||||||
|
(gint) transfer->actual_length);
|
||||||
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case CAPTURE_WRITE_REQS:
|
{
|
||||||
{
|
case CAPTURE_WRITE_REQS:
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, capture_reqs,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, capture_reqs,
|
||||||
sizeof(capture_reqs), NULL);
|
sizeof (capture_reqs), NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
capture_reqs_cb, NULL);
|
capture_reqs_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
case CAPTURE_READ_DATA:
|
||||||
transfer->ssm = ssm;
|
{
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
capture_read_data_cb, NULL);
|
|
||||||
fpi_usb_transfer_unref(transfer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CAPTURE_SET_IDLE:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
capture_set_idle_reqs,
|
transfer->ssm = ssm;
|
||||||
sizeof(capture_set_idle_reqs),
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
NULL);
|
capture_read_data_cb, NULL);
|
||||||
transfer->ssm = ssm;
|
fpi_usb_transfer_unref (transfer);
|
||||||
transfer->short_is_error = TRUE;
|
}
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
break;
|
||||||
capture_set_idle_reqs_cb, NULL);
|
|
||||||
fpi_usb_transfer_unref(transfer);
|
case CAPTURE_SET_IDLE:
|
||||||
}
|
{
|
||||||
break;
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
};
|
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
|
||||||
|
capture_set_idle_reqs,
|
||||||
|
sizeof (capture_set_idle_reqs),
|
||||||
|
NULL);
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
|
capture_set_idle_reqs_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
GError *error)
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(_dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (_dev);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg ("Capture completed");
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
g_clear_pointer (&error, g_error_free);
|
complete_deactivation (dev);
|
||||||
} else if (error) {
|
g_clear_pointer (&error, g_error_free);
|
||||||
fpi_image_device_session_error(dev, error);
|
}
|
||||||
} else {
|
else if (error)
|
||||||
start_finger_detection(dev);
|
{
|
||||||
}
|
fpi_image_device_session_error (dev, error);
|
||||||
fpi_ssm_free(ssm);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_finger_detection (dev);
|
||||||
|
}
|
||||||
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
return;
|
complete_deactivation (dev);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self->heartbeat_cnt = 0;
|
self->heartbeat_cnt = 0;
|
||||||
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
|
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
|
||||||
CAPTURE_NUM_STATES, dev);
|
CAPTURE_NUM_STATES, dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start (ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||||
|
|
||||||
static unsigned char init_reqs[] = {
|
static unsigned char init_reqs[] = {
|
||||||
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
|
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
|
||||||
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_FORCE_FINGER_PRESENT),
|
0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_FORCE_FINGER_PRESENT),
|
||||||
0x85, AES2550_REG85_FLUSH_PER_FRAME,
|
0x85, AES2550_REG85_FLUSH_PER_FRAME,
|
||||||
0xa8, AES2550_REGA8_DIG_BIT_EN,
|
0xa8, AES2550_REGA8_DIG_BIT_EN,
|
||||||
0x81, AES2550_REG81_NSHOT,
|
0x81, AES2550_REG81_NSHOT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char calibrate_reqs[] = {
|
static unsigned char calibrate_reqs[] = {
|
||||||
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
|
0x80, AES2550_REG80_MASTER_RESET, /* Master reset */
|
||||||
AES2550_CMD_CALIBRATE,
|
AES2550_CMD_CALIBRATE,
|
||||||
AES2550_CMD_READ_CALIBRATION_DATA,
|
AES2550_CMD_READ_CALIBRATION_DATA,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum activate_states {
|
enum activate_states {
|
||||||
WRITE_INIT,
|
WRITE_INIT,
|
||||||
READ_DATA,
|
READ_DATA,
|
||||||
CALIBRATE,
|
CALIBRATE,
|
||||||
READ_CALIB_TABLE,
|
READ_CALIB_TABLE,
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: use calibration table, datasheet is rather terse on that
|
/* TODO: use calibration table, datasheet is rather terse on that
|
||||||
* need more info for implementation */
|
* need more info for implementation */
|
||||||
static void calibrate_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
calibrate_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
activate_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case WRITE_INIT:
|
{
|
||||||
{
|
case WRITE_INIT:
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, init_reqs,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, init_reqs,
|
||||||
sizeof(init_reqs), NULL);
|
sizeof (init_reqs), NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
init_reqs_cb, NULL);
|
init_reqs_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_DATA:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
case READ_DATA:
|
||||||
transfer->ssm = ssm;
|
{
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
init_read_data_cb, NULL);
|
|
||||||
fpi_usb_transfer_unref(transfer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CALIBRATE:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
calibrate_reqs,
|
transfer->ssm = ssm;
|
||||||
sizeof(calibrate_reqs), NULL);
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
transfer->ssm = ssm;
|
init_read_data_cb, NULL);
|
||||||
transfer->short_is_error = TRUE;
|
fpi_usb_transfer_unref (transfer);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
}
|
||||||
init_reqs_cb, NULL);
|
break;
|
||||||
fpi_usb_transfer_unref(transfer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case READ_CALIB_TABLE:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
case CALIBRATE:
|
||||||
transfer->ssm = ssm;
|
{
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
calibrate_read_data_cb, NULL);
|
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
|
||||||
}
|
calibrate_reqs,
|
||||||
break;
|
sizeof (calibrate_reqs), NULL);
|
||||||
}
|
transfer->ssm = ssm;
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
|
init_reqs_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_CALIB_TABLE:
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
|
calibrate_read_data_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
void *user_data, GError *error)
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
|
|
||||||
fpi_image_device_activate_complete(dev, error);
|
fpi_image_device_activate_complete (dev, error);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), activate_run_state,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES, dev);
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
|
||||||
|
fpi_ssm_start (ssm, activate_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
|
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(FpImageDevice *dev)
|
static void
|
||||||
|
complete_deactivation (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
G_DEBUG_HERE ();
|
||||||
g_slist_free(self->strips);
|
|
||||||
self->strips = NULL;
|
self->deactivating = FALSE;
|
||||||
self->strips_len = 0;
|
g_slist_free (self->strips);
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
self->strips = NULL;
|
||||||
|
self->strips_len = 0;
|
||||||
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_init(FpImageDevice *dev)
|
static void
|
||||||
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
/* TODO check that device has endpoints we're using */
|
|
||||||
|
|
||||||
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
|
/* TODO check that device has endpoints we're using */
|
||||||
|
|
||||||
fpi_image_device_open_complete(dev, error);
|
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deinit (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x08ff, .pid = 0x2550,
|
{ .vid = 0x08ff, .pid = 0x2550, },/* AES2550 */
|
||||||
}, /* AES2550 */
|
{ .vid = 0x08ff, .pid = 0x2810, },/* AES2810 */
|
||||||
{ .vid = 0x08ff, .pid = 0x2810,
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
}, /* AES2810 */
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes2550_init(FpiDeviceAes2550 *self) {
|
static void
|
||||||
|
fpi_device_aes2550_init (FpiDeviceAes2550 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_aes2550_class_init(FpiDeviceAes2550Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes2550_class_init (FpiDeviceAes2550Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes2550";
|
dev_class->id = "aes2550";
|
||||||
dev_class->full_name = "AuthenTec AES2550/AES2810";
|
dev_class->full_name = "AuthenTec AES2550/AES2810";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
img_class->img_open = dev_init;
|
img_class->img_open = dev_init;
|
||||||
img_class->img_close = dev_deinit;
|
img_class->img_close = dev_deinit;
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,93 +22,93 @@
|
||||||
|
|
||||||
/* Registers bits */
|
/* Registers bits */
|
||||||
|
|
||||||
#define AES2550_REG80_MASTER_RESET (1 << 0)
|
#define AES2550_REG80_MASTER_RESET (1 << 0)
|
||||||
#define AES2550_REG80_FORCE_FINGER_PRESENT (1 << 1)
|
#define AES2550_REG80_FORCE_FINGER_PRESENT (1 << 1)
|
||||||
#define AES2550_REG80_LPO_START (1 << 2)
|
#define AES2550_REG80_LPO_START (1 << 2)
|
||||||
#define AES2550_REG80_HGC_ENABLE (1 << 3)
|
#define AES2550_REG80_HGC_ENABLE (1 << 3)
|
||||||
#define AES2550_REG80_SENSOR_MODE_OFS (4)
|
#define AES2550_REG80_SENSOR_MODE_OFS (4)
|
||||||
#define AES2550_REG80_AUTO_RESTART_FD (1 << 6)
|
#define AES2550_REG80_AUTO_RESTART_FD (1 << 6)
|
||||||
#define AES2550_REG80_EXT_REG_ENABLE (1 << 7)
|
#define AES2550_REG80_EXT_REG_ENABLE (1 << 7)
|
||||||
|
|
||||||
#define AES2550_REG81_CONT_SCAN (1 << 0)
|
#define AES2550_REG81_CONT_SCAN (1 << 0)
|
||||||
#define AES2550_REG81_READ_REG (1 << 1)
|
#define AES2550_REG81_READ_REG (1 << 1)
|
||||||
#define AES2550_REG81_NSHOT (1 << 2)
|
#define AES2550_REG81_NSHOT (1 << 2)
|
||||||
#define AES2550_REG81_RUN_FD (1 << 3)
|
#define AES2550_REG81_RUN_FD (1 << 3)
|
||||||
#define AES2550_REG81_READ_ID (1 << 4)
|
#define AES2550_REG81_READ_ID (1 << 4)
|
||||||
#define AES2550_REG81_RUN_CAL (1 << 5)
|
#define AES2550_REG81_RUN_CAL (1 << 5)
|
||||||
#define AES2550_REG81_RUN_TIMER (1 << 6)
|
#define AES2550_REG81_RUN_TIMER (1 << 6)
|
||||||
#define AES2550_REG81_RUN_BIST (1 << 7)
|
#define AES2550_REG81_RUN_BIST (1 << 7)
|
||||||
|
|
||||||
#define AES2550_REG83_FINGER_PRESENT (1 << 7)
|
#define AES2550_REG83_FINGER_PRESENT (1 << 7)
|
||||||
|
|
||||||
#define AES2550_REG85_FLUSH_PER_FRAME (1 << 7)
|
#define AES2550_REG85_FLUSH_PER_FRAME (1 << 7)
|
||||||
|
|
||||||
#define AES2550_REG8F_EDATA_DISABLE (1 << 1)
|
#define AES2550_REG8F_EDATA_DISABLE (1 << 1)
|
||||||
#define AES2550_REG8F_AUTH_DISABLE (1 << 2)
|
#define AES2550_REG8F_AUTH_DISABLE (1 << 2)
|
||||||
#define AES2550_REG8F_EHISTO_DISABLE (1 << 3)
|
#define AES2550_REG8F_EHISTO_DISABLE (1 << 3)
|
||||||
#define AES2550_REG8F_HISTO64 (1 << 4)
|
#define AES2550_REG8F_HISTO64 (1 << 4)
|
||||||
#define AES2550_REG8F_SINGLE_REG_ENABLE (1 << 6)
|
#define AES2550_REG8F_SINGLE_REG_ENABLE (1 << 6)
|
||||||
|
|
||||||
#define AES2550_REG95_COL_SCANNED_OFS (0)
|
#define AES2550_REG95_COL_SCANNED_OFS (0)
|
||||||
#define AES2550_REG95_EPIX_AVG_OFS (4)
|
#define AES2550_REG95_EPIX_AVG_OFS (4)
|
||||||
|
|
||||||
#define AES2550_REGA8_DIG_BIT_DATA_OFS (0)
|
#define AES2550_REGA8_DIG_BIT_DATA_OFS (0)
|
||||||
#define AES2550_REGA8_DIG_BIT_EN (1 << 4)
|
#define AES2550_REGA8_DIG_BIT_EN (1 << 4)
|
||||||
#define AES2550_REGA8_FIXED_BIT_DATA (1 << 5)
|
#define AES2550_REGA8_FIXED_BIT_DATA (1 << 5)
|
||||||
#define AES2550_REGA8_INVERT_BIT_DATA (1 << 6)
|
#define AES2550_REGA8_INVERT_BIT_DATA (1 << 6)
|
||||||
|
|
||||||
#define AES2550_REGAD_LPFD_AVG_OFS (0)
|
#define AES2550_REGAD_LPFD_AVG_OFS (0)
|
||||||
#define AES2550_REGAD_DETECT_FGROFF (1 << 4)
|
#define AES2550_REGAD_DETECT_FGROFF (1 << 4)
|
||||||
#define AES2550_REGAD_ADVRANGE_2V (1 << 6)
|
#define AES2550_REGAD_ADVRANGE_2V (1 << 6)
|
||||||
|
|
||||||
#define AES2550_REGB1_ATE_CONT_IMAGE (1 << 1)
|
#define AES2550_REGB1_ATE_CONT_IMAGE (1 << 1)
|
||||||
#define AES2550_REGB1_ANALOG_RESET (1 << 2)
|
#define AES2550_REGB1_ANALOG_RESET (1 << 2)
|
||||||
#define AES2550_REGB1_ANALOG_PD (1 << 3)
|
#define AES2550_REGB1_ANALOG_PD (1 << 3)
|
||||||
#define AES2550_REGB1_TEST_EMBD_WORD (1 << 4)
|
#define AES2550_REGB1_TEST_EMBD_WORD (1 << 4)
|
||||||
#define AES2550_REGB1_ORIG_EMBD_WORD (1 << 5)
|
#define AES2550_REGB1_ORIG_EMBD_WORD (1 << 5)
|
||||||
#define AES2550_REGB1_RESET_UHSM (1 << 6)
|
#define AES2550_REGB1_RESET_UHSM (1 << 6)
|
||||||
#define AES2550_REGB1_RESET_SENSOR (1 << 7)
|
#define AES2550_REGB1_RESET_SENSOR (1 << 7)
|
||||||
|
|
||||||
#define AES2550_REGBD_LPO_IN_15_8_OFS (0)
|
#define AES2550_REGBD_LPO_IN_15_8_OFS (0)
|
||||||
#define AES2550_REGBE_LPO_IN_7_0_OFS (0)
|
#define AES2550_REGBE_LPO_IN_7_0_OFS (0)
|
||||||
|
|
||||||
#define AES2550_REGBF_RSR_LEVEL_DISABLED (0 << 0)
|
#define AES2550_REGBF_RSR_LEVEL_DISABLED (0 << 0)
|
||||||
#define AES2550_REGBF_RSR_LEVEL_LEADING_RSR (1 << 0)
|
#define AES2550_REGBF_RSR_LEVEL_LEADING_RSR (1 << 0)
|
||||||
#define AES2550_REGBF_RSR_LEVEL_SIMPLE_RSR (2 << 0)
|
#define AES2550_REGBF_RSR_LEVEL_SIMPLE_RSR (2 << 0)
|
||||||
#define AES2550_REGBF_RSR_LEVEL_SUPER_RSR (3 << 0)
|
#define AES2550_REGBF_RSR_LEVEL_SUPER_RSR (3 << 0)
|
||||||
#define AES2550_REGBF_RSR_DIR_DOWN_MOTION (0 << 2)
|
#define AES2550_REGBF_RSR_DIR_DOWN_MOTION (0 << 2)
|
||||||
#define AES2550_REGBF_RSR_DIR_UP_MOTION (1 << 2)
|
#define AES2550_REGBF_RSR_DIR_UP_MOTION (1 << 2)
|
||||||
#define AES2550_REGBF_RSR_DIR_UPDOWN_MOTION (2 << 2)
|
#define AES2550_REGBF_RSR_DIR_UPDOWN_MOTION (2 << 2)
|
||||||
#define AES2550_REGBF_NOISE_FLOOR_MODE (1 << 4)
|
#define AES2550_REGBF_NOISE_FLOOR_MODE (1 << 4)
|
||||||
#define AES2550_REGBF_QUADRATURE_MODE (1 << 5)
|
#define AES2550_REGBF_QUADRATURE_MODE (1 << 5)
|
||||||
|
|
||||||
#define AES2550_REGCF_INTERFERENCE_CHK_EN (1 << 0)
|
#define AES2550_REGCF_INTERFERENCE_CHK_EN (1 << 0)
|
||||||
#define AES2550_REGCF_INTERFERENCE_AVG_EN (1 << 1)
|
#define AES2550_REGCF_INTERFERENCE_AVG_EN (1 << 1)
|
||||||
#define AES2550_REGCF_INTERFERENCE_AVG_OFFS (4)
|
#define AES2550_REGCF_INTERFERENCE_AVG_OFFS (4)
|
||||||
|
|
||||||
#define AES2550_REGDC_BP_NUM_REF_SWEEP_OFS (0)
|
#define AES2550_REGDC_BP_NUM_REF_SWEEP_OFS (0)
|
||||||
#define AES2550_REGDC_DEBUG_CTRL2_OFS (3)
|
#define AES2550_REGDC_DEBUG_CTRL2_OFS (3)
|
||||||
|
|
||||||
#define AES2550_REGDD_DEBUG_CTRL1_OFS (0)
|
#define AES2550_REGDD_DEBUG_CTRL1_OFS (0)
|
||||||
|
|
||||||
/* Commands */
|
/* Commands */
|
||||||
|
|
||||||
enum aes2550_cmds {
|
enum aes2550_cmds {
|
||||||
AES2550_CMD_SET_IDLE_MODE = 0x00,
|
AES2550_CMD_SET_IDLE_MODE = 0x00,
|
||||||
AES2550_CMD_RUN_FD = 0x01,
|
AES2550_CMD_RUN_FD = 0x01,
|
||||||
AES2550_CMD_GET_ENROLL_IMG = 0x02,
|
AES2550_CMD_GET_ENROLL_IMG = 0x02,
|
||||||
AES2550_CMD_CALIBRATE = 0x06,
|
AES2550_CMD_CALIBRATE = 0x06,
|
||||||
AES2550_CMD_READ_CALIBRATION_DATA = 0x10,
|
AES2550_CMD_READ_CALIBRATION_DATA = 0x10,
|
||||||
AES2550_CMD_HEARTBEAT = 0x70,
|
AES2550_CMD_HEARTBEAT = 0x70,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Messages */
|
/* Messages */
|
||||||
|
|
||||||
#define AES2550_STRIP_SIZE (0x31e + 3)
|
#define AES2550_STRIP_SIZE (0x31e + 3)
|
||||||
#define AES2550_HEARTBEAT_SIZE (4 + 3)
|
#define AES2550_HEARTBEAT_SIZE (4 + 3)
|
||||||
#define AES2550_EDATA_MAGIC 0xe0
|
#define AES2550_EDATA_MAGIC 0xe0
|
||||||
#define AES2550_HEARTBEAT_MAGIC 0xdb
|
#define AES2550_HEARTBEAT_MAGIC 0xdb
|
||||||
|
|
||||||
#define AES2550_EP_IN_BUF_SIZE 8192
|
#define AES2550_EP_IN_BUF_SIZE 8192
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,68 +25,73 @@
|
||||||
#include "aes2660.h"
|
#include "aes2660.h"
|
||||||
|
|
||||||
#define FRAME_WIDTH 192
|
#define FRAME_WIDTH 192
|
||||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||||
|
|
||||||
struct _FpiDeviceAes2660 {
|
struct _FpiDeviceAes2660
|
||||||
FpiDeviceAesX660 parent;
|
{
|
||||||
|
FpiDeviceAesX660 parent;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes2660, fpi_device_aes2660, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI,
|
||||||
DEVICE_AES2660, FpiDeviceAesX660);
|
DEVICE_AES2660, FpiDeviceAesX660);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes2660, fpi_device_aes2660, FPI_TYPE_DEVICE_AES_X660);
|
G_DEFINE_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI_TYPE_DEVICE_AES_X660);
|
||||||
|
|
||||||
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.frame_width = FRAME_WIDTH,
|
.frame_width = FRAME_WIDTH,
|
||||||
.frame_height = AESX660_FRAME_HEIGHT,
|
.frame_height = AESX660_FRAME_HEIGHT,
|
||||||
.image_width = IMAGE_WIDTH,
|
.image_width = IMAGE_WIDTH,
|
||||||
.get_pixel = aes_get_pixel,
|
.get_pixel = aes_get_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x08ff, .pid = 0x2660, },
|
{ .vid = 0x08ff, .pid = 0x2660, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2680, },
|
{ .vid = 0x08ff, .pid = 0x2680, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2681, },
|
{ .vid = 0x08ff, .pid = 0x2681, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2682, },
|
{ .vid = 0x08ff, .pid = 0x2682, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2683, },
|
{ .vid = 0x08ff, .pid = 0x2683, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2684, },
|
{ .vid = 0x08ff, .pid = 0x2684, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2685, },
|
{ .vid = 0x08ff, .pid = 0x2685, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2686, },
|
{ .vid = 0x08ff, .pid = 0x2686, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2687, },
|
{ .vid = 0x08ff, .pid = 0x2687, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2688, },
|
{ .vid = 0x08ff, .pid = 0x2688, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2689, },
|
{ .vid = 0x08ff, .pid = 0x2689, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268a, },
|
{ .vid = 0x08ff, .pid = 0x268a, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268b, },
|
{ .vid = 0x08ff, .pid = 0x268b, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268c, },
|
{ .vid = 0x08ff, .pid = 0x268c, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268d, },
|
{ .vid = 0x08ff, .pid = 0x268d, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268e, },
|
{ .vid = 0x08ff, .pid = 0x268e, },
|
||||||
{ .vid = 0x08ff, .pid = 0x268f, },
|
{ .vid = 0x08ff, .pid = 0x268f, },
|
||||||
{ .vid = 0x08ff, .pid = 0x2691, },
|
{ .vid = 0x08ff, .pid = 0x2691, },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes2660_init(FpiDeviceAes2660 *self) {
|
static void
|
||||||
|
fpi_device_aes2660_init (FpiDeviceAes2660 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes2660_class_init(FpiDeviceAes2660Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes2660_class_init (FpiDeviceAes2660Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes2660";
|
dev_class->id = "aes2660";
|
||||||
dev_class->full_name = "AuthenTec AES2660";
|
dev_class->full_name = "AuthenTec AES2660";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
img_class->bz3_threshold = 20;
|
img_class->bz3_threshold = 20;
|
||||||
|
|
||||||
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
|
|
||||||
aes_class->init_seqs[0] = aes2660_init_1;
|
aes_class->init_seqs[0] = aes2660_init_1;
|
||||||
aes_class->init_seqs_len[0] = G_N_ELEMENTS(aes2660_init_1);
|
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes2660_init_1);
|
||||||
aes_class->init_seqs[1] = aes2660_init_2;
|
aes_class->init_seqs[1] = aes2660_init_2;
|
||||||
aes_class->init_seqs_len[1] = G_N_ELEMENTS(aes2660_init_2);
|
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes2660_init_2);
|
||||||
aes_class->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd;
|
aes_class->start_imaging_cmd = (unsigned char *) aes2660_start_imaging_cmd;
|
||||||
aes_class->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd);
|
aes_class->start_imaging_cmd_len = sizeof (aes2660_start_imaging_cmd);
|
||||||
aes_class->assembling_ctx = &assembling_ctx;
|
aes_class->assembling_ctx = &assembling_ctx;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,123 +31,128 @@
|
||||||
|
|
||||||
#include "aes3k.h"
|
#include "aes3k.h"
|
||||||
|
|
||||||
#define DATA_BUFLEN 0x2089
|
#define DATA_BUFLEN 0x2089
|
||||||
|
|
||||||
/* image size = FRAME_WIDTH x FRAME_WIDTH */
|
/* image size = FRAME_WIDTH x FRAME_WIDTH */
|
||||||
#define FRAME_WIDTH 128
|
#define FRAME_WIDTH 128
|
||||||
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
|
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
|
||||||
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
|
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
|
||||||
#define ENLARGE_FACTOR 2
|
#define ENLARGE_FACTOR 2
|
||||||
|
|
||||||
|
|
||||||
static struct aes_regwrite init_reqs[] = {
|
static struct aes_regwrite init_reqs[] = {
|
||||||
/* master reset */
|
/* master reset */
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
/* scan reset */
|
/* scan reset */
|
||||||
{ 0x80, 0x02 },
|
{ 0x80, 0x02 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
/* disable register buffering */
|
/* disable register buffering */
|
||||||
{ 0x80, 0x04 },
|
{ 0x80, 0x04 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
/* windows driver reads registers now (81 02) */
|
/* windows driver reads registers now (81 02) */
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
|
|
||||||
/* set excitation bias current: 2mhz drive ring frequency,
|
/* set excitation bias current: 2mhz drive ring frequency,
|
||||||
* 4V drive ring voltage, 16.5mA excitation bias */
|
* 4V drive ring voltage, 16.5mA excitation bias */
|
||||||
{ 0x82, 0x04 },
|
{ 0x82, 0x04 },
|
||||||
|
|
||||||
/* continuously sample drive ring for finger detection,
|
/* continuously sample drive ring for finger detection,
|
||||||
* 62.50ms debounce delay */
|
* 62.50ms debounce delay */
|
||||||
{ 0x83, 0x13 },
|
{ 0x83, 0x13 },
|
||||||
|
|
||||||
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
|
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
|
||||||
{ 0x85, 0x3d }, /* set calibration capacitance */
|
{ 0x85, 0x3d }, /* set calibration capacitance */
|
||||||
{ 0x86, 0x03 }, /* detect drive voltage */
|
{ 0x86, 0x03 }, /* detect drive voltage */
|
||||||
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
|
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
|
||||||
{ 0x88, 0x02 }, /* set column scan period */
|
{ 0x88, 0x02 }, /* set column scan period */
|
||||||
{ 0x89, 0x02 }, /* set measure drive */
|
{ 0x89, 0x02 }, /* set measure drive */
|
||||||
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
|
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
|
||||||
{ 0x8b, 0x33 }, /* set matrix pattern */
|
{ 0x8b, 0x33 }, /* set matrix pattern */
|
||||||
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
|
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
|
||||||
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
|
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
|
||||||
{ 0x8e, 0x23 }, /* set sensor gain */
|
{ 0x8e, 0x23 }, /* set sensor gain */
|
||||||
{ 0x8f, 0x07 }, /* set image parameters */
|
{ 0x8f, 0x07 }, /* set image parameters */
|
||||||
{ 0x90, 0x00 }, /* carrier offset null */
|
{ 0x90, 0x00 }, /* carrier offset null */
|
||||||
{ 0x91, 0x1c }, /* set A/D reference high */
|
{ 0x91, 0x1c }, /* set A/D reference high */
|
||||||
{ 0x92, 0x08 }, /* set A/D reference low */
|
{ 0x92, 0x08 }, /* set A/D reference low */
|
||||||
{ 0x93, 0x00 }, /* set start row to 0 */
|
{ 0x93, 0x00 }, /* set start row to 0 */
|
||||||
{ 0x94, 0x07 }, /* set end row */
|
{ 0x94, 0x07 }, /* set end row */
|
||||||
{ 0x95, 0x00 }, /* set start column to 0 */
|
{ 0x95, 0x00 }, /* set start column to 0 */
|
||||||
{ 0x96, 0x1f }, /* set end column */
|
{ 0x96, 0x1f }, /* set end column */
|
||||||
{ 0x97, 0x04 }, /* data format and thresholds */
|
{ 0x97, 0x04 }, /* data format and thresholds */
|
||||||
{ 0x98, 0x28 }, /* image data control */
|
{ 0x98, 0x28 }, /* image data control */
|
||||||
{ 0x99, 0x00 }, /* disable general purpose outputs */
|
{ 0x99, 0x00 }, /* disable general purpose outputs */
|
||||||
{ 0x9a, 0x0b }, /* set initial scan state */
|
{ 0x9a, 0x0b }, /* set initial scan state */
|
||||||
{ 0x9b, 0x00 }, /* clear challenge word bits */
|
{ 0x9b, 0x00 }, /* clear challenge word bits */
|
||||||
{ 0x9c, 0x00 }, /* clear challenge word bits */
|
{ 0x9c, 0x00 }, /* clear challenge word bits */
|
||||||
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
||||||
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
||||||
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x81, 0x04 },
|
{ 0x81, 0x04 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FpiDeviceAes3500 {
|
struct _FpiDeviceAes3500
|
||||||
FpiDeviceAes3k parent;
|
{
|
||||||
|
FpiDeviceAes3k parent;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes3500, fpi_device_aes3500, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI,
|
||||||
DEVICE_AES3500, FpiDeviceAes3k);
|
DEVICE_AES3500, FpiDeviceAes3k);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes3500, fpi_device_aes3500, FPI_TYPE_DEVICE_AES3K);
|
G_DEFINE_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI_TYPE_DEVICE_AES3K);
|
||||||
|
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x08ff, .pid = 0x5731 },
|
{ .vid = 0x08ff, .pid = 0x5731 },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes3500_init(FpiDeviceAes3500 *self) {
|
static void
|
||||||
|
fpi_device_aes3500_init (FpiDeviceAes3500 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes3500_class_init(FpiDeviceAes3500Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes3500_class_init (FpiDeviceAes3500Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes3500";
|
dev_class->id = "aes3500";
|
||||||
dev_class->full_name = "AuthenTec AES3500";
|
dev_class->full_name = "AuthenTec AES3500";
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
|
|
||||||
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
|
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
|
||||||
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
|
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
|
||||||
|
|
||||||
aes_class->data_buflen = DATA_BUFLEN;
|
aes_class->data_buflen = DATA_BUFLEN;
|
||||||
aes_class->frame_width = FRAME_WIDTH;
|
aes_class->frame_width = FRAME_WIDTH;
|
||||||
aes_class->frame_size = FRAME_SIZE;
|
aes_class->frame_size = FRAME_SIZE;
|
||||||
aes_class->frame_number = FRAME_NUMBER;
|
aes_class->frame_number = FRAME_NUMBER;
|
||||||
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
||||||
aes_class->init_reqs = init_reqs;
|
aes_class->init_reqs = init_reqs;
|
||||||
aes_class->init_reqs_len = G_N_ELEMENTS(init_reqs);
|
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,169 +40,188 @@
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
#include "aes3k.h"
|
#include "aes3k.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
FpiUsbTransfer *img_trf;
|
{
|
||||||
gboolean deactivating;
|
FpiUsbTransfer *img_trf;
|
||||||
|
gboolean deactivating;
|
||||||
} FpiDeviceAes3kPrivate;
|
} FpiDeviceAes3kPrivate;
|
||||||
|
|
||||||
#define CTRL_TIMEOUT 1000
|
#define CTRL_TIMEOUT 1000
|
||||||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||||
|
|
||||||
static void do_capture(FpImageDevice *dev);
|
static void do_capture (FpImageDevice *dev);
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceAes3k, fpi_device_aes3k, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAes3k, fpi_device_aes3k, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
static void aes3k_assemble_image(unsigned char *input, size_t width, size_t height,
|
static void
|
||||||
unsigned char *output)
|
aes3k_assemble_image (unsigned char *input, size_t width, size_t height,
|
||||||
|
unsigned char *output)
|
||||||
{
|
{
|
||||||
size_t row, column;
|
size_t row, column;
|
||||||
|
|
||||||
for (column = 0; column < width; column++) {
|
for (column = 0; column < width; column++)
|
||||||
for (row = 0; row < height; row += 2) {
|
{
|
||||||
output[width * row + column] = (*input & 0x0f) * 17;
|
for (row = 0; row < height; row += 2)
|
||||||
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
|
{
|
||||||
input++;
|
output[width * row + column] = (*input & 0x0f) * 17;
|
||||||
}
|
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
|
||||||
}
|
input++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (device);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (device);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
unsigned char *ptr = transfer->buffer;
|
unsigned char *ptr = transfer->buffer;
|
||||||
FpImage *tmp;
|
FpImage *tmp;
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
priv->img_trf = NULL;
|
priv->img_trf = NULL;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
if (g_error_matches (error,
|
{
|
||||||
G_IO_ERROR,
|
if (g_error_matches (error,
|
||||||
G_IO_ERROR_CANCELLED)) {
|
G_IO_ERROR,
|
||||||
/* Deactivation was completed. */
|
G_IO_ERROR_CANCELLED))
|
||||||
g_error_free (error);
|
{
|
||||||
if (priv->deactivating)
|
/* Deactivation was completed. */
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
g_error_free (error);
|
||||||
return;
|
if (priv->deactivating)
|
||||||
}
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_image_device_session_error (dev, error);
|
fpi_image_device_session_error (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
|
|
||||||
tmp = fp_image_new(cls->frame_width, cls->frame_width);
|
tmp = fp_image_new (cls->frame_width, cls->frame_width);
|
||||||
tmp->width = cls->frame_width;
|
tmp->width = cls->frame_width;
|
||||||
tmp->height = cls->frame_width;
|
tmp->height = cls->frame_width;
|
||||||
tmp->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
|
tmp->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
|
||||||
for (i = 0; i < cls->frame_number; i++) {
|
for (i = 0; i < cls->frame_number; i++)
|
||||||
fp_dbg("frame header byte %02x", *ptr);
|
{
|
||||||
ptr++;
|
fp_dbg ("frame header byte %02x", *ptr);
|
||||||
aes3k_assemble_image(ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
|
ptr++;
|
||||||
ptr += cls->frame_size;
|
aes3k_assemble_image (ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
|
||||||
}
|
ptr += cls->frame_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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_image_resize(tmp, cls->enlarge_factor, cls->enlarge_factor);
|
img = fpi_image_resize (tmp, cls->enlarge_factor, cls->enlarge_factor);
|
||||||
g_object_unref (tmp);
|
g_object_unref (tmp);
|
||||||
fpi_image_device_image_captured(dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
|
|
||||||
/* FIXME: rather than assuming finger has gone, we should poll regs until
|
/* FIXME: rather than assuming finger has gone, we should poll regs until
|
||||||
* it really has, then restart the capture */
|
* it really has, then restart the capture */
|
||||||
fpi_image_device_report_finger_status(dev, FALSE);
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
|
|
||||||
do_capture(dev);
|
do_capture (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_capture(FpImageDevice *dev)
|
static void
|
||||||
|
do_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
|
|
||||||
priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
|
priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
fpi_usb_transfer_fill_bulk(priv->img_trf, EP_IN, cls->data_buflen);
|
fpi_usb_transfer_fill_bulk (priv->img_trf, EP_IN, cls->data_buflen);
|
||||||
priv->img_trf->short_is_error = TRUE;
|
priv->img_trf->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(priv->img_trf, 0,
|
fpi_usb_transfer_submit (priv->img_trf, 0,
|
||||||
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
img_cb, NULL);
|
img_cb, NULL);
|
||||||
fpi_usb_transfer_unref(priv->img_trf);
|
fpi_usb_transfer_unref (priv->img_trf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_reqs_cb(FpImageDevice *dev, GError *result, void *user_data)
|
static void
|
||||||
|
init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
|
||||||
{
|
{
|
||||||
fpi_image_device_activate_complete (dev, result);
|
fpi_image_device_activate_complete (dev, result);
|
||||||
if (!result)
|
if (!result)
|
||||||
do_capture(dev);
|
do_capture (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes3k_dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
aes3k_dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
|
|
||||||
priv->deactivating = FALSE;
|
priv->deactivating = FALSE;
|
||||||
aes_write_regv(dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
|
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes3k_dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
aes3k_dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
|
|
||||||
priv->deactivating = TRUE;
|
priv->deactivating = TRUE;
|
||||||
if (priv->img_trf)
|
if (priv->img_trf)
|
||||||
return;
|
return;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes3k_init(FpiDeviceAes3k *self) {
|
static void
|
||||||
}
|
fpi_device_aes3k_init (FpiDeviceAes3k *self)
|
||||||
|
|
||||||
static void aes3k_dev_init(FpImageDevice *dev)
|
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
|
|
||||||
fpi_image_device_open_complete(dev, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fpi_image_device_open_complete(dev, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes3k_dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
aes3k_dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
|
||||||
0, 0, &error);
|
{
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_open_complete (dev, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
aes3k_dev_deinit (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
|
0, 0, &error);
|
||||||
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fpi_device_aes3k_class_init(FpiDeviceAes3kClass *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes3k_class_init (FpiDeviceAes3kClass *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||||
|
|
||||||
img_class->img_open = aes3k_dev_init;
|
img_class->img_open = aes3k_dev_init;
|
||||||
img_class->img_close = aes3k_dev_deinit;
|
img_class->img_close = aes3k_dev_deinit;
|
||||||
img_class->activate = aes3k_dev_activate;
|
img_class->activate = aes3k_dev_activate;
|
||||||
img_class->deactivate = aes3k_dev_deactivate;
|
img_class->deactivate = aes3k_dev_deactivate;
|
||||||
|
|
||||||
/* Extremely low due to low image quality. */
|
/* Extremely low due to low image quality. */
|
||||||
img_class->bz3_threshold = 9;
|
img_class->bz3_threshold = 9;
|
||||||
|
|
||||||
/* Everything else is set by the subclasses. */
|
/* Everything else is set by the subclasses. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,22 +38,23 @@
|
||||||
#include "fpi-image-device.h"
|
#include "fpi-image-device.h"
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
|
|
||||||
#define AES3K_FRAME_HEIGHT 16
|
#define AES3K_FRAME_HEIGHT 16
|
||||||
|
|
||||||
G_DECLARE_DERIVABLE_TYPE(FpiDeviceAes3k, fpi_device_aes3k, FPI,
|
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAes3k, fpi_device_aes3k, FPI,
|
||||||
DEVICE_AES3K, FpImageDevice)
|
DEVICE_AES3K, FpImageDevice)
|
||||||
|
|
||||||
#define FPI_TYPE_DEVICE_AES3K (fpi_device_aes3k_get_type ())
|
#define FPI_TYPE_DEVICE_AES3K (fpi_device_aes3k_get_type ())
|
||||||
|
|
||||||
struct _FpiDeviceAes3kClass {
|
struct _FpiDeviceAes3kClass
|
||||||
FpImageDeviceClass parent;
|
{
|
||||||
|
FpImageDeviceClass parent;
|
||||||
|
|
||||||
gsize frame_width; /* image size = frame_width x frame_width */
|
gsize frame_width; /* image size = frame_width x frame_width */
|
||||||
gsize frame_size; /* 4 bits/pixel: frame_width x AES3K_FRAME_HEIGHT / 2 */
|
gsize frame_size; /* 4 bits/pixel: frame_width x AES3K_FRAME_HEIGHT / 2 */
|
||||||
gsize frame_number; /* number of frames */
|
gsize frame_number; /* number of frames */
|
||||||
gsize enlarge_factor;
|
gsize enlarge_factor;
|
||||||
|
|
||||||
gsize data_buflen; /* buffer length of usb bulk transfer */
|
gsize data_buflen; /* buffer length of usb bulk transfer */
|
||||||
struct aes_regwrite *init_reqs; /* initial values sent to device */
|
struct aes_regwrite *init_reqs; /* initial values sent to device */
|
||||||
gsize init_reqs_len;
|
gsize init_reqs_len;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,123 +28,128 @@
|
||||||
|
|
||||||
#include "aes3k.h"
|
#include "aes3k.h"
|
||||||
|
|
||||||
#define DATA_BUFLEN 0x1259
|
#define DATA_BUFLEN 0x1259
|
||||||
|
|
||||||
/* image size = FRAME_WIDTH x FRAME_WIDTH */
|
/* image size = FRAME_WIDTH x FRAME_WIDTH */
|
||||||
#define FRAME_WIDTH 96
|
#define FRAME_WIDTH 96
|
||||||
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
|
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
|
||||||
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
|
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
|
||||||
#define ENLARGE_FACTOR 3
|
#define ENLARGE_FACTOR 3
|
||||||
|
|
||||||
|
|
||||||
static struct aes_regwrite init_reqs[] = {
|
static struct aes_regwrite init_reqs[] = {
|
||||||
/* master reset */
|
/* master reset */
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
/* scan reset */
|
/* scan reset */
|
||||||
{ 0x80, 0x02 },
|
{ 0x80, 0x02 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
/* disable register buffering */
|
/* disable register buffering */
|
||||||
{ 0x80, 0x04 },
|
{ 0x80, 0x04 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
/* windows driver reads registers now (81 02) */
|
/* windows driver reads registers now (81 02) */
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
|
|
||||||
/* set excitation bias current: 2mhz drive ring frequency,
|
/* set excitation bias current: 2mhz drive ring frequency,
|
||||||
* 4V drive ring voltage, 16.5mA excitation bias */
|
* 4V drive ring voltage, 16.5mA excitation bias */
|
||||||
{ 0x82, 0x04 },
|
{ 0x82, 0x04 },
|
||||||
|
|
||||||
/* continuously sample drive ring for finger detection,
|
/* continuously sample drive ring for finger detection,
|
||||||
* 62.50ms debounce delay */
|
* 62.50ms debounce delay */
|
||||||
{ 0x83, 0x13 },
|
{ 0x83, 0x13 },
|
||||||
|
|
||||||
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
|
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
|
||||||
{ 0x85, 0x3d }, /* set calibration capacitance */
|
{ 0x85, 0x3d }, /* set calibration capacitance */
|
||||||
{ 0x86, 0x03 }, /* detect drive voltage */
|
{ 0x86, 0x03 }, /* detect drive voltage */
|
||||||
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
|
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
|
||||||
{ 0x88, 0x02 }, /* set column scan period */
|
{ 0x88, 0x02 }, /* set column scan period */
|
||||||
{ 0x89, 0x02 }, /* set measure drive */
|
{ 0x89, 0x02 }, /* set measure drive */
|
||||||
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
|
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
|
||||||
{ 0x8b, 0x33 }, /* set matrix pattern */
|
{ 0x8b, 0x33 }, /* set matrix pattern */
|
||||||
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
|
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
|
||||||
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
|
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
|
||||||
{ 0x8e, 0x23 }, /* set sensor gain */
|
{ 0x8e, 0x23 }, /* set sensor gain */
|
||||||
{ 0x8f, 0x07 }, /* set image parameters */
|
{ 0x8f, 0x07 }, /* set image parameters */
|
||||||
{ 0x90, 0x00 }, /* carrier offset null */
|
{ 0x90, 0x00 }, /* carrier offset null */
|
||||||
{ 0x91, 0x1c }, /* set A/D reference high */
|
{ 0x91, 0x1c }, /* set A/D reference high */
|
||||||
{ 0x92, 0x08 }, /* set A/D reference low */
|
{ 0x92, 0x08 }, /* set A/D reference low */
|
||||||
{ 0x93, 0x00 }, /* set start row to 0 */
|
{ 0x93, 0x00 }, /* set start row to 0 */
|
||||||
{ 0x94, 0x05 }, /* set end row to 5 */
|
{ 0x94, 0x05 }, /* set end row to 5 */
|
||||||
{ 0x95, 0x00 }, /* set start column to 0 */
|
{ 0x95, 0x00 }, /* set start column to 0 */
|
||||||
{ 0x96, 0x18 }, /* set end column to 24*4=96 */
|
{ 0x96, 0x18 }, /* set end column to 24*4=96 */
|
||||||
{ 0x97, 0x04 }, /* data format and thresholds */
|
{ 0x97, 0x04 }, /* data format and thresholds */
|
||||||
{ 0x98, 0x28 }, /* image data control */
|
{ 0x98, 0x28 }, /* image data control */
|
||||||
{ 0x99, 0x00 }, /* disable general purpose outputs */
|
{ 0x99, 0x00 }, /* disable general purpose outputs */
|
||||||
{ 0x9a, 0x0b }, /* set initial scan state */
|
{ 0x9a, 0x0b }, /* set initial scan state */
|
||||||
{ 0x9b, 0x00 }, /* clear challenge word bits */
|
{ 0x9b, 0x00 }, /* clear challenge word bits */
|
||||||
{ 0x9c, 0x00 }, /* clear challenge word bits */
|
{ 0x9c, 0x00 }, /* clear challenge word bits */
|
||||||
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
||||||
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
||||||
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x81, 0x04 },
|
{ 0x81, 0x04 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FpiDeviceAes4000 {
|
struct _FpiDeviceAes4000
|
||||||
FpiDeviceAes3k parent;
|
{
|
||||||
|
FpiDeviceAes3k parent;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes4000, fpi_device_aes4000, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI,
|
||||||
DEVICE_AES4000, FpiDeviceAes3k);
|
DEVICE_AES4000, FpiDeviceAes3k);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
|
G_DEFINE_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
|
||||||
|
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .pid = 0x08ff, .vid = 0x5501 },
|
{ .pid = 0x08ff, .vid = 0x5501 },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes4000_init(FpiDeviceAes4000 *self) {
|
static void
|
||||||
|
fpi_device_aes4000_init (FpiDeviceAes4000 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes4000_class_init(FpiDeviceAes4000Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes4000_class_init (FpiDeviceAes4000Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes4000";
|
dev_class->id = "aes4000";
|
||||||
dev_class->full_name = "AuthenTec AES4000";
|
dev_class->full_name = "AuthenTec AES4000";
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
|
|
||||||
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
|
img_class->img_height = FRAME_WIDTH * ENLARGE_FACTOR;
|
||||||
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
|
img_class->img_width = FRAME_WIDTH * ENLARGE_FACTOR;
|
||||||
|
|
||||||
aes_class->data_buflen = DATA_BUFLEN;
|
aes_class->data_buflen = DATA_BUFLEN;
|
||||||
aes_class->frame_width = FRAME_WIDTH;
|
aes_class->frame_width = FRAME_WIDTH;
|
||||||
aes_class->frame_size = FRAME_SIZE;
|
aes_class->frame_size = FRAME_SIZE;
|
||||||
aes_class->frame_number = FRAME_NUMBER;
|
aes_class->frame_number = FRAME_NUMBER;
|
||||||
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
aes_class->enlarge_factor = ENLARGE_FACTOR;
|
||||||
aes_class->init_reqs = init_reqs;
|
aes_class->init_reqs = init_reqs;
|
||||||
aes_class->init_reqs_len = G_N_ELEMENTS(init_reqs);
|
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,131 +28,145 @@
|
||||||
#include "fpi-assembling.h"
|
#include "fpi-assembling.h"
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
|
|
||||||
#define MAX_REGWRITES_PER_REQUEST 16
|
#define MAX_REGWRITES_PER_REQUEST 16
|
||||||
|
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||||
|
|
||||||
struct write_regv_data {
|
struct write_regv_data
|
||||||
unsigned int num_regs;
|
{
|
||||||
const struct aes_regwrite *regs;
|
unsigned int num_regs;
|
||||||
unsigned int offset;
|
const struct aes_regwrite *regs;
|
||||||
aes_write_regv_cb callback;
|
unsigned int offset;
|
||||||
void *user_data;
|
aes_write_regv_cb callback;
|
||||||
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdata);
|
static void continue_write_regv (FpImageDevice *dev,
|
||||||
|
struct write_regv_data *wdata);
|
||||||
|
|
||||||
/* libusb bulk callback for regv write completion transfer. continues the
|
/* libusb bulk callback for regv write completion transfer. continues the
|
||||||
* transaction */
|
* transaction */
|
||||||
static void write_regv_trf_complete(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
write_regv_trf_complete (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct write_regv_data *wdata = user_data;
|
struct write_regv_data *wdata = user_data;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
wdata->callback(FP_IMAGE_DEVICE (device), error, wdata->user_data);
|
{
|
||||||
g_free(wdata);
|
wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
|
||||||
} else {
|
g_free (wdata);
|
||||||
continue_write_regv(FP_IMAGE_DEVICE (device), wdata);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
continue_write_regv (FP_IMAGE_DEVICE (device), wdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write from wdata->offset to upper_bound (inclusive) of wdata->regs */
|
/* write from wdata->offset to upper_bound (inclusive) of wdata->regs */
|
||||||
static void do_write_regv(FpImageDevice *dev, struct write_regv_data *wdata, int upper_bound)
|
static void
|
||||||
|
do_write_regv (FpImageDevice *dev, struct write_regv_data *wdata, int upper_bound)
|
||||||
{
|
{
|
||||||
unsigned int offset = wdata->offset;
|
unsigned int offset = wdata->offset;
|
||||||
unsigned int num = upper_bound - offset + 1;
|
unsigned int num = upper_bound - offset + 1;
|
||||||
size_t alloc_size = num * 2;
|
size_t alloc_size = num * 2;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t data_offset = 0;
|
size_t data_offset = 0;
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE (dev));
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_OUT, alloc_size);
|
fpi_usb_transfer_fill_bulk (transfer, EP_OUT, alloc_size);
|
||||||
|
|
||||||
for (i = offset; i < offset + num; i++) {
|
for (i = offset; i < offset + num; i++)
|
||||||
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
{
|
||||||
transfer->buffer[data_offset++] = regwrite->reg;
|
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
||||||
transfer->buffer[data_offset++] = regwrite->value;
|
transfer->buffer[data_offset++] = regwrite->reg;
|
||||||
}
|
transfer->buffer[data_offset++] = regwrite->value;
|
||||||
|
}
|
||||||
|
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
write_regv_trf_complete, wdata);
|
write_regv_trf_complete, wdata);
|
||||||
fpi_usb_transfer_unref (transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the next batch of registers to be written, or if there are no more,
|
/* write the next batch of registers to be written, or if there are no more,
|
||||||
* indicate completion to the caller */
|
* indicate completion to the caller */
|
||||||
static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdata)
|
static void
|
||||||
|
continue_write_regv (FpImageDevice *dev, struct write_regv_data *wdata)
|
||||||
{
|
{
|
||||||
unsigned int offset = wdata->offset;
|
unsigned int offset = wdata->offset;
|
||||||
unsigned int regs_remaining;
|
unsigned int regs_remaining;
|
||||||
unsigned int limit;
|
unsigned int limit;
|
||||||
unsigned int upper_bound;
|
unsigned int upper_bound;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* skip all zeros and ensure there is still work to do */
|
/* skip all zeros and ensure there is still work to do */
|
||||||
while (TRUE) {
|
while (TRUE)
|
||||||
if (offset >= wdata->num_regs) {
|
{
|
||||||
fp_dbg("all registers written");
|
if (offset >= wdata->num_regs)
|
||||||
wdata->callback(dev, 0, wdata->user_data);
|
{
|
||||||
g_free(wdata);
|
fp_dbg ("all registers written");
|
||||||
return;
|
wdata->callback (dev, 0, wdata->user_data);
|
||||||
}
|
g_free (wdata);
|
||||||
if (wdata->regs[offset].reg)
|
return;
|
||||||
break;
|
}
|
||||||
offset++;
|
if (wdata->regs[offset].reg)
|
||||||
}
|
break;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
wdata->offset = offset;
|
wdata->offset = offset;
|
||||||
regs_remaining = wdata->num_regs - offset;
|
regs_remaining = wdata->num_regs - offset;
|
||||||
limit = MIN(regs_remaining, MAX_REGWRITES_PER_REQUEST);
|
limit = MIN (regs_remaining, MAX_REGWRITES_PER_REQUEST);
|
||||||
upper_bound = offset + limit - 1;
|
upper_bound = offset + limit - 1;
|
||||||
|
|
||||||
/* determine if we can write the entire of the regs at once, or if there
|
/* determine if we can write the entire of the regs at once, or if there
|
||||||
* is a zero dividing things up */
|
* is a zero dividing things up */
|
||||||
for (i = offset; i <= upper_bound; i++)
|
for (i = offset; i <= upper_bound; i++)
|
||||||
if (!wdata->regs[i].reg) {
|
if (!wdata->regs[i].reg)
|
||||||
upper_bound = i - 1;
|
{
|
||||||
break;
|
upper_bound = i - 1;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
do_write_regv(dev, wdata, upper_bound);
|
do_write_regv (dev, wdata, upper_bound);
|
||||||
|
|
||||||
wdata->offset = upper_bound + 1;
|
wdata->offset = upper_bound + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write a load of registers to the device, combining multiple writes in a
|
/* write a load of registers to the device, combining multiple writes in a
|
||||||
* single URB up to a limit. insert writes to non-existent register 0 to force
|
* single URB up to a limit. insert writes to non-existent register 0 to force
|
||||||
* specific groups of writes to be separated by different URBs. */
|
* specific groups of writes to be separated by different URBs. */
|
||||||
void aes_write_regv(FpImageDevice *dev, const struct aes_regwrite *regs,
|
void
|
||||||
unsigned int num_regs, aes_write_regv_cb callback,
|
aes_write_regv (FpImageDevice *dev, const struct aes_regwrite *regs,
|
||||||
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;
|
||||||
|
|
||||||
fp_dbg("write %d regs", num_regs);
|
fp_dbg ("write %d regs", num_regs);
|
||||||
wdata = g_malloc(sizeof(*wdata));
|
wdata = g_malloc (sizeof (*wdata));
|
||||||
wdata->num_regs = num_regs;
|
wdata->num_regs = num_regs;
|
||||||
wdata->regs = regs;
|
wdata->regs = regs;
|
||||||
wdata->offset = 0;
|
wdata->offset = 0;
|
||||||
wdata->callback = callback;
|
wdata->callback = callback;
|
||||||
wdata->user_data = user_data;
|
wdata->user_data = user_data;
|
||||||
continue_write_regv(dev, wdata);
|
continue_write_regv (dev, wdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
unsigned char
|
||||||
struct fpi_frame *frame,
|
aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
|
||||||
unsigned int x,
|
struct fpi_frame *frame,
|
||||||
unsigned int y)
|
unsigned int x,
|
||||||
|
unsigned int y)
|
||||||
{
|
{
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
|
|
||||||
ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)];
|
ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)];
|
||||||
ret = y % 2 ? ret >> 4 : ret & 0xf;
|
ret = y % 2 ? ret >> 4 : ret & 0xf;
|
||||||
ret *= 17;
|
ret *= 17;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,25 +22,28 @@
|
||||||
|
|
||||||
#include <fprint.h>
|
#include <fprint.h>
|
||||||
|
|
||||||
struct aes_regwrite {
|
struct aes_regwrite
|
||||||
unsigned char reg;
|
{
|
||||||
unsigned char value;
|
unsigned char reg;
|
||||||
|
unsigned char value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fpi_frame;
|
struct fpi_frame;
|
||||||
struct fpi_frame_asmbl_ctx;
|
struct fpi_frame_asmbl_ctx;
|
||||||
|
|
||||||
typedef void (*aes_write_regv_cb)(FpImageDevice *dev, GError *error,
|
typedef void (*aes_write_regv_cb)(FpImageDevice *dev,
|
||||||
void *user_data);
|
GError *error,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
void aes_write_regv(FpImageDevice *dev, const struct aes_regwrite *regs,
|
void aes_write_regv (FpImageDevice *dev,
|
||||||
unsigned int num_regs, aes_write_regv_cb callback,
|
const struct aes_regwrite *regs,
|
||||||
void *user_data);
|
unsigned int num_regs,
|
||||||
|
aes_write_regv_cb callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
unsigned char aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
|
||||||
struct fpi_frame *frame,
|
struct fpi_frame *frame,
|
||||||
unsigned int x,
|
unsigned int x,
|
||||||
unsigned int y);
|
unsigned int y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,69 +42,70 @@
|
||||||
|
|
||||||
#define AESX660_FRAME_HEIGHT 8
|
#define AESX660_FRAME_HEIGHT 8
|
||||||
|
|
||||||
G_DECLARE_DERIVABLE_TYPE(FpiDeviceAesX660, fpi_device_aes_x660, FPI,
|
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAesX660, fpi_device_aes_x660, FPI,
|
||||||
DEVICE_AES_X660, FpImageDevice)
|
DEVICE_AES_X660, FpImageDevice)
|
||||||
|
|
||||||
#define FPI_TYPE_DEVICE_AES_X660 (fpi_device_aes_x660_get_type ())
|
#define FPI_TYPE_DEVICE_AES_X660 (fpi_device_aes_x660_get_type ())
|
||||||
|
|
||||||
struct _FpiDeviceAesX660Class {
|
struct _FpiDeviceAesX660Class
|
||||||
FpImageDeviceClass parent;
|
{
|
||||||
|
FpImageDeviceClass parent;
|
||||||
|
|
||||||
struct aesX660_cmd *init_seqs[2];
|
struct aesX660_cmd *init_seqs[2];
|
||||||
gsize init_seqs_len[2];
|
gsize init_seqs_len[2];
|
||||||
guint8 *start_imaging_cmd;
|
guint8 *start_imaging_cmd;
|
||||||
gsize start_imaging_cmd_len;
|
gsize start_imaging_cmd_len;
|
||||||
struct fpi_frame_asmbl_ctx *assembling_ctx;
|
struct fpi_frame_asmbl_ctx *assembling_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct aesX660_cmd {
|
struct aesX660_cmd
|
||||||
|
{
|
||||||
const guint8 *cmd;
|
const guint8 *cmd;
|
||||||
gsize len;
|
gsize len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 0x77 cmd seems to control LED, this sequence
|
/* 0x77 cmd seems to control LED, this sequence
|
||||||
* makes LED blink
|
* makes LED blink
|
||||||
*/
|
*/
|
||||||
static const guint8 led_blink_cmd[] = {
|
static const guint8 led_blink_cmd[] = {
|
||||||
0x77, 0x18, 0x00,
|
0x77, 0x18, 0x00,
|
||||||
0x00, 0x3f, 0x00, 0xff, 0x00,
|
0x00, 0x3f, 0x00, 0xff, 0x00,
|
||||||
0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00,
|
0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00,
|
||||||
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3,
|
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3,
|
||||||
0x01, 0x00, 0x7f
|
0x01, 0x00, 0x7f
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This sequence makes LED light solid
|
/* This sequence makes LED light solid
|
||||||
*/
|
*/
|
||||||
static const guint8 led_solid_cmd[] = {
|
static const guint8 led_solid_cmd[] = {
|
||||||
0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00,
|
0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00,
|
||||||
0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00,
|
0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00,
|
||||||
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x7f
|
0x00, 0x00, 0x7f
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint8 wait_for_finger_cmd[] = {
|
static const guint8 wait_for_finger_cmd[] = {
|
||||||
0x20,
|
0x20,
|
||||||
0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32
|
0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 0x40 cmd response
|
/* 0x40 cmd response
|
||||||
*
|
*
|
||||||
static const guint8 pkt1371[] = {
|
static const guint8 pkt1371[] = {
|
||||||
0x40, 0x01, 0x00, 0x01
|
0x40, 0x01, 0x00, 0x01
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const guint8 set_idle_cmd[] = {
|
static const guint8 set_idle_cmd[] = {
|
||||||
0x0d, /* Reset or "set idle"? */
|
0x0d, /* Reset or "set idle"? */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint8 read_id_cmd[] = {
|
static const guint8 read_id_cmd[] = {
|
||||||
0x44, 0x02, 0x00, 0x08, 0x00, /* Max transfer size is 8 */
|
0x44, 0x02, 0x00, 0x08, 0x00, /* Max transfer size is 8 */
|
||||||
0x07, /* Read ID? */
|
0x07, /* Read ID? */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint8 calibrate_cmd[] = {
|
static const guint8 calibrate_cmd[] = {
|
||||||
0x44, 0x02, 0x00, 0x04, 0x00,
|
0x44, 0x02, 0x00, 0x04, 0x00,
|
||||||
0x06,
|
0x06,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,27 +21,27 @@
|
||||||
#define __DRIVER_IDS
|
#define __DRIVER_IDS
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UPEKTS_ID = 1,
|
UPEKTS_ID = 1,
|
||||||
URU4000_ID = 2,
|
URU4000_ID = 2,
|
||||||
AES4000_ID = 3,
|
AES4000_ID = 3,
|
||||||
AES2501_ID = 4,
|
AES2501_ID = 4,
|
||||||
UPEKTC_ID = 5,
|
UPEKTC_ID = 5,
|
||||||
AES1610_ID = 6,
|
AES1610_ID = 6,
|
||||||
/* FDU2000_ID = 7, */
|
/* FDU2000_ID = 7, */
|
||||||
VCOM5S_ID = 8,
|
VCOM5S_ID = 8,
|
||||||
UPEKSONLY_ID = 9,
|
UPEKSONLY_ID = 9,
|
||||||
VFS101_ID = 10,
|
VFS101_ID = 10,
|
||||||
VFS301_ID = 11,
|
VFS301_ID = 11,
|
||||||
AES2550_ID = 12,
|
AES2550_ID = 12,
|
||||||
/* UPEKE2_ID = 13 */
|
/* UPEKE2_ID = 13 */
|
||||||
AES1660_ID = 14,
|
AES1660_ID = 14,
|
||||||
AES2660_ID = 15,
|
AES2660_ID = 15,
|
||||||
AES3500_ID = 16,
|
AES3500_ID = 16,
|
||||||
UPEKTC_IMG_ID = 17,
|
UPEKTC_IMG_ID = 17,
|
||||||
ETES603_ID = 18,
|
ETES603_ID = 18,
|
||||||
VFS5011_ID = 19,
|
VFS5011_ID = 19,
|
||||||
VFS0050_ID = 20,
|
VFS0050_ID = 20,
|
||||||
ELAN_ID = 21,
|
ELAN_ID = 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -71,155 +71,158 @@
|
||||||
#define ELAN_CMD_TIMEOUT 10000
|
#define ELAN_CMD_TIMEOUT 10000
|
||||||
#define ELAN_FINGER_TIMEOUT 200
|
#define ELAN_FINGER_TIMEOUT 200
|
||||||
|
|
||||||
struct elan_cmd {
|
struct elan_cmd
|
||||||
unsigned char cmd[ELAN_CMD_LEN];
|
{
|
||||||
int response_len;
|
unsigned char cmd[ELAN_CMD_LEN];
|
||||||
int response_in;
|
int response_len;
|
||||||
unsigned short devices;
|
int response_in;
|
||||||
gboolean never_cancel;
|
unsigned short devices;
|
||||||
|
gboolean never_cancel;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_sensor_dim_cmd = {
|
static const struct elan_cmd get_sensor_dim_cmd = {
|
||||||
.cmd = {0x00, 0x0c},
|
.cmd = {0x00, 0x0c},
|
||||||
.response_len = 0x4,
|
.response_len = 0x4,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_fw_ver_cmd = {
|
static const struct elan_cmd get_fw_ver_cmd = {
|
||||||
.cmd = {0x40, 0x19},
|
.cmd = {0x40, 0x19},
|
||||||
.response_len = 0x2,
|
.response_len = 0x2,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* unknown, returns 0x0 0x1 on 0907 */
|
/* unknown, returns 0x0 0x1 on 0907 */
|
||||||
static const struct elan_cmd activate_cmd_1 = {
|
static const struct elan_cmd activate_cmd_1 = {
|
||||||
.cmd = {0x40, 0x2a},
|
.cmd = {0x40, 0x2a},
|
||||||
.response_len = 0x2,
|
.response_len = 0x2,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_0907,
|
.devices = ELAN_0907,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_image_cmd = {
|
static const struct elan_cmd get_image_cmd = {
|
||||||
.cmd = {0x00, 0x09},
|
.cmd = {0x00, 0x09},
|
||||||
/* raw frame sizes are calculated from image dimensions reported by the
|
/* raw frame sizes are calculated from image dimensions reported by the
|
||||||
* device */
|
* device */
|
||||||
.response_len = -1,
|
.response_len = -1,
|
||||||
.response_in = ELAN_EP_IMG_IN,
|
.response_in = ELAN_EP_IMG_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd read_sensor_status_cmd = {
|
static const struct elan_cmd read_sensor_status_cmd = {
|
||||||
.cmd = {0x40, 0x13},
|
.cmd = {0x40, 0x13},
|
||||||
.response_len = 0x1,
|
.response_len = 0x1,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_calib_status_cmd = {
|
static const struct elan_cmd get_calib_status_cmd = {
|
||||||
.cmd = {0x40, 0x23},
|
.cmd = {0x40, 0x23},
|
||||||
.response_len = 0x1,
|
.response_len = 0x1,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd get_calib_mean_cmd = {
|
static const struct elan_cmd get_calib_mean_cmd = {
|
||||||
.cmd = {0x40, 0x24},
|
.cmd = {0x40, 0x24},
|
||||||
.response_len = 0x2,
|
.response_len = 0x2,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct elan_cmd led_on_cmd = {
|
static const struct elan_cmd led_on_cmd = {
|
||||||
.cmd = {0x40, 0x31},
|
.cmd = {0x40, 0x31},
|
||||||
.response_len = ELAN_CMD_SKIP_READ,
|
.response_len = ELAN_CMD_SKIP_READ,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* wait for finger
|
/* wait for finger
|
||||||
* subsequent read will not complete until finger is placed on the reader */
|
* 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 pre_scan_cmd = {
|
||||||
.cmd = {0x40, 0x3f},
|
.cmd = {0x40, 0x3f},
|
||||||
.response_len = 0x1,
|
.response_len = 0x1,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* led off, stop waiting for finger */
|
/* led off, stop waiting for finger */
|
||||||
static const struct elan_cmd stop_cmd = {
|
static const struct elan_cmd stop_cmd = {
|
||||||
.cmd = {0x00, 0x0b},
|
.cmd = {0x00, 0x0b},
|
||||||
.response_len = ELAN_CMD_SKIP_READ,
|
.response_len = ELAN_CMD_SKIP_READ,
|
||||||
.response_in = ELAN_EP_CMD_IN,
|
.response_in = ELAN_EP_CMD_IN,
|
||||||
.devices = ELAN_ALL_DEV,
|
.devices = ELAN_ALL_DEV,
|
||||||
.never_cancel = TRUE,
|
.never_cancel = TRUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpIdEntry elan_id_table [ ] = {
|
static const FpIdEntry elan_id_table[] = {
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0903, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0903, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0907, .driver_data = ELAN_0907},
|
{.vid = ELAN_VEND_ID, .pid = 0x0907, .driver_data = ELAN_0907},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c01, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c01, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c02, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c02, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c03, .driver_data = ELAN_0C03},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c03, .driver_data = ELAN_0C03},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c04, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c04, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c05, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c05, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c06, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c06, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c07, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c07, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c08, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c08, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c09, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c09, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0a, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0a, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0b, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0b, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0c, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0c, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0d, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0e, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0e, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c0f, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c0f, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c10, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c10, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c11, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c11, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c12, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c12, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c13, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c13, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c14, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c14, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c15, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c15, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c16, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c16, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c17, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c17, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c18, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c18, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c19, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c19, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1a, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1a, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1b, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1b, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1c, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1c, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1d, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1e, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1e, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c1f, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c1f, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c20, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c20, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c21, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c21, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c22, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c22, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c23, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c23, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c24, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c24, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c25, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c25, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c26, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c26, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c27, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c27, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c28, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c28, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c29, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c29, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2a, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2a, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2b, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2b, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2c, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2c, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2d, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2d, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2e, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2e, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c2f, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c2f, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c30, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c30, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c31, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c31, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
|
||||||
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
|
||||||
{.vid = 0, .pid = 0, .driver_data = 0},
|
{.vid = 0, .pid = 0, .driver_data = 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void elan_cmd_done(FpiSsm *ssm);
|
static void elan_cmd_done (FpiSsm *ssm);
|
||||||
static void elan_cmd_read(FpiSsm *ssm, FpDevice *dev);
|
static void elan_cmd_read (FpiSsm *ssm,
|
||||||
|
FpDevice *dev);
|
||||||
|
|
||||||
static void elan_calibrate(FpDevice *dev);
|
static void elan_calibrate (FpDevice *dev);
|
||||||
static void elan_capture(FpDevice *dev);
|
static void elan_capture (FpDevice *dev);
|
||||||
|
|
||||||
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state);
|
static void dev_change_state (FpImageDevice *dev,
|
||||||
|
FpImageDeviceState state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,107 +21,107 @@
|
||||||
#define _BMKT_H_
|
#define _BMKT_H_
|
||||||
|
|
||||||
/**< User ID maximum length allowed */
|
/**< User ID maximum length allowed */
|
||||||
#define BMKT_MAX_USER_ID_LEN 100
|
#define BMKT_MAX_USER_ID_LEN 100
|
||||||
/**< Software Part Number length */
|
/**< Software Part Number length */
|
||||||
#define BMKT_PART_NUM_LEN 10
|
#define BMKT_PART_NUM_LEN 10
|
||||||
/**< Software supplier identification length */
|
/**< Software supplier identification length */
|
||||||
#define BMKT_SUPPLIER_ID_LEN 2
|
#define BMKT_SUPPLIER_ID_LEN 2
|
||||||
|
|
||||||
/**< Maximum namber of templates for storing in internal flash of the fingerprint sensor */
|
/**< Maximum namber of templates for storing in internal flash of the fingerprint sensor */
|
||||||
#define BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH 15
|
#define BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH 15
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "bmkt_response.h"
|
#include "bmkt_response.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
** Type definition for result
|
** Type definition for result
|
||||||
*/
|
*/
|
||||||
/** No error; Operation successfully completed. */
|
/** No error; Operation successfully completed. */
|
||||||
#define BMKT_SUCCESS 0
|
#define BMKT_SUCCESS 0
|
||||||
/** Fingerprint system not initialized */
|
/** Fingerprint system not initialized */
|
||||||
#define BMKT_FP_SYSTEM_NOT_INITIALIZED 101
|
#define BMKT_FP_SYSTEM_NOT_INITIALIZED 101
|
||||||
/** Fingerprint system busy performing another operation */
|
/** Fingerprint system busy performing another operation */
|
||||||
#define BMKT_FP_SYSTEM_BUSY 102
|
#define BMKT_FP_SYSTEM_BUSY 102
|
||||||
/** Operation not allowed */
|
/** Operation not allowed */
|
||||||
#define BMKT_OPERATION_DENIED 103
|
#define BMKT_OPERATION_DENIED 103
|
||||||
/** System ran out of memory while performing operation */
|
/** System ran out of memory while performing operation */
|
||||||
#define BMKT_OUT_OF_MEMORY 104
|
#define BMKT_OUT_OF_MEMORY 104
|
||||||
/** Corrupt message, CRC check fail or truncated message */
|
/** Corrupt message, CRC check fail or truncated message */
|
||||||
#define BMKT_CORRUPT_MESSAGE 110
|
#define BMKT_CORRUPT_MESSAGE 110
|
||||||
/** One of the command parameters is outside the range of valid values */
|
/** One of the command parameters is outside the range of valid values */
|
||||||
#define BMKT_INVALID_PARAM 111
|
#define BMKT_INVALID_PARAM 111
|
||||||
/** Unrecognized message or message with invalid message ID */
|
/** Unrecognized message or message with invalid message ID */
|
||||||
#define BMKT_UNRECOGNIZED_MESSAGE 112
|
#define BMKT_UNRECOGNIZED_MESSAGE 112
|
||||||
/** Operation time out */
|
/** Operation time out */
|
||||||
#define BMKT_OP_TIME_OUT 113
|
#define BMKT_OP_TIME_OUT 113
|
||||||
/** General error – cause of error cannot be determined */
|
/** General error – cause of error cannot be determined */
|
||||||
#define BMKT_GENERAL_ERROR 114
|
#define BMKT_GENERAL_ERROR 114
|
||||||
|
|
||||||
#define BMKT_SET_SECURITY_LEVEL_FAIL 120
|
#define BMKT_SET_SECURITY_LEVEL_FAIL 120
|
||||||
#define BMKT_GET_SECURITY_LEVEL_FAIL 121
|
#define BMKT_GET_SECURITY_LEVEL_FAIL 121
|
||||||
|
|
||||||
/** Fingerprint sensor reset while operation was being performed */
|
/** Fingerprint sensor reset while operation was being performed */
|
||||||
#define BMKT_SENSOR_RESET 201
|
#define BMKT_SENSOR_RESET 201
|
||||||
/** Fingerprint sensor malfunctioned */
|
/** Fingerprint sensor malfunctioned */
|
||||||
#define BMKT_SENSOR_MALFUNCTION 202
|
#define BMKT_SENSOR_MALFUNCTION 202
|
||||||
/** Fingerprint sensor cannot be accessed despite repeated attempts */
|
/** Fingerprint sensor cannot be accessed despite repeated attempts */
|
||||||
#define BMKT_SENSOR_TAMPERED 203
|
#define BMKT_SENSOR_TAMPERED 203
|
||||||
/**
|
/**
|
||||||
* BMKT_SENSOR_NOT_INIT:
|
* BMKT_SENSOR_NOT_INIT:
|
||||||
* Fingerprint sensor module not initialized yet – not ready for use
|
* Fingerprint sensor module not initialized yet – not ready for use
|
||||||
* (different from error code 101 which indicates that the entire system
|
* (different from error code 101 which indicates that the entire system
|
||||||
* has not been initialized)
|
* has not been initialized)
|
||||||
*/
|
*/
|
||||||
#define BMKT_SENSOR_NOT_INIT 204
|
#define BMKT_SENSOR_NOT_INIT 204
|
||||||
/** Number of re-pairing operations exceeded limit or re-pairing has been disabled */
|
/** Number of re-pairing operations exceeded limit or re-pairing has been disabled */
|
||||||
#define BMKT_OWNERSHIP_RESET_MAX_EXCEEDED 205
|
#define BMKT_OWNERSHIP_RESET_MAX_EXCEEDED 205
|
||||||
/**
|
/**
|
||||||
* BMKT_SENSOR_STIMULUS_ERROR:
|
* BMKT_SENSOR_STIMULUS_ERROR:
|
||||||
* There is a finger or debris on the sensor that needs to be removed
|
* There is a finger or debris on the sensor that needs to be removed
|
||||||
* before issuing this command
|
* before issuing this command
|
||||||
*/
|
*/
|
||||||
#define BMKT_SENSOR_STIMULUS_ERROR 213
|
#define BMKT_SENSOR_STIMULUS_ERROR 213
|
||||||
/**
|
/**
|
||||||
* BMKT_CORRUPT_TEMPLATE_DATA:
|
* BMKT_CORRUPT_TEMPLATE_DATA:
|
||||||
* One of the fingerprint templates stored on flash is corrupt.
|
* One of the fingerprint templates stored on flash is corrupt.
|
||||||
* This error code is returned in case of failure in finding a fingerprint match
|
* 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
|
* during identify or verify operations while also detecting that one or more
|
||||||
* fingerprint templates stored on the flash has become corrupted
|
* fingerprint templates stored on the flash has become corrupted
|
||||||
*/
|
*/
|
||||||
#define BMKT_CORRUPT_TEMPLATE_DATA 300
|
#define BMKT_CORRUPT_TEMPLATE_DATA 300
|
||||||
/** Failed to extract features from fingerprint image acquired by sensor */
|
/** Failed to extract features from fingerprint image acquired by sensor */
|
||||||
#define BMKT_FEATURE_EXTRACT_FAIL 301
|
#define BMKT_FEATURE_EXTRACT_FAIL 301
|
||||||
/** Failed to generate fingerprint template */
|
/** Failed to generate fingerprint template */
|
||||||
#define BMKT_ENROLL_FAIL 302
|
#define BMKT_ENROLL_FAIL 302
|
||||||
/** Specified finger already enrolled for this user */
|
/** Specified finger already enrolled for this user */
|
||||||
#define BMKT_ENROLLMENT_EXISTS 303
|
#define BMKT_ENROLLMENT_EXISTS 303
|
||||||
/** Invalid fingerprint image */
|
/** Invalid fingerprint image */
|
||||||
#define BMKT_INVALID_FP_IMAGE 304
|
#define BMKT_INVALID_FP_IMAGE 304
|
||||||
/** No matching user fingerprint template found in database */
|
/** No matching user fingerprint template found in database */
|
||||||
#define BMKT_FP_NO_MATCH 404
|
#define BMKT_FP_NO_MATCH 404
|
||||||
/** Fingerprint database is full */
|
/** Fingerprint database is full */
|
||||||
#define BMKT_FP_DATABASE_FULL 501
|
#define BMKT_FP_DATABASE_FULL 501
|
||||||
/** Fingerprint database is empty */
|
/** Fingerprint database is empty */
|
||||||
#define BMKT_FP_DATABASE_EMPTY 502
|
#define BMKT_FP_DATABASE_EMPTY 502
|
||||||
/** Cannot access fingerprint database */
|
/** Cannot access fingerprint database */
|
||||||
#define BMKT_FP_DATABASE_ACCESS_FAIL 503
|
#define BMKT_FP_DATABASE_ACCESS_FAIL 503
|
||||||
/** Fingerprint template record does not exist */
|
/** Fingerprint template record does not exist */
|
||||||
#define BMKT_FP_DATABASE_NO_RECORD_EXISTS 504
|
#define BMKT_FP_DATABASE_NO_RECORD_EXISTS 504
|
||||||
/** Failed to read/write system parameters stored on flash */
|
/** Failed to read/write system parameters stored on flash */
|
||||||
#define BMKT_FP_PARAM_ACCESS_FAIL 505
|
#define BMKT_FP_PARAM_ACCESS_FAIL 505
|
||||||
/** Fingerprint is a spoof */
|
/** Fingerprint is a spoof */
|
||||||
#define BMKT_FP_SPOOF_ALERT 801
|
#define BMKT_FP_SPOOF_ALERT 801
|
||||||
/** Anti-spoof module failure */
|
/** Anti-spoof module failure */
|
||||||
#define BMKT_ANTI_SPOOF_MODULE_FAIL 802
|
#define BMKT_ANTI_SPOOF_MODULE_FAIL 802
|
||||||
|
|
||||||
#define BMKT_CORRUPT_UPDATE_IMAGE 901
|
#define BMKT_CORRUPT_UPDATE_IMAGE 901
|
||||||
#define BMKT_SYSTEM_UPDATE_FAIL 902
|
#define BMKT_SYSTEM_UPDATE_FAIL 902
|
||||||
|
|
||||||
#define BMKT_EVENT_NOT_SET 1000
|
#define BMKT_EVENT_NOT_SET 1000
|
||||||
#define BMKT_SENSOR_NOT_READY 1001
|
#define BMKT_SENSOR_NOT_READY 1001
|
||||||
#define BMKT_TIMEOUT 1002
|
#define BMKT_TIMEOUT 1002
|
||||||
#define BMKT_SENSOR_RESPONSE_PENDING 1003
|
#define BMKT_SENSOR_RESPONSE_PENDING 1003
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -129,104 +129,100 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_mode:
|
* bmkt_mode:
|
||||||
* Fingerprint system operational mode values level 1
|
* Fingerprint system operational mode values level 1
|
||||||
*/
|
*/
|
||||||
typedef enum bmkt_mode
|
typedef enum bmkt_mode {
|
||||||
{
|
BMKT_STATE_UNINIT = 0xFF,
|
||||||
BMKT_STATE_UNINIT = 0xFF,
|
BMKT_STATE_IDLE = 0x00,
|
||||||
BMKT_STATE_IDLE = 0x00,
|
BMKT_STATE_ENROLL = 0x10,
|
||||||
BMKT_STATE_ENROLL = 0x10,
|
BMKT_STATE_IDENTIFY = 0x20,
|
||||||
BMKT_STATE_IDENTIFY = 0x20,
|
BMKT_STATE_VERIFY = 0x30,
|
||||||
BMKT_STATE_VERIFY = 0x30,
|
BMKT_STATE_DB_OPS = 0x40,
|
||||||
BMKT_STATE_DB_OPS = 0x40,
|
BMKT_STATE_SYS_TEST = 0x50,
|
||||||
BMKT_STATE_SYS_TEST = 0x50,
|
BMKT_STATE_SYS_OPS = 0x60,
|
||||||
BMKT_STATE_SYS_OPS = 0x60,
|
|
||||||
} bmkt_mode_t;
|
} bmkt_mode_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_mode_level2:
|
* bmkt_mode_level2:
|
||||||
* Fingerprint system operational mode values level 2
|
* Fingerprint system operational mode values level 2
|
||||||
*/
|
*/
|
||||||
typedef enum bmkt_mode_level2
|
typedef enum bmkt_mode_level2 {
|
||||||
{
|
BMKT_STATE_L2_IDLE = 0x00,
|
||||||
BMKT_STATE_L2_IDLE = 0x00,
|
BMKT_STATE_L2_STARTING = 0x11,
|
||||||
BMKT_STATE_L2_STARTING = 0x11,
|
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
|
||||||
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
|
BMKT_STATE_L2_CAPTURE_IMAGE = 0x13,
|
||||||
BMKT_STATE_L2_CAPTURE_IMAGE = 0x13,
|
BMKT_STATE_L2_CAPTURE_COMPLETE = 0x14,
|
||||||
BMKT_STATE_L2_CAPTURE_COMPLETE = 0x14,
|
BMKT_STATE_L2_EXTRACT_FEATURE = 0x15,
|
||||||
BMKT_STATE_L2_EXTRACT_FEATURE = 0x15,
|
BMKT_STATE_L2_CREATE_TEMPLATE = 0x16,
|
||||||
BMKT_STATE_L2_CREATE_TEMPLATE = 0x16,
|
BMKT_STATE_L2_READING_FROM_FLASH = 0x17,
|
||||||
BMKT_STATE_L2_READING_FROM_FLASH = 0x17,
|
BMKT_STATE_L2_WRITING_TO_FLASH = 0x18,
|
||||||
BMKT_STATE_L2_WRITING_TO_FLASH = 0x18,
|
BMKT_STATE_L2_FINISHING = 0x19,
|
||||||
BMKT_STATE_L2_FINISHING = 0x19,
|
BMKT_STATE_L2_CANCELING_OP = 0x20,
|
||||||
BMKT_STATE_L2_CANCELING_OP = 0x20,
|
BMKT_STATE_L2_MATCHING = 0x21,
|
||||||
BMKT_STATE_L2_MATCHING = 0x21,
|
BMKT_STATE_L2_TRANSMITTING_RESPONSE = 0x22,
|
||||||
BMKT_STATE_L2_TRANSMITTING_RESPONSE = 0x22,
|
BMKT_STATE_L2_READY_POWER_DOWN = 0xF0,
|
||||||
BMKT_STATE_L2_READY_POWER_DOWN = 0xF0,
|
|
||||||
} bmkt_mode_level2_t;
|
} bmkt_mode_level2_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_transport_type:
|
* bmkt_transport_type:
|
||||||
* Fingerprint system transport types
|
* Fingerprint system transport types
|
||||||
*/
|
*/
|
||||||
typedef enum bmkt_transport_type
|
typedef enum bmkt_transport_type {
|
||||||
{
|
BMKT_TRANSPORT_TYPE_USB = 0,
|
||||||
BMKT_TRANSPORT_TYPE_USB = 0,
|
|
||||||
} bmkt_transport_type_t;
|
} bmkt_transport_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_usb_config:
|
* bmkt_usb_config:
|
||||||
* Structure represcontainingenting USB configuration details
|
* Structure represcontainingenting USB configuration details
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_usb_config
|
typedef struct bmkt_usb_config
|
||||||
{
|
{
|
||||||
int product_id; /**< USB device product ID */
|
int product_id; /**< USB device product ID */
|
||||||
} bmkt_usb_config_t;
|
} bmkt_usb_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_transport_config_t:
|
* bmkt_transport_config_t:
|
||||||
* Union containing transport configuration details
|
* Union containing transport configuration details
|
||||||
*/
|
*/
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
bmkt_usb_config_t usb_config;
|
bmkt_usb_config_t usb_config;
|
||||||
} bmkt_transport_config_t;
|
} bmkt_transport_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_sensor_desc_t:
|
* bmkt_sensor_desc_t:
|
||||||
* Structure containing fingerprint system description
|
* Structure containing fingerprint system description
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_sensor_desc
|
typedef struct bmkt_sensor_desc
|
||||||
{
|
{
|
||||||
int product_id;
|
int product_id;
|
||||||
int flags;
|
int flags;
|
||||||
} bmkt_sensor_desc_t;
|
} bmkt_sensor_desc_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_finger_state_t:
|
* bmkt_finger_state_t:
|
||||||
* Finger state representation values.
|
* Finger state representation values.
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
BMKT_FINGER_STATE_UNKNOWN = 0,
|
||||||
BMKT_FINGER_STATE_UNKNOWN = 0,
|
BMKT_FINGER_STATE_ON_SENSOR,
|
||||||
BMKT_FINGER_STATE_ON_SENSOR,
|
BMKT_FINGER_STATE_NOT_ON_SENSOR,
|
||||||
BMKT_FINGER_STATE_NOT_ON_SENSOR,
|
|
||||||
} bmkt_finger_state_t;
|
} bmkt_finger_state_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_finger_event_t:
|
* bmkt_finger_event_t:
|
||||||
* Structure containing finger state
|
* Structure containing finger state
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_finger_event
|
typedef struct bmkt_finger_event
|
||||||
{
|
{
|
||||||
bmkt_finger_state_t finger_state;
|
bmkt_finger_state_t finger_state;
|
||||||
} bmkt_finger_event_t;
|
} bmkt_finger_event_t;
|
||||||
|
|
||||||
typedef struct bmkt_user_id
|
typedef struct bmkt_user_id
|
||||||
{
|
{
|
||||||
uint8_t user_id_len;
|
uint8_t user_id_len;
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
||||||
} bmkt_user_id_t;
|
} bmkt_user_id_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -20,395 +20,381 @@
|
||||||
#include "bmkt_response.h"
|
#include "bmkt_response.h"
|
||||||
#include "bmkt_message.h"
|
#include "bmkt_message.h"
|
||||||
|
|
||||||
static uint8_t extract8(const uint8_t *buf, int *offset)
|
static uint8_t
|
||||||
|
extract8 (const uint8_t *buf, int *offset)
|
||||||
{
|
{
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
int off = 0;
|
int off = 0;
|
||||||
if (offset)
|
|
||||||
off = *offset;
|
|
||||||
|
|
||||||
ret = *(buf + off);
|
if (offset)
|
||||||
|
off = *offset;
|
||||||
|
|
||||||
if (offset)
|
ret = *(buf + off);
|
||||||
*offset += 1;
|
|
||||||
|
|
||||||
return ret;
|
if (offset)
|
||||||
|
*offset += 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int parse_error_response(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
static int
|
||||||
|
parse_error_response (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
{
|
{
|
||||||
if (msg_resp->payload_len != 2)
|
if (msg_resp->payload_len != 2)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_init_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_init_resp_t *init_resp = &resp->response.init_resp;
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
if (msg_resp->payload_len != 1)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_resp->finger_presence = extract8(msg_resp->payload, NULL);
|
init_resp->finger_presence = extract8 (msg_resp->payload, NULL);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
static int
|
||||||
|
parse_fps_mode_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
|
bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
|
||||||
|
|
||||||
if (msg_resp->payload_len != sizeof(bmkt_fps_mode_resp_t))
|
if (msg_resp->payload_len != sizeof (bmkt_fps_mode_resp_t))
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fps_mode_resp->mode = extract8(msg_resp->payload, &offset);
|
fps_mode_resp->mode = extract8 (msg_resp->payload, &offset);
|
||||||
fps_mode_resp->level2_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->cmd_id = extract8 (msg_resp->payload, &offset);
|
||||||
fps_mode_resp->finger_presence = extract8(msg_resp->payload, &offset);
|
fps_mode_resp->finger_presence = extract8 (msg_resp->payload, &offset);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_enroll_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
if (msg_resp->payload_len != 1)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
enroll_resp->progress = extract8(msg_resp->payload, NULL);
|
enroll_resp->progress = extract8 (msg_resp->payload, NULL);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
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))
|
if (msg_resp->payload_len < 1 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 1))
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
enroll_resp->finger_id = msg_resp->payload[0];
|
enroll_resp->finger_id = msg_resp->payload[0];
|
||||||
memcpy(enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
|
memcpy (enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
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))
|
if (msg_resp->payload_len < 3 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 3))
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
id_resp->match_result = (double)msg_resp->payload[0] + 0.01 * (double)msg_resp->payload[1];
|
id_resp->match_result = (double) msg_resp->payload[0] + 0.01 * (double) msg_resp->payload[1];
|
||||||
id_resp->finger_id = msg_resp->payload[2];
|
id_resp->finger_id = msg_resp->payload[2];
|
||||||
memcpy(id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
|
memcpy (id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_security_level_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_set_sec_level_resp_t *sec_level_resp = &resp->response.sec_level_resp;
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
if (msg_resp->payload_len != 1)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec_level_resp->sec_level = extract8(msg_resp->payload, NULL);
|
sec_level_resp->sec_level = extract8 (msg_resp->payload, NULL);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_del_all_users_progress_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_del_all_users_resp_t *del_all_users_resp = &resp->response.del_all_users_resp;
|
||||||
|
|
||||||
if (msg_resp->payload_len != 1)
|
if (msg_resp->payload_len != 1)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
del_all_users_resp->progress = extract8(msg_resp->payload, NULL);
|
del_all_users_resp->progress = extract8 (msg_resp->payload, NULL);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_get_db_capacity_resp_t *db_cap_resp = &resp->response.db_cap_resp;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
|
if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
db_cap_resp->total = extract8(msg_resp->payload, &offset);
|
db_cap_resp->total = extract8 (msg_resp->payload, &offset);
|
||||||
db_cap_resp->empty = extract8(msg_resp->payload, &offset);
|
db_cap_resp->empty = extract8 (msg_resp->payload, &offset);
|
||||||
|
|
||||||
if (msg_resp->payload_len == 4)
|
if (msg_resp->payload_len == 4)
|
||||||
{
|
{
|
||||||
db_cap_resp->bad_slots = extract8(msg_resp->payload, &offset);
|
db_cap_resp->bad_slots = extract8 (msg_resp->payload, &offset);
|
||||||
db_cap_resp->corrupt_templates = extract8(msg_resp->payload, &offset);
|
db_cap_resp->corrupt_templates = extract8 (msg_resp->payload, &offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
static int
|
||||||
|
parse_get_enrolled_fingers_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (msg_resp->payload_len < 2)
|
if (msg_resp->payload_len < 2)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
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;
|
||||||
/* 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;
|
bmkt_enrolled_fingers_resp_t *get_enrolled_fingers_resp = &resp->response.enrolled_fingers_resp;
|
||||||
|
|
||||||
for (i = 0; i < num_fingers; i++)
|
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].finger_id = extract8 (msg_resp->payload, &offset);
|
||||||
get_enrolled_fingers_resp->fingers[i].template_status = extract8(msg_resp->payload, &offset);
|
get_enrolled_fingers_resp->fingers[i].template_status = extract8 (msg_resp->payload, &offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
static int
|
||||||
|
parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* the payload is 2 bytes + template data */
|
/* the payload is 2 bytes + template data */
|
||||||
if (msg_resp->payload_len < 2)
|
if (msg_resp->payload_len < 2)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
|
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->total_query_messages = extract8 (msg_resp->payload, &offset);
|
||||||
get_enroll_templates_resp->query_sequence = extract8(msg_resp->payload, &offset);
|
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||||
{
|
{
|
||||||
if (offset >= msg_resp->payload_len)
|
if (offset >= msg_resp->payload_len)
|
||||||
break;
|
break;
|
||||||
get_enroll_templates_resp->templates[n].user_id_len = extract8(msg_resp->payload, &offset) - 2;
|
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)
|
if(get_enroll_templates_resp->templates[n].user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
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);
|
||||||
get_enroll_templates_resp->templates[n].template_status = 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].finger_id = extract8(msg_resp->payload, &offset);
|
get_enroll_templates_resp->templates[n].user_id[i] = 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] = '\0';
|
||||||
{
|
}
|
||||||
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;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
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;
|
bmkt_get_version_resp_t *get_version_resp = &resp->response.get_version_resp;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if (msg_resp->payload_len != 15)
|
if (msg_resp->payload_len != 15)
|
||||||
{
|
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
|
memcpy (get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
|
||||||
offset += BMKT_PART_NUM_LEN;
|
offset += BMKT_PART_NUM_LEN;
|
||||||
get_version_resp->year = extract8(msg_resp->payload, &offset);
|
get_version_resp->year = extract8 (msg_resp->payload, &offset);
|
||||||
get_version_resp->week = extract8(msg_resp->payload, &offset);
|
get_version_resp->week = extract8 (msg_resp->payload, &offset);
|
||||||
get_version_resp->patch = 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);
|
memcpy (get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
int
|
||||||
uint8_t payload_size, const uint8_t *payload)
|
bmkt_compose_message (uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
||||||
|
uint8_t payload_size, const uint8_t *payload)
|
||||||
{
|
{
|
||||||
int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
|
int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
|
||||||
|
|
||||||
if (*cmd_len < message_len)
|
if (*cmd_len < message_len)
|
||||||
{
|
return BMKT_OUT_OF_MEMORY;
|
||||||
return BMKT_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
|
cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
|
||||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
||||||
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
||||||
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
||||||
memcpy(&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
||||||
|
|
||||||
*cmd_len = message_len;
|
*cmd_len = message_len;
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
|
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)
|
if (resp_buf[BMKT_MESSAGE_HEADER_ID_FIELD] != BMKT_MESSAGE_HEADER_ID)
|
||||||
{
|
return BMKT_CORRUPT_MESSAGE;
|
||||||
return BMKT_CORRUPT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
|
msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
|
||||||
msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
|
msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
|
||||||
msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
|
msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
|
||||||
if (msg_resp->payload_len > 0)
|
if (msg_resp->payload_len > 0)
|
||||||
{
|
msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
|
||||||
msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
|
else
|
||||||
}
|
msg_resp->payload = NULL;
|
||||||
else
|
|
||||||
{
|
|
||||||
msg_resp->payload = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BMKT_SUCCESS;
|
return BMKT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
int
|
||||||
|
bmkt_parse_message_payload (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
{
|
{
|
||||||
int ret = BMKT_SUCCESS;
|
int ret = BMKT_SUCCESS;
|
||||||
|
|
||||||
memset(resp, 0, sizeof(bmkt_response_t));
|
memset (resp, 0, sizeof (bmkt_response_t));
|
||||||
|
|
||||||
resp->response_id = msg_resp->msg_id;
|
resp->response_id = msg_resp->msg_id;
|
||||||
|
|
||||||
switch(msg_resp->msg_id)
|
switch(msg_resp->msg_id)
|
||||||
{
|
{
|
||||||
case BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL:
|
case BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL:
|
||||||
case BMKT_RSP_SENSOR_MODULE_TEST_FAIL:
|
case BMKT_RSP_SENSOR_MODULE_TEST_FAIL:
|
||||||
case BMKT_RSP_FPS_INIT_FAIL:
|
case BMKT_RSP_FPS_INIT_FAIL:
|
||||||
case BMKT_RSP_FPS_MODE_FAIL:
|
case BMKT_RSP_FPS_MODE_FAIL:
|
||||||
case BMKT_RSP_SET_SECURITY_LEVEL_FAIL:
|
case BMKT_RSP_SET_SECURITY_LEVEL_FAIL:
|
||||||
case BMKT_RSP_GET_SECURITY_LEVEL_FAIL:
|
case BMKT_RSP_GET_SECURITY_LEVEL_FAIL:
|
||||||
case BMKT_RSP_CANCEL_OP_FAIL:
|
case BMKT_RSP_CANCEL_OP_FAIL:
|
||||||
case BMKT_RSP_ENROLL_FAIL:
|
case BMKT_RSP_ENROLL_FAIL:
|
||||||
case BMKT_RSP_ID_FAIL:
|
case BMKT_RSP_ID_FAIL:
|
||||||
case BMKT_RSP_VERIFY_FAIL:
|
case BMKT_RSP_VERIFY_FAIL:
|
||||||
case BMKT_RSP_QUERY_FAIL:
|
case BMKT_RSP_QUERY_FAIL:
|
||||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||||
case BMKT_RSP_DEL_FULL_DB_FAIL:
|
case BMKT_RSP_DEL_FULL_DB_FAIL:
|
||||||
case BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
case BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
||||||
case BMKT_RSP_POWER_DOWN_FAIL:
|
case BMKT_RSP_POWER_DOWN_FAIL:
|
||||||
case BMKT_RSP_GET_VERSION_FAIL:
|
case BMKT_RSP_GET_VERSION_FAIL:
|
||||||
case BMKT_RSP_DISABLE_PAIRING_FAIL:
|
case BMKT_RSP_DISABLE_PAIRING_FAIL:
|
||||||
case BMKT_RSP_QUERY_PAIRING_FAIL:
|
case BMKT_RSP_QUERY_PAIRING_FAIL:
|
||||||
case BMKT_RSP_SENSOR_STATUS_FAIL:
|
case BMKT_RSP_SENSOR_STATUS_FAIL:
|
||||||
case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
||||||
ret = parse_error_response(msg_resp, resp);
|
ret = parse_error_response (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_FPS_INIT_OK:
|
case BMKT_RSP_FPS_INIT_OK:
|
||||||
ret = parse_init_ok(msg_resp, resp);
|
ret = parse_init_ok (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_CANCEL_OP_OK:
|
case BMKT_RSP_CANCEL_OP_OK:
|
||||||
case BMKT_RSP_DEL_FULL_DB_OK:
|
case BMKT_RSP_DEL_FULL_DB_OK:
|
||||||
case BMKT_RSP_DEL_USER_FP_OK:
|
case BMKT_RSP_DEL_USER_FP_OK:
|
||||||
/* responses with a payload of 0
|
/* responses with a payload of 0
|
||||||
so the response indicates success */
|
so the response indicates success */
|
||||||
resp->result = BMKT_SUCCESS;
|
resp->result = BMKT_SUCCESS;
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_FPS_MODE_REPORT:
|
case BMKT_RSP_FPS_MODE_REPORT:
|
||||||
// parse_fps_mode
|
// parse_fps_mode
|
||||||
ret = parse_fps_mode_report(msg_resp, resp);
|
ret = parse_fps_mode_report (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
||||||
case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
||||||
/* parse security level result */
|
/* parse security level result */
|
||||||
ret = parse_security_level_report(msg_resp, resp);
|
ret = parse_security_level_report (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_DELETE_PROGRESS:
|
case BMKT_RSP_DELETE_PROGRESS:
|
||||||
ret = parse_del_all_users_progress_report(msg_resp, resp);
|
ret = parse_del_all_users_progress_report (msg_resp, resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||||
resp->result = BMKT_SUCCESS;
|
resp->result = BMKT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_READY:
|
case BMKT_RSP_ENROLL_READY:
|
||||||
resp->result = BMKT_SUCCESS;
|
resp->result = BMKT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_REPORT:
|
case BMKT_RSP_ENROLL_REPORT:
|
||||||
ret = parse_enroll_report(msg_resp, resp);
|
ret = parse_enroll_report (msg_resp, resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_OK:
|
case BMKT_RSP_ENROLL_OK:
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
ret = parse_enroll_ok(msg_resp, resp);
|
ret = parse_enroll_ok (msg_resp, resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_ID_OK:
|
case BMKT_RSP_ID_OK:
|
||||||
case BMKT_RSP_VERIFY_OK:
|
case BMKT_RSP_VERIFY_OK:
|
||||||
ret = parse_auth_ok(msg_resp, resp);
|
ret = parse_auth_ok (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
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:
|
case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||||
ret = parse_get_version_report(msg_resp, resp);
|
ret = parse_get_enrolled_fingers_report (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
case BMKT_RSP_POWER_DOWN_READY:
|
|
||||||
resp->complete = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
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;
|
||||||
|
|
||||||
|
case BMKT_RSP_POWER_DOWN_READY:
|
||||||
|
resp->complete = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,66 +21,73 @@
|
||||||
#define BMKT_MESSAGE_H_
|
#define BMKT_MESSAGE_H_
|
||||||
|
|
||||||
|
|
||||||
#define BMKT_MESSAGE_HEADER_ID 0xFE
|
#define BMKT_MESSAGE_HEADER_ID 0xFE
|
||||||
#define BMKT_MESSAGE_HEADER_LEN (4)
|
#define BMKT_MESSAGE_HEADER_LEN (4)
|
||||||
#define BMKT_MESSAGE_CRC32_LEN (4)
|
#define BMKT_MESSAGE_CRC32_LEN (4)
|
||||||
#define BMKT_MESSAGE_HEADER_ID_FIELD 0
|
#define BMKT_MESSAGE_HEADER_ID_FIELD 0
|
||||||
#define BMKT_MESSAGE_SEQ_NUM_FIELD 1
|
#define BMKT_MESSAGE_SEQ_NUM_FIELD 1
|
||||||
#define BMKT_MESSAGE_ID_FIELD 2
|
#define BMKT_MESSAGE_ID_FIELD 2
|
||||||
#define BMKT_MESSAGE_PAYLOAD_LEN_FIELD 3
|
#define BMKT_MESSAGE_PAYLOAD_LEN_FIELD 3
|
||||||
#define BMKT_MESSAGE_PAYLOAD_FIELD 4
|
#define BMKT_MESSAGE_PAYLOAD_FIELD 4
|
||||||
|
|
||||||
// Command messages
|
// Command messages
|
||||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE 0x01
|
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE 0x01
|
||||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE_STOP 0x04
|
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE_STOP 0x04
|
||||||
#define BMKT_CMD_SENSOR_MODULE_TEST 0x06
|
#define BMKT_CMD_SENSOR_MODULE_TEST 0x06
|
||||||
#define BMKT_CMD_SENSOR_MODULE_TEST_START 0x08
|
#define BMKT_CMD_SENSOR_MODULE_TEST_START 0x08
|
||||||
#define BMKT_CMD_NEXT_TEST_REPORT_CHUNK 0x0B
|
#define BMKT_CMD_NEXT_TEST_REPORT_CHUNK 0x0B
|
||||||
#define BMKT_CMD_FPS_INIT 0x11
|
#define BMKT_CMD_FPS_INIT 0x11
|
||||||
#define BMKT_CMD_GET_FPS_MODE 0x21
|
#define BMKT_CMD_GET_FPS_MODE 0x21
|
||||||
#define BMKT_CMD_SET_SECURITY_LEVEL 0x31
|
#define BMKT_CMD_SET_SECURITY_LEVEL 0x31
|
||||||
#define BMKT_CMD_GET_SECURITY_LEVEL 0x34
|
#define BMKT_CMD_GET_SECURITY_LEVEL 0x34
|
||||||
#define BMKT_CMD_CANCEL_OP 0x41
|
#define BMKT_CMD_CANCEL_OP 0x41
|
||||||
#define BMKT_CMD_ENROLL_USER 0x51
|
#define BMKT_CMD_ENROLL_USER 0x51
|
||||||
#define BMKT_CMD_ENROLL_PAUSE 0x52
|
#define BMKT_CMD_ENROLL_PAUSE 0x52
|
||||||
#define BMKT_CMD_ENROLL_RESUME 0x53
|
#define BMKT_CMD_ENROLL_RESUME 0x53
|
||||||
#define BMKT_CMD_ID_USER 0x61
|
#define BMKT_CMD_ID_USER 0x61
|
||||||
#define BMKT_CMD_VERIFY_USER 0x65
|
#define BMKT_CMD_VERIFY_USER 0x65
|
||||||
#define BMKT_CMD_GET_TEMPLATE_RECORDS 0x71
|
#define BMKT_CMD_GET_TEMPLATE_RECORDS 0x71
|
||||||
#define BMKT_CMD_GET_NEXT_QUERY_RESPONSE 0x72
|
#define BMKT_CMD_GET_NEXT_QUERY_RESPONSE 0x72
|
||||||
#define BMKT_CMD_GET_ENROLLED_FINGERS 0x73
|
#define BMKT_CMD_GET_ENROLLED_FINGERS 0x73
|
||||||
#define BMKT_CMD_GET_DATABASE_CAPACITY 0x74
|
#define BMKT_CMD_GET_DATABASE_CAPACITY 0x74
|
||||||
#define BMKT_CMD_DEL_USER_FP 0x81
|
#define BMKT_CMD_DEL_USER_FP 0x81
|
||||||
#define BMKT_CMD_DEL_FULL_DB 0x84
|
#define BMKT_CMD_DEL_FULL_DB 0x84
|
||||||
#define BMKT_CMD_REPEAT_LAST_RSP 0x92
|
#define BMKT_CMD_REPEAT_LAST_RSP 0x92
|
||||||
#define BMKT_CMD_POWER_DOWN_NOTIFY 0xA1
|
#define BMKT_CMD_POWER_DOWN_NOTIFY 0xA1
|
||||||
#define BMKT_CMD_GET_VERSION 0xB1
|
#define BMKT_CMD_GET_VERSION 0xB1
|
||||||
#define BMKT_CMD_DISABLE_PAIRING 0xC2
|
#define BMKT_CMD_DISABLE_PAIRING 0xC2
|
||||||
#define BMKT_CMD_QUERY_PAIRING 0xC5
|
#define BMKT_CMD_QUERY_PAIRING 0xC5
|
||||||
#define BMKT_CMD_SENSOR_STATUS 0xD1
|
#define BMKT_CMD_SENSOR_STATUS 0xD1
|
||||||
#define BMKT_CMD_ID_USER_IN_ORDER 0xE1
|
#define BMKT_CMD_ID_USER_IN_ORDER 0xE1
|
||||||
#define BMKT_CMD_ID_NEXT_USER 0xE3
|
#define BMKT_CMD_ID_NEXT_USER 0xE3
|
||||||
#define BMKT_CMD_VERIFY_USER_IN_ORDER 0xF1
|
#define BMKT_CMD_VERIFY_USER_IN_ORDER 0xF1
|
||||||
#define BMKT_CMD_VERIFY_FINGERS_IN_ORDER 0xF2
|
#define BMKT_CMD_VERIFY_FINGERS_IN_ORDER 0xF2
|
||||||
#define BMKT_CMD_GET_FINAL_RESULT 0xE4
|
#define BMKT_CMD_GET_FINAL_RESULT 0xE4
|
||||||
|
|
||||||
#define BMKT_EVT_FINGER_REPORT 0x91
|
#define BMKT_EVT_FINGER_REPORT 0x91
|
||||||
|
|
||||||
#define BMKT_EVT_FINGER_STATE_NOT_ON_SENSOR 0x00
|
#define BMKT_EVT_FINGER_STATE_NOT_ON_SENSOR 0x00
|
||||||
#define BMKT_EVT_FINGER_STATE_ON_SENSOR 0x01
|
#define BMKT_EVT_FINGER_STATE_ON_SENSOR 0x01
|
||||||
|
|
||||||
typedef struct bmkt_msg_resp
|
typedef struct bmkt_msg_resp
|
||||||
{
|
{
|
||||||
uint8_t msg_id;
|
uint8_t msg_id;
|
||||||
uint8_t seq_num;
|
uint8_t seq_num;
|
||||||
uint8_t payload_len;
|
uint8_t payload_len;
|
||||||
uint8_t *payload;
|
uint8_t *payload;
|
||||||
int result;
|
int result;
|
||||||
} bmkt_msg_resp_t;
|
} bmkt_msg_resp_t;
|
||||||
|
|
||||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
int bmkt_compose_message (uint8_t *cmd,
|
||||||
uint8_t payload_size, const uint8_t *payload);
|
int *cmd_len,
|
||||||
|
uint8_t msg_id,
|
||||||
|
uint8_t seq_num,
|
||||||
|
uint8_t payload_size,
|
||||||
|
const 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_header (uint8_t *resp_buf,
|
||||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp);
|
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_ */
|
#endif /* BMKT_MESSAGE_H_ */
|
||||||
|
|
|
@ -24,466 +24,466 @@
|
||||||
#include "bmkt.h"
|
#include "bmkt.h"
|
||||||
|
|
||||||
/** List of response message IDs */
|
/** List of response message IDs */
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL 0x02
|
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL 0x02
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_READY 0x03
|
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_READY 0x03
|
||||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_STOPPED 0x05
|
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_STOPPED 0x05
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_READY 0x07
|
#define BMKT_RSP_SENSOR_MODULE_TEST_READY 0x07
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_FAIL 0x09
|
#define BMKT_RSP_SENSOR_MODULE_TEST_FAIL 0x09
|
||||||
#define BMKT_RSP_SENSOR_MODULE_TEST_REPORT 0x0A
|
#define BMKT_RSP_SENSOR_MODULE_TEST_REPORT 0x0A
|
||||||
#define BMKT_RSP_NEXT_TEST_REPORT_CHUNK 0x0C
|
#define BMKT_RSP_NEXT_TEST_REPORT_CHUNK 0x0C
|
||||||
|
|
||||||
/*! \addtogroup init
|
/*! \addtogroup init
|
||||||
* Response IDs returned by fingerprint initialization operation
|
* Response IDs returned by fingerprint initialization operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to initialize fingerprint sensor module */
|
/** Failed to initialize fingerprint sensor module */
|
||||||
#define BMKT_RSP_FPS_INIT_FAIL 0x12
|
#define BMKT_RSP_FPS_INIT_FAIL 0x12
|
||||||
/** Successfully initialized fingerprint sensor module */
|
/** Successfully initialized fingerprint sensor module */
|
||||||
#define BMKT_RSP_FPS_INIT_OK 0x13
|
#define BMKT_RSP_FPS_INIT_OK 0x13
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup mode
|
/*! \addtogroup mode
|
||||||
* Response IDs returned by get fingerprint mode operation
|
* Response IDs returned by get fingerprint mode operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to get fingerprint sensor module’s current operational mode */
|
/** Failed to get fingerprint sensor module’s current operational mode */
|
||||||
#define BMKT_RSP_FPS_MODE_FAIL 0x22
|
#define BMKT_RSP_FPS_MODE_FAIL 0x22
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_FPS_MODE_REPORT:
|
* BMKT_RSP_FPS_MODE_REPORT:
|
||||||
* Response containing the current operational mode of the fingerprint sensor module
|
* Response containing the current operational mode of the fingerprint sensor module
|
||||||
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
|
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_FPS_MODE_REPORT 0x23
|
#define BMKT_RSP_FPS_MODE_REPORT 0x23
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup setseclevel
|
/*! \addtogroup setseclevel
|
||||||
* Response IDs returned by set security level operation
|
* Response IDs returned by set security level operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to set fingerprint sensor module security level */
|
/** Failed to set fingerprint sensor module security level */
|
||||||
#define BMKT_RSP_SET_SECURITY_LEVEL_FAIL 0x32
|
#define BMKT_RSP_SET_SECURITY_LEVEL_FAIL 0x32
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
||||||
* Security level of the fingerprint sensor module was set successfully
|
* Security level of the fingerprint sensor module was set successfully
|
||||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_SET_SECURITY_LEVEL_REPORT 0x33
|
#define BMKT_RSP_SET_SECURITY_LEVEL_REPORT 0x33
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup getseclevel
|
/*! \addtogroup getseclevel
|
||||||
* Response IDs returned by get security level operation
|
* Response IDs returned by get security level operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to get fingerprint sensor module security level */
|
/** Failed to get fingerprint sensor module security level */
|
||||||
#define BMKT_RSP_GET_SECURITY_LEVEL_FAIL 0x35
|
#define BMKT_RSP_GET_SECURITY_LEVEL_FAIL 0x35
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
||||||
* Returns the current security level of the fingerprint sensor module
|
* Returns the current security level of the fingerprint sensor module
|
||||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_GET_SECURITY_LEVEL_REPORT 0x36
|
#define BMKT_RSP_GET_SECURITY_LEVEL_REPORT 0x36
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup cancelop
|
/*! \addtogroup cancelop
|
||||||
* Response IDs returned by cancel_operation operation
|
* Response IDs returned by cancel_operation operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_CANCEL_OP_OK:
|
* BMKT_RSP_CANCEL_OP_OK:
|
||||||
* Successfully canceled the current operation and returned
|
* Successfully canceled the current operation and returned
|
||||||
* fingerprint sensor module to idle mode
|
* fingerprint sensor module to idle mode
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_CANCEL_OP_OK 0x42
|
#define BMKT_RSP_CANCEL_OP_OK 0x42
|
||||||
/** Failed to cancel the current operation */
|
/** Failed to cancel the current operation */
|
||||||
#define BMKT_RSP_CANCEL_OP_FAIL 0x43
|
#define BMKT_RSP_CANCEL_OP_FAIL 0x43
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup enrollment
|
/*! \addtogroup enrollment
|
||||||
* Response IDs returned by enrollment operation
|
* Response IDs returned by enrollment operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_ENROLL_READY:
|
* BMKT_RSP_ENROLL_READY:
|
||||||
* Fingerprint enrollment session has begun and the user can place
|
* Fingerprint enrollment session has begun and the user can place
|
||||||
* their finger on the sensor
|
* their finger on the sensor
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_ENROLL_READY 0x54
|
#define BMKT_RSP_ENROLL_READY 0x54
|
||||||
/** Progress of the currently on-going fingerprint enrollment session */
|
/** Progress of the currently on-going fingerprint enrollment session */
|
||||||
#define BMKT_RSP_ENROLL_REPORT 0x55
|
#define BMKT_RSP_ENROLL_REPORT 0x55
|
||||||
/** Enrollment has been paused */
|
/** Enrollment has been paused */
|
||||||
#define BMKT_RSP_ENROLL_PAUSED 0x56
|
#define BMKT_RSP_ENROLL_PAUSED 0x56
|
||||||
/** Enrollment has been resume */
|
/** Enrollment has been resume */
|
||||||
#define BMKT_RSP_ENROLL_RESUMED 0x57
|
#define BMKT_RSP_ENROLL_RESUMED 0x57
|
||||||
/** The current enrollment session has encountered an error */
|
/** The current enrollment session has encountered an error */
|
||||||
#define BMKT_RSP_ENROLL_FAIL 0x58
|
#define BMKT_RSP_ENROLL_FAIL 0x58
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_ENROLL_OK:
|
* BMKT_RSP_ENROLL_OK:
|
||||||
* User has been successfully enrolled into the fingerprint sensor module
|
* User has been successfully enrolled into the fingerprint sensor module
|
||||||
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
|
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_ENROLL_OK 0x59
|
#define BMKT_RSP_ENROLL_OK 0x59
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_CAPTURE_COMPLETE:
|
* BMKT_RSP_CAPTURE_COMPLETE:
|
||||||
* Fingerprint image capture is complete and it is safe for the user
|
* Fingerprint image capture is complete and it is safe for the user
|
||||||
* to lift their finger off the sensor
|
* to lift their finger off the sensor
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_CAPTURE_COMPLETE 0x60
|
#define BMKT_RSP_CAPTURE_COMPLETE 0x60
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup identify
|
/*! \addtogroup identify
|
||||||
* Response IDs returned by identify operation.
|
* Response IDs returned by identify operation.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Fingerprint identification session has begun */
|
/* Fingerprint identification session has begun */
|
||||||
#define BMKT_RSP_ID_READY 0x62
|
#define BMKT_RSP_ID_READY 0x62
|
||||||
/* Identification has failed */
|
/* Identification has failed */
|
||||||
#define BMKT_RSP_ID_FAIL 0x63
|
#define BMKT_RSP_ID_FAIL 0x63
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_ID_OK:
|
* BMKT_RSP_ID_OK:
|
||||||
* User has been successfully identified
|
* User has been successfully identified
|
||||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_ID_OK 0x64
|
#define BMKT_RSP_ID_OK 0x64
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup verify
|
/*! \addtogroup verify
|
||||||
* Response IDs returned by identify operation.
|
* Response IDs returned by identify operation.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Fingerprint verification session has begun */
|
/** Fingerprint verification session has begun */
|
||||||
#define BMKT_RSP_VERIFY_READY 0x66
|
#define BMKT_RSP_VERIFY_READY 0x66
|
||||||
/** Verification has failed */
|
/** Verification has failed */
|
||||||
#define BMKT_RSP_VERIFY_FAIL 0x67
|
#define BMKT_RSP_VERIFY_FAIL 0x67
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_VERIFY_OK:
|
* BMKT_RSP_VERIFY_OK:
|
||||||
* User’s identity has been successfully verified
|
* User’s identity has been successfully verified
|
||||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_VERIFY_OK 0x68
|
#define BMKT_RSP_VERIFY_OK 0x68
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||||
* Response ID returned by get enrolled users templates record operation
|
* Response ID returned by get enrolled users templates record operation
|
||||||
* <br>Returns list of template records containing user IDs and corresponding finger IDs
|
* <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
|
* <br>Payload data represented in \ref bmkt_enroll_templates_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_TEMPLATE_RECORDS_REPORT 0x75
|
#define BMKT_RSP_TEMPLATE_RECORDS_REPORT 0x75
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||||
* Response ID returned by get next query response operation
|
* Response ID returned by get next query response operation
|
||||||
* <br>Complete sequence of messages containing the template records query response has been sent
|
* <br>Complete sequence of messages containing the template records query response has been sent
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_QUERY_RESPONSE_COMPLETE 0x76
|
#define BMKT_RSP_QUERY_RESPONSE_COMPLETE 0x76
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||||
* Response ID returned by get enrolled fingers operation
|
* Response ID returned by get enrolled fingers operation
|
||||||
* <br> Returns list of IDs of enrolled fingers for a specific user,
|
* <br> Returns list of IDs of enrolled fingers for a specific user,
|
||||||
* along with template record status corresponding to each enrolled finger
|
* along with template record status corresponding to each enrolled finger
|
||||||
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
|
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_GET_ENROLLED_FINGERS_REPORT 0x77
|
#define BMKT_RSP_GET_ENROLLED_FINGERS_REPORT 0x77
|
||||||
|
|
||||||
/*! \addtogroup dbcapacity
|
/*! \addtogroup dbcapacity
|
||||||
* Response IDs returned by get database capacity operation
|
* Response IDs returned by get database capacity operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
||||||
* Response specifying total capacity of fingerprint template database and
|
* Response specifying total capacity of fingerprint template database and
|
||||||
* how much free capacity is remaining along with how many templates are corrupted and
|
* how much free capacity is remaining along with how many templates are corrupted and
|
||||||
* how many bad (permanently unusable) storage slots are there.
|
* how many bad (permanently unusable) storage slots are there.
|
||||||
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
|
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_DATABASE_CAPACITY_REPORT 0x78
|
#define BMKT_RSP_DATABASE_CAPACITY_REPORT 0x78
|
||||||
/** Failed to execute database query */
|
/** Failed to execute database query */
|
||||||
#define BMKT_RSP_QUERY_FAIL 0x79
|
#define BMKT_RSP_QUERY_FAIL 0x79
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup deluser
|
/*! \addtogroup deluser
|
||||||
* Response IDs returned by delete fingerprint of specific user operation
|
* Response IDs returned by delete fingerprint of specific user operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to delete a user’s fingerprint template from the database */
|
/** Failed to delete a user’s fingerprint template from the database */
|
||||||
#define BMKT_RSP_DEL_USER_FP_FAIL 0x82
|
#define BMKT_RSP_DEL_USER_FP_FAIL 0x82
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_DEL_USER_FP_OK:
|
* BMKT_RSP_DEL_USER_FP_OK:
|
||||||
* Fingerprint template successfully deleted from the database.
|
* 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,
|
* 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
|
* 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
|
* <br>Payload data represented in \ref bmkt_del_user_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_DEL_USER_FP_OK 0x83
|
#define BMKT_RSP_DEL_USER_FP_OK 0x83
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup delfulldb
|
/*! \addtogroup delfulldb
|
||||||
* Response IDs returned by delete entire fingerprint template DB operation
|
* Response IDs returned by delete entire fingerprint template DB operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Failed to erase entire fingerprint template database */
|
/** Failed to erase entire fingerprint template database */
|
||||||
#define BMKT_RSP_DEL_FULL_DB_FAIL 0x85
|
#define BMKT_RSP_DEL_FULL_DB_FAIL 0x85
|
||||||
/** Successfully erased entire fingerprint template database */
|
/** Successfully erased entire fingerprint template database */
|
||||||
#define BMKT_RSP_DEL_FULL_DB_OK 0x86
|
#define BMKT_RSP_DEL_FULL_DB_OK 0x86
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_DELETE_PROGRESS:
|
* BMKT_RSP_DELETE_PROGRESS:
|
||||||
* Notify progress made during the on-going deletion of the full template database
|
* 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
|
* <br>Payload data represented in \ref bmkt_del_all_users_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_DELETE_PROGRESS 0x87
|
#define BMKT_RSP_DELETE_PROGRESS 0x87
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
||||||
* Response ID returned by repeate last response operation
|
* Response ID returned by repeate last response operation
|
||||||
* <br>Failed to retrieve and re-send last response
|
* <br>Failed to retrieve and re-send last response
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL 0x93
|
#define BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL 0x93
|
||||||
|
|
||||||
/*! \addtogroup pwrdwn
|
/*! \addtogroup pwrdwn
|
||||||
* Response IDs returned by power down notify operation
|
* Response IDs returned by power down notify operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Fingerprint sensor module is ready to be powered down */
|
/** Fingerprint sensor module is ready to be powered down */
|
||||||
#define BMKT_RSP_POWER_DOWN_READY 0xA2
|
#define BMKT_RSP_POWER_DOWN_READY 0xA2
|
||||||
/** Failed to go into power down mode */
|
/** Failed to go into power down mode */
|
||||||
#define BMKT_RSP_POWER_DOWN_FAIL 0xA3
|
#define BMKT_RSP_POWER_DOWN_FAIL 0xA3
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \addtogroup versioninfo
|
/*! \addtogroup versioninfo
|
||||||
* Response IDs returned by get version operation
|
* Response IDs returned by get version operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_VERSION_INFO:
|
* BMKT_RSP_VERSION_INFO:
|
||||||
* System version information of the fingerprint sensor module
|
* System version information of the fingerprint sensor module
|
||||||
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
|
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_VERSION_INFO 0xB2
|
#define BMKT_RSP_VERSION_INFO 0xB2
|
||||||
/* Failed to retrieve and send last response */
|
/* Failed to retrieve and send last response */
|
||||||
#define BMKT_RSP_GET_VERSION_FAIL 0xB3
|
#define BMKT_RSP_GET_VERSION_FAIL 0xB3
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_GENERAL_ERROR:
|
* BMKT_RSP_GENERAL_ERROR:
|
||||||
* Not tied to a specific command-response session.
|
* Not tied to a specific command-response session.
|
||||||
* <br>Could be caused by corrupt or truncated command message
|
* <br>Could be caused by corrupt or truncated command message
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_GENERAL_ERROR 0xC1
|
#define BMKT_RSP_GENERAL_ERROR 0xC1
|
||||||
#define BMKT_RSP_DISABLE_PAIRING_FAIL 0xC3
|
#define BMKT_RSP_DISABLE_PAIRING_FAIL 0xC3
|
||||||
#define BMKT_RSP_DISABLE_PAIRING_OK 0xC4
|
#define BMKT_RSP_DISABLE_PAIRING_OK 0xC4
|
||||||
#define BMKT_RSP_QUERY_PAIRING_FAIL 0xC6
|
#define BMKT_RSP_QUERY_PAIRING_FAIL 0xC6
|
||||||
#define BMKT_RSP_SENSOR_PAIRING_REPORT 0xC7
|
#define BMKT_RSP_SENSOR_PAIRING_REPORT 0xC7
|
||||||
|
|
||||||
/*! \addtogroup versioninfo
|
/*! \addtogroup versioninfo
|
||||||
* Response IDs returned by get sensor module status operation
|
* Response IDs returned by get sensor module status operation
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_SENSOR_STATUS_REPORT:
|
* BMKT_RSP_SENSOR_STATUS_REPORT:
|
||||||
* Response returning the current status of the sensor module
|
* Response returning the current status of the sensor module
|
||||||
* <br>Payload data represented in bmkt_XXX struct
|
* <br>Payload data represented in bmkt_XXX struct
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_SENSOR_STATUS_REPORT 0xD2
|
#define BMKT_RSP_SENSOR_STATUS_REPORT 0xD2
|
||||||
/** Failed to retrieve sensor status */
|
/** Failed to retrieve sensor status */
|
||||||
#define BMKT_RSP_SENSOR_STATUS_FAIL 0xD3
|
#define BMKT_RSP_SENSOR_STATUS_FAIL 0xD3
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_SEND_NEXT_USER_ID:
|
* BMKT_RSP_SEND_NEXT_USER_ID:
|
||||||
* Response ID returned by identify user in order operation
|
* Response ID returned by identify user in order operation
|
||||||
* <br>Notify to send the next batch of user IDs in the priority list
|
* <br>Notify to send the next batch of user IDs in the priority list
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_SEND_NEXT_USER_ID 0xE2
|
#define BMKT_RSP_SEND_NEXT_USER_ID 0xE2
|
||||||
/**
|
/**
|
||||||
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
||||||
* Response IDs returned by retrieve final result operation
|
* Response IDs returned by retrieve final result operation
|
||||||
* <br>Failed to retrieve and re-send cached final result
|
* <br>Failed to retrieve and re-send cached final result
|
||||||
*/
|
*/
|
||||||
#define BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL 0xE5
|
#define BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL 0xE5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response payload data structure returned by sensor initialization operation.
|
* Response payload data structure returned by sensor initialization operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_init_resp
|
typedef struct bmkt_init_resp
|
||||||
{
|
{
|
||||||
uint8_t finger_presence; /**< Indicates finger existence on the sensor during startup */
|
uint8_t finger_presence; /**< Indicates finger existence on the sensor during startup */
|
||||||
} bmkt_init_resp_t;
|
} bmkt_init_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_enroll_resp:
|
* bmkt_enroll_resp:
|
||||||
* Response payload data structure returned by enrollment operation.
|
* Response payload data structure returned by enrollment operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_enroll_resp
|
typedef struct bmkt_enroll_resp
|
||||||
{
|
{
|
||||||
int progress; /**< Shows current progress stutus [0-100] */
|
int progress; /**< Shows current progress stutus [0-100] */
|
||||||
uint8_t finger_id; /**< User's finger id [1-10] */
|
uint8_t finger_id; /**< User's finger id [1-10] */
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
|
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
|
||||||
} bmkt_enroll_resp_t;
|
} bmkt_enroll_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_auth_resp:
|
* bmkt_auth_resp:
|
||||||
* Response payload data structure returned by identify and verify operations.
|
* Response payload data structure returned by identify and verify operations.
|
||||||
*/
|
*/
|
||||||
struct bmkt_auth_resp
|
struct bmkt_auth_resp
|
||||||
{
|
{
|
||||||
double match_result; /**< match result returned by matcher */
|
double match_result; /**< match result returned by matcher */
|
||||||
uint8_t finger_id; /**< Matched templates's finger id */
|
uint8_t finger_id; /**< Matched templates's finger id */
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< Matched template's user 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_verify_resp_t; /**< Returned by verify */
|
||||||
typedef struct bmkt_auth_resp bmkt_identify_resp_t; /**< Returned by identify */
|
typedef struct bmkt_auth_resp bmkt_identify_resp_t; /**< Returned by identify */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_fps_mode_resp:
|
* bmkt_fps_mode_resp:
|
||||||
* Response payload data structure returned by get fingerprint mode operation.
|
* Response payload data structure returned by get fingerprint mode operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_fps_mode_resp
|
typedef struct bmkt_fps_mode_resp
|
||||||
{
|
{
|
||||||
uint8_t mode; /**< One of the Level I bmkt_mode_t values */
|
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 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 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 */
|
uint8_t finger_presence; /**< Finger presence status value finger on sensor 1 / finger not on sensor 0 */
|
||||||
} bmkt_fps_mode_resp_t;
|
} bmkt_fps_mode_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_get_version_resp:
|
* bmkt_get_version_resp:
|
||||||
* Response payload data structure returned by get version operation.
|
* Response payload data structure returned by get version operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_get_version_resp
|
typedef struct bmkt_get_version_resp
|
||||||
{
|
{
|
||||||
uint8_t part[BMKT_PART_NUM_LEN]; /**< Software Part Number */
|
uint8_t part[BMKT_PART_NUM_LEN]; /**< Software Part Number */
|
||||||
uint8_t year; /**< Software Version Year */
|
uint8_t year; /**< Software Version Year */
|
||||||
uint8_t week; /**< Software Version Week */
|
uint8_t week; /**< Software Version Week */
|
||||||
uint8_t patch; /**< Software Version Patch Level */
|
uint8_t patch; /**< Software Version Patch Level */
|
||||||
uint8_t supplier_id[BMKT_SUPPLIER_ID_LEN]; /**< Software Supplier Identification */
|
uint8_t supplier_id[BMKT_SUPPLIER_ID_LEN]; /**< Software Supplier Identification */
|
||||||
} bmkt_get_version_resp_t;
|
} bmkt_get_version_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_get_db_capacity_resp:
|
* bmkt_get_db_capacity_resp:
|
||||||
* Response payload data structure returned by get DB capacity operation.
|
* Response payload data structure returned by get DB capacity operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_get_db_capacity_resp
|
typedef struct bmkt_get_db_capacity_resp
|
||||||
{
|
{
|
||||||
uint8_t total; /**< Total Available Capacity: Total number of template records that can be stored */
|
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 empty; /**< Free Capacity: Number of template records that can still be stored */
|
||||||
uint8_t bad_slots; /**< Number of bad template storage slots */
|
uint8_t bad_slots; /**< Number of bad template storage slots */
|
||||||
uint8_t corrupt_templates; /**< Number of corrupt templates */
|
uint8_t corrupt_templates; /**< Number of corrupt templates */
|
||||||
} bmkt_get_db_capacity_resp_t;
|
} bmkt_get_db_capacity_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_sec_level:
|
* bmkt_sec_level:
|
||||||
* Security level values.
|
* Security level values.
|
||||||
*/
|
*/
|
||||||
typedef enum bmkt_sec_level
|
typedef enum bmkt_sec_level {
|
||||||
{
|
BMKT_SECURITY_LEVEL_LOW = 0x10,
|
||||||
BMKT_SECURITY_LEVEL_LOW = 0x10,
|
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
|
||||||
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
|
BMKT_SECURITY_LEVEL_HIGH = 0x60,
|
||||||
BMKT_SECURITY_LEVEL_HIGH = 0x60,
|
|
||||||
} bmkt_sec_level_t;
|
} bmkt_sec_level_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_set_sec_level_resp:
|
* bmkt_set_sec_level_resp:
|
||||||
* Response payload data structure returned by get/set security level operations.
|
* Response payload data structure returned by get/set security level operations.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_set_sec_level_resp
|
typedef struct bmkt_set_sec_level_resp
|
||||||
{
|
{
|
||||||
bmkt_sec_level_t sec_level; /**< One of the bmkt_sec_level_t values */
|
bmkt_sec_level_t sec_level; /**< One of the bmkt_sec_level_t values */
|
||||||
} bmkt_set_sec_level_resp_t;
|
} bmkt_set_sec_level_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_del_all_users_resp:
|
* bmkt_del_all_users_resp:
|
||||||
* Response payload data structure returned by delete all enrolled users operation.
|
* Response payload data structure returned by delete all enrolled users operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_del_all_users_resp
|
typedef struct bmkt_del_all_users_resp
|
||||||
{
|
{
|
||||||
int progress; /**< Progress indicator as a percentage */
|
int progress; /**< Progress indicator as a percentage */
|
||||||
} bmkt_del_all_users_resp_t;
|
} bmkt_del_all_users_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_del_user_resp:
|
* bmkt_del_user_resp:
|
||||||
* Response payload data structure returned by delete enrolled user operation.
|
* Response payload data structure returned by delete enrolled user operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_del_user_resp
|
typedef struct bmkt_del_user_resp
|
||||||
{
|
{
|
||||||
int progress; /**< Progress indicator as a percentage */
|
int progress; /**< Progress indicator as a percentage */
|
||||||
} bmkt_del_user_resp_t;
|
} bmkt_del_user_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_enroll_template:
|
* bmkt_enroll_template:
|
||||||
* Structure of enrolled users template record data.
|
* Structure of enrolled users template record data.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_enroll_template
|
typedef struct bmkt_enroll_template
|
||||||
{
|
{
|
||||||
uint8_t user_id_len; /**< Length of user_id string */
|
uint8_t user_id_len; /**< Length of user_id string */
|
||||||
uint8_t template_status; /**< Template record status */
|
uint8_t template_status; /**< Template record status */
|
||||||
uint8_t finger_id; /**< ID of enrolled finger */
|
uint8_t finger_id; /**< ID of enrolled finger */
|
||||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN + 1]; /**< Name of the enrolled user */
|
uint8_t user_id[BMKT_MAX_USER_ID_LEN + 1]; /**< Name of the enrolled user */
|
||||||
} bmkt_enroll_template_t;
|
} bmkt_enroll_template_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_enroll_templates_resp:
|
* bmkt_enroll_templates_resp:
|
||||||
* Response payload data structure returned by get enrolled user list operation.
|
* Response payload data structure returned by get enrolled user list operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_enroll_templates_resp
|
typedef struct bmkt_enroll_templates_resp
|
||||||
{
|
{
|
||||||
uint8_t total_query_messages; /**< Total query response messages */
|
uint8_t total_query_messages; /**< Total query response messages */
|
||||||
uint8_t query_sequence; /**< Query response sequence number */
|
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_template_t templates[BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH]; /**< Enrolled user template records list */
|
||||||
} bmkt_enroll_templates_resp_t;
|
} bmkt_enroll_templates_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_enrolled_fingers:
|
* bmkt_enrolled_fingers:
|
||||||
* Structure of template record status corresponding to each enrolled finger.
|
* Structure of template record status corresponding to each enrolled finger.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_enrolled_fingers
|
typedef struct bmkt_enrolled_fingers
|
||||||
{
|
{
|
||||||
uint8_t finger_id; /**< ID of enrolled finger */
|
uint8_t finger_id; /**< ID of enrolled finger */
|
||||||
uint8_t template_status; /**< Template record status of finger_id */
|
uint8_t template_status; /**< Template record status of finger_id */
|
||||||
} bmkt_enrolled_fingers_t;
|
} bmkt_enrolled_fingers_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_enrolled_fingers_resp:
|
* bmkt_enrolled_fingers_resp:
|
||||||
* Response payload data structure returned by get enrolled fingers operation.
|
* Response payload data structure returned by get enrolled fingers operation.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_enrolled_fingers_resp
|
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_t fingers[10]; /**< List of enroled fingers, max number of supported fingers per user is 10 */
|
||||||
} bmkt_enrolled_fingers_resp_t;
|
} bmkt_enrolled_fingers_resp_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_response_data_t:
|
* bmkt_response_data_t:
|
||||||
* Union combining all response payload data types.
|
* Union combining all response payload data types.
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union
|
||||||
bmkt_init_resp_t init_resp;
|
{
|
||||||
bmkt_enroll_resp_t enroll_resp;
|
bmkt_init_resp_t init_resp;
|
||||||
bmkt_verify_resp_t verify_resp;
|
bmkt_enroll_resp_t enroll_resp;
|
||||||
bmkt_identify_resp_t id_resp;
|
bmkt_verify_resp_t verify_resp;
|
||||||
bmkt_fps_mode_resp_t fps_mode_resp;
|
bmkt_identify_resp_t id_resp;
|
||||||
bmkt_get_version_resp_t get_version_resp;
|
bmkt_fps_mode_resp_t fps_mode_resp;
|
||||||
bmkt_get_db_capacity_resp_t db_cap_resp;
|
bmkt_get_version_resp_t get_version_resp;
|
||||||
bmkt_set_sec_level_resp_t sec_level_resp;
|
bmkt_get_db_capacity_resp_t db_cap_resp;
|
||||||
bmkt_del_all_users_resp_t del_all_users_resp;
|
bmkt_set_sec_level_resp_t sec_level_resp;
|
||||||
bmkt_enroll_templates_resp_t enroll_templates_resp;
|
bmkt_del_all_users_resp_t del_all_users_resp;
|
||||||
bmkt_del_user_resp_t del_user_resp;
|
bmkt_enroll_templates_resp_t enroll_templates_resp;
|
||||||
bmkt_enrolled_fingers_resp_t enrolled_fingers_resp;
|
bmkt_del_user_resp_t del_user_resp;
|
||||||
|
bmkt_enrolled_fingers_resp_t enrolled_fingers_resp;
|
||||||
} bmkt_response_data_t;
|
} bmkt_response_data_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bmkt_response:
|
* bmkt_response:
|
||||||
* Structure to abstract different response structure types in one API
|
* Structure to abstract different response structure types in one API
|
||||||
* to be used in bmkt_resp_cb_t callback function.
|
* to be used in bmkt_resp_cb_t callback function.
|
||||||
*/
|
*/
|
||||||
typedef struct bmkt_response
|
typedef struct bmkt_response
|
||||||
{
|
{
|
||||||
int response_id; /**< Response message ID, one of th BMKT_RSP_XXX */
|
int response_id; /**< Response message ID, one of th BMKT_RSP_XXX */
|
||||||
int result; /**< Operation execution result code */
|
int result; /**< Operation execution result code */
|
||||||
int complete; /**< Operation completion status 1: complete / 0: not completed */
|
int complete; /**< Operation completion status 1: complete / 0: not completed */
|
||||||
bmkt_response_data_t response; /**< Operation specific response union */
|
bmkt_response_data_t response; /**< Operation specific response union */
|
||||||
} bmkt_response_t;
|
} bmkt_response_t;
|
||||||
|
|
||||||
#endif /* _BMKT_RESPONSE_H_ */
|
#endif /* _BMKT_RESPONSE_H_ */
|
||||||
|
|
|
@ -20,61 +20,68 @@
|
||||||
#define _SENSOR_H_
|
#define _SENSOR_H_
|
||||||
|
|
||||||
#include "usb_transport.h"
|
#include "usb_transport.h"
|
||||||
#define BMKT_MAX_PENDING_SESSIONS 2
|
#define BMKT_MAX_PENDING_SESSIONS 2
|
||||||
|
|
||||||
typedef enum bmkt_sensor_state
|
typedef enum bmkt_sensor_state {
|
||||||
{
|
BMKT_SENSOR_STATE_UNINIT = 0,
|
||||||
BMKT_SENSOR_STATE_UNINIT = 0,
|
BMKT_SENSOR_STATE_IDLE,
|
||||||
BMKT_SENSOR_STATE_IDLE,
|
BMKT_SENSOR_STATE_INIT,
|
||||||
BMKT_SENSOR_STATE_INIT,
|
BMKT_SENSOR_STATE_EXIT,
|
||||||
BMKT_SENSOR_STATE_EXIT,
|
|
||||||
} bmkt_sensor_state_t;
|
} bmkt_sensor_state_t;
|
||||||
|
|
||||||
typedef struct bmkt_sensor_drv bmkt_sensor_drv_t;
|
typedef struct bmkt_sensor_drv bmkt_sensor_drv_t;
|
||||||
|
|
||||||
typedef struct bmkt_sensor_version
|
typedef struct bmkt_sensor_version
|
||||||
{
|
{
|
||||||
uint32_t build_time;
|
uint32_t build_time;
|
||||||
uint32_t build_num;
|
uint32_t build_num;
|
||||||
uint8_t version_major;
|
uint8_t version_major;
|
||||||
uint8_t version_minor;
|
uint8_t version_minor;
|
||||||
uint8_t target;
|
uint8_t target;
|
||||||
uint8_t product;
|
uint8_t product;
|
||||||
uint8_t silicon_rev;
|
uint8_t silicon_rev;
|
||||||
uint8_t formal_release;
|
uint8_t formal_release;
|
||||||
uint8_t platform;
|
uint8_t platform;
|
||||||
uint8_t patch;
|
uint8_t patch;
|
||||||
uint8_t serial_number[6];
|
uint8_t serial_number[6];
|
||||||
uint16_t security;
|
uint16_t security;
|
||||||
uint8_t iface;
|
uint8_t iface;
|
||||||
uint8_t device_type;
|
uint8_t device_type;
|
||||||
} bmkt_sensor_version_t;
|
} bmkt_sensor_version_t;
|
||||||
|
|
||||||
typedef struct bmkt_sensor
|
typedef struct bmkt_sensor
|
||||||
{
|
{
|
||||||
bmkt_usb_transport_t usb_xport;
|
bmkt_usb_transport_t usb_xport;
|
||||||
bmkt_sensor_version_t version;
|
bmkt_sensor_version_t version;
|
||||||
bmkt_session_ctx_t pending_sessions[BMKT_MAX_PENDING_SESSIONS];
|
bmkt_session_ctx_t pending_sessions[BMKT_MAX_PENDING_SESSIONS];
|
||||||
int empty_session_idx;
|
int empty_session_idx;
|
||||||
int flags;
|
int flags;
|
||||||
int seq_num;
|
int seq_num;
|
||||||
bmkt_sensor_state_t sensor_state;
|
bmkt_sensor_state_t sensor_state;
|
||||||
bmkt_event_cb_t finger_event_cb;
|
bmkt_event_cb_t finger_event_cb;
|
||||||
void *finger_cb_ctx;
|
void *finger_cb_ctx;
|
||||||
bmkt_general_error_cb_t gen_err_cb;
|
bmkt_general_error_cb_t gen_err_cb;
|
||||||
void *gen_err_cb_ctx;
|
void *gen_err_cb_ctx;
|
||||||
bmkt_op_state_t op_state;
|
bmkt_op_state_t op_state;
|
||||||
} bmkt_sensor_t;
|
} bmkt_sensor_t;
|
||||||
|
|
||||||
int bmkt_sensor_open(bmkt_sensor_t *sensor,
|
int bmkt_sensor_open (bmkt_sensor_t *sensor,
|
||||||
bmkt_general_error_cb_t err_cb, void *err_cb_ctx);
|
bmkt_general_error_cb_t err_cb,
|
||||||
int bmkt_sensor_close(bmkt_sensor_t *sensor);
|
void *err_cb_ctx);
|
||||||
|
int bmkt_sensor_close (bmkt_sensor_t *sensor);
|
||||||
|
|
||||||
int bmkt_sensor_init_fps(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,
|
int bmkt_sensor_send_message (bmkt_sensor_t *sensor,
|
||||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *resp_data);
|
uint8_t msg_id,
|
||||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
uint8_t payload_size,
|
||||||
|
uint8_t *payload,
|
||||||
|
bmkt_resp_cb_t resp_cb,
|
||||||
|
void *resp_data);
|
||||||
|
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);
|
int bmkt_sensor_send_async_read_command (bmkt_sensor_t *sensor);
|
||||||
#endif /* _SENSOR_H_ */
|
#endif /* _SENSOR_H_ */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,109 +22,109 @@
|
||||||
#include "fpi-device.h"
|
#include "fpi-device.h"
|
||||||
#include "fpi-ssm.h"
|
#include "fpi-ssm.h"
|
||||||
|
|
||||||
#define SYNAPTICS_VENDOR_ID 0x06cb
|
#define SYNAPTICS_VENDOR_ID 0x06cb
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceSynaptics, fpi_device_synaptics, FPI, DEVICE_SYNAPTICS, FpDevice)
|
G_DECLARE_FINAL_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FPI, DEVICE_SYNAPTICS, FpDevice)
|
||||||
|
|
||||||
|
|
||||||
#define MAX_TRANSFER_LEN 263 + 1 /* SPI Header */ + 2 /* VCSFW header */
|
#define MAX_TRANSFER_LEN 263 + 1 /* SPI Header */ + 2 /* VCSFW header */
|
||||||
|
|
||||||
#define USB_EP_REQUEST 0x01
|
#define USB_EP_REQUEST 0x01
|
||||||
#define USB_EP_REPLY 0x81
|
#define USB_EP_REPLY 0x81
|
||||||
#define USB_EP_FINGERPRINT 0x82
|
#define USB_EP_FINGERPRINT 0x82
|
||||||
#define USB_EP_INTERRUPT 0x83
|
#define USB_EP_INTERRUPT 0x83
|
||||||
|
|
||||||
#define USB_ASYNC_MESSAGE_PENDING 0x4
|
#define USB_ASYNC_MESSAGE_PENDING 0x4
|
||||||
#define USB_INTERRUPT_DATA_SIZE 7
|
#define USB_INTERRUPT_DATA_SIZE 7
|
||||||
|
|
||||||
#define SENSOR_CMD_GET_VERSION 1
|
#define SENSOR_CMD_GET_VERSION 1
|
||||||
#define SENSOR_CMD_ACE_COMMAND 167
|
#define SENSOR_CMD_ACE_COMMAND 167
|
||||||
#define SENSOR_CMD_ASYNCMSG_READ 168
|
#define SENSOR_CMD_ASYNCMSG_READ 168
|
||||||
|
|
||||||
#define SENSOR_FW_CMD_HEADER_LEN 1
|
#define SENSOR_FW_CMD_HEADER_LEN 1
|
||||||
#define SENSOR_FW_REPLY_HEADER_LEN 2
|
#define SENSOR_FW_REPLY_HEADER_LEN 2
|
||||||
|
|
||||||
|
|
||||||
/* Number of enroll stages */
|
/* Number of enroll stages */
|
||||||
#define ENROLL_SAMPLES 8
|
#define ENROLL_SAMPLES 8
|
||||||
|
|
||||||
|
|
||||||
#define SYNAPTICS_DRIVER_FULLNAME "Synaptics Sensors"
|
#define SYNAPTICS_DRIVER_FULLNAME "Synaptics Sensors"
|
||||||
#include "bmkt.h"
|
#include "bmkt.h"
|
||||||
#include "bmkt_response.h"
|
#include "bmkt_response.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct bmkt_sensor_version
|
typedef struct bmkt_sensor_version
|
||||||
{
|
{
|
||||||
uint32_t build_time;
|
uint32_t build_time;
|
||||||
uint32_t build_num;
|
uint32_t build_num;
|
||||||
uint8_t version_major;
|
uint8_t version_major;
|
||||||
uint8_t version_minor;
|
uint8_t version_minor;
|
||||||
uint8_t target;
|
uint8_t target;
|
||||||
uint8_t product;
|
uint8_t product;
|
||||||
uint8_t silicon_rev;
|
uint8_t silicon_rev;
|
||||||
uint8_t formal_release;
|
uint8_t formal_release;
|
||||||
uint8_t platform;
|
uint8_t platform;
|
||||||
uint8_t patch;
|
uint8_t patch;
|
||||||
uint8_t serial_number[6];
|
uint8_t serial_number[6];
|
||||||
uint16_t security;
|
uint16_t security;
|
||||||
uint8_t iface;
|
uint8_t iface;
|
||||||
uint8_t device_type;
|
uint8_t device_type;
|
||||||
} bmkt_sensor_version_t;
|
} bmkt_sensor_version_t;
|
||||||
|
|
||||||
|
|
||||||
struct syna_enroll_resp_data
|
struct syna_enroll_resp_data
|
||||||
{
|
{
|
||||||
int progress;
|
int progress;
|
||||||
};
|
};
|
||||||
typedef enum syna_state
|
typedef enum syna_state {
|
||||||
{
|
SYNA_STATE_UNINIT = 0,
|
||||||
SYNA_STATE_UNINIT = 0,
|
SYNA_STATE_IDLE,
|
||||||
SYNA_STATE_IDLE ,
|
SYNA_STATE_ENROLL,
|
||||||
SYNA_STATE_ENROLL ,
|
SYNA_STATE_IDENTIFY,
|
||||||
SYNA_STATE_IDENTIFY ,
|
SYNA_STATE_IDENTIFY_DELAY_RESULT,
|
||||||
SYNA_STATE_IDENTIFY_DELAY_RESULT ,
|
SYNA_STATE_VERIFY,
|
||||||
SYNA_STATE_VERIFY ,
|
SYNA_STATE_VERIFY_DELAY_RESULT,
|
||||||
SYNA_STATE_VERIFY_DELAY_RESULT ,
|
SYNA_STATE_DELETE,
|
||||||
SYNA_STATE_DELETE ,
|
|
||||||
} syna_state_t;
|
} syna_state_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
SYNAPTICS_CMD_SEND_PENDING = 0,
|
||||||
SYNAPTICS_CMD_SEND_PENDING = 0,
|
SYNAPTICS_CMD_GET_RESP,
|
||||||
SYNAPTICS_CMD_GET_RESP,
|
SYNAPTICS_CMD_WAIT_INTERRUPT,
|
||||||
SYNAPTICS_CMD_WAIT_INTERRUPT,
|
SYNAPTICS_CMD_SEND_ASYNC,
|
||||||
SYNAPTICS_CMD_SEND_ASYNC,
|
SYNAPTICS_CMD_RESTART,
|
||||||
SYNAPTICS_CMD_RESTART,
|
SYNAPTICS_CMD_NUM_STATES,
|
||||||
SYNAPTICS_CMD_NUM_STATES,
|
|
||||||
} SynapticsCmdState;
|
} SynapticsCmdState;
|
||||||
|
|
||||||
|
|
||||||
typedef void (*SynCmdMsgCallback) (FpiDeviceSynaptics *self, bmkt_response_t *resp, GError *error);
|
typedef void (*SynCmdMsgCallback) (FpiDeviceSynaptics *self,
|
||||||
|
bmkt_response_t *resp,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
struct _FpiDeviceSynaptics
|
struct _FpiDeviceSynaptics
|
||||||
{
|
{
|
||||||
FpDevice parent;
|
FpDevice parent;
|
||||||
|
|
||||||
guint8 cmd_seq_num;
|
guint8 cmd_seq_num;
|
||||||
guint8 last_seq_num;
|
guint8 last_seq_num;
|
||||||
FpiSsm *cmd_ssm;
|
FpiSsm *cmd_ssm;
|
||||||
FpiUsbTransfer *cmd_pending_transfer;
|
FpiUsbTransfer *cmd_pending_transfer;
|
||||||
gboolean cmd_complete_on_removal;
|
gboolean cmd_complete_on_removal;
|
||||||
GError *cmd_complete_error;
|
GError *cmd_complete_error;
|
||||||
void *cmd_complete_data;
|
void *cmd_complete_data;
|
||||||
|
|
||||||
bmkt_sensor_version_t mis_version;
|
bmkt_sensor_version_t mis_version;
|
||||||
|
|
||||||
GCancellable *interrupt_cancellable;
|
GCancellable *interrupt_cancellable;
|
||||||
|
|
||||||
gint enroll_stage;
|
gint enroll_stage;
|
||||||
gboolean finger_on_sensor;
|
gboolean finger_on_sensor;
|
||||||
GPtrArray *list_result;
|
GPtrArray *list_result;
|
||||||
|
|
||||||
|
|
||||||
struct syna_enroll_resp_data enroll_resp_data;
|
struct syna_enroll_resp_data enroll_resp_data;
|
||||||
syna_state_t state;
|
syna_state_t state;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__synaptics_h__
|
#endif //__synaptics_h__
|
||||||
|
|
|
@ -21,46 +21,47 @@
|
||||||
#include "upek_proto.h"
|
#include "upek_proto.h"
|
||||||
|
|
||||||
static const uint16_t crc_table[256] = {
|
static const uint16_t crc_table[256] = {
|
||||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
udf_crc(unsigned char *buffer, size_t size)
|
udf_crc (unsigned char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
while (size--)
|
|
||||||
crc = (uint16_t) ((crc << 8) ^
|
while (size--)
|
||||||
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
crc = (uint16_t) ((crc << 8) ^
|
||||||
return crc;
|
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
||||||
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,4 +21,5 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
uint16_t udf_crc(unsigned char *buffer, size_t size);
|
uint16_t udf_crc (unsigned char *buffer,
|
||||||
|
size_t size);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,297 +23,298 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IMG_WIDTH_2016 288
|
#define IMG_WIDTH_2016 288
|
||||||
#define IMG_WIDTH_1000 288
|
#define IMG_WIDTH_1000 288
|
||||||
#define IMG_WIDTH_1001 216
|
#define IMG_WIDTH_1001 216
|
||||||
|
|
||||||
struct sonly_regwrite {
|
struct sonly_regwrite
|
||||||
guint8 reg;
|
{
|
||||||
guint8 value;
|
guint8 reg;
|
||||||
|
guint8 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** AWAIT FINGER *****/
|
/***** AWAIT FINGER *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_2016_writev_1[] = {
|
static const struct sonly_regwrite awfsm_2016_writev_1[] = {
|
||||||
{ 0x0a, 0x00 }, { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x3b },
|
{ 0x0a, 0x00 }, { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x3b },
|
||||||
{ 0x00, 0x67 }, { 0x00, 0x67 },
|
{ 0x00, 0x67 }, { 0x00, 0x67 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_1000_writev_1[] = {
|
static const struct sonly_regwrite awfsm_1000_writev_1[] = {
|
||||||
/* Initialize sensor settings */
|
/* Initialize sensor settings */
|
||||||
{ 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f },
|
{ 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f },
|
||||||
{ 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d },
|
{ 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d },
|
||||||
{ 0x0e, 0x0e }, { 0x0f, 0x0d },
|
{ 0x0e, 0x0e }, { 0x0f, 0x0d },
|
||||||
|
|
||||||
{ 0x13, 0x05 }, { 0x13, 0x45 },
|
{ 0x13, 0x05 }, { 0x13, 0x45 },
|
||||||
|
|
||||||
/* Initialize finger detection registers (not enabling yet) */
|
/* Initialize finger detection registers (not enabling yet) */
|
||||||
{ 0x30, 0xe0 }, { 0x15, 0x26 },
|
{ 0x30, 0xe0 }, { 0x15, 0x26 },
|
||||||
|
|
||||||
{ 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 },
|
{ 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 },
|
||||||
{ 0x10, 0x00 }, { 0x11, 0xbf },
|
{ 0x10, 0x00 }, { 0x11, 0xbf },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_2016_writev_2[] = {
|
static const struct sonly_regwrite awfsm_2016_writev_2[] = {
|
||||||
{ 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
{ 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
||||||
{ 0x0f, 0x0d }, { 0x0b, 0x00 },
|
{ 0x0f, 0x0d }, { 0x0b, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_1000_writev_2[] = {
|
static const struct sonly_regwrite awfsm_1000_writev_2[] = {
|
||||||
/* Enable finger detection */
|
/* Enable finger detection */
|
||||||
{ 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 },
|
{ 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_2016_writev_3[] = {
|
static const struct sonly_regwrite awfsm_2016_writev_3[] = {
|
||||||
{ 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 },
|
{ 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 },
|
||||||
{ 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 },
|
{ 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_2016_writev_4[] = {
|
static const struct sonly_regwrite awfsm_2016_writev_4[] = {
|
||||||
{ 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf },
|
{ 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf },
|
||||||
{ 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\
|
{ 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 }, \
|
||||||
{ 0x05, 0x00 }, { 0x0b, 0x00 },
|
{ 0x05, 0x00 }, { 0x0b, 0x00 },
|
||||||
|
|
||||||
/* enter finger detection mode */
|
/* enter finger detection mode */
|
||||||
{ 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 },
|
{ 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 },
|
||||||
{ 0x15, 0x84 },
|
{ 0x15, 0x84 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** CAPTURE MODE *****/
|
/***** CAPTURE MODE *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_2016_writev[] = {
|
static const struct sonly_regwrite capsm_2016_writev[] = {
|
||||||
/* enter capture mode */
|
/* enter capture mode */
|
||||||
{ 0x09, 0x28 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, { 0x04, 0x00 },
|
{ 0x09, 0x28 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, { 0x04, 0x00 },
|
||||||
{ 0x05, 0x00 },
|
{ 0x05, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1000_writev[] = {
|
static const struct sonly_regwrite capsm_1000_writev[] = {
|
||||||
{ 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */
|
{ 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1001_writev_1[] = {
|
static const struct sonly_regwrite capsm_1001_writev_1[] = {
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4e, 0x05 },
|
{ 0x4e, 0x05 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1001_writev_2[] = {
|
static const struct sonly_regwrite capsm_1001_writev_2[] = {
|
||||||
{ 0x4d, 0xc0 }, { 0x4e, 0x09 },
|
{ 0x4d, 0xc0 }, { 0x4e, 0x09 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1001_writev_3[] = {
|
static const struct sonly_regwrite capsm_1001_writev_3[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x0b, 0x00 },
|
{ 0x0b, 0x00 },
|
||||||
{ 0x04, 0x00 },
|
{ 0x04, 0x00 },
|
||||||
{ 0x05, 0x00 },
|
{ 0x05, 0x00 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4d, 0x40 }, { 0x4e, 0x09 },
|
{ 0x4d, 0x40 }, { 0x4e, 0x09 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1001_writev_4[] = {
|
static const struct sonly_regwrite capsm_1001_writev_4[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4e, 0x08 },
|
{ 0x4e, 0x08 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_1001_writev_5[] = {
|
static const struct sonly_regwrite capsm_1001_writev_5[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x00, 0x5f }, { 0x01, 0xee },
|
{ 0x00, 0x5f }, { 0x01, 0xee },
|
||||||
{ 0x03, 0x2c },
|
{ 0x03, 0x2c },
|
||||||
{ 0x07, 0x00 }, { 0x08, 0x00 }, { 0x09, 0x29 }, { 0x0a, 0x00 }, { 0x0b, 0x00 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
{ 0x07, 0x00 }, { 0x08, 0x00 }, { 0x09, 0x29 }, { 0x0a, 0x00 }, { 0x0b, 0x00 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
||||||
{ 0x0f, 0x0d }, { 0x10, 0x00 }, { 0x11, 0x8f }, { 0x12, 0x01 }, { 0x13, 0x45 },
|
{ 0x0f, 0x0d }, { 0x10, 0x00 }, { 0x11, 0x8f }, { 0x12, 0x01 }, { 0x13, 0x45 },
|
||||||
{ 0x15, 0x26 },
|
{ 0x15, 0x26 },
|
||||||
{ 0x1e, 0x02 },
|
{ 0x1e, 0x02 },
|
||||||
{ 0x20, 0x01 },
|
{ 0x20, 0x01 },
|
||||||
{ 0x25, 0x8f },
|
{ 0x25, 0x8f },
|
||||||
{ 0x27, 0x23 },
|
{ 0x27, 0x23 },
|
||||||
{ 0x30, 0xe0 },
|
{ 0x30, 0xe0 },
|
||||||
{ 0x07, 0x10 },
|
{ 0x07, 0x10 },
|
||||||
{ 0x09, 0x21 },
|
{ 0x09, 0x21 },
|
||||||
{ 0x13, 0x75 },
|
{ 0x13, 0x75 },
|
||||||
{ 0x0b, 0x80 },
|
{ 0x0b, 0x80 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** DEINITIALIZATION *****/
|
/***** DEINITIALIZATION *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite deinitsm_2016_writev[] = {
|
static const struct sonly_regwrite deinitsm_2016_writev[] = {
|
||||||
/* reset + enter low power mode */
|
/* reset + enter low power mode */
|
||||||
{ 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 },
|
{ 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite deinitsm_1000_writev[] = {
|
static const struct sonly_regwrite deinitsm_1000_writev[] = {
|
||||||
{ 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */
|
{ 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */
|
||||||
|
|
||||||
{ 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */
|
{ 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite deinitsm_1001_writev[] = {
|
static const struct sonly_regwrite deinitsm_1001_writev[] = {
|
||||||
{ 0x0b, 0x00 },
|
{ 0x0b, 0x00 },
|
||||||
{ 0x13, 0x45 },
|
{ 0x13, 0x45 },
|
||||||
{ 0x09, 0x29 },
|
{ 0x09, 0x29 },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** INITIALIZATION *****/
|
/***** INITIALIZATION *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_2016_writev_1[] = {
|
static const struct sonly_regwrite initsm_2016_writev_1[] = {
|
||||||
{ 0x49, 0x00 },
|
{ 0x49, 0x00 },
|
||||||
|
|
||||||
/* BSAPI writes different values to register 0x3e each time. I initially
|
/* BSAPI writes different values to register 0x3e each time. I initially
|
||||||
* thought this was some kind of clever authentication, but just blasting
|
* thought this was some kind of clever authentication, but just blasting
|
||||||
* these sniffed values each time seems to work. */
|
* these sniffed values each time seems to work. */
|
||||||
{ 0x3e, 0x83 }, { 0x3e, 0x4f }, { 0x3e, 0x0f }, { 0x3e, 0xbf },
|
{ 0x3e, 0x83 }, { 0x3e, 0x4f }, { 0x3e, 0x0f }, { 0x3e, 0xbf },
|
||||||
{ 0x3e, 0x45 }, { 0x3e, 0x35 }, { 0x3e, 0x1c }, { 0x3e, 0xae },
|
{ 0x3e, 0x45 }, { 0x3e, 0x35 }, { 0x3e, 0x1c }, { 0x3e, 0xae },
|
||||||
|
|
||||||
{ 0x44, 0x01 }, { 0x43, 0x06 }, { 0x43, 0x05 }, { 0x43, 0x04 },
|
{ 0x44, 0x01 }, { 0x43, 0x06 }, { 0x43, 0x05 }, { 0x43, 0x04 },
|
||||||
{ 0x44, 0x00 }, { 0x0b, 0x00 },
|
{ 0x44, 0x00 }, { 0x0b, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1000_writev_1[] = {
|
static const struct sonly_regwrite initsm_1000_writev_1[] = {
|
||||||
{ 0x49, 0x00 }, /* Encryption disabled */
|
{ 0x49, 0x00 }, /* Encryption disabled */
|
||||||
|
|
||||||
/* Setting encryption key. Doesn't need to be random since we don't use any
|
/* Setting encryption key. Doesn't need to be random since we don't use any
|
||||||
* encryption. */
|
* encryption. */
|
||||||
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
||||||
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
||||||
|
|
||||||
{ 0x04, 0x00 }, { 0x05, 0x00 },
|
{ 0x04, 0x00 }, { 0x05, 0x00 },
|
||||||
|
|
||||||
{ 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */
|
{ 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1001_writev_1[] = {
|
static const struct sonly_regwrite initsm_1001_writev_1[] = {
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4f, 0x06 },
|
{ 0x4f, 0x06 },
|
||||||
{ 0x4f, 0x05 },
|
{ 0x4f, 0x05 },
|
||||||
{ 0x4f, 0x04 },
|
{ 0x4f, 0x04 },
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x3e, 0xa6 },
|
{ 0x3e, 0xa6 },
|
||||||
{ 0x3e, 0x01 },
|
{ 0x3e, 0x01 },
|
||||||
{ 0x3e, 0x68 },
|
{ 0x3e, 0x68 },
|
||||||
{ 0x3e, 0xfd },
|
{ 0x3e, 0xfd },
|
||||||
{ 0x3e, 0x72 },
|
{ 0x3e, 0x72 },
|
||||||
{ 0x3e, 0xef },
|
{ 0x3e, 0xef },
|
||||||
{ 0x3e, 0x5d },
|
{ 0x3e, 0x5d },
|
||||||
{ 0x3e, 0xc5 },
|
{ 0x3e, 0xc5 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4c, 0x1f }, { 0x4d, 0xb8 }, { 0x4e, 0x00 },
|
{ 0x4c, 0x1f }, { 0x4d, 0xb8 }, { 0x4e, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1001_writev_2[] = {
|
static const struct sonly_regwrite initsm_1001_writev_2[] = {
|
||||||
{ 0x4c, 0x03 }, { 0x4d, 0xb8 }, { 0x4e, 0x00 },
|
{ 0x4c, 0x03 }, { 0x4d, 0xb8 }, { 0x4e, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1001_writev_3[] = {
|
static const struct sonly_regwrite initsm_1001_writev_3[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4c, 0xff }, { 0x4d, 0xc0 }, { 0x4e, 0x00 },
|
{ 0x4c, 0xff }, { 0x4d, 0xc0 }, { 0x4e, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1001_writev_4[] = {
|
static const struct sonly_regwrite initsm_1001_writev_4[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x09, 0x27 },
|
{ 0x09, 0x27 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x49, 0x01 },
|
{ 0x49, 0x01 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x0a },
|
{ 0x47, 0x0a },
|
||||||
{ 0x47, 0x00 },
|
{ 0x47, 0x00 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x0a },
|
{ 0x47, 0x0a },
|
||||||
{ 0x47, 0x00 },
|
{ 0x47, 0x00 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x0a },
|
{ 0x47, 0x0a },
|
||||||
{ 0x47, 0x00 },
|
{ 0x47, 0x00 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x02 },
|
{ 0x47, 0x02 },
|
||||||
{ 0x47, 0x0a },
|
{ 0x47, 0x0a },
|
||||||
{ 0x47, 0x00 },
|
{ 0x47, 0x00 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x47, 0x04 },
|
{ 0x47, 0x04 },
|
||||||
{ 0x49, 0x00 },
|
{ 0x49, 0x00 },
|
||||||
{ 0x3e, 0x90 },
|
{ 0x3e, 0x90 },
|
||||||
{ 0x3e, 0xbd },
|
{ 0x3e, 0xbd },
|
||||||
{ 0x3e, 0xbf },
|
{ 0x3e, 0xbf },
|
||||||
{ 0x3e, 0x48 },
|
{ 0x3e, 0x48 },
|
||||||
{ 0x3e, 0x2a },
|
{ 0x3e, 0x2a },
|
||||||
{ 0x3e, 0xe3 },
|
{ 0x3e, 0xe3 },
|
||||||
{ 0x3e, 0xd2 },
|
{ 0x3e, 0xd2 },
|
||||||
{ 0x3e, 0x58 },
|
{ 0x3e, 0x58 },
|
||||||
{ 0x09, 0x2f },
|
{ 0x09, 0x2f },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
{ 0x1a, 0x02 },
|
{ 0x1a, 0x02 },
|
||||||
{ 0x4a, 0x9d },
|
{ 0x4a, 0x9d },
|
||||||
{ 0x4d, 0x40 }, { 0x4e, 0x03 },
|
{ 0x4d, 0x40 }, { 0x4e, 0x03 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_1001_writev_5[] = {
|
static const struct sonly_regwrite initsm_1001_writev_5[] = {
|
||||||
{ 0x4a, 0x9c },
|
{ 0x4a, 0x9c },
|
||||||
{ 0x1a, 0x00 },
|
{ 0x1a, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,412 +29,456 @@
|
||||||
#define UPEKET_EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
#define UPEKET_EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
struct _FpiDeviceUpektc {
|
struct _FpiDeviceUpektc
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
const struct setup_cmd *setup_commands;
|
const struct setup_cmd *setup_commands;
|
||||||
size_t setup_commands_len;
|
size_t setup_commands_len;
|
||||||
int ep_in;
|
int ep_in;
|
||||||
int ep_out;
|
int ep_out;
|
||||||
int init_idx;
|
int init_idx;
|
||||||
int sum_threshold;
|
int sum_threshold;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceUpektc, fpi_device_upektc, FPI, DEVICE_UPEKTC,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUpektc, fpi_device_upektc, FPI, DEVICE_UPEKTC,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpiDeviceUpektc, fpi_device_upektc, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceUpektc, fpi_device_upektc, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
enum upektc_driver_data {
|
enum upektc_driver_data {
|
||||||
UPEKTC_2015,
|
UPEKTC_2015,
|
||||||
UPEKTC_3001,
|
UPEKTC_3001,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev);
|
static void start_capture (FpImageDevice *dev);
|
||||||
static void complete_deactivation(FpImageDevice *dev, GError *error);
|
static void complete_deactivation (FpImageDevice *dev,
|
||||||
static void start_finger_detection(FpImageDevice *dev);
|
GError *error);
|
||||||
|
static void start_finger_detection (FpImageDevice *dev);
|
||||||
|
|
||||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||||
|
|
||||||
enum activate_states {
|
enum activate_states {
|
||||||
WRITE_INIT,
|
WRITE_INIT,
|
||||||
READ_DATA,
|
READ_DATA,
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
upektc_next_init_cmd(FpiSsm *ssm,
|
upektc_next_init_cmd (FpiSsm *ssm,
|
||||||
FpImageDevice *dev)
|
FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
self->init_idx += 1;
|
self->init_idx += 1;
|
||||||
if (self->init_idx == self->setup_commands_len)
|
if (self->init_idx == self->setup_commands_len)
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_jump_to_state(ssm, WRITE_INIT);
|
fpi_ssm_jump_to_state (ssm, WRITE_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
write_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
if (!error) {
|
if (!error)
|
||||||
if (self->setup_commands[self->init_idx].response_len)
|
{
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
if (self->setup_commands[self->init_idx].response_len)
|
||||||
else
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
upektc_next_init_cmd(transfer->ssm, dev);
|
else
|
||||||
} else {
|
upektc_next_init_cmd (transfer->ssm, dev);
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_init_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
read_init_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
upektc_next_init_cmd(transfer->ssm, dev);
|
upektc_next_init_cmd (transfer->ssm, dev);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
activate_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case WRITE_INIT:
|
{
|
||||||
{
|
case WRITE_INIT:
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer,
|
fpi_usb_transfer_fill_bulk_full (transfer,
|
||||||
self->ep_out,
|
self->ep_out,
|
||||||
(unsigned char *) self->setup_commands[self->init_idx].cmd,
|
(unsigned char *) self->setup_commands[self->init_idx].cmd,
|
||||||
UPEKTC_CMD_LEN,
|
UPEKTC_CMD_LEN,
|
||||||
NULL);
|
NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
write_init_cb, NULL);
|
write_init_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_DATA:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer,
|
case READ_DATA:
|
||||||
self->ep_in,
|
{
|
||||||
self->setup_commands[self->init_idx].response_len);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
transfer->ssm = ssm;
|
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_fill_bulk (transfer,
|
||||||
read_init_data_cb, NULL);
|
self->ep_in,
|
||||||
fpi_usb_transfer_unref(transfer);
|
self->setup_commands[self->init_idx].response_len);
|
||||||
}
|
transfer->ssm = ssm;
|
||||||
break;
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
}
|
read_init_data_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
void *user_data, GError *error)
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(_dev);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
|
|
||||||
fpi_image_device_activate_complete(dev, error);
|
fpi_image_device_activate_complete (dev, error);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****** FINGER PRESENCE DETECTION ******/
|
/****** FINGER PRESENCE DETECTION ******/
|
||||||
|
|
||||||
static int finger_present(unsigned char *img, size_t len, int sum_threshold)
|
static int
|
||||||
|
finger_present (unsigned char *img, size_t len, int sum_threshold)
|
||||||
{
|
{
|
||||||
int i, sum;
|
int i, sum;
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++)
|
||||||
if (img[i] < 160) {
|
if (img[i] < 160)
|
||||||
sum++;
|
sum++;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_dbg("finger_present: sum is %d\n", sum);
|
fp_dbg ("finger_present: sum is %d\n", sum);
|
||||||
return sum < sum_threshold ? 0 : 1;
|
return sum < sum_threshold ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("data transfer status %s\n", error->message);
|
{
|
||||||
fpi_image_device_session_error(dev, error);
|
fp_dbg ("data transfer status %s\n", error->message);
|
||||||
return;
|
fpi_image_device_session_error (dev, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (finger_present(transfer->buffer, IMAGE_SIZE, self->sum_threshold)) {
|
if (finger_present (transfer->buffer, IMAGE_SIZE, self->sum_threshold))
|
||||||
/* finger present, start capturing */
|
{
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
/* finger present, start capturing */
|
||||||
start_capture(dev);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
} else {
|
start_capture (dev);
|
||||||
/* no finger, poll for a new histogram */
|
}
|
||||||
start_finger_detection(dev);
|
else
|
||||||
}
|
{
|
||||||
|
/* no finger, poll for a new histogram */
|
||||||
|
start_finger_detection (dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_cmd_cb(FpiUsbTransfer *t, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
finger_det_cmd_cb (FpiUsbTransfer *t, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("req transfer status %s\n", error->message);
|
{
|
||||||
fpi_image_device_session_error(dev, error);
|
fp_dbg ("req transfer status %s\n", error->message);
|
||||||
return;
|
fpi_image_device_session_error (dev, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new (device);
|
transfer = fpi_usb_transfer_new (device);
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk(transfer, self->ep_in,
|
fpi_usb_transfer_fill_bulk (transfer, self->ep_in,
|
||||||
IMAGE_SIZE);
|
IMAGE_SIZE);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
finger_det_data_cb, NULL);
|
finger_det_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_finger_detection(FpImageDevice *dev)
|
static void
|
||||||
|
start_finger_detection (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
|
||||||
if (self->deactivating) {
|
G_DEBUG_HERE ();
|
||||||
complete_deactivation(dev, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
if (self->deactivating)
|
||||||
transfer->short_is_error = TRUE;
|
{
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, self->ep_out,
|
complete_deactivation (dev, NULL);
|
||||||
(unsigned char *)scan_cmd,
|
return;
|
||||||
UPEKTC_CMD_LEN, NULL);
|
}
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
|
||||||
finger_det_cmd_cb, NULL);
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
fpi_usb_transfer_unref(transfer);
|
transfer->short_is_error = TRUE;
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, self->ep_out,
|
||||||
|
(unsigned char *) scan_cmd,
|
||||||
|
UPEKTC_CMD_LEN, NULL);
|
||||||
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
|
finger_det_cmd_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
|
||||||
enum capture_states {
|
enum capture_states {
|
||||||
CAPTURE_WRITE_CMD,
|
CAPTURE_WRITE_CMD,
|
||||||
CAPTURE_READ_DATA,
|
CAPTURE_READ_DATA,
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
capture_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("request is not completed, %s", error->message);
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fp_dbg ("request is not completed, %s", error->message);
|
||||||
return;
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
img = fp_image_new(IMAGE_WIDTH, IMAGE_HEIGHT);
|
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||||
memcpy(img->data, transfer->buffer, IMAGE_SIZE);
|
memcpy (img->data, transfer->buffer, IMAGE_SIZE);
|
||||||
fpi_image_device_image_captured(dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
fpi_image_device_report_finger_status(dev, FALSE);
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(_dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (_dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case CAPTURE_WRITE_CMD:
|
{
|
||||||
{
|
case CAPTURE_WRITE_CMD:
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, self->ep_out,
|
fpi_usb_transfer_fill_bulk_full (transfer, self->ep_out,
|
||||||
(unsigned char *)scan_cmd,
|
(unsigned char *) scan_cmd,
|
||||||
UPEKTC_CMD_LEN, NULL);
|
UPEKTC_CMD_LEN, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
capture_cmd_cb, NULL);
|
capture_cmd_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
|
||||||
{
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk(transfer, self->ep_in,
|
case CAPTURE_READ_DATA:
|
||||||
IMAGE_SIZE);
|
{
|
||||||
transfer->ssm = ssm;
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
transfer->short_is_error = TRUE;
|
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_fill_bulk (transfer, self->ep_in,
|
||||||
capture_read_data_cb, NULL);
|
IMAGE_SIZE);
|
||||||
fpi_usb_transfer_unref(transfer);
|
transfer->ssm = ssm;
|
||||||
}
|
transfer->short_is_error = TRUE;
|
||||||
break;
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
};
|
capture_read_data_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
GError *error)
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(_dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (_dev);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg ("Capture completed");
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
complete_deactivation(dev, error);
|
complete_deactivation (dev, error);
|
||||||
else if (error)
|
else if (error)
|
||||||
fpi_image_device_session_error(dev, error);
|
fpi_image_device_session_error (dev, error);
|
||||||
else
|
else
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev, NULL);
|
{
|
||||||
return;
|
complete_deactivation (dev, NULL);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
|
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
|
||||||
CAPTURE_NUM_STATES, dev);
|
CAPTURE_NUM_STATES, dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start (ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), activate_run_state,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES, dev);
|
||||||
self->init_idx = 0;
|
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
self->init_idx = 0;
|
||||||
|
fpi_ssm_start (ssm, activate_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
|
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(FpImageDevice *dev, GError *error)
|
static void
|
||||||
|
complete_deactivation (FpImageDevice *dev, GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
G_DEBUG_HERE ();
|
||||||
fpi_image_device_deactivate_complete(dev, error);
|
|
||||||
|
self->deactivating = FALSE;
|
||||||
|
fpi_image_device_deactivate_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_init(FpImageDevice *dev)
|
static void
|
||||||
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
|
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||||
guint64 driver_data = fpi_device_get_driver_data (FP_DEVICE (dev));
|
guint64 driver_data = fpi_device_get_driver_data (FP_DEVICE (dev));
|
||||||
|
|
||||||
/* TODO check that device has endpoints we're using */
|
/* TODO check that device has endpoints we're using */
|
||||||
|
|
||||||
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
|
||||||
fpi_image_device_open_complete(dev, error);
|
{
|
||||||
return;
|
fpi_image_device_open_complete (dev, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (driver_data) {
|
switch (driver_data)
|
||||||
case UPEKTC_2015:
|
{
|
||||||
self->ep_in = UPEKTC_EP_IN;
|
case UPEKTC_2015:
|
||||||
self->ep_out = UPEKTC_EP_OUT;
|
self->ep_in = UPEKTC_EP_IN;
|
||||||
self->setup_commands = upektc_setup_commands;
|
self->ep_out = UPEKTC_EP_OUT;
|
||||||
self->setup_commands_len = G_N_ELEMENTS(upektc_setup_commands);
|
self->setup_commands = upektc_setup_commands;
|
||||||
self->sum_threshold = UPEKTC_SUM_THRESHOLD;
|
self->setup_commands_len = G_N_ELEMENTS (upektc_setup_commands);
|
||||||
break;
|
self->sum_threshold = UPEKTC_SUM_THRESHOLD;
|
||||||
case UPEKTC_3001:
|
break;
|
||||||
self->ep_in = UPEKET_EP_IN;
|
|
||||||
self->ep_out = UPEKET_EP_OUT;
|
case UPEKTC_3001:
|
||||||
self->setup_commands = upeket_setup_commands;
|
self->ep_in = UPEKET_EP_IN;
|
||||||
self->setup_commands_len = G_N_ELEMENTS(upeket_setup_commands);
|
self->ep_out = UPEKET_EP_OUT;
|
||||||
self->sum_threshold = UPEKET_SUM_THRESHOLD;
|
self->setup_commands = upeket_setup_commands;
|
||||||
break;
|
self->setup_commands_len = G_N_ELEMENTS (upeket_setup_commands);
|
||||||
default:
|
self->sum_threshold = UPEKET_SUM_THRESHOLD;
|
||||||
fp_err("Device variant %lu is not known\n", driver_data);
|
break;
|
||||||
g_assert_not_reached ();
|
|
||||||
fpi_image_device_open_complete(dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
default:
|
||||||
return;
|
fp_err ("Device variant %lu is not known\n", driver_data);
|
||||||
}
|
g_assert_not_reached ();
|
||||||
fpi_image_device_open_complete(dev, NULL);
|
fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deinit (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x0483, .pid = 0x2015, .driver_data = UPEKTC_2015 },
|
{ .vid = 0x0483, .pid = 0x2015, .driver_data = UPEKTC_2015 },
|
||||||
{ .vid = 0x147e, .pid = 0x3001, .driver_data = UPEKTC_3001 },
|
{ .vid = 0x147e, .pid = 0x3001, .driver_data = UPEKTC_3001 },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_upektc_init(FpiDeviceUpektc *self) {
|
static void
|
||||||
|
fpi_device_upektc_init (FpiDeviceUpektc *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_upektc_class_init(FpiDeviceUpektcClass *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_upektc_class_init (FpiDeviceUpektcClass *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "upektc";
|
dev_class->id = "upektc";
|
||||||
dev_class->full_name = "UPEK TouchChip/Eikon Touch 300";
|
dev_class->full_name = "UPEK TouchChip/Eikon Touch 300";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||||
|
|
||||||
img_class->img_open = dev_init;
|
img_class->img_open = dev_init;
|
||||||
img_class->img_close = dev_deinit;
|
img_class->img_close = dev_deinit;
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
img_class->bz3_threshold = 30;
|
img_class->bz3_threshold = 30;
|
||||||
|
|
||||||
img_class->img_width = IMAGE_WIDTH;
|
img_class->img_width = IMAGE_WIDTH;
|
||||||
img_class->img_height = IMAGE_HEIGHT;
|
img_class->img_height = IMAGE_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -21,124 +21,124 @@
|
||||||
#define __UPEKTC_IMG_H
|
#define __UPEKTC_IMG_H
|
||||||
|
|
||||||
static const unsigned char upek2020_init_1[] = {
|
static const unsigned char upek2020_init_1[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x04,
|
0x04,
|
||||||
0x00, 0x0d,
|
0x00, 0x0d,
|
||||||
0x01, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
0x01, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x01, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00,
|
||||||
0xda, 0xc1
|
0xda, 0xc1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_init_2[] = {
|
static const unsigned char upek2020_init_2[] = {
|
||||||
0x43, 0x69, 0x61, 0x6f,
|
0x43, 0x69, 0x61, 0x6f,
|
||||||
0x07,
|
0x07,
|
||||||
0x00, 0x01,
|
0x00, 0x01,
|
||||||
0x01,
|
0x01,
|
||||||
0x3d, 0x72
|
0x3d, 0x72
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_init_3[] = {
|
static const unsigned char upek2020_init_3[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x04,
|
0x04,
|
||||||
0x00, 0x0d,
|
0x00, 0x0d,
|
||||||
0x01, 0x00, 0xbc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,
|
0x01, 0x00, 0xbc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x01, 0x00, 0x00, 0x00,
|
0x01, 0x00, 0x00, 0x00,
|
||||||
0x55, 0x2f
|
0x55, 0x2f
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_init_4[] = {
|
static const unsigned char upek2020_init_4[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x00,
|
0x00,
|
||||||
0x00, 0x07,
|
0x00, 0x07,
|
||||||
0x28, 0x04, 0x00, 0x00, 0x00, 0x06, 0x04,
|
0x28, 0x04, 0x00, 0x00, 0x00, 0x06, 0x04,
|
||||||
0xc0, 0xd6
|
0xc0, 0xd6
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_deinit[] = {
|
static const unsigned char upek2020_deinit[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x07,
|
0x07,
|
||||||
0x00, 0x01,
|
0x00, 0x01,
|
||||||
0x01,
|
0x01,
|
||||||
0x3d,
|
0x3d,
|
||||||
0x72
|
0x72
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_init_capture[] = {
|
static const unsigned char upek2020_init_capture[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x00,
|
0x00,
|
||||||
0x00, 0x0e, /* Seq = 7, len = 0x00e */
|
0x00, 0x0e, /* Seq = 7, len = 0x00e */
|
||||||
0x28, /* CMD = 0x28 */
|
0x28, /* CMD = 0x28 */
|
||||||
0x0b, 0x00, /* Inner len = 0x000b */
|
0x0b, 0x00, /* Inner len = 0x000b */
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
0x0e, /* SUBCMD = 0x0e */
|
0x0e, /* SUBCMD = 0x0e */
|
||||||
0x02,
|
0x02,
|
||||||
0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */
|
0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */
|
||||||
0x02,
|
0x02,
|
||||||
0x00, /* Wait for acceptable finger */
|
0x00, /* Wait for acceptable finger */
|
||||||
0x02,
|
0x02,
|
||||||
0x14, 0x9a /* CRC */
|
0x14, 0x9a /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static const unsigned char finger_status[] = {
|
static const unsigned char finger_status[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x00,
|
0x00,
|
||||||
0x70, 0x14, /* Seq = 7, len = 0x014 */
|
0x70, 0x14, /* Seq = 7, len = 0x014 */
|
||||||
0x28, /* CMD = 0x28 */
|
0x28, /* CMD = 0x28 */
|
||||||
0x11, 0x00, /* Inner len = 0x0011 */
|
0x11, 0x00, /* Inner len = 0x0011 */
|
||||||
0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
|
||||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00,
|
0x00,
|
||||||
0x26, 0x03, /* CRC */
|
0x26, 0x03, /* CRC */
|
||||||
0x00, 0x00, 0x00, /* Rest is garbage */
|
0x00, 0x00, 0x00, /* Rest is garbage */
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const unsigned char upek2020_ack_00_28[] = {
|
static const unsigned char upek2020_ack_00_28[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x00,
|
0x00,
|
||||||
0x80, 0x08, /* Seq = 8, len = 0x008 */
|
0x80, 0x08, /* Seq = 8, len = 0x008 */
|
||||||
0x28, /* CMD = 0x28 */
|
0x28, /* CMD = 0x28 */
|
||||||
0x05, 0x00, /* Inner len = 0x0005 */
|
0x05, 0x00, /* Inner len = 0x0005 */
|
||||||
0x00, 0x00, 0x00, 0x30, 0x01,
|
0x00, 0x00, 0x00, 0x30, 0x01,
|
||||||
0x6a, 0xc4 /* CRC */
|
0x6a, 0xc4 /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* No seq should be tracked here */
|
/* No seq should be tracked here */
|
||||||
static const unsigned char got_finger[] = {
|
static const unsigned char got_finger[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x08,
|
0x08,
|
||||||
0x00, 0x00, /* Seq = 0, len = 0x000 */
|
0x00, 0x00, /* Seq = 0, len = 0x000 */
|
||||||
0xa1, 0xa9, /* CRC */
|
0xa1, 0xa9, /* CRC */
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest is garbage */
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest is garbage */
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* No seq should be put in there */
|
/* No seq should be put in there */
|
||||||
static const unsigned char upek2020_ack_08[] = {
|
static const unsigned char upek2020_ack_08[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x09,
|
0x09,
|
||||||
0x00, 0x00, /* Seq = 0, len = 0x0 */
|
0x00, 0x00, /* Seq = 0, len = 0x0 */
|
||||||
0x91, 0x9e /* CRC */
|
0x91, 0x9e /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char upek2020_ack_frame[] = {
|
static const unsigned char upek2020_ack_frame[] = {
|
||||||
'C', 'i', 'a', 'o',
|
'C', 'i', 'a', 'o',
|
||||||
0x00,
|
0x00,
|
||||||
0x50, 0x01, /* Seq = 5, len = 0x001 */
|
0x50, 0x01, /* Seq = 5, len = 0x001 */
|
||||||
0x30,
|
0x30,
|
||||||
0xac, 0x5b /* CRC */
|
0xac, 0x5b /* CRC */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -28,109 +28,112 @@
|
||||||
* powerdown? does windows do anything special on exit?
|
* powerdown? does windows do anything special on exit?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CTRL_TIMEOUT 1000
|
#define CTRL_TIMEOUT 1000
|
||||||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
|
|
||||||
#define IMG_WIDTH 300
|
#define IMG_WIDTH 300
|
||||||
#define IMG_HEIGHT 288
|
#define IMG_HEIGHT 288
|
||||||
#define ROWS_PER_RQ 12
|
#define ROWS_PER_RQ 12
|
||||||
#define NR_REQS (IMG_HEIGHT / ROWS_PER_RQ)
|
#define NR_REQS (IMG_HEIGHT / ROWS_PER_RQ)
|
||||||
#define RQ_SIZE (IMG_WIDTH * ROWS_PER_RQ)
|
#define RQ_SIZE (IMG_WIDTH * ROWS_PER_RQ)
|
||||||
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
|
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
|
||||||
|
|
||||||
struct _FpDeviceVcom5s {
|
struct _FpDeviceVcom5s
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
int capture_iteration;
|
int capture_iteration;
|
||||||
FpImage *capture_img;
|
FpImage *capture_img;
|
||||||
gboolean loop_running;
|
gboolean loop_running;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpDeviceVcom5s, fpi_device_vcom5s, FPI, DEVICE_VCOM5S,
|
G_DECLARE_FINAL_TYPE (FpDeviceVcom5s, fpi_device_vcom5s, FPI, DEVICE_VCOM5S,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpDeviceVcom5s, fpi_device_vcom5s, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpDeviceVcom5s, fpi_device_vcom5s, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
enum v5s_regs {
|
enum v5s_regs {
|
||||||
/* when using gain 0x29:
|
/* when using gain 0x29:
|
||||||
* a value of 0x00 produces mostly-black image
|
* a value of 0x00 produces mostly-black image
|
||||||
* 0x09 destroys ridges (too white)
|
* 0x09 destroys ridges (too white)
|
||||||
* 0x01 or 0x02 seem good values */
|
* 0x01 or 0x02 seem good values */
|
||||||
REG_CONTRAST = 0x02,
|
REG_CONTRAST = 0x02,
|
||||||
|
|
||||||
/* when using contrast 0x01:
|
/* when using contrast 0x01:
|
||||||
* a value of 0x00 will produce an all-black image.
|
* a value of 0x00 will produce an all-black image.
|
||||||
* 0x29 produces a good contrast image: ridges quite dark, but some
|
* 0x29 produces a good contrast image: ridges quite dark, but some
|
||||||
* light grey noise as background
|
* light grey noise as background
|
||||||
* 0x46 produces all-white image with grey ridges (not very dark) */
|
* 0x46 produces all-white image with grey ridges (not very dark) */
|
||||||
REG_GAIN = 0x03,
|
REG_GAIN = 0x03,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum v5s_cmd {
|
enum v5s_cmd {
|
||||||
/* scan one row. has parameter, at a guess this is which row to scan? */
|
/* scan one row. has parameter, at a guess this is which row to scan? */
|
||||||
CMD_SCAN_ONE_ROW = 0xc0,
|
CMD_SCAN_ONE_ROW = 0xc0,
|
||||||
|
|
||||||
/* scan whole image */
|
/* scan whole image */
|
||||||
CMD_SCAN = 0xc1,
|
CMD_SCAN = 0xc1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***** REGISTER I/O *****/
|
/***** REGISTER I/O *****/
|
||||||
|
|
||||||
static void sm_write_reg_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
sm_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_write_reg(FpiSsm *ssm,
|
sm_write_reg (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
unsigned char reg,
|
unsigned char reg,
|
||||||
unsigned char value)
|
unsigned char value)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fp_dbg("set %02x=%02x", reg, value);
|
fp_dbg ("set %02x=%02x", reg, value);
|
||||||
fpi_usb_transfer_fill_control(transfer,
|
fpi_usb_transfer_fill_control (transfer,
|
||||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||||
reg, value, 0, 0);
|
reg, value, 0, 0);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb,
|
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb,
|
||||||
NULL);
|
NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
|
||||||
|
|
||||||
static void sm_exec_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|
||||||
gpointer user_data, GError *error)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
|
||||||
else
|
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_exec_cmd(FpiSsm *ssm,
|
sm_exec_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
FpDevice *dev,
|
gpointer user_data, GError *error)
|
||||||
unsigned char cmd,
|
|
||||||
unsigned char param)
|
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
if (error)
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
else
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
|
|
||||||
fp_dbg("cmd %02x param %02x", cmd, param);
|
static void
|
||||||
fpi_usb_transfer_fill_control(transfer,
|
sm_exec_cmd (FpiSsm *ssm,
|
||||||
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
FpDevice *dev,
|
||||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
unsigned char cmd,
|
||||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
unsigned char param)
|
||||||
cmd, param, 0, 0);
|
{
|
||||||
transfer->ssm = ssm;
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
|
|
||||||
NULL);
|
fp_dbg ("cmd %02x param %02x", cmd, param);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_fill_control (transfer,
|
||||||
|
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
||||||
|
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||||
|
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||||
|
cmd, param, 0, 0);
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
|
||||||
|
NULL);
|
||||||
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** FINGER DETECTION *****/
|
/***** FINGER DETECTION *****/
|
||||||
|
@ -145,217 +148,246 @@ sm_exec_cmd(FpiSsm *ssm,
|
||||||
#define DETBOX_COL_END (DETBOX_COL_START + DETBOX_COLS)
|
#define DETBOX_COL_END (DETBOX_COL_START + DETBOX_COLS)
|
||||||
#define FINGER_PRESENCE_THRESHOLD 100
|
#define FINGER_PRESENCE_THRESHOLD 100
|
||||||
|
|
||||||
static gboolean finger_is_present(unsigned char *data)
|
static gboolean
|
||||||
|
finger_is_present (unsigned char *data)
|
||||||
{
|
{
|
||||||
int row;
|
int row;
|
||||||
guint16 imgavg = 0;
|
guint16 imgavg = 0;
|
||||||
|
|
||||||
for (row = DETBOX_ROW_START; row < DETBOX_ROW_END; row++) {
|
for (row = DETBOX_ROW_START; row < DETBOX_ROW_END; row++)
|
||||||
unsigned char *rowdata = data + (row * IMG_WIDTH);
|
{
|
||||||
guint16 rowavg = 0;
|
unsigned char *rowdata = data + (row * IMG_WIDTH);
|
||||||
int col;
|
guint16 rowavg = 0;
|
||||||
|
int col;
|
||||||
|
|
||||||
for (col = DETBOX_COL_START; col < DETBOX_COL_END; col++)
|
for (col = DETBOX_COL_START; col < DETBOX_COL_END; col++)
|
||||||
rowavg += rowdata[col];
|
rowavg += rowdata[col];
|
||||||
rowavg /= DETBOX_COLS;
|
rowavg /= DETBOX_COLS;
|
||||||
imgavg += rowavg;
|
imgavg += rowavg;
|
||||||
}
|
}
|
||||||
imgavg /= DETBOX_ROWS;
|
imgavg /= DETBOX_ROWS;
|
||||||
fp_dbg("img avg %d", imgavg);
|
fp_dbg ("img avg %d", imgavg);
|
||||||
|
|
||||||
return (imgavg <= FINGER_PRESENCE_THRESHOLD);
|
return imgavg <= FINGER_PRESENCE_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***** IMAGE ACQUISITION *****/
|
/***** IMAGE ACQUISITION *****/
|
||||||
|
|
||||||
static void capture_iterate(FpiSsm *ssm, FpDevice *dev);
|
static void capture_iterate (FpiSsm *ssm,
|
||||||
|
FpDevice *dev);
|
||||||
|
|
||||||
static void capture_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
gpointer user_data, GError *error)
|
capture_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *imgdev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *imgdev = FP_IMAGE_DEVICE (device);
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(device);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (device);
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
{
|
||||||
return;
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (++self->capture_iteration == NR_REQS) {
|
if (++self->capture_iteration == NR_REQS)
|
||||||
FpImage *img = self->capture_img;
|
{
|
||||||
/* must clear this early, otherwise the call chain takes us into
|
FpImage *img = self->capture_img;
|
||||||
* loopsm_complete where we would free it, when in fact we are
|
/* must clear this early, otherwise the call chain takes us into
|
||||||
* supposed to be handing off this image */
|
* loopsm_complete where we would free it, when in fact we are
|
||||||
self->capture_img = NULL;
|
* supposed to be handing off this image */
|
||||||
|
self->capture_img = NULL;
|
||||||
|
|
||||||
fpi_image_device_report_finger_status(imgdev,
|
fpi_image_device_report_finger_status (imgdev,
|
||||||
finger_is_present(img->data));
|
finger_is_present (img->data));
|
||||||
fpi_image_device_image_captured(imgdev, img);
|
fpi_image_device_image_captured (imgdev, img);
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
}
|
||||||
capture_iterate(transfer->ssm, device);
|
else
|
||||||
}
|
{
|
||||||
|
capture_iterate (transfer->ssm, device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
capture_iterate(FpiSsm *ssm,
|
capture_iterate (FpiSsm *ssm,
|
||||||
FpDevice *dev)
|
FpDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
int iteration = self->capture_iteration;
|
int iteration = self->capture_iteration;
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
|
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk_full (transfer,
|
fpi_usb_transfer_fill_bulk_full (transfer,
|
||||||
EP_IN,
|
EP_IN,
|
||||||
self->capture_img->data + (RQ_SIZE * iteration),
|
self->capture_img->data + (RQ_SIZE * iteration),
|
||||||
RQ_SIZE,
|
RQ_SIZE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, capture_cb, NULL);
|
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, capture_cb, NULL);
|
||||||
fpi_usb_transfer_unref (transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sm_do_capture(FpiSsm *ssm,
|
sm_do_capture (FpiSsm *ssm,
|
||||||
FpDevice *dev)
|
FpDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (dev);
|
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
self->capture_img = fp_image_new (cls->img_width, cls->img_height);
|
self->capture_img = fp_image_new (cls->img_width, cls->img_height);
|
||||||
self->capture_iteration = 0;
|
self->capture_iteration = 0;
|
||||||
capture_iterate(ssm, dev);
|
capture_iterate (ssm, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** CAPTURE LOOP *****/
|
/***** CAPTURE LOOP *****/
|
||||||
|
|
||||||
enum loop_states {
|
enum loop_states {
|
||||||
LOOP_SET_CONTRAST,
|
LOOP_SET_CONTRAST,
|
||||||
LOOP_SET_GAIN,
|
LOOP_SET_GAIN,
|
||||||
LOOP_CMD_SCAN,
|
LOOP_CMD_SCAN,
|
||||||
LOOP_CAPTURE,
|
LOOP_CAPTURE,
|
||||||
LOOP_CAPTURE_DONE,
|
LOOP_CAPTURE_DONE,
|
||||||
LOOP_NUM_STATES,
|
LOOP_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void loop_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
loop_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case LOOP_SET_CONTRAST:
|
{
|
||||||
sm_write_reg(ssm, dev, REG_CONTRAST, 0x01);
|
case LOOP_SET_CONTRAST:
|
||||||
break;
|
sm_write_reg (ssm, dev, REG_CONTRAST, 0x01);
|
||||||
case LOOP_SET_GAIN:
|
break;
|
||||||
sm_write_reg(ssm, dev, REG_GAIN, 0x29);
|
|
||||||
break;
|
case LOOP_SET_GAIN:
|
||||||
case LOOP_CMD_SCAN:
|
sm_write_reg (ssm, dev, REG_GAIN, 0x29);
|
||||||
if (self->deactivating) {
|
break;
|
||||||
fp_dbg("deactivating, marking completed");
|
|
||||||
fpi_ssm_mark_completed(ssm);
|
case LOOP_CMD_SCAN:
|
||||||
} else
|
if (self->deactivating)
|
||||||
sm_exec_cmd(ssm, dev, CMD_SCAN, 0x00);
|
{
|
||||||
break;
|
fp_dbg ("deactivating, marking completed");
|
||||||
case LOOP_CAPTURE:
|
fpi_ssm_mark_completed (ssm);
|
||||||
sm_do_capture(ssm, dev);
|
}
|
||||||
break;
|
else
|
||||||
case LOOP_CAPTURE_DONE:
|
{
|
||||||
fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
|
sm_exec_cmd (ssm, dev, CMD_SCAN, 0x00);
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
case LOOP_CAPTURE:
|
||||||
|
sm_do_capture (ssm, dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOOP_CAPTURE_DONE:
|
||||||
|
fpi_ssm_jump_to_state (ssm, LOOP_CMD_SCAN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loopsm_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
static void
|
||||||
GError *error)
|
loopsm_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *imgdev = FP_IMAGE_DEVICE (dev);
|
FpImageDevice *imgdev = FP_IMAGE_DEVICE (dev);
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
g_object_unref (self->capture_img);
|
g_object_unref (self->capture_img);
|
||||||
self->capture_img = NULL;
|
self->capture_img = NULL;
|
||||||
self->loop_running = FALSE;
|
self->loop_running = FALSE;
|
||||||
|
|
||||||
if (error && !self->deactivating)
|
if (error && !self->deactivating)
|
||||||
fpi_image_device_session_error(imgdev, error);
|
fpi_image_device_session_error (imgdev, error);
|
||||||
else if (error)
|
else if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
fpi_image_device_deactivate_complete(imgdev, NULL);
|
fpi_image_device_deactivate_complete (imgdev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), loop_run_state,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), loop_run_state,
|
||||||
LOOP_NUM_STATES, dev);
|
LOOP_NUM_STATES, dev);
|
||||||
self->deactivating = FALSE;
|
|
||||||
fpi_ssm_start(ssm, loopsm_complete);
|
self->deactivating = FALSE;
|
||||||
self->loop_running = TRUE;
|
fpi_ssm_start (ssm, loopsm_complete);
|
||||||
fpi_image_device_activate_complete(dev, NULL);
|
self->loop_running = TRUE;
|
||||||
|
fpi_image_device_activate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
|
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||||
if (self->loop_running)
|
|
||||||
self->deactivating = TRUE;
|
if (self->loop_running)
|
||||||
else
|
self->deactivating = TRUE;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
else
|
||||||
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_init(FpImageDevice *dev)
|
static void
|
||||||
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_usb_device_claim_interface (fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
|
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
fpi_image_device_open_complete(dev, error);
|
fpi_image_device_open_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deinit (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
|
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x061a, .pid = 0x0110, },
|
{ .vid = 0x061a, .pid = 0x0110, },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_vcom5s_init(FpDeviceVcom5s *self) {
|
static void
|
||||||
|
fpi_device_vcom5s_init (FpDeviceVcom5s *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_vcom5s_class_init(FpDeviceVcom5sClass *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_vcom5s_class_init (FpDeviceVcom5sClass *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "vcom5s";
|
dev_class->id = "vcom5s";
|
||||||
dev_class->full_name = "Veridicom 5thSense";
|
dev_class->full_name = "Veridicom 5thSense";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||||
|
|
||||||
img_class->img_open = dev_init;
|
img_class->img_open = dev_init;
|
||||||
img_class->img_close = dev_deinit;
|
img_class->img_close = dev_deinit;
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
img_class->img_width = IMG_WIDTH;
|
img_class->img_width = IMG_WIDTH;
|
||||||
img_class->img_height = IMG_HEIGHT;
|
img_class->img_height = IMG_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -51,334 +51,336 @@
|
||||||
#define EP3_IN 0x83
|
#define EP3_IN 0x83
|
||||||
|
|
||||||
/* Fingerprint horizontal line */
|
/* Fingerprint horizontal line */
|
||||||
struct vfs_line {
|
struct vfs_line
|
||||||
/* It must be always 0x01 */
|
{
|
||||||
unsigned char _0x01;
|
/* It must be always 0x01 */
|
||||||
/* It must be always 0xfe */
|
unsigned char _0x01;
|
||||||
unsigned char _0xfe;
|
/* It must be always 0xfe */
|
||||||
|
unsigned char _0xfe;
|
||||||
|
|
||||||
/* line number starting from some number in Little-Endian */
|
/* line number starting from some number in Little-Endian */
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
|
|
||||||
/* Some hashes which are useful to detect noise */
|
/* Some hashes which are useful to detect noise */
|
||||||
unsigned char noise_hash_1;
|
unsigned char noise_hash_1;
|
||||||
unsigned char noise_hash_2;
|
unsigned char noise_hash_2;
|
||||||
|
|
||||||
/* The first byte of _somedata is always 0x00, the second is strange useless cyclic line number */
|
/* The first byte of _somedata is always 0x00, the second is strange useless cyclic line number */
|
||||||
unsigned short _somedata;
|
unsigned short _somedata;
|
||||||
|
|
||||||
/* Fingerprint image */
|
/* Fingerprint image */
|
||||||
unsigned char data[VFS_IMAGE_WIDTH];
|
unsigned char data[VFS_IMAGE_WIDTH];
|
||||||
|
|
||||||
/* Narrow fingerprint part from the center used for variable speed lines assembling */
|
/* Narrow fingerprint part from the center used for variable speed lines assembling */
|
||||||
unsigned char next_line_part[VFS_NEXT_LINE_WIDTH];
|
unsigned char next_line_part[VFS_NEXT_LINE_WIDTH];
|
||||||
|
|
||||||
/* scan_data is 0xfb except some rare cases, it's skipped */
|
/* scan_data is 0xfb except some rare cases, it's skipped */
|
||||||
unsigned char scan_data[8];
|
unsigned char scan_data[8];
|
||||||
} __attribute__ ((__packed__));
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
/* The main driver structure */
|
/* The main driver structure */
|
||||||
struct _FpDeviceVfs0050 {
|
struct _FpDeviceVfs0050
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
/* One if we were asked to read fingerprint, zero otherwise */
|
/* One if we were asked to read fingerprint, zero otherwise */
|
||||||
char active;
|
char active;
|
||||||
|
|
||||||
/* Control packet parameter for send_control_packet */
|
/* Control packet parameter for send_control_packet */
|
||||||
unsigned char *control_packet;
|
unsigned char *control_packet;
|
||||||
|
|
||||||
/* For dev_deactivate to check whether ssm still running or not */
|
/* For dev_deactivate to check whether ssm still running or not */
|
||||||
char ssm_active;
|
char ssm_active;
|
||||||
|
|
||||||
/* Should we call fpi_imgdev_activate_complete or fpi_imgdev_deactivate_complete */
|
/* Should we call fpi_imgdev_activate_complete or fpi_imgdev_deactivate_complete */
|
||||||
char need_report;
|
char need_report;
|
||||||
|
|
||||||
/* Received fingerprint raw lines */
|
/* Received fingerprint raw lines */
|
||||||
struct vfs_line *lines_buffer;
|
struct vfs_line *lines_buffer;
|
||||||
|
|
||||||
/* Current number of received bytes and current memory used by data */
|
/* Current number of received bytes and current memory used by data */
|
||||||
int bytes, memory;
|
int bytes, memory;
|
||||||
|
|
||||||
/* USB buffer for fingerprint */
|
/* USB buffer for fingerprint */
|
||||||
char *usb_buffer;
|
char *usb_buffer;
|
||||||
|
|
||||||
/* Received interrupt data */
|
/* Received interrupt data */
|
||||||
unsigned char interrupt[8];
|
unsigned char interrupt[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpDeviceVfs0050, fpi_device_vfs0050, FPI, DEVICE_VFS0050, FpImageDevice)
|
G_DECLARE_FINAL_TYPE (FpDeviceVfs0050, fpi_device_vfs0050, FPI, DEVICE_VFS0050, FpImageDevice)
|
||||||
|
|
||||||
/* SSM states for clear_ep2 */
|
/* SSM states for clear_ep2 */
|
||||||
enum SUBSM1 {
|
enum SUBSM1 {
|
||||||
SUBSM1_COMMAND_04,
|
SUBSM1_COMMAND_04,
|
||||||
SUBSM1_RETURN_CODE,
|
SUBSM1_RETURN_CODE,
|
||||||
SUBSM1_ABORT_2,
|
SUBSM1_ABORT_2,
|
||||||
|
|
||||||
SUBSM1_STATES,
|
SUBSM1_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SSM states for control */
|
/* SSM states for control */
|
||||||
enum SUBSM2 {
|
enum SUBSM2 {
|
||||||
SUBSM2_SEND_CONTROL,
|
SUBSM2_SEND_CONTROL,
|
||||||
SUBSM2_RETURN_CODE, /* If next_receive, send another control packet */
|
SUBSM2_RETURN_CODE, /* If next_receive, send another control packet */
|
||||||
|
|
||||||
SUBSM2_SEND_COMMIT,
|
SUBSM2_SEND_COMMIT,
|
||||||
SUBSM2_COMMIT_RESPONSE,
|
SUBSM2_COMMIT_RESPONSE,
|
||||||
SUBSM2_READ_EMPTY_INTERRUPT,
|
SUBSM2_READ_EMPTY_INTERRUPT,
|
||||||
SUBSM2_ABORT_3,
|
SUBSM2_ABORT_3,
|
||||||
SUBSM2_CLEAR_EP2,
|
SUBSM2_CLEAR_EP2,
|
||||||
|
|
||||||
SUBSM2_STATES,
|
SUBSM2_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SSM states for activate_ssm */
|
/* SSM states for activate_ssm */
|
||||||
enum SSM_STATE {
|
enum SSM_STATE {
|
||||||
SSM_INITIAL_ABORT_1,
|
SSM_INITIAL_ABORT_1,
|
||||||
SSM_INITIAL_ABORT_2,
|
SSM_INITIAL_ABORT_2,
|
||||||
SSM_INITIAL_ABORT_3,
|
SSM_INITIAL_ABORT_3,
|
||||||
SSM_CLEAR_EP2,
|
SSM_CLEAR_EP2,
|
||||||
SSM_TURN_OFF,
|
SSM_TURN_OFF,
|
||||||
|
|
||||||
/* Here the device is turned off; if not active, complete ssm */
|
/* Here the device is turned off; if not active, complete ssm */
|
||||||
SSM_TURN_ON,
|
SSM_TURN_ON,
|
||||||
|
|
||||||
SSM_ASK_INTERRUPT,
|
SSM_ASK_INTERRUPT,
|
||||||
SSM_WAIT_INTERRUPT,
|
SSM_WAIT_INTERRUPT,
|
||||||
|
|
||||||
SSM_RECEIVE_FINGER,
|
SSM_RECEIVE_FINGER,
|
||||||
SSM_SUBMIT_IMAGE,
|
SSM_SUBMIT_IMAGE,
|
||||||
|
|
||||||
/* If not active, jump to CLEAR_EP2 */
|
/* If not active, jump to CLEAR_EP2 */
|
||||||
SSM_NEXT_RECEIVE,
|
SSM_NEXT_RECEIVE,
|
||||||
SSM_WAIT_ANOTHER_SCAN,
|
SSM_WAIT_ANOTHER_SCAN,
|
||||||
/* Jump to TURN_ON */
|
/* Jump to TURN_ON */
|
||||||
|
|
||||||
SSM_STATES
|
SSM_STATES
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Blocks of data from USB sniffer */
|
/* Blocks of data from USB sniffer */
|
||||||
|
|
||||||
/* Turns on the light */
|
/* Turns on the light */
|
||||||
static unsigned char turn_on[] = {
|
static unsigned char turn_on[] = {
|
||||||
0x39, 0x20, 0xBF, 0x02, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
0x39, 0x20, 0xBF, 0x02, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
||||||
0x20, 0xD1, 0xD1, 0x00,
|
0x20, 0xD1, 0xD1, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x01, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x01, 0x00,
|
||||||
0x00, 0x01, 0x00, 0x00,
|
0x00, 0x01, 0x00, 0x00,
|
||||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xF4, 0x01, 0x00,
|
0x00, 0xF4, 0x01, 0x00,
|
||||||
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xF4, 0x01, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
0x00, 0xF4, 0x01, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00,
|
0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Power off */
|
/* Power off */
|
||||||
static unsigned char turn_off[] = {
|
static unsigned char turn_off[] = {
|
||||||
0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00,
|
0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Turns on orange light */
|
/* Turns on orange light */
|
||||||
static unsigned char next_receive_1[] = {
|
static unsigned char next_receive_1[] = {
|
||||||
0x39, 0xB8, 0x0B, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
0x39, 0xB8, 0x0B, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
||||||
0x20, 0x00, 0x00, 0x00,
|
0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x01, 0x00, 0x00,
|
0x00, 0x01, 0x00, 0x00,
|
||||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xB8, 0x0B, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
0x00, 0xB8, 0x0B, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00,
|
0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Packet directly after next_receive_1 */
|
/* Packet directly after next_receive_1 */
|
||||||
static unsigned char next_receive_2[] = {
|
static unsigned char next_receive_2[] = {
|
||||||
0x39, 0xE8, 0x03, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
0x39, 0xE8, 0x03, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x01, 0xD1, 0x00,
|
||||||
0x20, 0x00, 0x00, 0x00,
|
0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x01, 0x00, 0x00,
|
0x00, 0x01, 0x00, 0x00,
|
||||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xE8, 0x03, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
0x00, 0xE8, 0x03, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00,
|
0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Commit message */
|
/* Commit message */
|
||||||
static unsigned char commit_out[] = {
|
static unsigned char commit_out[] = {
|
||||||
0x02, 0x94, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x2C, 0x03, 0x00,
|
0x02, 0x94, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x2C, 0x03, 0x00,
|
||||||
0x30, 0x1B, 0x00, 0x00,
|
0x30, 0x1B, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x20, 0x03, 0x00, 0x30, 0x3D, 0x10, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x20, 0x03, 0x00, 0x30, 0x3D, 0x10, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x18, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x18, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x24, 0x03, 0x00,
|
0x00, 0x24, 0x03, 0x00,
|
||||||
0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x28, 0x03, 0x00,
|
0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x28, 0x03, 0x00,
|
||||||
0x30, 0x08, 0x00, 0x00,
|
0x30, 0x08, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x30, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x30, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x38, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x38, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x3C, 0x03, 0x00,
|
0x00, 0x3C, 0x03, 0x00,
|
||||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x44, 0x03, 0x00,
|
0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x44, 0x03, 0x00,
|
||||||
0x30, 0x14, 0x00, 0x00,
|
0x30, 0x14, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x48, 0x03, 0x00, 0x30, 0x01, 0x04, 0x02,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x48, 0x03, 0x00, 0x30, 0x01, 0x04, 0x02,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x4C, 0x03, 0x00, 0x30, 0x01, 0x0C, 0x02, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x4C, 0x03, 0x00, 0x30, 0x01, 0x0C, 0x02, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x54, 0x03, 0x00,
|
0x00, 0x54, 0x03, 0x00,
|
||||||
0x30, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x5C, 0x03, 0x00,
|
0x30, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x5C, 0x03, 0x00,
|
||||||
0x30, 0x90, 0x01, 0x02,
|
0x30, 0x90, 0x01, 0x02,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x60, 0x03, 0x00, 0x30, 0x2C, 0x01, 0x19,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x60, 0x03, 0x00, 0x30, 0x2C, 0x01, 0x19,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x64, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x64, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x6C, 0x03, 0x00,
|
0x00, 0x6C, 0x03, 0x00,
|
||||||
0x30, 0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x70, 0x03, 0x00,
|
0x30, 0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x70, 0x03, 0x00,
|
||||||
0x30, 0x21, 0x80, 0x00,
|
0x30, 0x21, 0x80, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x78, 0x03, 0x00, 0x30, 0x09, 0x00, 0x02,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x78, 0x03, 0x00, 0x30, 0x09, 0x00, 0x02,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x7C, 0x03, 0x00, 0x30, 0x0B, 0x00, 0x19, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x7C, 0x03, 0x00, 0x30, 0x0B, 0x00, 0x19, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x80, 0x03, 0x00,
|
0x00, 0x80, 0x03, 0x00,
|
||||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x84, 0x03, 0x00,
|
0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x84, 0x03, 0x00,
|
||||||
0x30, 0x3A, 0x00, 0x00,
|
0x30, 0x3A, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x88, 0x03, 0x00, 0x30, 0x14, 0x00, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x88, 0x03, 0x00, 0x30, 0x14, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x8C, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x8C, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x90, 0x03, 0x00,
|
0x00, 0x90, 0x03, 0x00,
|
||||||
0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x94, 0x03, 0x00,
|
0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x94, 0x03, 0x00,
|
||||||
0x30, 0x08, 0x00, 0x00,
|
0x30, 0x08, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x98, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x98, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1,
|
||||||
0x01, 0x20, 0x00, 0x08,
|
0x01, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x9C, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1, 0x01, 0x20, 0x00, 0x08,
|
0x00, 0x9C, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1, 0x01, 0x20, 0x00, 0x08,
|
||||||
0x00, 0xA8, 0x03, 0x00,
|
0x00, 0xA8, 0x03, 0x00,
|
||||||
0x30, 0x64, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xAC, 0x03, 0x00,
|
0x30, 0x64, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xAC, 0x03, 0x00,
|
||||||
0x30, 0x64, 0x01, 0x00,
|
0x30, 0x64, 0x01, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0xB0, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0xB0, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0xB4, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0xB4, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0xB8, 0x03, 0x00,
|
0x00, 0xB8, 0x03, 0x00,
|
||||||
0x30, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xBC, 0x03, 0x00,
|
0x30, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xBC, 0x03, 0x00,
|
||||||
0x30, 0x05, 0x00, 0x00,
|
0x30, 0x05, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0xC0, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0xC0, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x84, 0x03, 0x00, 0x30, 0x3B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x84, 0x03, 0x00, 0x30, 0x3B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x08, 0x07, 0x00,
|
0x00, 0x08, 0x07, 0x00,
|
||||||
0x30, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x0C, 0x07, 0x00,
|
0x30, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x0C, 0x07, 0x00,
|
||||||
0x30, 0x00, 0x00, 0x00,
|
0x30, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08, 0x00, 0x14, 0x07, 0x00, 0x30, 0x20, 0x00, 0x00,
|
0x00, 0x20, 0x00, 0x08, 0x00, 0x14, 0x07, 0x00, 0x30, 0x20, 0x00, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x1C, 0x07, 0x00, 0x30, 0x1A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x1C, 0x07, 0x00, 0x30, 0x1A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x70, 0x0D, 0x00,
|
0x00, 0x70, 0x0D, 0x00,
|
||||||
0x30, 0x01, 0x00, 0x00, 0x00, 0x25, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00,
|
0x30, 0x01, 0x00, 0x00, 0x00, 0x25, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x02, 0x00, 0x90, 0x00, 0x00, 0x00, 0x2B, 0xFF, 0x2B, 0xFF, 0x2B,
|
0x00, 0x02, 0x00, 0x90, 0x00, 0x00, 0x00, 0x2B, 0xFF, 0x2B, 0xFF, 0x2B,
|
||||||
0xED, 0x00, 0x00, 0x2B,
|
0xED, 0x00, 0x00, 0x2B,
|
||||||
0xFB, 0x00, 0x00, 0x2B, 0xC5, 0x00, 0x00, 0x2B, 0x05, 0x80, 0x70, 0x00,
|
0xFB, 0x00, 0x00, 0x2B, 0xC5, 0x00, 0x00, 0x2B, 0x05, 0x80, 0x70, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x24, 0xD3, 0x2E, 0xC0, 0x2C, 0x3B, 0x08, 0xF0, 0x3B, 0x09, 0x24,
|
0x00, 0x24, 0xD3, 0x2E, 0xC0, 0x2C, 0x3B, 0x08, 0xF0, 0x3B, 0x09, 0x24,
|
||||||
0xBB, 0x3B, 0x0B, 0x24,
|
0xBB, 0x3B, 0x0B, 0x24,
|
||||||
0xAA, 0x3B, 0x1F, 0xF8, 0x00, 0x3B, 0x3F, 0xF0, 0x00, 0x3B, 0x35, 0xC0,
|
0xAA, 0x3B, 0x1F, 0xF8, 0x00, 0x3B, 0x3F, 0xF0, 0x00, 0x3B, 0x35, 0xC0,
|
||||||
0x00, 0x38, 0x80, 0x2C,
|
0x00, 0x38, 0x80, 0x2C,
|
||||||
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x80, 0x2C, 0x70, 0x00,
|
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x80, 0x2C, 0x70, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xC0,
|
0x00, 0x00, 0x00, 0xC0,
|
||||||
0x3A, 0x80, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3B, 0x0A, 0x80,
|
0x3A, 0x80, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3B, 0x0A, 0x80,
|
||||||
0x2E, 0x83, 0x24, 0xDB,
|
0x2E, 0x83, 0x24, 0xDB,
|
||||||
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x2C, 0x31, 0x83, 0x2C, 0x70,
|
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x2C, 0x31, 0x83, 0x2C, 0x70,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0xCB, 0x33, 0x1B, 0x83, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x31,
|
0xCB, 0x33, 0x1B, 0x83, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x31,
|
||||||
0x83, 0x2C, 0x70, 0x00,
|
0x83, 0x2C, 0x70, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xCB, 0x00, 0x33, 0x1E, 0x83, 0x2E, 0x25, 0xFF, 0xC4,
|
0x00, 0x00, 0x00, 0xCB, 0x00, 0x33, 0x1E, 0x83, 0x2E, 0x25, 0xFF, 0xC4,
|
||||||
0x00, 0x2F, 0x06, 0x84,
|
0x00, 0x2F, 0x06, 0x84,
|
||||||
0x2E, 0x00, 0x00, 0x10, 0x20, 0x29, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00,
|
0x2E, 0x00, 0x00, 0x10, 0x20, 0x29, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00,
|
||||||
0x00, 0x23, 0x00, 0x00,
|
0x00, 0x23, 0x00, 0x00,
|
||||||
0x00, 0x21, 0x00, 0x10, 0x00, 0x48, 0x03, 0x00, 0x30, 0xFF, 0xF0, 0xFF,
|
0x00, 0x21, 0x00, 0x10, 0x00, 0x48, 0x03, 0x00, 0x30, 0xFF, 0xF0, 0xFF,
|
||||||
0xFF, 0x00, 0x00, 0x00,
|
0xFF, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x4C, 0x03, 0x00,
|
0x00, 0x00, 0x04, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x4C, 0x03, 0x00,
|
||||||
0x30, 0xFF, 0xF0, 0xFF,
|
0x30, 0xFF, 0xF0, 0xFF,
|
||||||
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x21, 0x00, 0x10,
|
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x21, 0x00, 0x10,
|
||||||
0x00, 0x20, 0x03, 0x00,
|
0x00, 0x20, 0x03, 0x00,
|
||||||
0x30, 0x7F, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00,
|
0x30, 0x7F, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00,
|
||||||
0x00, 0x20, 0x00, 0x08,
|
0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x24, 0x03, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0x00, 0x24, 0x03, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x1C, 0x07, 0x00,
|
0x00, 0x1C, 0x07, 0x00,
|
||||||
0x30, 0x1A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x20, 0x03, 0x00,
|
0x30, 0x1A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x20, 0x03, 0x00,
|
||||||
0x30, 0xC3, 0xFF, 0xFF,
|
0x30, 0xC3, 0xFF, 0xFF,
|
||||||
0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08,
|
||||||
0x00, 0x80, 0x03, 0x00,
|
0x00, 0x80, 0x03, 0x00,
|
||||||
0x30, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x84, 0x00, 0x31, 0x65, 0x77,
|
0x30, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x84, 0x00, 0x31, 0x65, 0x77,
|
||||||
0x77, 0x77, 0x78, 0x88,
|
0x77, 0x77, 0x78, 0x88,
|
||||||
0x77, 0x77, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x77, 0x67,
|
0x77, 0x77, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x77, 0x67,
|
||||||
0x66, 0x66, 0x66, 0x66,
|
0x66, 0x66, 0x66, 0x66,
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x66, 0x66, 0x66,
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x66, 0x66, 0x66,
|
||||||
0x66, 0x77, 0x66, 0x66,
|
0x66, 0x77, 0x66, 0x66,
|
||||||
0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x76, 0x66, 0x56,
|
0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x76, 0x66, 0x56,
|
||||||
0x66, 0x66, 0x56, 0x55,
|
0x66, 0x66, 0x56, 0x55,
|
||||||
0x65, 0x66, 0x66, 0x66, 0x65, 0x66, 0x66, 0x55, 0x66, 0x66, 0x65, 0x66,
|
0x65, 0x66, 0x66, 0x66, 0x65, 0x66, 0x66, 0x55, 0x66, 0x66, 0x65, 0x66,
|
||||||
0x76, 0x76, 0x77, 0x77,
|
0x76, 0x76, 0x77, 0x77,
|
||||||
0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x77, 0x67, 0x66, 0x66, 0x66, 0x56,
|
0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x77, 0x67, 0x66, 0x66, 0x66, 0x56,
|
||||||
0x65, 0x66, 0x65, 0x66,
|
0x65, 0x66, 0x65, 0x66,
|
||||||
0x66, 0x55, 0x55, 0x54, 0x55, 0x65, 0x66, 0x66, 0x66, 0x76, 0x77, 0x87,
|
0x66, 0x55, 0x55, 0x54, 0x55, 0x65, 0x66, 0x66, 0x66, 0x76, 0x77, 0x87,
|
||||||
0x88, 0x77, 0x66, 0x66,
|
0x88, 0x77, 0x66, 0x66,
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x65, 0x66, 0x55, 0x55, 0x65, 0x56, 0x55,
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x65, 0x66, 0x55, 0x55, 0x65, 0x56, 0x55,
|
||||||
0x55, 0x55, 0x54, 0x45,
|
0x55, 0x55, 0x54, 0x45,
|
||||||
0x54, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77,
|
0x54, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77,
|
||||||
0x66, 0x26, 0x00, 0x28,
|
0x66, 0x26, 0x00, 0x28,
|
||||||
0x00, 0xFF, 0x00, 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x00, 0x20, 0x00, 0x00,
|
0x00, 0xFF, 0x00, 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x00, 0x20, 0x00, 0x00,
|
||||||
0x00, 0x30, 0x01, 0x02,
|
0x00, 0x30, 0x01, 0x02,
|
||||||
0x00, 0x2C, 0x01, 0x28, 0x00, 0x20, 0x80, 0x00, 0x00, 0x0A, 0x00, 0x02,
|
0x00, 0x2C, 0x01, 0x28, 0x00, 0x20, 0x80, 0x00, 0x00, 0x0A, 0x00, 0x02,
|
||||||
0x00, 0x0B, 0x00, 0x19,
|
0x00, 0x0B, 0x00, 0x19,
|
||||||
0x00, 0x40, 0x1F, 0x10, 0x27, 0x00, 0x0F, 0x03, 0x00,
|
0x00, 0x40, 0x1F, 0x10, 0x27, 0x00, 0x0F, 0x03, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Known interrupts */
|
/* Known interrupts */
|
||||||
|
|
||||||
static unsigned char empty_interrupt[] = {
|
static unsigned char empty_interrupt[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char interrupt1[] = {
|
static unsigned char interrupt1[] = {
|
||||||
0x02, 0x00, 0x0E, 0x00, 0xF0,
|
0x02, 0x00, 0x0E, 0x00, 0xF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char interrupt2[] = {
|
static unsigned char interrupt2[] = {
|
||||||
0x02, 0x04, 0x0A, 0x00, 0xF0,
|
0x02, 0x04, 0x0A, 0x00, 0xF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char interrupt3[] = {
|
static unsigned char interrupt3[] = {
|
||||||
0x02, 0x00, 0x0A, 0x00, 0xF0,
|
0x02, 0x00, 0x0A, 0x00, 0xF0,
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,249 +30,268 @@ G_DEFINE_TYPE (FpDeviceVfs301, fpi_device_vfs301, FP_TYPE_IMAGE_DEVICE)
|
||||||
|
|
||||||
/* Submit asynchronous sleep */
|
/* Submit asynchronous sleep */
|
||||||
static void
|
static void
|
||||||
async_sleep(unsigned int msec,
|
async_sleep (unsigned int msec,
|
||||||
FpiSsm *ssm,
|
FpiSsm *ssm,
|
||||||
FpImageDevice *dev)
|
FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
/* Add timeout */
|
/* Add timeout */
|
||||||
fpi_device_add_timeout(FP_DEVICE(dev), msec,
|
fpi_device_add_timeout (FP_DEVICE (dev), msec,
|
||||||
fpi_ssm_next_state_timeout_cb, ssm);
|
fpi_ssm_next_state_timeout_cb, ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
submit_image(FpiSsm *ssm,
|
submit_image (FpiSsm *ssm,
|
||||||
FpImageDevice *dev)
|
FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
|
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
|
||||||
int height;
|
int height;
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* XXX: This is probably handled by libfprint automagically? */
|
/* XXX: This is probably handled by libfprint automagically? */
|
||||||
if (vdev->scanline_count < 20) {
|
if (vdev->scanline_count < 20)
|
||||||
fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
|
{
|
||||||
return 0;
|
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
img = fp_image_new(VFS301_FP_OUTPUT_WIDTH, self->scanline_count);
|
img = fp_image_new (VFS301_FP_OUTPUT_WIDTH, self->scanline_count);
|
||||||
if (img == NULL)
|
if (img == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vfs301_extract_image(self, img->data, &height);
|
vfs301_extract_image (self, img->data, &height);
|
||||||
|
|
||||||
/* TODO: how to detect flip? should the resulting image be
|
/* TODO: how to detect flip? should the resulting image be
|
||||||
* oriented so that it is equal e.g. to a fingerprint on a paper,
|
* oriented so that it is equal e.g. to a fingerprint on a paper,
|
||||||
* or to the finger when I look at it?) */
|
* or to the finger when I look at it?) */
|
||||||
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
|
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
|
||||||
|
|
||||||
/* The image buffer is larger at this point, but that does not
|
/* The image buffer is larger at this point, but that does not
|
||||||
* matter. */
|
* matter. */
|
||||||
img->width = VFS301_FP_OUTPUT_WIDTH;
|
img->width = VFS301_FP_OUTPUT_WIDTH;
|
||||||
img->height = height;
|
img->height = height;
|
||||||
|
|
||||||
fpi_image_device_image_captured(dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop ssm states */
|
/* Loop ssm states */
|
||||||
enum
|
enum {
|
||||||
{
|
/* Step 0 - Scan finger */
|
||||||
/* Step 0 - Scan finger */
|
M_REQUEST_PRINT,
|
||||||
M_REQUEST_PRINT,
|
M_WAIT_PRINT,
|
||||||
M_WAIT_PRINT,
|
M_CHECK_PRINT,
|
||||||
M_CHECK_PRINT,
|
M_READ_PRINT_START,
|
||||||
M_READ_PRINT_START,
|
M_READ_PRINT_WAIT,
|
||||||
M_READ_PRINT_WAIT,
|
M_READ_PRINT_POLL,
|
||||||
M_READ_PRINT_POLL,
|
M_SUBMIT_PRINT,
|
||||||
M_SUBMIT_PRINT,
|
|
||||||
|
|
||||||
/* Number of states */
|
/* Number of states */
|
||||||
M_LOOP_NUM_STATES,
|
M_LOOP_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Exec loop sequential state machine */
|
/* Exec loop sequential state machine */
|
||||||
static void m_loop_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
m_loop_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(_dev);
|
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
case M_REQUEST_PRINT:
|
{
|
||||||
vfs301_proto_request_fingerprint(self);
|
case M_REQUEST_PRINT:
|
||||||
fpi_ssm_next_state(ssm);
|
vfs301_proto_request_fingerprint (self);
|
||||||
break;
|
fpi_ssm_next_state (ssm);
|
||||||
|
break;
|
||||||
|
|
||||||
case M_WAIT_PRINT:
|
case M_WAIT_PRINT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(200, ssm, dev);
|
async_sleep (200, ssm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_CHECK_PRINT:
|
case M_CHECK_PRINT:
|
||||||
if (!vfs301_proto_peek_event(self))
|
if (!vfs301_proto_peek_event (self))
|
||||||
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);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_READ_PRINT_START:
|
case M_READ_PRINT_START:
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
vfs301_proto_process_event_start(self);
|
vfs301_proto_process_event_start (self);
|
||||||
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, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_READ_PRINT_POLL:
|
case M_READ_PRINT_POLL:
|
||||||
{
|
{
|
||||||
int rv = vfs301_proto_process_event_poll(self);
|
int rv = vfs301_proto_process_event_poll (self);
|
||||||
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);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_SUBMIT_PRINT:
|
case M_SUBMIT_PRINT:
|
||||||
if (submit_image(ssm, dev)) {
|
if (submit_image (ssm, dev))
|
||||||
fpi_ssm_mark_completed(ssm);
|
{
|
||||||
/* NOTE: finger off is expected only after submitting image... */
|
fpi_ssm_mark_completed (ssm);
|
||||||
fpi_image_device_report_finger_status(dev, FALSE);
|
/* NOTE: finger off is expected only after submitting image... */
|
||||||
} else {
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
|
}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
default:
|
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||||
g_assert_not_reached ();
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete loop sequential state machine */
|
/* Complete loop sequential state machine */
|
||||||
static void m_loop_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
GError *error)
|
m_loop_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
g_warning ("State machine completed with an error: %s", error->message);
|
{
|
||||||
g_error_free (error);
|
g_warning ("State machine completed with an error: %s", error->message);
|
||||||
}
|
g_error_free (error);
|
||||||
/* Free sequential state machine */
|
}
|
||||||
fpi_ssm_free(ssm);
|
/* Free sequential state machine */
|
||||||
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exec init sequential state machine */
|
/* Exec init sequential state machine */
|
||||||
static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
m_init_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(_dev);
|
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
|
||||||
|
|
||||||
g_assert(fpi_ssm_get_cur_state(ssm) == 0);
|
g_assert (fpi_ssm_get_cur_state (ssm) == 0);
|
||||||
|
|
||||||
vfs301_proto_init(self);
|
vfs301_proto_init (self);
|
||||||
|
|
||||||
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(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
static void
|
||||||
GError *error)
|
m_init_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm_loop;
|
FpiSsm *ssm_loop;
|
||||||
|
|
||||||
fpi_image_device_activate_complete(FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
|
||||||
if (!error) {
|
if (!error)
|
||||||
/* Notify activate complete */
|
{
|
||||||
|
/* Notify activate complete */
|
||||||
|
|
||||||
/* Start loop ssm */
|
/* Start loop ssm */
|
||||||
ssm_loop = fpi_ssm_new(dev, m_loop_state,
|
ssm_loop = fpi_ssm_new (dev, m_loop_state,
|
||||||
M_LOOP_NUM_STATES, dev);
|
M_LOOP_NUM_STATES, dev);
|
||||||
fpi_ssm_start(ssm_loop, m_loop_complete);
|
fpi_ssm_start (ssm_loop, m_loop_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free sequential state machine */
|
/* Free sequential state machine */
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate device */
|
/* Activate device */
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
/* Start init ssm */
|
/* Start init ssm */
|
||||||
ssm = fpi_ssm_new(FP_DEVICE(dev), m_init_state, 1, dev);
|
ssm = fpi_ssm_new (FP_DEVICE (dev), m_init_state, 1, dev);
|
||||||
fpi_ssm_start(ssm, m_init_complete);
|
fpi_ssm_start (ssm, m_init_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deactivate device */
|
/* Deactivate device */
|
||||||
static void dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *self;
|
FpDeviceVfs301 *self;
|
||||||
|
|
||||||
self = FPI_DEVICE_VFS301(dev);
|
self = FPI_DEVICE_VFS301 (dev);
|
||||||
vfs301_proto_deinit(self);
|
vfs301_proto_deinit (self);
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_open(FpImageDevice *dev)
|
static void
|
||||||
|
dev_open (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
|
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
|
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
/* Initialize private structure */
|
/* Initialize private structure */
|
||||||
self->scanline_count = 0;
|
self->scanline_count = 0;
|
||||||
|
|
||||||
/* Notify open complete */
|
/* Notify open complete */
|
||||||
fpi_image_device_open_complete(dev, error);
|
fpi_image_device_open_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_close(FpImageDevice *dev)
|
static void
|
||||||
|
dev_close (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
|
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* Release private structure */
|
/* Release private structure */
|
||||||
g_clear_pointer (&self->scanline_buf, g_free);
|
g_clear_pointer (&self->scanline_buf, g_free);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
|
|
||||||
/* Notify close complete */
|
/* Notify close complete */
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Usb id table of device */
|
/* Usb id table of device */
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ /* vfs301 */ .vid = 0x138a, .pid = 0x0005, },
|
{ /* vfs301 */ .vid = 0x138a, .pid = 0x0005, },
|
||||||
{ /* vfs300 */ .vid = 0x138a, .pid = 0x0008, },
|
{ /* vfs300 */ .vid = 0x138a, .pid = 0x0008, },
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_vfs301_init(FpDeviceVfs301 *self) {
|
static void
|
||||||
|
fpi_device_vfs301_init (FpDeviceVfs301 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_vfs301_class_init(FpDeviceVfs301Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_vfs301_class_init (FpDeviceVfs301Class *klass)
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "vfs301";
|
dev_class->id = "vfs301";
|
||||||
dev_class->full_name = "Validity VFS301";
|
dev_class->full_name = "Validity VFS301";
|
||||||
dev_class->type = FP_DEVICE_TYPE_USB;
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
dev_class->id_table = id_table;
|
dev_class->id_table = id_table;
|
||||||
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
img_class->img_open = dev_open;
|
img_class->img_open = dev_open;
|
||||||
img_class->img_close = dev_close;
|
img_class->img_close = dev_close;
|
||||||
img_class->activate = dev_activate;
|
img_class->activate = dev_activate;
|
||||||
img_class->deactivate = dev_deactivate;
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
img_class->bz3_threshold = 24;
|
img_class->bz3_threshold = 24;
|
||||||
|
|
||||||
img_class->img_width = VFS301_FP_WIDTH;
|
img_class->img_width = VFS301_FP_WIDTH;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,113 +25,118 @@
|
||||||
#include "fpi-image-device.h"
|
#include "fpi-image-device.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VFS301_DEFAULT_WAIT_TIMEOUT = 300,
|
VFS301_DEFAULT_WAIT_TIMEOUT = 300,
|
||||||
|
|
||||||
VFS301_SEND_ENDPOINT = 0x01,
|
VFS301_SEND_ENDPOINT = 0x01,
|
||||||
VFS301_RECEIVE_ENDPOINT_CTRL = 0x81,
|
VFS301_RECEIVE_ENDPOINT_CTRL = 0x81,
|
||||||
VFS301_RECEIVE_ENDPOINT_DATA = 0x82
|
VFS301_RECEIVE_ENDPOINT_DATA = 0x82
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VFS301_FP_RECV_LEN_1 (84032)
|
#define VFS301_FP_RECV_LEN_1 (84032)
|
||||||
#define VFS301_FP_RECV_LEN_2 (84096)
|
#define VFS301_FP_RECV_LEN_2 (84096)
|
||||||
|
|
||||||
struct _FpDeviceVfs301 {
|
struct _FpDeviceVfs301
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
/* buffer to hold raw scanlines */
|
/* buffer to hold raw scanlines */
|
||||||
unsigned char *scanline_buf;
|
unsigned char *scanline_buf;
|
||||||
int scanline_count;
|
int scanline_count;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VFS301_ONGOING = 0,
|
VFS301_ONGOING = 0,
|
||||||
VFS301_ENDED = 1,
|
VFS301_ENDED = 1,
|
||||||
VFS301_FAILURE = -1
|
VFS301_FAILURE = -1
|
||||||
} recv_progress;
|
} recv_progress;
|
||||||
int recv_exp_amt;
|
int recv_exp_amt;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpDeviceVfs301, fpi_device_vfs301, FPI, DEVICE_VFS301, FpImageDevice)
|
G_DECLARE_FINAL_TYPE (FpDeviceVfs301, fpi_device_vfs301, FPI, DEVICE_VFS301, FpImageDevice)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* Width of the scanned data in px */
|
/* Width of the scanned data in px */
|
||||||
VFS301_FP_WIDTH = 200,
|
VFS301_FP_WIDTH = 200,
|
||||||
|
|
||||||
/* sizeof(fp_line_t) */
|
/* sizeof(fp_line_t) */
|
||||||
VFS301_FP_FRAME_SIZE = 288,
|
VFS301_FP_FRAME_SIZE = 288,
|
||||||
/* Width of output line */
|
/* Width of output line */
|
||||||
#ifndef OUTPUT_RAW
|
#ifndef OUTPUT_RAW
|
||||||
VFS301_FP_OUTPUT_WIDTH = VFS301_FP_WIDTH,
|
VFS301_FP_OUTPUT_WIDTH = VFS301_FP_WIDTH,
|
||||||
#else
|
#else
|
||||||
VFS301_FP_OUTPUT_WIDTH = VFS301_FP_FRAME_SIZE,
|
VFS301_FP_OUTPUT_WIDTH = VFS301_FP_FRAME_SIZE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VFS301_FP_SUM_LINES = 3,
|
VFS301_FP_SUM_LINES = 3,
|
||||||
|
|
||||||
#ifdef SCAN_FINISH_DETECTION
|
#ifdef SCAN_FINISH_DETECTION
|
||||||
/* TODO: The following changes (seen ~60 and ~80) In that
|
/* TODO: The following changes (seen ~60 and ~80) In that
|
||||||
* case we'll need to calibrate this from empty data somehow... */
|
* case we'll need to calibrate this from empty data somehow... */
|
||||||
VFS301_FP_SUM_MEDIAN = 60,
|
VFS301_FP_SUM_MEDIAN = 60,
|
||||||
VFS301_FP_SUM_EMPTY_RANGE = 5,
|
VFS301_FP_SUM_EMPTY_RANGE = 5,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Minimum average difference between returned lines */
|
/* Minimum average difference between returned lines */
|
||||||
VFS301_FP_LINE_DIFF_THRESHOLD = 15,
|
VFS301_FP_LINE_DIFF_THRESHOLD = 15,
|
||||||
|
|
||||||
/* Maximum waiting time for a single fingerprint frame */
|
/* Maximum waiting time for a single fingerprint frame */
|
||||||
VFS301_FP_RECV_TIMEOUT = 2000
|
VFS301_FP_RECV_TIMEOUT = 2000
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Arrays of this structure is returned during the initialization as a response
|
/* Arrays of this structure is returned during the initialization as a response
|
||||||
* to the 0x02D0 messages.
|
* to the 0x02D0 messages.
|
||||||
* It seems to be always the same - what is it for? Some kind of confirmation?
|
* It seems to be always the same - what is it for? Some kind of confirmation?
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct
|
||||||
unsigned char sync_0x01;
|
{
|
||||||
unsigned char sync_0xfe;
|
unsigned char sync_0x01;
|
||||||
|
unsigned char sync_0xfe;
|
||||||
|
|
||||||
unsigned char counter_lo;
|
unsigned char counter_lo;
|
||||||
unsigned char counter_hi; /* FIXME ? */
|
unsigned char counter_hi; /* FIXME ? */
|
||||||
|
|
||||||
unsigned char flags[3];
|
unsigned char flags[3];
|
||||||
|
|
||||||
unsigned char sync_0x00;
|
unsigned char sync_0x00;
|
||||||
|
|
||||||
unsigned char scan[VFS301_FP_WIDTH];
|
unsigned char scan[VFS301_FP_WIDTH];
|
||||||
} vfs301_init_line_t;
|
} vfs301_init_line_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
unsigned char sync_0x01;
|
{
|
||||||
unsigned char sync_0xfe;
|
unsigned char sync_0x01;
|
||||||
|
unsigned char sync_0xfe;
|
||||||
|
|
||||||
unsigned char counter_lo;
|
unsigned char counter_lo;
|
||||||
unsigned char counter_hi;
|
unsigned char counter_hi;
|
||||||
|
|
||||||
unsigned char sync_0x08[2]; /* XXX: always? 0x08 0x08 */
|
unsigned char sync_0x08[2]; /* XXX: always? 0x08 0x08 */
|
||||||
/* 0x08 | 0x18 - Looks like 0x08 marks good quality lines */
|
/* 0x08 | 0x18 - Looks like 0x08 marks good quality lines */
|
||||||
unsigned char flag_1;
|
unsigned char flag_1;
|
||||||
unsigned char sync_0x00;
|
unsigned char sync_0x00;
|
||||||
|
|
||||||
unsigned char scan[VFS301_FP_WIDTH];
|
unsigned char scan[VFS301_FP_WIDTH];
|
||||||
|
|
||||||
/* A offsetted, stretched, inverted copy of scan... probably could
|
/* A offsetted, stretched, inverted copy of scan... probably could
|
||||||
* serve finger motion speed detection?
|
* serve finger motion speed detection?
|
||||||
* Seems to be subdivided to some 10B + 53B + 1B blocks */
|
* Seems to be subdivided to some 10B + 53B + 1B blocks */
|
||||||
unsigned char mirror[64];
|
unsigned char mirror[64];
|
||||||
|
|
||||||
/* Some kind of sum of the scan, very low contrast */
|
/* Some kind of sum of the scan, very low contrast */
|
||||||
unsigned char sum1[2];
|
unsigned char sum1[2];
|
||||||
unsigned char sum2[11];
|
unsigned char sum2[11];
|
||||||
unsigned char sum3[3];
|
unsigned char sum3[3];
|
||||||
} vfs301_line_t;
|
} vfs301_line_t;
|
||||||
|
|
||||||
void vfs301_proto_init(FpDeviceVfs301 *dev);
|
void vfs301_proto_init (FpDeviceVfs301 *dev);
|
||||||
void vfs301_proto_deinit(FpDeviceVfs301 *dev);
|
void vfs301_proto_deinit (FpDeviceVfs301 *dev);
|
||||||
|
|
||||||
void vfs301_proto_request_fingerprint(FpDeviceVfs301 *dev);
|
void vfs301_proto_request_fingerprint (FpDeviceVfs301 *dev);
|
||||||
|
|
||||||
/** returns 0 if no event is ready, or 1 if there is one... */
|
/** returns 0 if no event is ready, or 1 if there is one... */
|
||||||
int vfs301_proto_peek_event(FpDeviceVfs301 *dev);
|
int vfs301_proto_peek_event (FpDeviceVfs301 *dev);
|
||||||
void vfs301_proto_process_event_start(FpDeviceVfs301 *dev);
|
void vfs301_proto_process_event_start (FpDeviceVfs301 *dev);
|
||||||
int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev);
|
int vfs301_proto_process_event_poll (FpDeviceVfs301 *dev);
|
||||||
|
|
||||||
void vfs301_extract_image(FpDeviceVfs301 *vfs, unsigned char *output, int *output_height);
|
void vfs301_extract_image (FpDeviceVfs301 *vfs,
|
||||||
|
unsigned char *output,
|
||||||
|
int *output_height);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -36,60 +36,64 @@
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gio/gunixsocketaddress.h>
|
#include <gio/gunixsocketaddress.h>
|
||||||
|
|
||||||
struct _FpDeviceVirtualImage {
|
struct _FpDeviceVirtualImage
|
||||||
FpImageDevice parent;
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
GSocketListener *listener;
|
GSocketListener *listener;
|
||||||
GSocketConnection *connection;
|
GSocketConnection *connection;
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
gint socket_fd;
|
gint socket_fd;
|
||||||
gint client_fd;
|
gint client_fd;
|
||||||
|
|
||||||
FpImage *recv_img;
|
FpImage *recv_img;
|
||||||
gint recv_img_hdr[2];
|
gint recv_img_hdr[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FPI, DEVICE_VIRTUAL_IMAGE, FpImageDevice)
|
G_DECLARE_FINAL_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FPI, DEVICE_VIRTUAL_IMAGE, FpImageDevice)
|
||||||
G_DEFINE_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FP_TYPE_IMAGE_DEVICE)
|
G_DEFINE_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FP_TYPE_IMAGE_DEVICE)
|
||||||
|
|
||||||
static void start_listen (FpDeviceVirtualImage *dev);
|
static void start_listen (FpDeviceVirtualImage *dev);
|
||||||
static void recv_image (FpDeviceVirtualImage *dev, GInputStream *stream);
|
static void recv_image (FpDeviceVirtualImage *dev,
|
||||||
|
GInputStream *stream);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_image_img_recv_cb (GObject *source_object,
|
recv_image_img_recv_cb (GObject *source_object,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
FpDeviceVirtualImage *self;
|
FpDeviceVirtualImage *self;
|
||||||
FpImageDevice *device;
|
FpImageDevice *device;
|
||||||
gssize bytes;
|
gssize bytes;
|
||||||
|
|
||||||
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
|
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
|
||||||
|
|
||||||
if (bytes <= 0) {
|
if (bytes <= 0)
|
||||||
if (bytes < 0) {
|
{
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
if (bytes < 0)
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
{
|
||||||
return;
|
g_warning ("Error receiving header for image data: %s", error->message);
|
||||||
}
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||||
self->connection = NULL;
|
self->connection = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
device = FP_IMAGE_DEVICE (self);
|
device = FP_IMAGE_DEVICE (self);
|
||||||
|
|
||||||
fpi_image_device_report_finger_status (device, TRUE);
|
fpi_image_device_report_finger_status (device, TRUE);
|
||||||
fpi_image_device_image_captured (device, g_steal_pointer (&self->recv_img));
|
fpi_image_device_image_captured (device, g_steal_pointer (&self->recv_img));
|
||||||
fpi_image_device_report_finger_status (device, FALSE);
|
fpi_image_device_report_finger_status (device, FALSE);
|
||||||
|
|
||||||
/* And, listen for more images from the same client. */
|
/* And, listen for more images from the same client. */
|
||||||
recv_image(self, G_INPUT_STREAM (source_object));
|
recv_image (self, G_INPUT_STREAM (source_object));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -97,180 +101,189 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
FpDeviceVirtualImage *self;
|
FpDeviceVirtualImage *self;
|
||||||
gssize bytes;
|
gssize bytes;
|
||||||
|
|
||||||
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
|
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
|
||||||
|
|
||||||
if (bytes <= 0) {
|
if (bytes <= 0)
|
||||||
if (bytes < 0) {
|
{
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
if (bytes < 0)
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
{
|
||||||
return;
|
g_warning ("Error receiving header for image data: %s", error->message);
|
||||||
}
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||||
self->connection = NULL;
|
self->connection = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||||
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000) {
|
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000)
|
||||||
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
{
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
||||||
self->connection = NULL;
|
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||||
}
|
self->connection = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0) {
|
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
|
||||||
switch (self->recv_img_hdr[0]) {
|
{
|
||||||
case -1:
|
switch (self->recv_img_hdr[0])
|
||||||
/* -1 is a retry error, just pass it through */
|
{
|
||||||
fpi_image_device_retry_scan (FP_IMAGE_DEVICE (self), self->recv_img_hdr[1]);
|
case -1:
|
||||||
break;
|
/* -1 is a retry error, just pass it through */
|
||||||
|
fpi_image_device_retry_scan (FP_IMAGE_DEVICE (self), self->recv_img_hdr[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
case -2:
|
case -2:
|
||||||
/* -2 is a fatal error, just pass it through*/
|
/* -2 is a fatal error, just pass it through*/
|
||||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (self),
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (self),
|
||||||
fpi_device_error_new (self->recv_img_hdr[1]));
|
fpi_device_error_new (self->recv_img_hdr[1]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* disconnect client, it didn't play fair */
|
/* disconnect client, it didn't play fair */
|
||||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||||
self->connection = NULL;
|
self->connection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And, listen for more images from the same client. */
|
/* And, listen for more images from the same client. */
|
||||||
recv_image(self, G_INPUT_STREAM (source_object));
|
recv_image (self, G_INPUT_STREAM (source_object));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
|
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
|
||||||
g_debug ("image data: %p", self->recv_img->data);
|
g_debug ("image data: %p", self->recv_img->data);
|
||||||
g_input_stream_read_async (G_INPUT_STREAM (source_object),
|
g_input_stream_read_async (G_INPUT_STREAM (source_object),
|
||||||
(guint8*)self->recv_img->data,
|
(guint8 *) self->recv_img->data,
|
||||||
self->recv_img->width * self->recv_img->height,
|
self->recv_img->width * self->recv_img->height,
|
||||||
G_PRIORITY_DEFAULT,
|
G_PRIORITY_DEFAULT,
|
||||||
self->cancellable,
|
self->cancellable,
|
||||||
recv_image_img_recv_cb,
|
recv_image_img_recv_cb,
|
||||||
self);
|
self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recv_image (FpDeviceVirtualImage *dev, GInputStream *stream)
|
recv_image (FpDeviceVirtualImage *dev, GInputStream *stream)
|
||||||
{
|
{
|
||||||
g_input_stream_read_async (stream,
|
g_input_stream_read_async (stream,
|
||||||
dev->recv_img_hdr,
|
dev->recv_img_hdr,
|
||||||
sizeof(dev->recv_img_hdr),
|
sizeof (dev->recv_img_hdr),
|
||||||
G_PRIORITY_DEFAULT,
|
G_PRIORITY_DEFAULT,
|
||||||
dev->cancellable,
|
dev->cancellable,
|
||||||
recv_image_hdr_recv_cb,
|
recv_image_hdr_recv_cb,
|
||||||
dev);
|
dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
GSocketConnection *connection;
|
GSocketConnection *connection;
|
||||||
GInputStream *stream;
|
GInputStream *stream;
|
||||||
FpDeviceVirtualImage *dev = user_data;
|
FpDeviceVirtualImage *dev = user_data;
|
||||||
|
|
||||||
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
||||||
res,
|
res,
|
||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);
|
||||||
if (!connection) {
|
if (!connection)
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
{
|
||||||
return;
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
return;
|
||||||
|
|
||||||
g_warning ("Error accepting a new connection: %s", error->message);
|
g_warning ("Error accepting a new connection: %s", error->message);
|
||||||
start_listen(dev);
|
start_listen (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always further connections (but we disconnect them immediately
|
/* Always further connections (but we disconnect them immediately
|
||||||
* if we already have a connection). */
|
* if we already have a connection). */
|
||||||
start_listen(dev);
|
start_listen (dev);
|
||||||
if (dev->connection) {
|
if (dev->connection)
|
||||||
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
{
|
||||||
return;
|
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dev->connection = connection;
|
dev->connection = connection;
|
||||||
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
|
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
|
||||||
|
|
||||||
recv_image (dev, stream);
|
recv_image (dev, stream);
|
||||||
|
|
||||||
fp_dbg("Got a new connection!");
|
fp_dbg ("Got a new connection!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
start_listen (FpDeviceVirtualImage *dev)
|
start_listen (FpDeviceVirtualImage *dev)
|
||||||
{
|
{
|
||||||
g_socket_listener_accept_async (dev->listener,
|
g_socket_listener_accept_async (dev->listener,
|
||||||
dev->cancellable,
|
dev->cancellable,
|
||||||
new_connection_cb,
|
new_connection_cb,
|
||||||
dev);
|
dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_init(FpImageDevice *dev)
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GSocketListener) listener = NULL;
|
g_autoptr(GSocketListener) listener = NULL;
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||||
const char *env;
|
const char *env;
|
||||||
g_autoptr(GSocketAddress) addr = NULL;
|
g_autoptr(GSocketAddress) addr = NULL;
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->client_fd = -1;
|
self->client_fd = -1;
|
||||||
|
|
||||||
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||||
|
|
||||||
listener = g_socket_listener_new ();
|
listener = g_socket_listener_new ();
|
||||||
g_socket_listener_set_backlog (listener, 1);
|
g_socket_listener_set_backlog (listener, 1);
|
||||||
|
|
||||||
/* Remove any left over socket. */
|
/* Remove any left over socket. */
|
||||||
g_unlink (env);
|
g_unlink (env);
|
||||||
|
|
||||||
addr = g_unix_socket_address_new (env);
|
addr = g_unix_socket_address_new (env);
|
||||||
|
|
||||||
if (!g_socket_listener_add_address (listener,
|
if (!g_socket_listener_add_address (listener,
|
||||||
addr,
|
addr,
|
||||||
G_SOCKET_TYPE_STREAM,
|
G_SOCKET_TYPE_STREAM,
|
||||||
G_SOCKET_PROTOCOL_DEFAULT,
|
G_SOCKET_PROTOCOL_DEFAULT,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&error)) {
|
&error))
|
||||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
{
|
||||||
|
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||||
|
|
||||||
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->listener = g_steal_pointer (&listener);
|
self->listener = g_steal_pointer (&listener);
|
||||||
self->cancellable = g_cancellable_new ();
|
self->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
start_listen (self);
|
start_listen (self);
|
||||||
|
|
||||||
fpi_image_device_open_complete (dev, NULL);
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
dev_deinit (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
g_cancellable_cancel (self->cancellable);
|
g_cancellable_cancel (self->cancellable);
|
||||||
g_clear_object (&self->cancellable);
|
g_clear_object (&self->cancellable);
|
||||||
g_clear_object (&self->listener);
|
g_clear_object (&self->listener);
|
||||||
g_clear_object (&self->connection);
|
g_clear_object (&self->connection);
|
||||||
|
|
||||||
fpi_image_device_close_complete(dev, NULL);
|
fpi_image_device_close_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -279,22 +292,21 @@ fpi_device_virtual_image_init (FpDeviceVirtualImage *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry driver_ids[] = {
|
static const FpIdEntry driver_ids[] = {
|
||||||
{ .virtual_envvar = "FP_VIRTUAL_IMAGE" },
|
{ .virtual_envvar = "FP_VIRTUAL_IMAGE" },
|
||||||
{ .virtual_envvar = NULL }
|
{ .virtual_envvar = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||||
{
|
{
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = FP_COMPONENT;
|
dev_class->id = FP_COMPONENT;
|
||||||
dev_class->full_name = "Virtual image device for debugging";
|
dev_class->full_name = "Virtual image device for debugging";
|
||||||
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||||
dev_class->id_table = driver_ids;
|
dev_class->id_table = driver_ids;
|
||||||
|
|
||||||
img_class->img_open = dev_init;
|
img_class->img_open = dev_init;
|
||||||
img_class->img_close = dev_deinit;
|
img_class->img_close = dev_deinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,26 +26,28 @@
|
||||||
#include "fpi-image-device.h"
|
#include "fpi-image-device.h"
|
||||||
|
|
||||||
/* fp_minutia structure definition */
|
/* fp_minutia structure definition */
|
||||||
struct fp_minutia {
|
struct fp_minutia
|
||||||
int x;
|
{
|
||||||
int y;
|
int x;
|
||||||
int ex;
|
int y;
|
||||||
int ey;
|
int ex;
|
||||||
int direction;
|
int ey;
|
||||||
double reliability;
|
int direction;
|
||||||
int type;
|
double reliability;
|
||||||
int appearing;
|
int type;
|
||||||
int feature_id;
|
int appearing;
|
||||||
int *nbrs;
|
int feature_id;
|
||||||
int *ridge_counts;
|
int *nbrs;
|
||||||
int num_nbrs;
|
int *ridge_counts;
|
||||||
|
int num_nbrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_minutiae structure definition */
|
/* fp_minutiae structure definition */
|
||||||
struct fp_minutiae {
|
struct fp_minutiae
|
||||||
int alloc;
|
{
|
||||||
int num;
|
int alloc;
|
||||||
struct fp_minutia **list;
|
int num;
|
||||||
|
struct fp_minutia **list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,10 @@
|
||||||
|
|
||||||
GHashTable *printed = NULL;
|
GHashTable *printed = NULL;
|
||||||
|
|
||||||
static GList *insert_drivers (GList *list)
|
static GList *
|
||||||
|
insert_drivers (GList *list)
|
||||||
{
|
{
|
||||||
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof(GType));
|
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof (GType));
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
fpi_get_driver_types (drivers);
|
fpi_get_driver_types (drivers);
|
||||||
|
@ -42,10 +43,11 @@ static GList *insert_drivers (GList *list)
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
||||||
const FpIdEntry *entry;
|
const FpIdEntry *entry;
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB) {
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
g_type_class_unref (cls);
|
{
|
||||||
continue;
|
g_type_class_unref (cls);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (entry = cls->id_table; entry->vid; entry++)
|
for (entry = cls->id_table; entry->vid; entry++)
|
||||||
{
|
{
|
||||||
|
@ -53,53 +55,55 @@ static GList *insert_drivers (GList *list)
|
||||||
|
|
||||||
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
||||||
|
|
||||||
if (g_hash_table_lookup (printed, key) != NULL) {
|
if (g_hash_table_lookup (printed, key) != NULL)
|
||||||
g_free (key);
|
{
|
||||||
continue;
|
g_free (key);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
||||||
|
|
||||||
list = g_list_prepend (list, g_strdup_printf ("%s | %s\n", key, cls->full_name));
|
list = g_list_prepend (list, g_strdup_printf ("%s | %s\n", key, cls->full_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_type_class_unref (cls);
|
g_type_class_unref (cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GList *list, *l;
|
GList *list, *l;
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
|
|
||||||
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
g_print ("%% lifprint — Supported Devices\n");
|
g_print ("%% lifprint — Supported Devices\n");
|
||||||
g_print ("%% Bastien Nocera, Daniel Drake\n");
|
g_print ("%% Bastien Nocera, Daniel Drake\n");
|
||||||
g_print ("%% 2018\n");
|
g_print ("%% 2018\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
|
|
||||||
g_print ("# Supported Devices\n");
|
g_print ("# Supported Devices\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
g_print ("This is a list of supported devices in libfprint's development version. Those drivers might not all be available in the stable, released version. If in doubt, contact your distribution or systems integrator for details.\n");
|
g_print ("This is a list of supported devices in libfprint's development version. Those drivers might not all be available in the stable, released version. If in doubt, contact your distribution or systems integrator for details.\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
g_print ("## USB devices\n");
|
g_print ("## USB devices\n");
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
g_print ("USB ID | Driver\n");
|
g_print ("USB ID | Driver\n");
|
||||||
g_print ("------------ | ------------\n");
|
g_print ("------------ | ------------\n");
|
||||||
|
|
||||||
list = NULL;
|
list = NULL;
|
||||||
list = insert_drivers (list);
|
list = insert_drivers (list);
|
||||||
|
|
||||||
list = g_list_sort (list, (GCompareFunc) g_strcmp0);
|
list = g_list_sort (list, (GCompareFunc) g_strcmp0);
|
||||||
for (l = list; l != NULL; l = l->next)
|
for (l = list; l != NULL; l = l->next)
|
||||||
g_print ("%s", (char *) l->data);
|
g_print ("%s", (char *) l->data);
|
||||||
|
|
||||||
g_list_free_full (list, g_free);
|
g_list_free_full (list, g_free);
|
||||||
g_hash_table_destroy (printed);
|
g_hash_table_destroy (printed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,100 +25,105 @@
|
||||||
#include "fpi-device.h"
|
#include "fpi-device.h"
|
||||||
|
|
||||||
static const FpIdEntry whitelist_id_table[] = {
|
static const FpIdEntry whitelist_id_table[] = {
|
||||||
/* Unsupported (for now) Validity Sensors finger print readers */
|
/* Unsupported (for now) Validity Sensors finger print readers */
|
||||||
{ .vid = 0x138a, .pid = 0x0090 }, /* Found on e.g. Lenovo T460s */
|
{ .vid = 0x138a, .pid = 0x0090 }, /* Found on e.g. Lenovo T460s */
|
||||||
{ .vid = 0x138a, .pid = 0x0091 },
|
{ .vid = 0x138a, .pid = 0x0091 },
|
||||||
{ .vid = 0x138a, .pid = 0x0094 },
|
{ .vid = 0x138a, .pid = 0x0094 },
|
||||||
{ .vid = 0x138a, .pid = 0x0097 }, /* Found on e.g. Lenovo T470s */
|
{ .vid = 0x138a, .pid = 0x0097 }, /* Found on e.g. Lenovo T470s */
|
||||||
{ .vid = 0 },
|
{ .vid = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpIdEntry blacklist_id_table[] = {
|
static const FpIdEntry blacklist_id_table[] = {
|
||||||
{ .vid = 0x0483, .pid = 0x2016 },
|
{ .vid = 0x0483, .pid = 0x2016 },
|
||||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
/* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */
|
||||||
{ .vid = 0x045e, .pid = 0x00bb },
|
{ .vid = 0x045e, .pid = 0x00bb },
|
||||||
{ .vid = 0 },
|
{ .vid = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FpDeviceClass whitelist = {
|
static const FpDeviceClass whitelist = {
|
||||||
.type = FP_DEVICE_TYPE_USB,
|
.type = FP_DEVICE_TYPE_USB,
|
||||||
.id_table = whitelist_id_table,
|
.id_table = whitelist_id_table,
|
||||||
.full_name = "Hardcoded whitelist"
|
.full_name = "Hardcoded whitelist"
|
||||||
};
|
};
|
||||||
|
|
||||||
GHashTable *printed = NULL;
|
GHashTable *printed = NULL;
|
||||||
|
|
||||||
static void print_driver (const FpDeviceClass *cls)
|
static void
|
||||||
|
print_driver (const FpDeviceClass *cls)
|
||||||
{
|
{
|
||||||
const FpIdEntry *entry;
|
const FpIdEntry *entry;
|
||||||
gint num_printed = 0;
|
gint num_printed = 0;
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (entry = cls->id_table; entry->vid != 0; entry++) {
|
for (entry = cls->id_table; entry->vid != 0; entry++)
|
||||||
const FpIdEntry *bl_entry;
|
{
|
||||||
char *key;
|
const FpIdEntry *bl_entry;
|
||||||
|
char *key;
|
||||||
|
|
||||||
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++) {
|
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++)
|
||||||
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid) {
|
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bl_entry->vid != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
if (bl_entry->vid != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (g_hash_table_lookup (printed, key) != NULL) {
|
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
||||||
g_free (key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
if (g_hash_table_lookup (printed, key) != NULL)
|
||||||
|
{
|
||||||
|
g_free (key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (num_printed == 0)
|
g_hash_table_insert (printed, key, GINT_TO_POINTER (1));
|
||||||
g_print ("# %s\n", cls->full_name);
|
|
||||||
|
|
||||||
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n",
|
if (num_printed == 0)
|
||||||
entry->vid, entry->pid);
|
g_print ("# %s\n", cls->full_name);
|
||||||
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n",
|
|
||||||
entry->vid, entry->pid, cls->full_name);
|
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", TEST==\"power/control\", ATTR{power/control}=\"auto\"\n",
|
||||||
num_printed++;
|
entry->vid, entry->pid);
|
||||||
|
g_print ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ENV{LIBFPRINT_DRIVER}=\"%s\"\n",
|
||||||
|
entry->vid, entry->pid, cls->full_name);
|
||||||
|
num_printed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_printed > 0)
|
if (num_printed > 0)
|
||||||
g_print ("\n");
|
g_print ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof(GType));
|
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof (GType));
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
g_print ("%p\n", drivers);
|
g_print ("%p\n", drivers);
|
||||||
g_print ("%p\n", fpi_get_driver_types);
|
g_print ("%p\n", fpi_get_driver_types);
|
||||||
fpi_get_driver_types (drivers);
|
fpi_get_driver_types (drivers);
|
||||||
|
|
||||||
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
for (i = 0; i < drivers->len; i++) {
|
for (i = 0; i < drivers->len; i++)
|
||||||
GType driver = g_array_index (drivers, GType, i);
|
{
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
GType driver = g_array_index (drivers, GType, i);
|
||||||
|
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB) {
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
g_type_class_unref (cls);
|
{
|
||||||
continue;
|
g_type_class_unref (cls);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
print_driver (cls);
|
print_driver (cls);
|
||||||
|
|
||||||
g_type_class_unref (cls);
|
g_type_class_unref (cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_driver (&whitelist);
|
print_driver (&whitelist);
|
||||||
|
|
||||||
g_hash_table_destroy (printed);
|
g_hash_table_destroy (printed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,3 @@
|
||||||
#include "fp-context.h"
|
#include "fp-context.h"
|
||||||
#include "fp-device.h"
|
#include "fp-device.h"
|
||||||
#include "fp-image.h"
|
#include "fp-image.h"
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ case "$1" in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
pushd "$SRCROOT"
|
pushd "$SRCROOT"
|
||||||
uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep -E '(fp|fpi)-.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/`
|
uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/`
|
||||||
RES=$?
|
RES=$?
|
||||||
popd
|
popd
|
||||||
exit $RES
|
exit $RES
|
Loading…
Reference in a new issue