Uncrustify everything except for nbis
This commit is contained in:
parent
fd5f511b33
commit
d1fb1e26f3
60 changed files with 30386 additions and 28683 deletions
|
@ -33,7 +33,8 @@ typedef enum {
|
||||||
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;
|
||||||
|
@ -79,7 +80,8 @@ img_to_rgbdata (const guint8 *imgdata,
|
||||||
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;
|
||||||
|
@ -97,33 +99,35 @@ plot_minutiae (unsigned char *rgbdata,
|
||||||
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);
|
struct fp_minutia *min = g_ptr_array_index (minutiae, i);
|
||||||
int x, y;
|
int x, y;
|
||||||
size_t pixel_offset;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +153,8 @@ img_to_pixbuf (FpImage *img,
|
||||||
|
|
||||||
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);
|
||||||
|
@ -167,7 +172,8 @@ update_image (LibfprintDemoWindow *win)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
if (win->img == NULL) {
|
if (win->img == NULL)
|
||||||
|
{
|
||||||
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -197,15 +203,18 @@ 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:
|
case FP_SCAN_TYPE_PRESS:
|
||||||
message = "Place your finger on the fingerprint reader";
|
message = "Place your finger on the fingerprint reader";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FP_SCAN_TYPE_SWIPE:
|
case FP_SCAN_TYPE_SWIPE:
|
||||||
message = "Swipe your finger across the fingerprint reader";
|
message = "Swipe your finger across the fingerprint reader";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
@ -225,7 +234,8 @@ dev_capture_start_cb (FpDevice *dev,
|
||||||
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);
|
g_warning ("Error capturing data: %s", error->message);
|
||||||
if (error->domain == FP_DEVICE_RETRY ||
|
if (error->domain == FP_DEVICE_RETRY ||
|
||||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
@ -254,15 +264,17 @@ 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;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
libfprint_demo_set_mode (win, ERROR_MODE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_start_capture(win);
|
dev_start_capture (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -278,7 +290,8 @@ activate_capture (GSimpleAction *action,
|
||||||
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);
|
dev_start_capture (win);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -411,19 +424,22 @@ libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
||||||
{
|
{
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode)
|
||||||
|
{
|
||||||
case EMPTY_MODE:
|
case EMPTY_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOIMAGING_MODE:
|
case NOIMAGING_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
|
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->capture_button, FALSE);
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_MODE:
|
case CAPTURE_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "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->capture_button, TRUE);
|
||||||
|
@ -435,24 +451,28 @@ libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
||||||
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPINNER_MODE:
|
case SPINNER_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
gtk_widget_set_sensitive (win->cancel_button, TRUE);
|
gtk_widget_set_sensitive (win->cancel_button, TRUE);
|
||||||
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ERROR_MODE:
|
case ERROR_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
||||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RETRY_MODE:
|
case RETRY_MODE:
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "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->capture_button, TRUE);
|
||||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
@ -489,19 +509,22 @@ libfprint_demo_window_init (LibfprintDemoWindow *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);
|
libfprint_demo_set_mode (window, ERROR_MODE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Empty list? */
|
/* Empty list? */
|
||||||
if (devices->len == 0) {
|
if (devices->len == 0)
|
||||||
|
{
|
||||||
libfprint_demo_set_mode (window, EMPTY_MODE);
|
libfprint_demo_set_mode (window, EMPTY_MODE);
|
||||||
return;
|
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);
|
libfprint_demo_set_mode (window, NOIMAGING_MODE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -527,7 +550,8 @@ libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
|
||||||
//FIXME setup dispose
|
//FIXME setup dispose
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GtkApplication *app;
|
GtkApplication *app;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
typedef struct _EnrollData {
|
typedef struct _EnrollData
|
||||||
|
{
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
int ret_value;
|
int ret_value;
|
||||||
} EnrollData;
|
} EnrollData;
|
||||||
|
@ -37,20 +38,23 @@ enroll_data_free (EnrollData *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)
|
if (!devices->len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dev = g_ptr_array_index (devices, 0);
|
dev = g_ptr_array_index (devices, 0);
|
||||||
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
||||||
return 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;
|
EnrollData *enroll_data = user_data;
|
||||||
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
fp_device_close_finish (dev, res, &error);
|
fp_device_close_finish (dev, res, &error);
|
||||||
|
@ -62,26 +66,33 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
EnrollData *enroll_data = user_data;
|
||||||
|
|
||||||
g_autoptr(FpPrint) print = NULL;
|
g_autoptr(FpPrint) print = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
print = fp_device_enroll_finish (dev, res, &error);
|
print = fp_device_enroll_finish (dev, res, &error);
|
||||||
|
|
||||||
if (!error) {
|
if (!error)
|
||||||
|
{
|
||||||
enroll_data->ret_value = EXIT_SUCCESS;
|
enroll_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
||||||
if (!fp_device_has_storage (dev)) {
|
if (!fp_device_has_storage (dev))
|
||||||
g_debug("Device has not storage, saving locally");
|
{
|
||||||
int r = print_data_save(print, FP_FINGER_RIGHT_INDEX);
|
g_debug ("Device has not storage, saving locally");
|
||||||
if (r < 0) {
|
int r = print_data_save (print, FP_FINGER_RIGHT_INDEX);
|
||||||
g_warning("Data save failed, code %d", r);
|
if (r < 0)
|
||||||
|
{
|
||||||
|
g_warning ("Data save failed, code %d", r);
|
||||||
enroll_data->ret_value = EXIT_FAILURE;
|
enroll_data->ret_value = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
g_warning("Enroll failed with error %s\n", error->message);
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Enroll failed with error %s\n", error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||||
|
@ -95,7 +106,8 @@ on_enroll_progress (FpDevice *device,
|
||||||
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",
|
g_warning ("Enroll stage %d of %d failed with error %s",
|
||||||
completed_stages,
|
completed_stages,
|
||||||
fp_device_get_nr_enroll_stages (device),
|
fp_device_get_nr_enroll_stages (device),
|
||||||
|
@ -104,9 +116,8 @@ on_enroll_progress (FpDevice *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
@ -117,9 +128,11 @@ 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;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
g_main_loop_quit (enroll_data->loop);
|
g_main_loop_quit (enroll_data->loop);
|
||||||
return;
|
return;
|
||||||
|
@ -136,32 +149,35 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
enroll_data);
|
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");
|
{
|
||||||
|
g_warning ("Impossible to get devices");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = discover_device (devices);
|
dev = discover_device (devices);
|
||||||
if (!dev) {
|
if (!dev)
|
||||||
g_warning("No devices detected.");
|
{
|
||||||
|
g_warning ("No devices detected.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,11 +252,9 @@ 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
|
||||||
{
|
{
|
||||||
g_warning ("Getting prints failed with error %s", error->message);
|
g_warning ("Getting prints failed with error %s", error->message);
|
||||||
|
|
|
@ -34,103 +34,112 @@ 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);
|
driver = fp_print_get_driver (print);
|
||||||
dev_id = fp_print_get_device_id (print);
|
dev_id = fp_print_get_device_id (print);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
driver = fp_device_get_driver (dev);
|
driver = fp_device_get_driver (dev);
|
||||||
dev_id = fp_device_get_device_id (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");
|
g_warning ("Error loading storage, assuming it is empty");
|
||||||
return g_variant_dict_new(NULL);
|
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,!");
|
g_warning ("Error saving storage,!");
|
||||||
return -1;
|
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_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
g_autofree guchar *data = NULL;
|
g_autofree guchar *data = NULL;
|
||||||
GVariant *val;
|
GVariant *val;
|
||||||
gsize size;
|
gsize size;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
dict = load_data();
|
dict = load_data ();
|
||||||
|
|
||||||
fp_print_serialize (print, &data, &size, &error);
|
fp_print_serialize (print, &data, &size, &error);
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_warning ("Error serializing data: %s", error->message);
|
g_warning ("Error serializing data: %s", error->message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val = g_variant_new_fixed_array (G_VARIANT_TYPE("y"), data, size, 1);
|
val = g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), data, size, 1);
|
||||||
g_variant_dict_insert_value (dict, descr, val);
|
g_variant_dict_insert_value (dict, descr, val);
|
||||||
|
|
||||||
res = save_data(g_variant_dict_end(dict));
|
res = save_data (g_variant_dict_end (dict));
|
||||||
|
|
||||||
return res;
|
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_autoptr(GVariant) val = NULL;
|
||||||
|
g_autoptr(GVariantDict) dict = NULL;
|
||||||
g_autofree guchar *stored_data = NULL;
|
g_autofree guchar *stored_data = NULL;
|
||||||
gsize stored_len;
|
gsize stored_len;
|
||||||
|
|
||||||
dict = load_data();
|
dict = load_data ();
|
||||||
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
||||||
|
|
||||||
if (val) {
|
if (val)
|
||||||
|
{
|
||||||
FpPrint *print;
|
FpPrint *print;
|
||||||
g_autoptr (GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
stored_data = (guchar*) g_variant_get_fixed_array (val, &stored_len, 1);
|
stored_data = (guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
|
||||||
print = fp_print_deserialize (stored_data, stored_len, &error);
|
print = fp_print_deserialize (stored_data, stored_len, &error);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -171,23 +180,26 @@ save_image_to_pgm (FpImage *img, const char *path)
|
||||||
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);
|
{
|
||||||
|
g_warning ("could not open '%s' for writing: %d", path, errno);
|
||||||
return FALSE;
|
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);
|
||||||
|
g_critical ("pgm header write failed, error %d", r);
|
||||||
return FALSE;
|
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);
|
||||||
|
g_critical ("short write (%d)", r);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +209,8 @@ save_image_to_pgm (FpImage *img, const char *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;
|
||||||
|
|
||||||
|
|
|
@ -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,7 +24,8 @@
|
||||||
|
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
typedef struct _VerifyData {
|
typedef struct _VerifyData
|
||||||
|
{
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
int ret_value;
|
int ret_value;
|
||||||
} VerifyData;
|
} VerifyData;
|
||||||
|
@ -37,20 +38,23 @@ verify_data_free (VerifyData *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)
|
if (!devices->len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dev = g_ptr_array_index (devices, 0);
|
dev = g_ptr_array_index (devices, 0);
|
||||||
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
||||||
return 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;
|
VerifyData *verify_data = user_data;
|
||||||
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
fp_device_close_finish (dev, res, &error);
|
fp_device_close_finish (dev, res, &error);
|
||||||
|
@ -61,39 +65,45 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||||
g_main_loop_quit (verify_data->loop);
|
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(FpPrint) print = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
gboolean match;
|
gboolean match;
|
||||||
|
|
||||||
if (!fp_device_verify_finish (dev, res, &match, &print, &error)) {
|
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
|
||||||
|
{
|
||||||
g_warning ("Failed to verify print: %s", error->message);
|
g_warning ("Failed to verify print: %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
g_main_loop_quit (verify_data->loop);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match)
|
||||||
|
{
|
||||||
g_print ("MATCH!\n");
|
g_print ("MATCH!\n");
|
||||||
if (fp_device_supports_capture (dev) &&
|
if (fp_device_supports_capture (dev) &&
|
||||||
print_image_save (print, "verify.pgm")) {
|
print_image_save (print, "verify.pgm"))
|
||||||
g_print("Print image saved as verify.pgm");
|
g_print ("Print image saved as verify.pgm");
|
||||||
}
|
|
||||||
|
|
||||||
verify_data->ret_value = EXIT_SUCCESS;
|
verify_data->ret_value = EXIT_SUCCESS;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_print ("NO MATCH!\n");
|
g_print ("NO MATCH!\n");
|
||||||
verify_data->ret_value = EXIT_FAILURE;
|
verify_data->ret_value = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("Verify again? [Y/n]? ");
|
g_print ("Verify again? [Y/n]? ");
|
||||||
if (fgets (buffer, sizeof (buffer), stdin) &&
|
if (fgets (buffer, sizeof (buffer), stdin) &&
|
||||||
(buffer[0] == 'Y' || buffer[0] == 'y')) {
|
(buffer[0] == 'Y' || buffer[0] == 'y'))
|
||||||
|
{
|
||||||
start_verification (dev, verify_data);
|
start_verification (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,23 +116,27 @@ 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(GPtrArray) prints = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
prints = fp_device_list_prints_finish (dev, res, &error);
|
prints = fp_device_list_prints_finish (dev, res, &error);
|
||||||
|
|
||||||
if (!error) {
|
if (!error)
|
||||||
|
{
|
||||||
FpPrint *verify_print = NULL;
|
FpPrint *verify_print = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!prints->len)
|
if (!prints->len)
|
||||||
g_warning ("No prints saved on device");
|
g_warning ("No prints saved on device");
|
||||||
|
|
||||||
for (i = 0; i < prints->len; ++i) {
|
for (i = 0; i < prints->len; ++i)
|
||||||
|
{
|
||||||
FpPrint *print = prints->pdata[i];
|
FpPrint *print = prints->pdata[i];
|
||||||
|
|
||||||
if (fp_print_get_finger (print) == FP_FINGER_RIGHT_INDEX &&
|
if (fp_print_get_finger (print) == FP_FINGER_RIGHT_INDEX &&
|
||||||
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0) {
|
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
|
||||||
|
{
|
||||||
if (!verify_print ||
|
if (!verify_print ||
|
||||||
(g_date_compare (fp_print_get_enroll_date (print),
|
(g_date_compare (fp_print_get_enroll_date (print),
|
||||||
fp_print_get_enroll_date (verify_print)) >= 0))
|
fp_print_get_enroll_date (verify_print)) >= 0))
|
||||||
|
@ -130,7 +144,8 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verify_print) {
|
if (!verify_print)
|
||||||
|
{
|
||||||
g_warning ("Did you remember to enroll your right index "
|
g_warning ("Did you remember to enroll your right index "
|
||||||
"finger first?");
|
"finger first?");
|
||||||
g_main_loop_quit (verify_data->loop);
|
g_main_loop_quit (verify_data->loop);
|
||||||
|
@ -144,7 +159,9 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
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);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_warning ("Loading prints failed with error %s", error->message);
|
g_warning ("Loading prints failed with error %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
g_main_loop_quit (verify_data->loop);
|
||||||
}
|
}
|
||||||
|
@ -153,18 +170,22 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||||
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");
|
g_print ("Creating finger template, using device storage...\n");
|
||||||
fp_device_list_prints (dev, NULL,
|
fp_device_list_prints (dev, NULL,
|
||||||
(GAsyncReadyCallback) on_list_completed,
|
(GAsyncReadyCallback) on_list_completed,
|
||||||
verify_data);
|
verify_data);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_print ("Loading previously enrolled right index finger data...\n");
|
g_print ("Loading previously enrolled right index finger data...\n");
|
||||||
g_autoptr(FpPrint) verify_print;
|
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 ("Failed to load fingerprint data");
|
||||||
g_warning ("Did you remember to enroll your right index "
|
g_warning ("Did you remember to enroll your right index "
|
||||||
"finger first?");
|
"finger first?");
|
||||||
|
@ -183,9 +204,11 @@ 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;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
if (!fp_device_open_finish (dev, res, &error)) {
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
|
{
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
g_main_loop_quit (verify_data->loop);
|
||||||
return;
|
return;
|
||||||
|
@ -196,10 +219,11 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||||
start_verification (dev, verify_data);
|
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;
|
||||||
|
|
||||||
|
@ -209,14 +233,16 @@ int main(void)
|
||||||
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");
|
{
|
||||||
|
g_warning ("Impossible to get devices");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = discover_device (devices);
|
dev = discover_device (devices);
|
||||||
if (!dev) {
|
if (!dev)
|
||||||
g_warning("No devices detected.");
|
{
|
||||||
|
g_warning ("No devices detected.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,5 +257,3 @@ int main(void)
|
||||||
|
|
||||||
return verify_data->ret_value;
|
return verify_data->ret_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,10 @@
|
||||||
#include "drivers_api.h"
|
#include "drivers_api.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);
|
||||||
static int adjust_gain(unsigned char *buffer, int status);
|
static int adjust_gain (unsigned char *buffer,
|
||||||
|
int status);
|
||||||
|
|
||||||
#define FIRST_AES1610_REG 0x1B
|
#define FIRST_AES1610_REG 0x1B
|
||||||
#define LAST_AES1610_REG 0xFF
|
#define LAST_AES1610_REG 0xFF
|
||||||
|
@ -69,7 +70,8 @@ static int adjust_gain(unsigned char *buffer, int status);
|
||||||
|
|
||||||
/****** GENERAL FUNCTIONS ******/
|
/****** GENERAL FUNCTIONS ******/
|
||||||
|
|
||||||
struct _FpiDeviceAes1610 {
|
struct _FpiDeviceAes1610
|
||||||
|
{
|
||||||
FpImageDevice parent;
|
FpImageDevice parent;
|
||||||
|
|
||||||
guint8 read_regs_retry_count;
|
guint8 read_regs_retry_count;
|
||||||
|
@ -78,9 +80,9 @@ struct _FpiDeviceAes1610 {
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
guint8 blanks_count;
|
guint8 blanks_count;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes1610, fpi_device_aes1610, FPI, DEVICE_AES1610,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes1610, fpi_device_aes1610, FPI, DEVICE_AES1610,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes1610, fpi_device_aes1610, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceAes1610, fpi_device_aes1610, 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,
|
||||||
|
@ -89,10 +91,13 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.get_pixel = aes_get_pixel,
|
.get_pixel = aes_get_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*aes1610_read_regs_cb)(FpImageDevice *dev, int status,
|
typedef void (*aes1610_read_regs_cb)(FpImageDevice *dev,
|
||||||
unsigned char *regs, void *user_data);
|
int status,
|
||||||
|
unsigned char *regs,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
struct aes1610_read_regs {
|
struct aes1610_read_regs
|
||||||
|
{
|
||||||
FpImageDevice *dev;
|
FpImageDevice *dev;
|
||||||
aes1610_read_regs_cb callback;
|
aes1610_read_regs_cb callback;
|
||||||
struct aes_regwrite *regwrite;
|
struct aes_regwrite *regwrite;
|
||||||
|
@ -100,10 +105,12 @@ struct aes1610_read_regs {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: what to do here? */
|
/* FIXME: what to do here? */
|
||||||
static void stub_capture_stop_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
stub_capture_stop_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fp_warn ("Error stopping capture: %s", error->message);
|
fp_warn ("Error stopping capture: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
@ -111,40 +118,44 @@ static void stub_capture_stop_cb(FpImageDevice *dev, GError *error,
|
||||||
|
|
||||||
|
|
||||||
/* check that read succeeded but ignore all data */
|
/* check that read succeeded but ignore all data */
|
||||||
static void generic_ignore_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
generic_ignore_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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 generic_write_regv_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
generic_write_regv_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the specified number of bytes from the IN endpoint but throw them
|
/* read the specified number of bytes from the IN endpoint but throw them
|
||||||
* away, then increment the SSM */
|
* away, then increment the SSM */
|
||||||
static void generic_read_ignore_data(FpiSsm *ssm, FpDevice *dev,
|
static void
|
||||||
|
generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
|
||||||
size_t bytes)
|
size_t bytes)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = g_malloc(bytes);
|
data = g_malloc (bytes);
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN, data, bytes, NULL);
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, 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,
|
||||||
generic_ignore_data_cb, NULL);
|
generic_ignore_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** FINGER PRESENCE DETECTION ******/
|
/****** FINGER PRESENCE DETECTION ******/
|
||||||
|
@ -175,17 +186,19 @@ static const struct aes_regwrite finger_det_reqs[] = {
|
||||||
{ 0x81, 0x04 }
|
{ 0x81, 0x04 }
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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;
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_image_device_session_error (dev, error);
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -193,46 +206,53 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
/* examine histogram to determine finger presence */
|
/* examine histogram to determine finger presence */
|
||||||
for (i = 3; i < 17; i++)
|
for (i = 3; i < 17; i++)
|
||||||
sum += (data[i] & 0xf) + (data[i] >> 4);
|
sum += (data[i] & 0xf) + (data[i] >> 4);
|
||||||
if (sum > 20) {
|
if (sum > 20)
|
||||||
|
{
|
||||||
/* reset default gain */
|
/* reset default gain */
|
||||||
adjust_gain(data,GAIN_STATUS_FIRST);
|
adjust_gain (data, GAIN_STATUS_FIRST);
|
||||||
/* finger present, start capturing */
|
/* finger present, start capturing */
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
finger_det_reqs_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_image_device_session_error(dev, error);
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
|
||||||
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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs), finger_det_reqs_cb, NULL);
|
aes_write_regv (dev, finger_det_reqs, G_N_ELEMENTS (finger_det_reqs), finger_det_reqs_cb, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +393,7 @@ static struct aes_regwrite strip_scan_reqs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes_regwrite capture_stop[] = {
|
static const struct aes_regwrite capture_stop[] = {
|
||||||
{ 0x81,0x00 }
|
{ 0x81, 0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -393,7 +413,8 @@ static unsigned char list_BD_values[10] = {
|
||||||
* 0xbd, 0xbe, 0x29 and 0x2A registers are affected
|
* 0xbd, 0xbe, 0x29 and 0x2A registers are affected
|
||||||
* Returns 0 if no problem occurred
|
* Returns 0 if no problem occurred
|
||||||
* TODO: This is a basic support for gain. It needs testing/tweaking. */
|
* TODO: This is a basic support for gain. It needs testing/tweaking. */
|
||||||
static int adjust_gain(unsigned char *buffer, int status)
|
static int
|
||||||
|
adjust_gain (unsigned char *buffer, int status)
|
||||||
{
|
{
|
||||||
// The position in the array of possible values for 0xBE and 0xBD registers
|
// The position in the array of possible values for 0xBE and 0xBD registers
|
||||||
static int pos_list_BE = 0;
|
static int pos_list_BE = 0;
|
||||||
|
@ -401,26 +422,31 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
|
|
||||||
// This is the first adjustment (we begin acquisition)
|
// This is the first adjustment (we begin acquisition)
|
||||||
// We adjust strip_scan_reqs for future strips and capture_reqs that is sent just after this step
|
// We adjust strip_scan_reqs for future strips and capture_reqs that is sent just after this step
|
||||||
if (status == GAIN_STATUS_FIRST) {
|
if (status == GAIN_STATUS_FIRST)
|
||||||
if (buffer[1] > 0x78) { // maximum gain needed
|
{
|
||||||
|
if (buffer[1] > 0x78) // maximum gain needed
|
||||||
|
{
|
||||||
strip_scan_reqs[0].value = 0x6B;
|
strip_scan_reqs[0].value = 0x6B;
|
||||||
strip_scan_reqs[1].value = 0x06;
|
strip_scan_reqs[1].value = 0x06;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
strip_scan_reqs[3].value = 0x4B;
|
strip_scan_reqs[3].value = 0x4B;
|
||||||
}
|
}
|
||||||
else if (buffer[1] > 0x55) {
|
else if (buffer[1] > 0x55)
|
||||||
|
{
|
||||||
strip_scan_reqs[0].value = 0x63;
|
strip_scan_reqs[0].value = 0x63;
|
||||||
strip_scan_reqs[1].value = 0x15;
|
strip_scan_reqs[1].value = 0x15;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
strip_scan_reqs[3].value = 0x3b;
|
strip_scan_reqs[3].value = 0x3b;
|
||||||
}
|
}
|
||||||
else if (buffer[1] > 0x40 || buffer[16] > 0x19) {
|
else if (buffer[1] > 0x40 || buffer[16] > 0x19)
|
||||||
|
{
|
||||||
strip_scan_reqs[0].value = 0x43;
|
strip_scan_reqs[0].value = 0x43;
|
||||||
strip_scan_reqs[1].value = 0x13;
|
strip_scan_reqs[1].value = 0x13;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
strip_scan_reqs[3].value = 0x30;
|
strip_scan_reqs[3].value = 0x30;
|
||||||
}
|
}
|
||||||
else { // minimum gain needed
|
else // minimum gain needed
|
||||||
|
{
|
||||||
strip_scan_reqs[0].value = 0x23;
|
strip_scan_reqs[0].value = 0x23;
|
||||||
strip_scan_reqs[1].value = 0x07;
|
strip_scan_reqs[1].value = 0x07;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
|
@ -433,14 +459,15 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
capture_reqs[10].value = strip_scan_reqs[2].value;
|
capture_reqs[10].value = strip_scan_reqs[2].value;
|
||||||
capture_reqs[21].value = strip_scan_reqs[3].value;
|
capture_reqs[21].value = strip_scan_reqs[3].value;
|
||||||
|
|
||||||
fp_dbg("first gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
|
fp_dbg ("first gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every 2/3 strips
|
// Every 2/3 strips
|
||||||
// We try to soften big changes of the gain (at least for 0xBE and 0xBD
|
// We try to soften big changes of the gain (at least for 0xBE and 0xBD
|
||||||
// FIXME: This softenning will need testing and tweaking too
|
// FIXME: This softenning will need testing and tweaking too
|
||||||
else if (status == GAIN_STATUS_NORMAL) {
|
else if (status == GAIN_STATUS_NORMAL)
|
||||||
if (buffer[514] > 0x78) { // maximum gain needed
|
{
|
||||||
|
if (buffer[514] > 0x78) // maximum gain needed
|
||||||
|
{
|
||||||
if (pos_list_BE < 7)
|
if (pos_list_BE < 7)
|
||||||
pos_list_BE++;
|
pos_list_BE++;
|
||||||
|
|
||||||
|
@ -450,7 +477,8 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
strip_scan_reqs[1].value = 0x04;
|
strip_scan_reqs[1].value = 0x04;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
}
|
}
|
||||||
else if (buffer[514] > 0x55) {
|
else if (buffer[514] > 0x55)
|
||||||
|
{
|
||||||
if (pos_list_BE < 2)
|
if (pos_list_BE < 2)
|
||||||
pos_list_BE++;
|
pos_list_BE++;
|
||||||
else if (pos_list_BE > 2)
|
else if (pos_list_BE > 2)
|
||||||
|
@ -464,7 +492,8 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
strip_scan_reqs[1].value = 0x15;
|
strip_scan_reqs[1].value = 0x15;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
}
|
}
|
||||||
else if (buffer[514] > 0x40 || buffer[529] > 0x19) {
|
else if (buffer[514] > 0x40 || buffer[529] > 0x19)
|
||||||
|
{
|
||||||
if (pos_list_BE < 1)
|
if (pos_list_BE < 1)
|
||||||
pos_list_BE++;
|
pos_list_BE++;
|
||||||
else if (pos_list_BE > 1)
|
else if (pos_list_BE > 1)
|
||||||
|
@ -478,7 +507,8 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
strip_scan_reqs[1].value = 0x13;
|
strip_scan_reqs[1].value = 0x13;
|
||||||
strip_scan_reqs[2].value = 0x35;
|
strip_scan_reqs[2].value = 0x35;
|
||||||
}
|
}
|
||||||
else { // minimum gain needed
|
else // minimum gain needed
|
||||||
|
{
|
||||||
if (pos_list_BE > 0)
|
if (pos_list_BE > 0)
|
||||||
pos_list_BE--;
|
pos_list_BE--;
|
||||||
|
|
||||||
|
@ -492,11 +522,12 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
strip_scan_reqs[0].value = list_BE_values[pos_list_BE];
|
strip_scan_reqs[0].value = list_BE_values[pos_list_BE];
|
||||||
strip_scan_reqs[3].value = list_BD_values[pos_list_BD];
|
strip_scan_reqs[3].value = list_BD_values[pos_list_BD];
|
||||||
|
|
||||||
fp_dbg("gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
|
fp_dbg ("gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
|
||||||
}
|
}
|
||||||
// Unknown status
|
// Unknown status
|
||||||
else {
|
else
|
||||||
fp_err("Unexpected gain status.");
|
{
|
||||||
|
fp_err ("Unexpected gain status.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +536,8 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore the default gain values */
|
* Restore the default gain values */
|
||||||
static void restore_gain(void)
|
static void
|
||||||
|
restore_gain (void)
|
||||||
{
|
{
|
||||||
strip_scan_reqs[0].value = list_BE_values[0];
|
strip_scan_reqs[0].value = list_BE_values[0];
|
||||||
strip_scan_reqs[1].value = 0x04;
|
strip_scan_reqs[1].value = 0x04;
|
||||||
|
@ -532,16 +564,18 @@ enum capture_states {
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
gint sum, i;
|
gint sum, i;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -550,134 +584,152 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (i = 516; i < 530; i++)
|
for (i = 516; i < 530; i++)
|
||||||
{
|
|
||||||
/* histogram[i] = number of pixels of value i
|
/* histogram[i] = number of pixels of value i
|
||||||
Only the pixel values from 10 to 15 are used to detect finger. */
|
Only the pixel values from 10 to 15 are used to detect finger. */
|
||||||
sum += data[i];
|
sum += data[i];
|
||||||
}
|
|
||||||
|
|
||||||
fp_dbg("sum=%d", sum);
|
fp_dbg ("sum=%d", sum);
|
||||||
if (sum > 0) {
|
if (sum > 0)
|
||||||
|
{
|
||||||
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
||||||
struct fpi_frame *stripe = g_malloc(FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof(struct fpi_frame));
|
struct fpi_frame *stripe = g_malloc (FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof (struct fpi_frame));
|
||||||
stripe->delta_x = 0;
|
stripe->delta_x = 0;
|
||||||
stripe->delta_y = 0;
|
stripe->delta_y = 0;
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
memcpy(stripdata, data + 1, FRAME_WIDTH * (FRAME_HEIGHT / 2));
|
memcpy (stripdata, data + 1, 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++;
|
||||||
self->blanks_count = 0;
|
self->blanks_count = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* FIXME: 0 might be too low as a threshold */
|
/* FIXME: 0 might be too low as a threshold */
|
||||||
/* FIXME: sometimes we get 0 in the middle of a scan, should we wait for
|
/* FIXME: sometimes we get 0 in the middle of a scan, should we wait for
|
||||||
* a few consecutive zeroes? */
|
* a few consecutive zeroes? */
|
||||||
|
|
||||||
/* sum cannot be negative, so is 0 */
|
/* sum cannot be negative, so is 0 */
|
||||||
self->blanks_count++;
|
self->blanks_count++;
|
||||||
fp_dbg("got blank frame");
|
fp_dbg ("got blank frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* use histogram data above for gain calibration (0xbd, 0xbe, 0x29 and 0x2A ) */
|
/* use histogram data above for gain calibration (0xbd, 0xbe, 0x29 and 0x2A ) */
|
||||||
adjust_gain(data, GAIN_STATUS_NORMAL);
|
adjust_gain (data, GAIN_STATUS_NORMAL);
|
||||||
|
|
||||||
/* stop capturing if MAX_FRAMES is reached */
|
/* stop capturing if MAX_FRAMES is reached */
|
||||||
if (self->blanks_count > 10 || g_slist_length(self->strips) >= MAX_FRAMES) {
|
if (self->blanks_count > 10 || g_slist_length (self->strips) >= MAX_FRAMES)
|
||||||
|
{
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
fp_dbg("sending stop capture.... blanks=%d frames=%d",
|
fp_dbg ("sending stop capture.... blanks=%d frames=%d",
|
||||||
self->blanks_count, g_slist_length(self->strips));
|
self->blanks_count, g_slist_length (self->strips));
|
||||||
/* send stop capture bits */
|
/* send stop capture bits */
|
||||||
aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL);
|
aes_write_regv (dev, capture_stop, G_N_ELEMENTS (capture_stop), stub_capture_stop_cb, NULL);
|
||||||
self->strips = g_slist_reverse(self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
fpi_do_movement_estimation(&assembling_ctx, self->strips);
|
fpi_do_movement_estimation (&assembling_ctx, 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;
|
||||||
self->blanks_count = 0;
|
self->blanks_count = 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);
|
||||||
/* Acquisition finished: restore default gain values */
|
/* Acquisition finished: restore default gain values */
|
||||||
restore_gain();
|
restore_gain ();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* obtain next strip */
|
/* obtain next strip */
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_REQUEST_STRIP);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_REQUEST_STRIP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(_dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case CAPTURE_WRITE_REQS:
|
case CAPTURE_WRITE_REQS:
|
||||||
fp_dbg("write reqs");
|
fp_dbg ("write reqs");
|
||||||
aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs),
|
aes_write_regv (dev, capture_reqs, G_N_ELEMENTS (capture_reqs),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
fp_dbg("read data");
|
fp_dbg ("read data");
|
||||||
generic_read_ignore_data(ssm, _dev, STRIP_CAPTURE_LEN);
|
generic_read_ignore_data (ssm, _dev, STRIP_CAPTURE_LEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_REQUEST_STRIP:
|
case CAPTURE_REQUEST_STRIP:
|
||||||
fp_dbg("request strip");
|
fp_dbg ("request strip");
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
else
|
else
|
||||||
aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
|
aes_write_regv (dev, strip_scan_reqs, G_N_ELEMENTS (strip_scan_reqs),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_STRIP: ;
|
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
case CAPTURE_READ_STRIP:;
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
|
||||||
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_read_strip_cb, NULL);
|
capture_read_strip_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(_dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
if (error)
|
if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else if (error) {
|
|
||||||
fpi_image_device_session_error(dev, error);
|
|
||||||
} else {
|
|
||||||
start_finger_detection(dev);
|
|
||||||
}
|
}
|
||||||
fpi_ssm_free(ssm);
|
else if (error)
|
||||||
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_finger_detection (dev);
|
||||||
|
}
|
||||||
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||||
|
@ -687,108 +739,125 @@ static const struct aes_regwrite init[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static const struct aes_regwrite stop_reader[] = {
|
static const struct aes_regwrite stop_reader[] = {
|
||||||
{ 0xFF, 0x00 }
|
{ 0xFF, 0x00 }
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum activate_states {
|
enum activate_states {
|
||||||
WRITE_INIT,
|
WRITE_INIT,
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
activate_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
|
|
||||||
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
||||||
/* verify there's anything missing here */
|
/* verify there's anything missing here */
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case WRITE_INIT:
|
case WRITE_INIT:
|
||||||
fp_dbg("write init");
|
fp_dbg ("write init");
|
||||||
aes_write_regv(dev, init, G_N_ELEMENTS(init), generic_write_regv_cb, ssm);
|
aes_write_regv (dev, init, G_N_ELEMENTS (init), generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jump to finger detection */
|
/* jump to finger detection */
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
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)
|
||||||
{
|
{
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (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->read_regs_retry_count = 0;
|
self->read_regs_retry_count = 0;
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||||
|
|
||||||
/* FIXME: audit cancellation points, probably need more, specifically
|
/* FIXME: audit cancellation points, probably need more, specifically
|
||||||
* in error handling paths? */
|
* in error handling paths? */
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(FpImageDevice *dev)
|
static void
|
||||||
|
complete_deactivation (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
|
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
||||||
* maybe we can do this with a master reset, unconditionally? */
|
* maybe we can do this with a master reset, unconditionally? */
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
g_slist_free(self->strips);
|
g_slist_free (self->strips);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
self->blanks_count = 0;
|
self->blanks_count = 0;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
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;
|
||||||
|
|
||||||
/* FIXME check endpoints */
|
/* FIXME check endpoints */
|
||||||
|
|
||||||
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);
|
{
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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 = 0x1600,
|
{ .vid = 0x08ff, .pid = 0x1600, },/* AES1600 */
|
||||||
}, /* AES1600 */
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes1610_init(FpiDeviceAes1610 *self) {
|
static void
|
||||||
|
fpi_device_aes1610_init (FpiDeviceAes1610 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_aes1610_class_init(FpiDeviceAes1610Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes1610_class_init (FpiDeviceAes1610Class *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 = "aes1610";
|
dev_class->id = "aes1610";
|
||||||
dev_class->full_name = "AuthenTec AES1610";
|
dev_class->full_name = "AuthenTec AES1610";
|
||||||
|
@ -806,4 +875,3 @@ static void fpi_device_aes1610_class_init(FpiDeviceAes1610Class *klass) {
|
||||||
img_class->img_width = IMAGE_WIDTH;
|
img_class->img_width = IMAGE_WIDTH;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,13 @@
|
||||||
#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,
|
||||||
|
@ -41,7 +42,7 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.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, },
|
||||||
|
@ -62,11 +63,15 @@ static const FpIdEntry id_table [ ] = {
|
||||||
{ .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);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes1660";
|
dev_class->id = "aes1660";
|
||||||
|
@ -81,10 +86,10 @@ static void fpi_device_aes1660_class_init(FpiDeviceAes1660Class *klass) {
|
||||||
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
|
@ -27,8 +27,8 @@
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
#include "aes2501.h"
|
#include "aes2501.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);
|
||||||
|
|
||||||
/* FIXME these need checking */
|
/* FIXME these need checking */
|
||||||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
|
@ -63,7 +63,8 @@ static void complete_deactivation(FpImageDevice *dev);
|
||||||
|
|
||||||
/****** GENERAL FUNCTIONS ******/
|
/****** GENERAL FUNCTIONS ******/
|
||||||
|
|
||||||
struct _FpiDeviceAes2501 {
|
struct _FpiDeviceAes2501
|
||||||
|
{
|
||||||
FpImageDevice parent;
|
FpImageDevice parent;
|
||||||
|
|
||||||
guint8 read_regs_retry_count;
|
guint8 read_regs_retry_count;
|
||||||
|
@ -72,9 +73,9 @@ struct _FpiDeviceAes2501 {
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
int no_finger_cnt;
|
int no_finger_cnt;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceAes2501, fpi_device_aes2501, FPI, DEVICE_AES2501,
|
G_DECLARE_FINAL_TYPE (FpiDeviceAes2501, fpi_device_aes2501, FPI, DEVICE_AES2501,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpiDeviceAes2501, fpi_device_aes2501, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceAes2501, fpi_device_aes2501, 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,
|
||||||
|
@ -83,54 +84,61 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.get_pixel = aes_get_pixel,
|
.get_pixel = aes_get_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*aes2501_read_regs_cb)(FpImageDevice *dev, GError *error,
|
typedef void (*aes2501_read_regs_cb)(FpImageDevice *dev,
|
||||||
unsigned char *regs, void *user_data);
|
GError *error,
|
||||||
|
unsigned char *regs,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
struct aes2501_read_regs {
|
struct aes2501_read_regs
|
||||||
|
{
|
||||||
FpImageDevice *dev;
|
FpImageDevice *dev;
|
||||||
aes2501_read_regs_cb callback;
|
aes2501_read_regs_cb callback;
|
||||||
struct aes_regwrite *regwrite;
|
struct aes_regwrite *regwrite;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void read_regs_data_cb(FpiUsbTransfer *transfer, FpDevice *dev,
|
static void
|
||||||
|
read_regs_data_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct aes2501_read_regs *rdata = user_data;
|
struct aes2501_read_regs *rdata = user_data;
|
||||||
|
|
||||||
rdata->callback(rdata->dev, error, transfer->buffer, rdata->user_data);
|
rdata->callback (rdata->dev, error, transfer->buffer, rdata->user_data);
|
||||||
g_free(rdata);
|
g_free (rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_regs_rq_cb(FpImageDevice *dev, GError *error, void *user_data)
|
static void
|
||||||
|
read_regs_rq_cb (FpImageDevice *dev, GError *error, void *user_data)
|
||||||
{
|
{
|
||||||
struct aes2501_read_regs *rdata = user_data;
|
struct aes2501_read_regs *rdata = user_data;
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
g_free(rdata->regwrite);
|
g_free (rdata->regwrite);
|
||||||
if (error) {
|
if (error)
|
||||||
rdata->callback(dev, error, NULL, rdata->user_data);
|
{
|
||||||
|
rdata->callback (dev, error, NULL, rdata->user_data);
|
||||||
g_free (rdata);
|
g_free (rdata);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, READ_REGS_LEN);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, READ_REGS_LEN);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
read_regs_data_cb, rdata);
|
read_regs_data_cb, rdata);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_regs(FpImageDevice *dev, aes2501_read_regs_cb callback,
|
static void
|
||||||
|
read_regs (FpImageDevice *dev, aes2501_read_regs_cb callback,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
/* FIXME: regwrite is dynamic because of asynchronity. is this really
|
/* FIXME: regwrite is dynamic because of asynchronity. is this really
|
||||||
* required? */
|
* required? */
|
||||||
struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite));
|
struct aes_regwrite *regwrite = g_malloc (sizeof (*regwrite));
|
||||||
struct aes2501_read_regs *rdata = g_malloc(sizeof(*rdata));
|
struct aes2501_read_regs *rdata = g_malloc (sizeof (*rdata));
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
regwrite->reg = AES2501_REG_CTRL2;
|
regwrite->reg = AES2501_REG_CTRL2;
|
||||||
regwrite->value = AES2501_CTRL2_READ_REGS;
|
regwrite->value = AES2501_CTRL2_READ_REGS;
|
||||||
rdata->dev = dev;
|
rdata->dev = dev;
|
||||||
|
@ -138,20 +146,23 @@ static void read_regs(FpImageDevice *dev, aes2501_read_regs_cb callback,
|
||||||
rdata->user_data = user_data;
|
rdata->user_data = user_data;
|
||||||
rdata->regwrite = regwrite;
|
rdata->regwrite = regwrite;
|
||||||
|
|
||||||
aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1,
|
aes_write_regv (dev, (const struct aes_regwrite *) regwrite, 1,
|
||||||
read_regs_rq_cb, rdata);
|
read_regs_rq_cb, rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the value of a specific register from a register dump */
|
/* Read the value of a specific register from a register dump */
|
||||||
static int regval_from_dump(unsigned char *data, guint8 target)
|
static int
|
||||||
|
regval_from_dump (unsigned char *data, guint8 target)
|
||||||
{
|
{
|
||||||
if (*data != FIRST_AES2501_REG) {
|
if (*data != FIRST_AES2501_REG)
|
||||||
fp_err("not a register dump");
|
{
|
||||||
|
fp_err ("not a register dump");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG)) {
|
if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG))
|
||||||
fp_err("out of range");
|
{
|
||||||
|
fp_err ("out of range");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,50 +171,56 @@ static int regval_from_dump(unsigned char *data, guint8 target)
|
||||||
return data[target + 1];
|
return data[target + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_write_regv_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
generic_write_regv_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that read succeeded but ignore all data */
|
/* check that read succeeded but ignore all data */
|
||||||
static void generic_ignore_data_cb(FpiUsbTransfer *transfer, FpDevice *dev,
|
static void
|
||||||
|
generic_ignore_data_cb (FpiUsbTransfer *transfer, FpDevice *dev,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = transfer->ssm;
|
FpiSsm *ssm = transfer->ssm;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the specified number of bytes from the IN endpoint but throw them
|
/* read the specified number of bytes from the IN endpoint but throw them
|
||||||
* away, then increment the SSM */
|
* away, then increment the SSM */
|
||||||
static void generic_read_ignore_data(FpiSsm *ssm, FpDevice *dev,
|
static void
|
||||||
|
generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
|
||||||
size_t bytes)
|
size_t bytes)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, bytes);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, bytes);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
generic_ignore_data_cb, NULL);
|
generic_ignore_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** IMAGE PROCESSING ******/
|
/****** IMAGE PROCESSING ******/
|
||||||
|
|
||||||
static int sum_histogram_values(unsigned char *data, guint8 threshold)
|
static int
|
||||||
|
sum_histogram_values (unsigned char *data, guint8 threshold)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int i;
|
int i;
|
||||||
guint16 *histogram = (guint16 *)(data + 1);
|
guint16 *histogram = (guint16 *) (data + 1);
|
||||||
|
|
||||||
if (*data != 0xde)
|
if (*data != 0xde)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -248,63 +265,73 @@ static const struct aes_regwrite finger_det_reqs[] = {
|
||||||
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void start_finger_detection(FpImageDevice *dev);
|
static void start_finger_detection (FpImageDevice *dev);
|
||||||
|
|
||||||
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
|
static void
|
||||||
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(_dev);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_image_device_session_error(dev, error);
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* examine histogram to determine finger presence */
|
/* examine histogram to determine finger presence */
|
||||||
for (i = 1; i < 9; i++)
|
for (i = 1; i < 9; i++)
|
||||||
sum += (data[i] & 0xf) + (data[i] >> 4);
|
sum += (data[i] & 0xf) + (data[i] >> 4);
|
||||||
if (sum > 20) {
|
if (sum > 20)
|
||||||
|
{
|
||||||
/* finger present, start capturing */
|
/* finger present, start capturing */
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
finger_det_reqs_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_image_device_session_error (dev, error);
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, FINGER_DETECTION_LEN);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
|
||||||
if (self->deactivating) {
|
G_DEBUG_HERE ();
|
||||||
complete_deactivation(dev);
|
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs),
|
aes_write_regv (dev, finger_det_reqs, G_N_ELEMENTS (finger_det_reqs),
|
||||||
finger_det_reqs_cb, NULL);
|
finger_det_reqs_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,165 +410,194 @@ enum capture_states {
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
|
static void
|
||||||
|
capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = transfer->ssm;
|
FpiSsm *ssm = transfer->ssm;
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(_dev);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(_dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (_dev);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int sum;
|
int sum;
|
||||||
int threshold;
|
int threshold;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
{
|
||||||
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
|
threshold = regval_from_dump (data + 1 + 192 * 8 + 1 + 16 * 2 + 1 + 8,
|
||||||
AES2501_REG_DATFMT);
|
AES2501_REG_DATFMT);
|
||||||
if (threshold < 0) {
|
if (threshold < 0)
|
||||||
fpi_ssm_mark_failed(ssm,
|
{
|
||||||
|
fpi_ssm_mark_failed (ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f);
|
sum = sum_histogram_values (data + 1 + 192 * 8, threshold & 0x0f);
|
||||||
if (sum < 0) {
|
if (sum < 0)
|
||||||
fpi_ssm_mark_failed(ssm,
|
{
|
||||||
|
fpi_ssm_mark_failed (ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fp_dbg("sum=%d", sum);
|
fp_dbg ("sum=%d", sum);
|
||||||
|
|
||||||
if (sum < AES2501_SUM_LOW_THRESH) {
|
if (sum < AES2501_SUM_LOW_THRESH)
|
||||||
|
{
|
||||||
strip_scan_reqs[4].value -= 0x8;
|
strip_scan_reqs[4].value -= 0x8;
|
||||||
if (strip_scan_reqs[4].value < AES2501_ADREFHI_MIN_VALUE)
|
if (strip_scan_reqs[4].value < AES2501_ADREFHI_MIN_VALUE)
|
||||||
strip_scan_reqs[4].value = AES2501_ADREFHI_MIN_VALUE;
|
strip_scan_reqs[4].value = AES2501_ADREFHI_MIN_VALUE;
|
||||||
} else if (sum > AES2501_SUM_HIGH_THRESH) {
|
}
|
||||||
|
else if (sum > AES2501_SUM_HIGH_THRESH)
|
||||||
|
{
|
||||||
strip_scan_reqs[4].value += 0x8;
|
strip_scan_reqs[4].value += 0x8;
|
||||||
if (strip_scan_reqs[4].value > AES2501_ADREFHI_MAX_VALUE)
|
if (strip_scan_reqs[4].value > AES2501_ADREFHI_MAX_VALUE)
|
||||||
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
||||||
}
|
}
|
||||||
fp_dbg("ADREFHI is %.2x", strip_scan_reqs[4].value);
|
fp_dbg ("ADREFHI is %.2x", strip_scan_reqs[4].value);
|
||||||
|
|
||||||
/* Sum is 0, maybe finger was removed? Wait for 3 empty frames
|
/* Sum is 0, maybe finger was removed? Wait for 3 empty frames
|
||||||
* to ensure
|
* to ensure
|
||||||
*/
|
*/
|
||||||
if (sum == 0) {
|
if (sum == 0)
|
||||||
|
{
|
||||||
self->no_finger_cnt++;
|
self->no_finger_cnt++;
|
||||||
if (self->no_finger_cnt == 3) {
|
if (self->no_finger_cnt == 3)
|
||||||
|
{
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
self->strips = g_slist_reverse(self->strips);
|
self->strips = g_slist_reverse (self->strips);
|
||||||
fpi_do_movement_estimation(&assembling_ctx, self->strips);
|
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||||
img = fpi_assemble_frames(&assembling_ctx,
|
img = fpi_assemble_frames (&assembling_ctx,
|
||||||
self->strips);
|
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(ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
} else {
|
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
|
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* obtain next strip */
|
/* obtain next strip */
|
||||||
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
||||||
struct fpi_frame *stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame));
|
struct fpi_frame *stripe = g_malloc (FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame));
|
||||||
stripe->delta_x = 0;
|
stripe->delta_x = 0;
|
||||||
stripe->delta_y = 0;
|
stripe->delta_y = 0;
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
memcpy(stripdata, data + 1, 192*8);
|
memcpy (stripdata, data + 1, 192 * 8);
|
||||||
self->no_finger_cnt = 0;
|
self->no_finger_cnt = 0;
|
||||||
self->strips = g_slist_prepend(self->strips, stripe);
|
self->strips = g_slist_prepend (self->strips, stripe);
|
||||||
self->strips_len++;
|
self->strips_len++;
|
||||||
|
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
|
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *device, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *device, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(device);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (device);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case CAPTURE_WRITE_REQS_1:
|
case CAPTURE_WRITE_REQS_1:
|
||||||
aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1),
|
aes_write_regv (dev, capture_reqs_1, G_N_ELEMENTS (capture_reqs_1),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_DATA_1:
|
case CAPTURE_READ_DATA_1:
|
||||||
generic_read_ignore_data(ssm, device, READ_REGS_RESP_LEN);
|
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_WRITE_REQS_2:
|
case CAPTURE_WRITE_REQS_2:
|
||||||
aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
|
aes_write_regv (dev, capture_reqs_2, G_N_ELEMENTS (capture_reqs_2),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_DATA_2:
|
case CAPTURE_READ_DATA_2:
|
||||||
generic_read_ignore_data(ssm, device, READ_REGS_RESP_LEN);
|
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_REQUEST_STRIP:
|
case CAPTURE_REQUEST_STRIP:
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
else
|
else
|
||||||
aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
|
aes_write_regv (dev, strip_scan_reqs, G_N_ELEMENTS (strip_scan_reqs),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_STRIP: {
|
case CAPTURE_READ_STRIP: {
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(device);
|
transfer = fpi_usb_transfer_new (device);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk(transfer, EP_IN, STRIP_CAPTURE_LEN);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
capture_read_strip_cb, NULL);
|
capture_read_strip_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(_dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (_dev);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
g_clear_pointer (&error, g_error_free);
|
g_clear_pointer (&error, g_error_free);
|
||||||
} else if (error) {
|
|
||||||
fpi_image_device_session_error(dev, error);
|
|
||||||
} else {
|
|
||||||
start_finger_detection(dev);
|
|
||||||
}
|
}
|
||||||
fpi_ssm_free(ssm);
|
else if (error)
|
||||||
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_finger_detection (dev);
|
||||||
|
}
|
||||||
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->no_finger_cnt = 0;
|
self->no_finger_cnt = 0;
|
||||||
/* Reset gain */
|
/* Reset gain */
|
||||||
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
|
||||||
ssm = fpi_ssm_new(FP_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 ******/
|
||||||
|
@ -649,34 +705,41 @@ enum activate_states {
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
void activate_read_regs_cb(FpImageDevice *dev, GError *error,
|
void
|
||||||
|
activate_read_regs_cb (FpImageDevice *dev, GError *error,
|
||||||
unsigned char *regs, void *user_data)
|
unsigned char *regs, void *user_data)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
{
|
||||||
} else {
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
fp_dbg("reg 0xaf = %x", regs[0x5f]);
|
}
|
||||||
if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13)
|
|
||||||
fpi_ssm_jump_to_state(ssm, WRITE_INIT_4);
|
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
{
|
||||||
|
fp_dbg ("reg 0xaf = %x", regs[0x5f]);
|
||||||
|
if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13)
|
||||||
|
fpi_ssm_jump_to_state (ssm, WRITE_INIT_4);
|
||||||
|
else
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_init3_cb(FpImageDevice *dev, GError *error,
|
static void
|
||||||
|
activate_init3_cb (FpImageDevice *dev, GError *error,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
fpi_ssm_jump_to_state(ssm, READ_REGS);
|
fpi_ssm_jump_to_state (ssm, READ_REGS);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(ssm, error);
|
fpi_ssm_mark_failed (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)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
|
|
||||||
|
@ -699,110 +762,129 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
aes_write_regv(init_4);
|
aes_write_regv(init_4);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case WRITE_INIT_1:
|
case WRITE_INIT_1:
|
||||||
aes_write_regv(dev, init_1, G_N_ELEMENTS(init_1),
|
aes_write_regv (dev, init_1, G_N_ELEMENTS (init_1),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_DATA_1:
|
case READ_DATA_1:
|
||||||
fp_dbg("read data 1");
|
fp_dbg ("read data 1");
|
||||||
generic_read_ignore_data(ssm, _dev, FINGER_DETECTION_LEN);
|
generic_read_ignore_data (ssm, _dev, FINGER_DETECTION_LEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_INIT_2:
|
case WRITE_INIT_2:
|
||||||
aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2),
|
aes_write_regv (dev, init_2, G_N_ELEMENTS (init_2),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_REGS:
|
case READ_REGS:
|
||||||
read_regs(dev, activate_read_regs_cb, ssm);
|
read_regs (dev, activate_read_regs_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_INIT_3:
|
case WRITE_INIT_3:
|
||||||
aes_write_regv(dev, init_3, G_N_ELEMENTS(init_3),
|
aes_write_regv (dev, init_3, G_N_ELEMENTS (init_3),
|
||||||
activate_init3_cb, ssm);
|
activate_init3_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_INIT_4:
|
case WRITE_INIT_4:
|
||||||
aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
|
aes_write_regv (dev, init_4, G_N_ELEMENTS (init_4),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_INIT_5:
|
case WRITE_INIT_5:
|
||||||
aes_write_regv(dev, init_5, G_N_ELEMENTS(init_5),
|
aes_write_regv (dev, init_5, G_N_ELEMENTS (init_5),
|
||||||
generic_write_regv_cb, ssm);
|
generic_write_regv_cb, ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_image_device_activate_complete(FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
start_finger_detection(FP_IMAGE_DEVICE (dev));
|
start_finger_detection (FP_IMAGE_DEVICE (dev));
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (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->read_regs_retry_count = 0;
|
self->read_regs_retry_count = 0;
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||||
|
|
||||||
/* FIXME: audit cancellation points, probably need more, specifically
|
/* FIXME: audit cancellation points, probably need more, specifically
|
||||||
* in error handling paths? */
|
* in error handling paths? */
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(FpImageDevice *dev)
|
static void
|
||||||
|
complete_deactivation (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
|
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||||
G_DEBUG_HERE();
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
|
||||||
* maybe we can do this with a master reset, unconditionally? */
|
* maybe we can do this with a master reset, unconditionally? */
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
g_slist_free(self->strips);
|
g_slist_free (self->strips);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
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;
|
||||||
|
|
||||||
/* FIXME check endpoints */
|
/* FIXME check endpoints */
|
||||||
|
|
||||||
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 = 0x08ff, .pid = 0x2500,
|
{ .vid = 0x08ff, .pid = 0x2500, },/* AES2500 */
|
||||||
}, /* AES2500 */
|
{ .vid = 0x08ff, .pid = 0x2580, },/* AES2501 */
|
||||||
{ .vid = 0x08ff, .pid = 0x2580,
|
|
||||||
}, /* AES2501 */
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_aes2501_init(FpiDeviceAes2501 *self) {
|
static void
|
||||||
|
fpi_device_aes2501_init (FpiDeviceAes2501 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_aes2501_class_init(FpiDeviceAes2501Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes2501_class_init (FpiDeviceAes2501Class *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 = "aes2501";
|
dev_class->id = "aes2501";
|
||||||
dev_class->full_name = "AuthenTec AES2501";
|
dev_class->full_name = "AuthenTec AES2501";
|
||||||
|
@ -818,4 +900,3 @@ static void fpi_device_aes2501_class_init(FpiDeviceAes2501Class *klass) {
|
||||||
img_class->img_width = IMAGE_WIDTH;
|
img_class->img_width = IMAGE_WIDTH;
|
||||||
img_class->img_height = -1;
|
img_class->img_height = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@ enum aes2501_regs {
|
||||||
#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
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#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)
|
||||||
|
@ -51,7 +51,8 @@ static void complete_deactivation(FpImageDevice *dev);
|
||||||
#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;
|
||||||
|
@ -59,9 +60,9 @@ struct _FpiDeviceAes2550 {
|
||||||
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,
|
||||||
|
@ -83,70 +84,80 @@ static unsigned char finger_det_reqs[] = {
|
||||||
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
|
||||||
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
{
|
||||||
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
||||||
return;
|
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 */
|
/* finger present, start capturing */
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
|
static void
|
||||||
|
finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
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);
|
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, finger_det_reqs,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, finger_det_reqs,
|
||||||
sizeof(finger_det_reqs), NULL);
|
sizeof (finger_det_reqs), NULL);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
finger_det_reqs_cb, NULL);
|
finger_det_reqs_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
@ -177,202 +188,230 @@ enum capture_states {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
|
static gboolean
|
||||||
|
process_strip_data (FpiSsm *ssm, FpImageDevice *dev,
|
||||||
unsigned char *data)
|
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]));
|
{
|
||||||
|
fp_dbg ("Bogus magic: %.2x\n", (int) (data[0]));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
len = data[1] * 256 + data[2];
|
len = data[1] * 256 + data[2];
|
||||||
if (len != (AES2550_STRIP_SIZE - 3)) {
|
if (len != (AES2550_STRIP_SIZE - 3))
|
||||||
fp_dbg("Bogus frame len: %.4x\n", len);
|
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
|
||||||
|
capture_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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
|
||||||
|
capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device, gpointer user_data,
|
FpDevice *device, gpointer user_data,
|
||||||
GError *error)
|
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)
|
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
{
|
||||||
|
if (error)
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
else
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
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:
|
case AES2550_STRIP_SIZE:
|
||||||
if (!process_strip_data(transfer->ssm, dev, data)) {
|
if (!process_strip_data (transfer->ssm, dev, data))
|
||||||
fp_dbg("Processing strip data failed");
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fp_dbg ("Processing strip data failed");
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->heartbeat_cnt = 0;
|
self->heartbeat_cnt = 0;
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AES2550_HEARTBEAT_SIZE:
|
case AES2550_HEARTBEAT_SIZE:
|
||||||
if (data[0] == AES2550_HEARTBEAT_MAGIC) {
|
if (data[0] == AES2550_HEARTBEAT_MAGIC)
|
||||||
|
{
|
||||||
/* No data for a long time => finger was removed or there's no movement */
|
/* No data for a long time => finger was removed or there's no movement */
|
||||||
self->heartbeat_cnt++;
|
self->heartbeat_cnt++;
|
||||||
if (self->heartbeat_cnt == 3) {
|
if (self->heartbeat_cnt == 3)
|
||||||
|
{
|
||||||
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
||||||
* assemble image and submit it to the library */
|
* assemble image and submit it to the library */
|
||||||
fp_dbg("Got 3 heartbeats => finger removed");
|
fp_dbg ("Got 3 heartbeats => finger removed");
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
}
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_READ_DATA);
|
CAPTURE_READ_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_dbg("Short frame %d, skip",
|
fp_dbg ("Short frame %d, skip",
|
||||||
(gint)transfer->actual_length);
|
(gint) transfer->actual_length);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
break;
|
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:
|
case CAPTURE_READ_DATA:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
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);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
capture_read_data_cb, NULL);
|
capture_read_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_SET_IDLE:
|
case CAPTURE_SET_IDLE:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
|
||||||
capture_set_idle_reqs,
|
capture_set_idle_reqs,
|
||||||
sizeof(capture_set_idle_reqs),
|
sizeof (capture_set_idle_reqs),
|
||||||
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,
|
||||||
capture_set_idle_reqs_cb, NULL);
|
capture_set_idle_reqs_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
GError *error)
|
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);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
g_clear_pointer (&error, g_error_free);
|
g_clear_pointer (&error, g_error_free);
|
||||||
} else if (error) {
|
|
||||||
fpi_image_device_session_error(dev, error);
|
|
||||||
} else {
|
|
||||||
start_finger_detection(dev);
|
|
||||||
}
|
}
|
||||||
fpi_ssm_free(ssm);
|
else if (error)
|
||||||
|
{
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
|
}
|
||||||
|
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);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
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 ******/
|
||||||
|
@ -399,163 +438,179 @@ enum activate_states {
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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
|
||||||
|
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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
|
||||||
|
calibrate_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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:
|
case READ_DATA:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
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);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
init_read_data_cb, NULL);
|
init_read_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CALIBRATE:
|
case CALIBRATE:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
|
||||||
calibrate_reqs,
|
calibrate_reqs,
|
||||||
sizeof(calibrate_reqs), NULL);
|
sizeof (calibrate_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_CALIB_TABLE:
|
case READ_CALIB_TABLE:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
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);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
calibrate_read_data_cb, NULL);
|
calibrate_read_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
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();
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
g_slist_free(self->strips);
|
g_slist_free (self->strips);
|
||||||
self->strips = NULL;
|
self->strips = NULL;
|
||||||
self->strips_len = 0;
|
self->strips_len = 0;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
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 */
|
/* 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);
|
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 = 0x08ff, .pid = 0x2550,
|
{ .vid = 0x08ff, .pid = 0x2550, },/* AES2550 */
|
||||||
}, /* AES2550 */
|
{ .vid = 0x08ff, .pid = 0x2810, },/* AES2810 */
|
||||||
{ .vid = 0x08ff, .pid = 0x2810,
|
|
||||||
}, /* AES2810 */
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .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";
|
||||||
|
|
|
@ -27,12 +27,13 @@
|
||||||
#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,
|
||||||
|
@ -41,7 +42,7 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.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, },
|
||||||
|
@ -63,12 +64,16 @@ static const FpIdEntry id_table [ ] = {
|
||||||
{ .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);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes2660";
|
dev_class->id = "aes2660";
|
||||||
|
@ -83,10 +88,10 @@ static void fpi_device_aes2660_class_init(FpiDeviceAes2660Class *klass) {
|
||||||
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
|
@ -115,25 +115,30 @@ static struct aes_regwrite init_reqs[] = {
|
||||||
{ 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);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes3500";
|
dev_class->id = "aes3500";
|
||||||
|
@ -149,5 +154,5 @@ static void fpi_device_aes3500_class_init(FpiDeviceAes3500Class *klass) {
|
||||||
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,7 +40,8 @@
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
#include "aes3k.h"
|
#include "aes3k.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
FpiUsbTransfer *img_trf;
|
FpiUsbTransfer *img_trf;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
} FpiDeviceAes3kPrivate;
|
} FpiDeviceAes3kPrivate;
|
||||||
|
@ -49,17 +50,20 @@ typedef struct {
|
||||||
#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
|
||||||
|
aes3k_assemble_image (unsigned char *input, size_t width, size_t height,
|
||||||
unsigned char *output)
|
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) {
|
{
|
||||||
|
for (row = 0; row < height; row += 2)
|
||||||
|
{
|
||||||
output[width * row + column] = (*input & 0x0f) * 17;
|
output[width * row + column] = (*input & 0x0f) * 17;
|
||||||
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
|
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
|
||||||
input++;
|
input++;
|
||||||
|
@ -67,7 +71,8 @@ static void aes3k_assemble_image(unsigned char *input, size_t width, size_t heig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
|
@ -81,79 +86,86 @@ static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
|
||||||
priv->img_trf = NULL;
|
priv->img_trf = NULL;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
if (g_error_matches (error,
|
if (g_error_matches (error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_CANCELLED)) {
|
G_IO_ERROR_CANCELLED))
|
||||||
|
{
|
||||||
/* Deactivation was completed. */
|
/* Deactivation was completed. */
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
if (priv->deactivating)
|
if (priv->deactivating)
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
return;
|
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);
|
{
|
||||||
|
fp_dbg ("frame header byte %02x", *ptr);
|
||||||
ptr++;
|
ptr++;
|
||||||
aes3k_assemble_image(ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
|
aes3k_assemble_image (ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
|
||||||
ptr += cls->frame_size;
|
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);
|
||||||
|
@ -161,37 +173,44 @@ static void aes3k_dev_deactivate(FpImageDevice *dev)
|
||||||
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)
|
static void
|
||||||
|
aes3k_dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
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);
|
{
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_image_device_open_complete(dev, NULL);
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes3k_dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
aes3k_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 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;
|
||||||
|
|
|
@ -40,12 +40,13 @@
|
||||||
|
|
||||||
#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 */
|
||||||
|
|
|
@ -112,25 +112,30 @@ static struct aes_regwrite init_reqs[] = {
|
||||||
{ 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);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = "aes4000";
|
dev_class->id = "aes4000";
|
||||||
|
@ -146,5 +151,5 @@ static void fpi_device_aes4000_class_init(FpiDeviceAes4000Class *klass) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
#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;
|
unsigned int num_regs;
|
||||||
const struct aes_regwrite *regs;
|
const struct aes_regwrite *regs;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
@ -42,50 +43,58 @@ struct write_regv_data {
|
||||||
void *user_data;
|
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
|
||||||
|
write_regv_trf_complete (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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];
|
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
||||||
transfer->buffer[data_offset++] = regwrite->reg;
|
transfer->buffer[data_offset++] = regwrite->reg;
|
||||||
transfer->buffer[data_offset++] = regwrite->value;
|
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;
|
||||||
|
@ -94,11 +103,13 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
|
||||||
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");
|
||||||
|
wdata->callback (dev, 0, wdata->user_data);
|
||||||
|
g_free (wdata);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (wdata->regs[offset].reg)
|
if (wdata->regs[offset].reg)
|
||||||
|
@ -108,18 +119,19 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
|
||||||
|
|
||||||
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;
|
upper_bound = i - 1;
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -127,23 +139,25 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
|
||||||
/* 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
|
||||||
|
aes_write_regv (FpImageDevice *dev, const struct aes_regwrite *regs,
|
||||||
unsigned int num_regs, aes_write_regv_cb callback,
|
unsigned int num_regs, aes_write_regv_cb callback,
|
||||||
void *user_data)
|
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
|
||||||
|
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)
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
#include <fprint.h>
|
#include <fprint.h>
|
||||||
|
|
||||||
struct aes_regwrite {
|
struct aes_regwrite
|
||||||
|
{
|
||||||
unsigned char reg;
|
unsigned char reg;
|
||||||
unsigned char value;
|
unsigned char value;
|
||||||
};
|
};
|
||||||
|
@ -30,17 +31,19 @@ struct aes_regwrite {
|
||||||
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,
|
||||||
|
GError *error,
|
||||||
void *user_data);
|
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,
|
||||||
|
unsigned int num_regs,
|
||||||
|
aes_write_regv_cb callback,
|
||||||
void *user_data);
|
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
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
#include "aesx660.h"
|
#include "aesx660.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
GByteArray *stripe_packet;
|
GByteArray *stripe_packet;
|
||||||
GSList *strips;
|
GSList *strips;
|
||||||
size_t strips_len;
|
size_t strips_len;
|
||||||
|
@ -38,10 +39,10 @@ typedef struct {
|
||||||
unsigned int init_seq_idx;
|
unsigned int init_seq_idx;
|
||||||
} FpiDeviceAesX660Private;
|
} FpiDeviceAesX660Private;
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceAesX660, fpi_device_aes_x660, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAesX660, fpi_device_aes_x660, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
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)
|
||||||
|
@ -54,84 +55,87 @@ static void complete_deactivation(FpImageDevice *dev);
|
||||||
#define FINGER_DET_DATA_LEN 4
|
#define FINGER_DET_DATA_LEN 4
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aesX660_send_cmd_timeout(FpiSsm *ssm,
|
aesX660_send_cmd_timeout (FpiSsm *ssm,
|
||||||
FpDevice *_dev,
|
FpDevice *_dev,
|
||||||
const unsigned char *cmd,
|
const unsigned char *cmd,
|
||||||
size_t cmd_len,
|
size_t cmd_len,
|
||||||
FpiUsbTransferCallback callback,
|
FpiUsbTransferCallback callback,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, (unsigned char *)cmd,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, (unsigned char *) cmd,
|
||||||
cmd_len, NULL);
|
cmd_len, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, timeout, NULL, callback, NULL);
|
fpi_usb_transfer_submit (transfer, timeout, NULL, callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aesX660_send_cmd(FpiSsm *ssm,
|
aesX660_send_cmd (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
const unsigned char *cmd,
|
const unsigned char *cmd,
|
||||||
size_t cmd_len,
|
size_t cmd_len,
|
||||||
FpiUsbTransferCallback callback)
|
FpiUsbTransferCallback callback)
|
||||||
{
|
{
|
||||||
return aesX660_send_cmd_timeout(ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
|
return aesX660_send_cmd_timeout (ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
aesX660_read_response(FpiSsm *ssm,
|
aesX660_read_response (FpiSsm *ssm,
|
||||||
FpDevice *_dev,
|
FpDevice *_dev,
|
||||||
gboolean short_is_error,
|
gboolean short_is_error,
|
||||||
gboolean cancellable,
|
gboolean cancellable,
|
||||||
size_t buf_len,
|
size_t buf_len,
|
||||||
FpiUsbTransferCallback callback)
|
FpiUsbTransferCallback callback)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
GCancellable *cancel = NULL;
|
GCancellable *cancel = NULL;
|
||||||
|
|
||||||
if (cancellable)
|
if (cancellable)
|
||||||
cancel = fpi_device_get_cancellable (_dev);
|
cancel = fpi_device_get_cancellable (_dev);
|
||||||
data = g_malloc(buf_len);
|
data = g_malloc (buf_len);
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN, data, buf_len, NULL);
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, buf_len, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = short_is_error;
|
transfer->short_is_error = short_is_error;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, cancel, callback, NULL);
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, cancel, callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_send_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
aesX660_send_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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 aesX660_read_calibrate_data_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
|
aesX660_read_calibrate_data_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device,
|
FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Calibrate response was read correctly? */
|
/* Calibrate response was read correctly? */
|
||||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
|
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE)
|
||||||
fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fp_dbg ("Bogus calibrate response: %.2x\n", data[0]);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Bogus calibrate response"));
|
"Bogus calibrate response"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** FINGER PRESENCE DETECTION ******/
|
/****** FINGER PRESENCE DETECTION ******/
|
||||||
|
@ -144,7 +148,8 @@ enum finger_det_states {
|
||||||
FINGER_DET_NUM_STATES,
|
FINGER_DET_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void finger_det_read_fd_data_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
|
finger_det_read_fd_data_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device, gpointer user_data,
|
FpDevice *device, gpointer user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
|
@ -152,104 +157,123 @@ static void finger_det_read_fd_data_cb(FpiUsbTransfer *transfer,
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
{
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("Failed to read FD data\n");
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fp_dbg ("Failed to read FD data\n");
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
|
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE)
|
||||||
fp_dbg("Bogus FD response: %.2x\n", data[0]);
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fp_dbg ("Bogus FD response: %.2x\n", data[0]);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Bogus FD response"));
|
"Bogus FD response"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || priv->deactivating) {
|
if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || priv->deactivating)
|
||||||
|
{
|
||||||
/* Finger present or we're deactivating... */
|
/* Finger present or we're deactivating... */
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
}
|
||||||
fp_dbg("Wait for finger returned %.2x as result\n",
|
else
|
||||||
|
{
|
||||||
|
fp_dbg ("Wait for finger returned %.2x as result\n",
|
||||||
data[AESX660_FINGER_PRESENT_OFFSET]);
|
data[AESX660_FINGER_PRESENT_OFFSET]);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, FINGER_DET_SEND_FD_CMD);
|
fpi_ssm_jump_to_state (transfer->ssm, FINGER_DET_SEND_FD_CMD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_set_idle_cmd_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
|
finger_det_set_idle_cmd_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device, gpointer user_data,
|
FpDevice *device, gpointer user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
finger_det_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
|
||||||
fp_dbg("Finger detection completed");
|
fp_dbg ("Finger detection completed");
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
|
|
||||||
if (priv->deactivating) {
|
if (priv->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
if (error)
|
if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else if (error) {
|
}
|
||||||
fpi_image_device_session_error(dev, error);
|
else if (error)
|
||||||
} else {
|
{
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_session_error (dev, error);
|
||||||
start_capture(dev);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
|
start_capture (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
finger_det_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case FINGER_DET_SEND_LED_CMD:
|
case FINGER_DET_SEND_LED_CMD:
|
||||||
aesX660_send_cmd(ssm, dev, led_blink_cmd, sizeof(led_blink_cmd),
|
aesX660_send_cmd (ssm, dev, led_blink_cmd, sizeof (led_blink_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINGER_DET_SEND_FD_CMD:
|
case FINGER_DET_SEND_FD_CMD:
|
||||||
aesX660_send_cmd_timeout(ssm, dev, wait_for_finger_cmd, sizeof(wait_for_finger_cmd),
|
aesX660_send_cmd_timeout (ssm, dev, wait_for_finger_cmd, sizeof (wait_for_finger_cmd),
|
||||||
aesX660_send_cmd_cb, 0);
|
aesX660_send_cmd_cb, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINGER_DET_READ_FD_DATA:
|
case FINGER_DET_READ_FD_DATA:
|
||||||
aesX660_read_response(ssm, dev, TRUE, TRUE, FINGER_DET_DATA_LEN, finger_det_read_fd_data_cb);
|
aesX660_read_response (ssm, dev, TRUE, TRUE, FINGER_DET_DATA_LEN, finger_det_read_fd_data_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINGER_DET_SET_IDLE:
|
case FINGER_DET_SET_IDLE:
|
||||||
aesX660_send_cmd(ssm, dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd (ssm, dev, set_idle_cmd, sizeof (set_idle_cmd),
|
||||||
finger_det_set_idle_cmd_cb);
|
finger_det_set_idle_cmd_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_finger_detection(FpImageDevice *dev)
|
static void
|
||||||
|
start_finger_detection (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (priv->deactivating) {
|
if (priv->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEVICE(dev), finger_det_run_state,
|
ssm = fpi_ssm_new (FP_DEVICE (dev), finger_det_run_state,
|
||||||
FINGER_DET_NUM_STATES, dev);
|
FINGER_DET_NUM_STATES, dev);
|
||||||
fpi_ssm_start(ssm, finger_det_sm_complete);
|
fpi_ssm_start (ssm, finger_det_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
@ -263,7 +287,8 @@ enum capture_states {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static int process_stripe_data(FpiSsm *ssm, FpiDeviceAesX660 *self,
|
static int
|
||||||
|
process_stripe_data (FpiSsm *ssm, FpiDeviceAesX660 *self,
|
||||||
unsigned char *data, gsize length)
|
unsigned char *data, gsize length)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
@ -271,36 +296,39 @@ static int process_stripe_data(FpiSsm *ssm, FpiDeviceAesX660 *self,
|
||||||
struct fpi_frame *stripe;
|
struct fpi_frame *stripe;
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
|
|
||||||
if (length < AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2) {
|
if (length < AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2)
|
||||||
|
{
|
||||||
fp_warn ("Received stripe data is too short, got %zi expected %i bytes!",
|
fp_warn ("Received stripe data is too short, got %zi expected %i bytes!",
|
||||||
length,
|
length,
|
||||||
AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
|
AESX660_IMAGE_OFFSET + cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
stripe = g_malloc(cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
|
stripe = g_malloc (cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bpp */
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
|
|
||||||
fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
|
fp_dbg ("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
|
||||||
data[AESX660_LAST_FRAME_OFFSET]);
|
data[AESX660_LAST_FRAME_OFFSET]);
|
||||||
|
|
||||||
stripe->delta_x = (int8_t)data[AESX660_FRAME_DELTA_X_OFFSET];
|
stripe->delta_x = (int8_t) data[AESX660_FRAME_DELTA_X_OFFSET];
|
||||||
stripe->delta_y = -(int8_t)data[AESX660_FRAME_DELTA_Y_OFFSET];
|
stripe->delta_y = -(int8_t) data[AESX660_FRAME_DELTA_Y_OFFSET];
|
||||||
fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
|
fp_dbg ("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
|
||||||
|
|
||||||
if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) {
|
if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK)
|
||||||
memcpy(stripdata, data + AESX660_IMAGE_OFFSET, cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
|
{
|
||||||
|
memcpy (stripdata, data + AESX660_IMAGE_OFFSET, cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
|
||||||
|
|
||||||
priv->strips = g_slist_prepend(priv->strips, stripe);
|
priv->strips = g_slist_prepend (priv->strips, stripe);
|
||||||
priv->strips_len++;
|
priv->strips_len++;
|
||||||
return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
|
return data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(stripe);
|
g_free (stripe);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_set_idle_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_set_idle_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
|
@ -308,24 +336,28 @@ static void capture_set_idle_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
||||||
|
|
||||||
if (!error) {
|
if (!error)
|
||||||
|
{
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
|
|
||||||
priv->strips = g_slist_reverse(priv->strips);
|
priv->strips = g_slist_reverse (priv->strips);
|
||||||
img = fpi_assemble_frames(cls->assembling_ctx, priv->strips);
|
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
|
||||||
g_slist_foreach(priv->strips, (GFunc) g_free, NULL);
|
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
|
||||||
g_slist_free(priv->strips);
|
g_slist_free (priv->strips);
|
||||||
priv->strips = NULL;
|
priv->strips = NULL;
|
||||||
priv->strips_len = 0;
|
priv->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);
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
} else {
|
}
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
|
capture_read_stripe_data_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device, gpointer user_data,
|
FpDevice *device, gpointer user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
|
@ -335,14 +367,16 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
||||||
int finger_missing = 0;
|
int finger_missing = 0;
|
||||||
size_t actual_length = transfer->actual_length;
|
size_t actual_length = transfer->actual_length;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_byte_array_set_size (priv->stripe_packet, 0);
|
g_byte_array_set_size (priv->stripe_packet, 0);
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("Got %lu bytes of data", actual_length);
|
fp_dbg ("Got %lu bytes of data", actual_length);
|
||||||
while (actual_length) {
|
while (actual_length)
|
||||||
|
{
|
||||||
gssize payload_length;
|
gssize payload_length;
|
||||||
gssize still_needed_len;
|
gssize still_needed_len;
|
||||||
gssize copy_len;
|
gssize copy_len;
|
||||||
|
@ -359,7 +393,7 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
||||||
|
|
||||||
payload_length = priv->stripe_packet->data[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
|
payload_length = priv->stripe_packet->data[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
|
||||||
(priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8);
|
(priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8);
|
||||||
fp_dbg("Got frame, type %.2x payload of size %.4lx",
|
fp_dbg ("Got frame, type %.2x payload of size %.4lx",
|
||||||
priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET],
|
priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET],
|
||||||
payload_length);
|
payload_length);
|
||||||
|
|
||||||
|
@ -373,7 +407,7 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
||||||
if (priv->stripe_packet->len < payload_length + AESX660_HEADER_SIZE)
|
if (priv->stripe_packet->len < payload_length + AESX660_HEADER_SIZE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
finger_missing |= process_stripe_data(transfer->ssm,
|
finger_missing |= process_stripe_data (transfer->ssm,
|
||||||
self,
|
self,
|
||||||
priv->stripe_packet->data,
|
priv->stripe_packet->data,
|
||||||
priv->stripe_packet->len);
|
priv->stripe_packet->len);
|
||||||
|
@ -381,79 +415,91 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
||||||
g_byte_array_set_size (priv->stripe_packet, 0);
|
g_byte_array_set_size (priv->stripe_packet, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("finger %s\n", finger_missing ? "missing" : "present");
|
fp_dbg ("finger %s\n", finger_missing ? "missing" : "present");
|
||||||
|
|
||||||
if (finger_missing) {
|
if (finger_missing)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_STRIPE_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_STRIPE_DATA);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case CAPTURE_SEND_LED_CMD:
|
case CAPTURE_SEND_LED_CMD:
|
||||||
aesX660_send_cmd(ssm, _dev, led_solid_cmd, sizeof(led_solid_cmd),
|
aesX660_send_cmd (ssm, _dev, led_solid_cmd, sizeof (led_solid_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_SEND_CAPTURE_CMD:
|
case CAPTURE_SEND_CAPTURE_CMD:
|
||||||
g_byte_array_set_size (priv->stripe_packet, 0);
|
g_byte_array_set_size (priv->stripe_packet, 0);
|
||||||
aesX660_send_cmd(ssm, _dev, cls->start_imaging_cmd,
|
aesX660_send_cmd (ssm, _dev, cls->start_imaging_cmd,
|
||||||
cls->start_imaging_cmd_len,
|
cls->start_imaging_cmd_len,
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_STRIPE_DATA:
|
case CAPTURE_READ_STRIPE_DATA:
|
||||||
aesX660_read_response(ssm, _dev, FALSE, FALSE, AESX660_BULK_TRANSFER_SIZE,
|
aesX660_read_response (ssm, _dev, FALSE, FALSE, AESX660_BULK_TRANSFER_SIZE,
|
||||||
capture_read_stripe_data_cb);
|
capture_read_stripe_data_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_SET_IDLE:
|
case CAPTURE_SET_IDLE:
|
||||||
fp_dbg("Got %lu frames\n", priv->strips_len);
|
fp_dbg ("Got %lu frames\n", priv->strips_len);
|
||||||
aesX660_send_cmd(ssm, _dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
|
||||||
capture_set_idle_cmd_cb);
|
capture_set_idle_cmd_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *device, void *user_data,
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *device, void *user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg ("Capture completed");
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
|
|
||||||
if (priv->deactivating) {
|
if (priv->deactivating)
|
||||||
complete_deactivation(FP_IMAGE_DEVICE (device));
|
{
|
||||||
|
complete_deactivation (FP_IMAGE_DEVICE (device));
|
||||||
if (error)
|
if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else if (error) {
|
}
|
||||||
|
else if (error)
|
||||||
|
{
|
||||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
||||||
} else {
|
}
|
||||||
start_finger_detection(FP_IMAGE_DEVICE (device));
|
else
|
||||||
|
{
|
||||||
|
start_finger_detection (FP_IMAGE_DEVICE (device));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (priv->deactivating) {
|
if (priv->deactivating)
|
||||||
complete_deactivation(dev);
|
{
|
||||||
|
complete_deactivation (dev);
|
||||||
return;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||||
|
@ -469,7 +515,8 @@ enum activate_states {
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
||||||
|
@ -477,146 +524,169 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("read_id cmd failed\n");
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fp_dbg ("read_id cmd failed\n");
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* ID was read correctly */
|
/* ID was read correctly */
|
||||||
if (data[0] == 0x07) {
|
if (data[0] == 0x07)
|
||||||
fp_dbg("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n",
|
{
|
||||||
|
fp_dbg ("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n",
|
||||||
data[4], data[3], data[5], data[6], data[7]);
|
data[4], data[3], data[5], data[6], data[7]);
|
||||||
} else {
|
}
|
||||||
fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
{
|
||||||
|
fp_dbg ("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Bogus read ID response"));
|
"Bogus read ID response"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (priv->init_seq_idx) {
|
switch (priv->init_seq_idx)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
priv->init_seq = cls->init_seqs[0];
|
priv->init_seq = cls->init_seqs[0];
|
||||||
priv->init_seq_len = cls->init_seqs_len[0];
|
priv->init_seq_len = cls->init_seqs_len[0];
|
||||||
priv->init_seq_idx = 1;
|
priv->init_seq_idx = 1;
|
||||||
priv->init_cmd_idx = 0;
|
priv->init_cmd_idx = 0;
|
||||||
/* Do calibration only after 1st init sequence */
|
/* Do calibration only after 1st init sequence */
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, ACTIVATE_SEND_INIT_CMD);
|
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
priv->init_seq = cls->init_seqs[1];
|
priv->init_seq = cls->init_seqs[1];
|
||||||
priv->init_seq_len = cls->init_seqs_len[1];
|
priv->init_seq_len = cls->init_seqs_len[1];
|
||||||
priv->init_seq_idx = 2;
|
priv->init_seq_idx = 2;
|
||||||
priv->init_cmd_idx = 0;
|
priv->init_cmd_idx = 0;
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_dbg("Failed to init device! init status: %.2x\n", data[7]);
|
fp_dbg ("Failed to init device! init status: %.2x\n", data[7]);
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Failed to init device"));
|
"Failed to init device"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
fp_dbg("read_init_cb\n");
|
fp_dbg ("read_init_cb\n");
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_dbg("read_init transfer status: %s, actual_len: %d\n", error->message,
|
{
|
||||||
(gint)transfer->actual_length);
|
fp_dbg ("read_init transfer status: %s, actual_len: %d\n", error->message,
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
(gint) transfer->actual_length);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* ID was read correctly */
|
/* ID was read correctly */
|
||||||
if (data[0] != 0x42 || data[3] != 0x01) {
|
if (data[0] != 0x42 || data[3] != 0x01)
|
||||||
fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
|
{
|
||||||
|
fp_dbg ("Bogus read init response: %.2x %.2x\n", data[0],
|
||||||
data[3]);
|
data[3]);
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Bogus read init response"));
|
"Bogus read init response"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
priv->init_cmd_idx++;
|
priv->init_cmd_idx++;
|
||||||
if (priv->init_cmd_idx == priv->init_seq_len) {
|
if (priv->init_cmd_idx == priv->init_seq_len)
|
||||||
|
{
|
||||||
if (priv->init_seq_idx < 2)
|
if (priv->init_seq_idx < 2)
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
ACTIVATE_SEND_READ_ID_CMD);
|
ACTIVATE_SEND_READ_ID_CMD);
|
||||||
else
|
else
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, ACTIVATE_SEND_INIT_CMD);
|
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
activate_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case ACTIVATE_SET_IDLE:
|
case ACTIVATE_SET_IDLE:
|
||||||
priv->init_seq_idx = 0;
|
priv->init_seq_idx = 0;
|
||||||
fp_dbg("Activate: set idle\n");
|
fp_dbg ("Activate: set idle\n");
|
||||||
aesX660_send_cmd(ssm, _dev, set_idle_cmd, sizeof(set_idle_cmd),
|
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_SEND_READ_ID_CMD:
|
case ACTIVATE_SEND_READ_ID_CMD:
|
||||||
fp_dbg("Activate: read ID\n");
|
fp_dbg ("Activate: read ID\n");
|
||||||
aesX660_send_cmd(ssm, _dev, read_id_cmd, sizeof(read_id_cmd),
|
aesX660_send_cmd (ssm, _dev, read_id_cmd, sizeof (read_id_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_READ_ID:
|
case ACTIVATE_READ_ID:
|
||||||
aesX660_read_response(ssm, _dev, TRUE, FALSE, ID_LEN, activate_read_id_cb);
|
aesX660_read_response (ssm, _dev, TRUE, FALSE, ID_LEN, activate_read_id_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_SEND_INIT_CMD:
|
case ACTIVATE_SEND_INIT_CMD:
|
||||||
fp_dbg("Activate: send init seq #%d cmd #%d\n",
|
fp_dbg ("Activate: send init seq #%d cmd #%d\n",
|
||||||
priv->init_seq_idx,
|
priv->init_seq_idx,
|
||||||
priv->init_cmd_idx);
|
priv->init_cmd_idx);
|
||||||
aesX660_send_cmd(ssm, _dev,
|
aesX660_send_cmd (ssm, _dev,
|
||||||
priv->init_seq[priv->init_cmd_idx].cmd,
|
priv->init_seq[priv->init_cmd_idx].cmd,
|
||||||
priv->init_seq[priv->init_cmd_idx].len,
|
priv->init_seq[priv->init_cmd_idx].len,
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_READ_INIT_RESPONSE:
|
case ACTIVATE_READ_INIT_RESPONSE:
|
||||||
fp_dbg("Activate: read init response\n");
|
fp_dbg ("Activate: read init response\n");
|
||||||
aesX660_read_response(ssm, _dev, TRUE, FALSE, INIT_LEN, activate_read_init_cb);
|
aesX660_read_response (ssm, _dev, TRUE, FALSE, INIT_LEN, activate_read_init_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_SEND_CALIBRATE_CMD:
|
case ACTIVATE_SEND_CALIBRATE_CMD:
|
||||||
aesX660_send_cmd(ssm, _dev, calibrate_cmd, sizeof(calibrate_cmd),
|
aesX660_send_cmd (ssm, _dev, calibrate_cmd, sizeof (calibrate_cmd),
|
||||||
aesX660_send_cmd_cb);
|
aesX660_send_cmd_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_READ_CALIBRATE_DATA:
|
case ACTIVATE_READ_CALIBRATE_DATA:
|
||||||
aesX660_read_response(ssm, _dev, TRUE, FALSE, CALIBRATE_DATA_LEN, aesX660_read_calibrate_data_cb);
|
aesX660_read_response (ssm, _dev, TRUE, FALSE, CALIBRATE_DATA_LEN, aesX660_read_calibrate_data_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (_dev), error);
|
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (_dev), error);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
start_finger_detection(FP_IMAGE_DEVICE (_dev));
|
start_finger_detection (FP_IMAGE_DEVICE (_dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
aesX660_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 aesX660_dev_deactivate(FpImageDevice *dev)
|
static void
|
||||||
|
aesX660_dev_deactivate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
@ -624,54 +694,61 @@ static void aesX660_dev_deactivate(FpImageDevice *dev)
|
||||||
priv->deactivating = TRUE;
|
priv->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_dev_init(FpImageDevice *dev)
|
static void
|
||||||
|
aesX660_dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
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);
|
||||||
|
|
||||||
priv->stripe_packet = g_byte_array_new ();
|
priv->stripe_packet = g_byte_array_new ();
|
||||||
|
|
||||||
fpi_image_device_open_complete(dev, error);
|
fpi_image_device_open_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aesX660_dev_deinit(FpImageDevice *dev)
|
static void
|
||||||
|
aesX660_dev_deinit (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
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);
|
||||||
|
|
||||||
g_clear_pointer (&priv->stripe_packet, g_byte_array_unref);
|
g_clear_pointer (&priv->stripe_packet, g_byte_array_unref);
|
||||||
|
|
||||||
fpi_image_device_close_complete(dev, error);
|
fpi_image_device_close_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void complete_deactivation(FpImageDevice *dev)
|
static void
|
||||||
|
complete_deactivation (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
priv->deactivating = FALSE;
|
priv->deactivating = FALSE;
|
||||||
g_slist_free(priv->strips);
|
g_slist_free (priv->strips);
|
||||||
priv->strips = NULL;
|
priv->strips = NULL;
|
||||||
priv->strips_len = 0;
|
priv->strips_len = 0;
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes_x660_init(FpiDeviceAesX660 *self) {
|
static void
|
||||||
|
fpi_device_aes_x660_init (FpiDeviceAesX660 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fpi_device_aes_x660_class_init(FpiDeviceAesX660Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_aes_x660_class_init (FpiDeviceAesX660Class *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_SWIPE;
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
|
@ -42,12 +42,13 @@
|
||||||
|
|
||||||
#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];
|
||||||
|
@ -57,7 +58,8 @@ struct _FpiDeviceAesX660Class {
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
@ -66,33 +68,33 @@ struct aesX660_cmd {
|
||||||
* 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"? */
|
||||||
|
@ -107,4 +109,3 @@ static const guint8 calibrate_cmd[] = {
|
||||||
0x44, 0x02, 0x00, 0x04, 0x00,
|
0x44, 0x02, 0x00, 0x04, 0x00,
|
||||||
0x06,
|
0x06,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -71,7 +71,8 @@
|
||||||
#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];
|
unsigned char cmd[ELAN_CMD_LEN];
|
||||||
int response_len;
|
int response_len;
|
||||||
int response_in;
|
int response_in;
|
||||||
|
@ -156,7 +157,7 @@ static const struct elan_cmd stop_cmd = {
|
||||||
.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},
|
||||||
|
@ -214,12 +215,14 @@ static const FpIdEntry elan_id_table [ ] = {
|
||||||
{.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
|
@ -34,9 +34,9 @@
|
||||||
#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 */
|
||||||
|
@ -68,27 +68,27 @@
|
||||||
/** 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
|
||||||
|
@ -129,11 +129,10 @@ 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,
|
||||||
|
@ -145,11 +144,10 @@ typedef enum bmkt_mode
|
||||||
} 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,
|
||||||
|
@ -167,36 +165,35 @@ typedef enum bmkt_mode_level2
|
||||||
} 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;
|
||||||
|
@ -204,20 +201,19 @@ typedef struct bmkt_sensor_desc
|
||||||
} 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;
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
#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)
|
if (offset)
|
||||||
off = *offset;
|
off = *offset;
|
||||||
|
|
||||||
|
@ -36,155 +38,145 @@ static uint8_t extract8(const uint8_t *buf, int *offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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*/
|
/* 2 bytes per finger so calculate the total number of fingers to process*/
|
||||||
int num_fingers = (msg_resp->payload_len) / 2;
|
int num_fingers = (msg_resp->payload_len) / 2;
|
||||||
|
|
||||||
|
@ -192,118 +184,107 @@ static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_res
|
||||||
|
|
||||||
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].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].finger_id = extract8(msg_resp->payload, &offset);
|
|
||||||
for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
|
for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
|
||||||
{
|
get_enroll_templates_resp->templates[n].user_id[i] = extract8 (msg_resp->payload, &offset);
|
||||||
get_enroll_templates_resp->templates[n].user_id[i] = extract8(msg_resp->payload, &offset);
|
|
||||||
}
|
|
||||||
get_enroll_templates_resp->templates[n].user_id[i] = '\0';
|
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
|
||||||
|
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)
|
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
|
else
|
||||||
{
|
|
||||||
msg_resp->payload = NULL;
|
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;
|
||||||
|
|
||||||
|
@ -329,12 +310,12 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
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;
|
||||||
|
|
||||||
|
@ -349,19 +330,19 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
|
|
||||||
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:
|
||||||
|
@ -373,38 +354,43 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||||
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:
|
case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||||
ret = parse_get_enrolled_fingers_report(msg_resp, resp);
|
ret = parse_get_enrolled_fingers_report (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
case BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
ret = parse_db_cap_report(msg_resp, resp);
|
ret = parse_db_cap_report (msg_resp, resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||||
ret = parse_get_enrolled_users_report(msg_resp, resp);
|
ret = parse_get_enrolled_users_report (msg_resp, resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_VERSION_INFO:
|
case BMKT_RSP_VERSION_INFO:
|
||||||
ret = parse_get_version_report(msg_resp, resp);
|
ret = parse_get_version_report (msg_resp, resp);
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_POWER_DOWN_READY:
|
case BMKT_RSP_POWER_DOWN_READY:
|
||||||
resp->complete = 1;
|
resp->complete = 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -78,9 +78,16 @@ typedef struct bmkt_msg_resp
|
||||||
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_ */
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
#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 */
|
||||||
|
@ -43,70 +43,70 @@
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \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
|
||||||
|
@ -117,135 +117,135 @@
|
||||||
/** 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 */
|
||||||
|
@ -253,24 +253,24 @@
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! \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
|
||||||
|
@ -278,44 +278,44 @@
|
||||||
#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] */
|
||||||
|
@ -324,9 +324,9 @@ typedef struct bmkt_enroll_resp
|
||||||
} 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 */
|
||||||
|
@ -338,9 +338,9 @@ 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 */
|
||||||
|
@ -350,9 +350,9 @@ typedef struct bmkt_fps_mode_resp
|
||||||
} 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 */
|
||||||
|
@ -363,9 +363,9 @@ typedef struct bmkt_get_version_resp
|
||||||
} 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 */
|
||||||
|
@ -375,47 +375,46 @@ typedef struct bmkt_get_db_capacity_resp
|
||||||
} 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 */
|
||||||
|
@ -425,9 +424,9 @@ typedef struct bmkt_enroll_template
|
||||||
} 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 */
|
||||||
|
@ -436,9 +435,9 @@ typedef struct bmkt_enroll_templates_resp
|
||||||
} 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 */
|
||||||
|
@ -446,19 +445,20 @@ typedef struct bmkt_enrolled_fingers
|
||||||
} 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_init_resp_t init_resp;
|
||||||
bmkt_enroll_resp_t enroll_resp;
|
bmkt_enroll_resp_t enroll_resp;
|
||||||
bmkt_verify_resp_t verify_resp;
|
bmkt_verify_resp_t verify_resp;
|
||||||
|
@ -474,10 +474,10 @@ typedef union {
|
||||||
} 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 */
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
#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,
|
||||||
|
@ -66,15 +65,23 @@ typedef struct bmkt_sensor
|
||||||
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_ */
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
#include "synaptics.h"
|
#include "synaptics.h"
|
||||||
#include "bmkt_message.h"
|
#include "bmkt_message.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE(FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
|
G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
|
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
|
||||||
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
|
||||||
|
@ -46,16 +46,18 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
bmkt_msg_resp_t msg_resp;
|
bmkt_msg_resp_t msg_resp;
|
||||||
bmkt_response_t resp;
|
bmkt_response_t resp;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
/* NOTE: assumes timeout should never happen for receiving. */
|
/* NOTE: assumes timeout should never happen for receiving. */
|
||||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = bmkt_parse_message_header(&transfer->buffer[SENSOR_FW_REPLY_HEADER_LEN],
|
res = bmkt_parse_message_header (&transfer->buffer[SENSOR_FW_REPLY_HEADER_LEN],
|
||||||
transfer->actual_length - SENSOR_FW_REPLY_HEADER_LEN,
|
transfer->actual_length - SENSOR_FW_REPLY_HEADER_LEN,
|
||||||
&msg_resp);
|
&msg_resp);
|
||||||
if (res != BMKT_SUCCESS) {
|
if (res != BMKT_SUCCESS)
|
||||||
|
{
|
||||||
g_warning ("Corrupted message received");
|
g_warning ("Corrupted message received");
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
|
@ -63,19 +65,25 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special case events */
|
/* Special case events */
|
||||||
if (msg_resp.msg_id == BMKT_EVT_FINGER_REPORT) {
|
if (msg_resp.msg_id == BMKT_EVT_FINGER_REPORT)
|
||||||
if (msg_resp.payload_len != 1) {
|
{
|
||||||
|
if (msg_resp.payload_len != 1)
|
||||||
|
{
|
||||||
g_warning ("Corrupted finger report received");
|
g_warning ("Corrupted finger report received");
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_resp.payload[0] == 0x01) {
|
if (msg_resp.payload[0] == 0x01)
|
||||||
|
{
|
||||||
self->finger_on_sensor = TRUE;
|
self->finger_on_sensor = TRUE;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
self->finger_on_sensor = FALSE;
|
self->finger_on_sensor = FALSE;
|
||||||
if (self->cmd_complete_on_removal) {
|
if (self->cmd_complete_on_removal)
|
||||||
|
{
|
||||||
fpi_ssm_mark_completed (transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +95,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
res = bmkt_parse_message_payload (&msg_resp, &resp);
|
res = bmkt_parse_message_payload (&msg_resp, &resp);
|
||||||
if (res != BMKT_SUCCESS) {
|
if (res != BMKT_SUCCESS)
|
||||||
|
{
|
||||||
g_warning ("Could not parse message payload: %i", res);
|
g_warning ("Could not parse message payload: %i", res);
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
|
@ -95,14 +104,18 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special cancellation handling */
|
/* Special cancellation handling */
|
||||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK || resp.response_id == BMKT_RSP_CANCEL_OP_FAIL) {
|
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK || resp.response_id == BMKT_RSP_CANCEL_OP_FAIL)
|
||||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK) {
|
{
|
||||||
|
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK)
|
||||||
|
{
|
||||||
fp_dbg ("Received cancellation success resonse");
|
fp_dbg ("Received cancellation success resonse");
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
g_error_new_literal (G_IO_ERROR,
|
g_error_new_literal (G_IO_ERROR,
|
||||||
G_IO_ERROR_CANCELLED,
|
G_IO_ERROR_CANCELLED,
|
||||||
"Device reported cancellation of operation"));
|
"Device reported cancellation of operation"));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fp_dbg ("Cancellation failed, this should not happen");
|
fp_dbg ("Cancellation failed, this should not happen");
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
|
@ -110,22 +123,26 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_resp.seq_num == 0) {
|
if (msg_resp.seq_num == 0)
|
||||||
|
{
|
||||||
/* XXX: Should we really abort the command on general error?
|
/* XXX: Should we really abort the command on general error?
|
||||||
* The original code did not! */
|
* The original code did not! */
|
||||||
if (msg_resp.msg_id == BMKT_RSP_GENERAL_ERROR) {
|
if (msg_resp.msg_id == BMKT_RSP_GENERAL_ERROR)
|
||||||
|
{
|
||||||
guint16 err;
|
guint16 err;
|
||||||
|
|
||||||
/* XXX: It is weird that this is big endian. */
|
/* XXX: It is weird that this is big endian. */
|
||||||
err = FP_READ_UINT16_BE(msg_resp.payload);
|
err = FP_READ_UINT16_BE (msg_resp.payload);
|
||||||
|
|
||||||
fp_warn("Received General Error %d from the sensor", (guint) err);
|
fp_warn ("Received General Error %d from the sensor", (guint) err);
|
||||||
fpi_ssm_mark_failed (transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
"Received general error from device"));
|
"Received general error from device"));
|
||||||
//fpi_ssm_jump_to_state (transfer->ssm, fpi_ssm_get_cur_state (transfer->ssm));
|
//fpi_ssm_jump_to_state (transfer->ssm, fpi_ssm_get_cur_state (transfer->ssm));
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fp_dbg ("Received message with 0 sequence number 0x%02x, ignoring!",
|
fp_dbg ("Received message with 0 sequence number 0x%02x, ignoring!",
|
||||||
msg_resp.msg_id);
|
msg_resp.msg_id);
|
||||||
fpi_ssm_next_state (transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
@ -135,7 +152,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
||||||
|
|
||||||
/* We should only ever have one command running, and the sequence num needs
|
/* We should only ever have one command running, and the sequence num needs
|
||||||
* to match. */
|
* to match. */
|
||||||
if (msg_resp.seq_num != self->cmd_seq_num) {
|
if (msg_resp.seq_num != self->cmd_seq_num)
|
||||||
|
{
|
||||||
fp_warn ("Got unexpected sequence number from device, %d instead of %d",
|
fp_warn ("Got unexpected sequence number from device, %d instead of %d",
|
||||||
msg_resp.seq_num,
|
msg_resp.seq_num,
|
||||||
self->cmd_seq_num);
|
self->cmd_seq_num);
|
||||||
|
@ -162,8 +180,10 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
g_debug ("interrupt transfer done");
|
g_debug ("interrupt transfer done");
|
||||||
if (error) {
|
if (error)
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
{
|
||||||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
{
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
fpi_ssm_jump_to_state (transfer->ssm, SYNAPTICS_CMD_GET_RESP);
|
fpi_ssm_jump_to_state (transfer->ssm, SYNAPTICS_CMD_GET_RESP);
|
||||||
return;
|
return;
|
||||||
|
@ -181,16 +201,18 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
synaptics_cmd_run_state(FpiSsm *ssm,
|
synaptics_cmd_run_state (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (dev);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case SYNAPTICS_CMD_SEND_PENDING:
|
case SYNAPTICS_CMD_SEND_PENDING:
|
||||||
if (self->cmd_pending_transfer) {
|
if (self->cmd_pending_transfer)
|
||||||
|
{
|
||||||
self->cmd_pending_transfer->ssm = ssm;
|
self->cmd_pending_transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit (self->cmd_pending_transfer,
|
fpi_usb_transfer_submit (self->cmd_pending_transfer,
|
||||||
1000,
|
1000,
|
||||||
|
@ -198,7 +220,9 @@ synaptics_cmd_run_state(FpiSsm *ssm,
|
||||||
fpi_ssm_usb_transfer_cb,
|
fpi_ssm_usb_transfer_cb,
|
||||||
NULL);
|
NULL);
|
||||||
g_clear_pointer (&self->cmd_pending_transfer, fpi_usb_transfer_unref);
|
g_clear_pointer (&self->cmd_pending_transfer, fpi_usb_transfer_unref);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fpi_ssm_next_state (ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -258,9 +282,12 @@ cmd_ssm_done (FpiSsm *ssm,
|
||||||
self->cmd_ssm = NULL;
|
self->cmd_ssm = NULL;
|
||||||
|
|
||||||
/* Notify about the SSM failure from here instead. */
|
/* Notify about the SSM failure from here instead. */
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
callback (self, NULL, error);
|
callback (self, NULL, error);
|
||||||
} else if (self->cmd_complete_on_removal) {
|
}
|
||||||
|
else if (self->cmd_complete_on_removal)
|
||||||
|
{
|
||||||
callback (self, NULL, self->cmd_complete_error);
|
callback (self, NULL, self->cmd_complete_error);
|
||||||
self->cmd_complete_error = NULL;
|
self->cmd_complete_error = NULL;
|
||||||
}
|
}
|
||||||
|
@ -275,10 +302,13 @@ cmd_forget_cb (FpiUsbTransfer *transfer,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_warning ("Async command sending failed: %s", error->message);
|
g_warning ("Async command sending failed: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_debug ("Async command sent successfully");
|
g_debug ("Async command sent successfully");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,7 +317,7 @@ static void
|
||||||
synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
||||||
gint seq_num,
|
gint seq_num,
|
||||||
guint8 msg_id,
|
guint8 msg_id,
|
||||||
const guint8* payload,
|
const guint8 * payload,
|
||||||
gssize payload_len,
|
gssize payload_len,
|
||||||
SynCmdMsgCallback callback)
|
SynCmdMsgCallback callback)
|
||||||
{
|
{
|
||||||
|
@ -304,12 +334,15 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
||||||
/* seq_num of 0 means a normal command, -1 means the current commands
|
/* seq_num of 0 means a normal command, -1 means the current commands
|
||||||
* sequence number should not be udpated (i.e. second async command which
|
* sequence number should not be udpated (i.e. second async command which
|
||||||
* may only be a cancellation currently). */
|
* may only be a cancellation currently). */
|
||||||
if (seq_num <= 0) {
|
if (seq_num <= 0)
|
||||||
self->last_seq_num = MAX(1, self->last_seq_num + 1);
|
{
|
||||||
|
self->last_seq_num = MAX (1, self->last_seq_num + 1);
|
||||||
real_seq_num = self->last_seq_num;
|
real_seq_num = self->last_seq_num;
|
||||||
if (seq_num == 0)
|
if (seq_num == 0)
|
||||||
self->cmd_seq_num = self->last_seq_num;
|
self->cmd_seq_num = self->last_seq_num;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
real_seq_num = seq_num;
|
real_seq_num = seq_num;
|
||||||
self->last_seq_num = real_seq_num;
|
self->last_seq_num = real_seq_num;
|
||||||
}
|
}
|
||||||
|
@ -338,23 +371,29 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
|
||||||
|
|
||||||
/* Special case for async command sending (should only be used for
|
/* Special case for async command sending (should only be used for
|
||||||
* cancellation). */
|
* cancellation). */
|
||||||
if (seq_num == -1) {
|
if (seq_num == -1)
|
||||||
g_assert(callback == NULL);
|
{
|
||||||
|
g_assert (callback == NULL);
|
||||||
|
|
||||||
/* We just send and forget here. */
|
/* We just send and forget here. */
|
||||||
fpi_usb_transfer_submit (transfer, 1000, NULL, cmd_forget_cb, NULL);
|
fpi_usb_transfer_submit (transfer, 1000, NULL, cmd_forget_cb, NULL);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Command should be send using the state machine. */
|
/* Command should be send using the state machine. */
|
||||||
g_assert (self->cmd_pending_transfer == NULL);
|
g_assert (self->cmd_pending_transfer == NULL);
|
||||||
|
|
||||||
self->cmd_pending_transfer = g_steal_pointer (&transfer);
|
self->cmd_pending_transfer = g_steal_pointer (&transfer);
|
||||||
|
|
||||||
if (self->cmd_ssm) {
|
if (self->cmd_ssm)
|
||||||
|
{
|
||||||
/* Continued command, we already have an SSM with a callback.
|
/* Continued command, we already have an SSM with a callback.
|
||||||
* There is nothing to do in this case, the command will be
|
* There is nothing to do in this case, the command will be
|
||||||
* sent automatically. */
|
* sent automatically. */
|
||||||
g_assert (callback == NULL);
|
g_assert (callback == NULL);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Start of a new command, create the state machine. */
|
/* Start of a new command, create the state machine. */
|
||||||
g_assert (callback != NULL);
|
g_assert (callback != NULL);
|
||||||
|
|
||||||
|
@ -387,7 +426,7 @@ parse_print_data (GVariant *data,
|
||||||
if (!g_variant_check_format_string (data, "(y@ay)", FALSE))
|
if (!g_variant_check_format_string (data, "(y@ay)", FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_variant_get(data,
|
g_variant_get (data,
|
||||||
"(y@ay)",
|
"(y@ay)",
|
||||||
finger,
|
finger,
|
||||||
&user_id_var);
|
&user_id_var);
|
||||||
|
@ -404,13 +443,14 @@ parse_print_data (GVariant *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
list_msg_cb(FpiDeviceSynaptics *self,
|
list_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp;
|
bmkt_enroll_templates_resp_t *get_enroll_templates_resp;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
||||||
fpi_device_list_complete (FP_DEVICE (self), NULL, error);
|
fpi_device_list_complete (FP_DEVICE (self), NULL, error);
|
||||||
return;
|
return;
|
||||||
|
@ -421,14 +461,17 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
switch (resp->response_id)
|
switch (resp->response_id)
|
||||||
{
|
{
|
||||||
case BMKT_RSP_QUERY_FAIL:
|
case BMKT_RSP_QUERY_FAIL:
|
||||||
if (resp->result == BMKT_FP_DATABASE_EMPTY) {
|
if (resp->result == BMKT_FP_DATABASE_EMPTY)
|
||||||
fp_info("Database is empty");
|
{
|
||||||
|
fp_info ("Database is empty");
|
||||||
|
|
||||||
fpi_device_list_complete (FP_DEVICE (self),
|
fpi_device_list_complete (FP_DEVICE (self),
|
||||||
g_steal_pointer (&self->list_result),
|
g_steal_pointer (&self->list_result),
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
}
|
||||||
fp_info("Failed to query enrolled users: %d", resp->result);
|
else
|
||||||
|
{
|
||||||
|
fp_info ("Failed to query enrolled users: %d", resp->result);
|
||||||
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
||||||
fpi_device_list_complete (FP_DEVICE (self),
|
fpi_device_list_complete (FP_DEVICE (self),
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -436,14 +479,16 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
"Failed to query enrolled users"));
|
"Failed to query enrolled users"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||||
fp_info("Query complete!");
|
fp_info ("Query complete!");
|
||||||
|
|
||||||
fpi_device_list_complete (FP_DEVICE (self),
|
fpi_device_list_complete (FP_DEVICE (self),
|
||||||
g_steal_pointer (&self->list_result),
|
g_steal_pointer (&self->list_result),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||||
|
|
||||||
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||||
|
@ -456,7 +501,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fp_info("![query %d of %d] template %d: status=0x%x, userId=%s, fingerId=%d",
|
fp_info ("![query %d of %d] template %d: status=0x%x, userId=%s, fingerId=%d",
|
||||||
get_enroll_templates_resp->query_sequence,
|
get_enroll_templates_resp->query_sequence,
|
||||||
get_enroll_templates_resp->total_query_messages,
|
get_enroll_templates_resp->total_query_messages,
|
||||||
n,
|
n,
|
||||||
|
@ -481,9 +526,10 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
|
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
|
||||||
|
|
||||||
/* The format has 24 bytes at the start and some dashes in the right places */
|
/* The format has 24 bytes at the start and some dashes in the right places */
|
||||||
if (g_str_has_prefix (userid, "FP1-") && strlen(userid) >= 24 &&
|
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
|
||||||
userid[12] == '-' && userid[14] == '-' && userid[23] == '-') {
|
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
|
||||||
g_autofree gchar *copy = g_strdup(userid);
|
{
|
||||||
|
g_autofree gchar *copy = g_strdup (userid);
|
||||||
gint32 date_ymd;
|
gint32 date_ymd;
|
||||||
GDate *date = NULL;
|
GDate *date = NULL;
|
||||||
gint32 finger;
|
gint32 finger;
|
||||||
|
@ -510,7 +556,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
* Then comes the username; nobody is the default if the metadata
|
* Then comes the username; nobody is the default if the metadata
|
||||||
* is unknown */
|
* is unknown */
|
||||||
username = copy + 24;
|
username = copy + 24;
|
||||||
if (strlen(username) > 0 && g_strcmp0 (username, "nobody") != 0)
|
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
|
||||||
fp_print_set_username (print, username);
|
fp_print_set_username (print, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,30 +575,32 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
list(FpDevice *device)
|
list (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->list_result = g_ptr_array_new_with_free_func (g_object_unref);
|
self->list_result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
|
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
verify_msg_cb(FpiDeviceSynaptics *self,
|
verify_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
bmkt_verify_resp_t *verify_resp;
|
bmkt_verify_resp_t *verify_resp;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
|
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp == NULL && self->cmd_complete_on_removal) {
|
if (resp == NULL && self->cmd_complete_on_removal)
|
||||||
|
{
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device,
|
||||||
GPOINTER_TO_INT (self->cmd_complete_data),
|
GPOINTER_TO_INT (self->cmd_complete_data),
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -565,38 +613,45 @@ verify_msg_cb(FpiDeviceSynaptics *self,
|
||||||
switch (resp->response_id)
|
switch (resp->response_id)
|
||||||
{
|
{
|
||||||
case BMKT_RSP_VERIFY_READY:
|
case BMKT_RSP_VERIFY_READY:
|
||||||
fp_info("Place Finger on the Sensor!");
|
fp_info ("Place Finger on the Sensor!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||||
fp_info("Fingerprint image capture complete!");
|
fp_info ("Fingerprint image capture complete!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_VERIFY_FAIL:
|
case BMKT_RSP_VERIFY_FAIL:
|
||||||
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR) {
|
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
||||||
|
{
|
||||||
fp_dbg ("delaying retry error until after finger removal!");
|
fp_dbg ("delaying retry error until after finger removal!");
|
||||||
self->cmd_complete_on_removal = TRUE;
|
self->cmd_complete_on_removal = TRUE;
|
||||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_ERROR);
|
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_ERROR);
|
||||||
self->cmd_complete_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
self->cmd_complete_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
||||||
} else if (resp->result == BMKT_FP_NO_MATCH) {
|
}
|
||||||
|
else if (resp->result == BMKT_FP_NO_MATCH)
|
||||||
|
{
|
||||||
fp_dbg ("delaying match failure until after finger removal!");
|
fp_dbg ("delaying match failure until after finger removal!");
|
||||||
self->cmd_complete_on_removal = TRUE;
|
self->cmd_complete_on_removal = TRUE;
|
||||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_FAIL);
|
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_FAIL);
|
||||||
self->cmd_complete_error = NULL;
|
self->cmd_complete_error = NULL;
|
||||||
} else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS) {
|
}
|
||||||
fp_info("Print is not in database");
|
else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||||
|
{
|
||||||
|
fp_info ("Print is not in database");
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device,
|
||||||
FPI_MATCH_ERROR,
|
FPI_MATCH_ERROR,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||||
} else {
|
}
|
||||||
fp_warn("Verify has failed: %d", resp->result);
|
else
|
||||||
|
{
|
||||||
|
fp_warn ("Verify has failed: %d", resp->result);
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
|
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_VERIFY_OK:
|
case BMKT_RSP_VERIFY_OK:
|
||||||
fp_info("Verify was successful! for user: %s finger: %d score: %f",
|
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
||||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
fpi_device_verify_complete (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -604,10 +659,11 @@ verify_msg_cb(FpiDeviceSynaptics *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
verify(FpDevice *device)
|
verify (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
|
|
||||||
g_autoptr(GVariant) data = NULL;
|
g_autoptr(GVariant) data = NULL;
|
||||||
guint8 finger;
|
guint8 finger;
|
||||||
const guint8 *user_id;
|
const guint8 *user_id;
|
||||||
|
@ -617,7 +673,8 @@ verify(FpDevice *device)
|
||||||
|
|
||||||
g_object_get (print, "fp-data", &data, NULL);
|
g_object_get (print, "fp-data", &data, NULL);
|
||||||
g_debug ("data is %p", data);
|
g_debug ("data is %p", data);
|
||||||
if (!parse_print_data (data, &finger, &user_id, &user_id_len)) {
|
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
||||||
|
{
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device,
|
||||||
FPI_MATCH_ERROR,
|
FPI_MATCH_ERROR,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -625,20 +682,21 @@ verify(FpDevice *device)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_VERIFY_USER, user_id, user_id_len, verify_msg_cb);
|
synaptics_sensor_cmd (self, 0, BMKT_CMD_VERIFY_USER, user_id, user_id_len, verify_msg_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enroll_msg_cb(FpiDeviceSynaptics *self,
|
enroll_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
bmkt_enroll_resp_t *enroll_resp;
|
bmkt_enroll_resp_t *enroll_resp;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_device_enroll_complete (device, NULL, error);
|
fpi_device_enroll_complete (device, NULL, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -650,67 +708,80 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
|
||||||
case BMKT_RSP_ENROLL_READY:
|
case BMKT_RSP_ENROLL_READY:
|
||||||
{
|
{
|
||||||
self->enroll_stage = 0;
|
self->enroll_stage = 0;
|
||||||
fp_info("Place Finger on the Sensor!");
|
fp_info ("Place Finger on the Sensor!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||||
{
|
{
|
||||||
fp_info("Fingerprint image capture complete!");
|
fp_info ("Fingerprint image capture complete!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_REPORT:
|
case BMKT_RSP_ENROLL_REPORT:
|
||||||
{
|
{
|
||||||
gint done_stages;
|
gint done_stages;
|
||||||
fp_info("Enrollment is %d %% ", enroll_resp->progress);
|
fp_info ("Enrollment is %d %% ", enroll_resp->progress);
|
||||||
|
|
||||||
done_stages = (enroll_resp->progress * ENROLL_SAMPLES + 99) / 100;
|
done_stages = (enroll_resp->progress * ENROLL_SAMPLES + 99) / 100;
|
||||||
if (enroll_resp->progress < 100)
|
if (enroll_resp->progress < 100)
|
||||||
done_stages = MIN(done_stages, ENROLL_SAMPLES - 1);
|
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
|
||||||
|
|
||||||
/* Emit a retry error if there has been no discernable
|
/* Emit a retry error if there has been no discernable
|
||||||
* progress. Some firmware revisions report more required
|
* progress. Some firmware revisions report more required
|
||||||
* touches. */
|
* touches. */
|
||||||
if (self->enroll_stage == done_stages)
|
if (self->enroll_stage == done_stages)
|
||||||
|
{
|
||||||
fpi_device_enroll_progress (device,
|
fpi_device_enroll_progress (device,
|
||||||
done_stages,
|
done_stages,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||||
|
}
|
||||||
|
|
||||||
while (self->enroll_stage < done_stages) {
|
while (self->enroll_stage < done_stages)
|
||||||
|
{
|
||||||
self->enroll_stage += 1;
|
self->enroll_stage += 1;
|
||||||
fpi_device_enroll_progress (device, self->enroll_stage, NULL, NULL);
|
fpi_device_enroll_progress (device, self->enroll_stage, NULL, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_PAUSED:
|
case BMKT_RSP_ENROLL_PAUSED:
|
||||||
{
|
{
|
||||||
fp_info("Enrollment has been paused!");
|
fp_info ("Enrollment has been paused!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_RESUMED:
|
case BMKT_RSP_ENROLL_RESUMED:
|
||||||
{
|
{
|
||||||
fp_info("Enrollment has been resumed!");
|
fp_info ("Enrollment has been resumed!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_FAIL:
|
case BMKT_RSP_ENROLL_FAIL:
|
||||||
{
|
{
|
||||||
fp_info("Enrollment has failed!: %d", resp->result);
|
fp_info ("Enrollment has failed!: %d", resp->result);
|
||||||
if (resp->result == BMKT_FP_DATABASE_FULL)
|
if (resp->result == BMKT_FP_DATABASE_FULL)
|
||||||
|
{
|
||||||
fpi_device_enroll_complete (device,
|
fpi_device_enroll_complete (device,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fpi_device_enroll_complete (device,
|
fpi_device_enroll_complete (device,
|
||||||
NULL,
|
NULL,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||||
"Enrollment failed"));
|
"Enrollment failed"));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BMKT_RSP_ENROLL_OK:
|
case BMKT_RSP_ENROLL_OK:
|
||||||
{
|
{
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
|
|
||||||
fp_info("Enrollment was successful!");
|
fp_info ("Enrollment was successful!");
|
||||||
|
|
||||||
fpi_device_get_enroll_data (device, &print);
|
fpi_device_get_enroll_data (device, &print);
|
||||||
|
|
||||||
|
@ -723,7 +794,7 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
|
||||||
#define TEMPLATE_ID_SIZE 20
|
#define TEMPLATE_ID_SIZE 20
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enroll(FpDevice *device)
|
enroll (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
|
@ -740,14 +811,17 @@ enroll(FpDevice *device)
|
||||||
|
|
||||||
fpi_device_get_enroll_data (device, &print);
|
fpi_device_get_enroll_data (device, &print);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
date = fp_print_get_enroll_date (print);
|
date = fp_print_get_enroll_date (print);
|
||||||
if (date && g_date_valid (date)) {
|
if (date && g_date_valid (date))
|
||||||
|
{
|
||||||
y = date->year;
|
y = date->year;
|
||||||
m = date->month;
|
m = date->month;
|
||||||
d = date->day;
|
d = date->day;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
y = 0;
|
y = 0;
|
||||||
m = 0;
|
m = 0;
|
||||||
d = 0;
|
d = 0;
|
||||||
|
@ -760,7 +834,7 @@ enroll(FpDevice *device)
|
||||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||||
rand_id = 0;
|
rand_id = 0;
|
||||||
else
|
else
|
||||||
rand_id = g_random_int();
|
rand_id = g_random_int ();
|
||||||
|
|
||||||
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
|
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
|
||||||
y, m, d,
|
y, m, d,
|
||||||
|
@ -769,7 +843,7 @@ enroll(FpDevice *device)
|
||||||
username);
|
username);
|
||||||
|
|
||||||
user_id_len = strlen (user_id);
|
user_id_len = strlen (user_id);
|
||||||
user_id_len = MIN(BMKT_MAX_USER_ID_LEN, user_id_len);
|
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
|
||||||
|
|
||||||
/* We currently always use finger 1 from the devices piont of view */
|
/* We currently always use finger 1 from the devices piont of view */
|
||||||
finger = 1;
|
finger = 1;
|
||||||
|
@ -787,9 +861,9 @@ enroll(FpDevice *device)
|
||||||
g_object_set (print, "fp-data", data, NULL);
|
g_object_set (print, "fp-data", data, NULL);
|
||||||
g_object_set (print, "description", user_id, NULL);
|
g_object_set (print, "description", user_id, NULL);
|
||||||
|
|
||||||
g_debug("user_id: %s, finger: %d", user_id, finger);
|
g_debug ("user_id: %s, finger: %d", user_id, finger);
|
||||||
|
|
||||||
payload = g_malloc0(user_id_len + 2);
|
payload = g_malloc0 (user_id_len + 2);
|
||||||
|
|
||||||
/* Backup options are not supported for Prometheus */
|
/* Backup options are not supported for Prometheus */
|
||||||
payload[0] = 0;
|
payload[0] = 0;
|
||||||
|
@ -800,14 +874,15 @@ enroll(FpDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_msg_cb(FpiDeviceSynaptics *self,
|
delete_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpDevice *device = FP_DEVICE (self);
|
FpDevice *device = FP_DEVICE (self);
|
||||||
bmkt_del_user_resp_t *del_user_resp;
|
bmkt_del_user_resp_t *del_user_resp;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_device_delete_complete (device, error);
|
fpi_device_delete_complete (device, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -817,11 +892,12 @@ delete_msg_cb(FpiDeviceSynaptics *self,
|
||||||
switch (resp->response_id)
|
switch (resp->response_id)
|
||||||
{
|
{
|
||||||
case BMKT_RSP_DELETE_PROGRESS:
|
case BMKT_RSP_DELETE_PROGRESS:
|
||||||
fp_info("Deleting Enrolled Users is %d%% complete",
|
fp_info ("Deleting Enrolled Users is %d%% complete",
|
||||||
del_user_resp->progress);
|
del_user_resp->progress);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||||
fp_info("Failed to delete enrolled user: %d", resp->result);
|
fp_info ("Failed to delete enrolled user: %d", resp->result);
|
||||||
if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||||
fpi_device_delete_complete (device,
|
fpi_device_delete_complete (device,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||||
|
@ -829,18 +905,20 @@ delete_msg_cb(FpiDeviceSynaptics *self,
|
||||||
fpi_device_delete_complete (device,
|
fpi_device_delete_complete (device,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_DEL_USER_FP_OK:
|
case BMKT_RSP_DEL_USER_FP_OK:
|
||||||
fp_info("Successfully deleted enrolled user");
|
fp_info ("Successfully deleted enrolled user");
|
||||||
fpi_device_delete_complete (device, NULL);
|
fpi_device_delete_complete (device, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_print(FpDevice *device)
|
delete_print (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
FpPrint *print = NULL;
|
FpPrint *print = NULL;
|
||||||
|
|
||||||
g_autoptr(GVariant) data = NULL;
|
g_autoptr(GVariant) data = NULL;
|
||||||
guint8 finger;
|
guint8 finger;
|
||||||
const guint8 *user_id;
|
const guint8 *user_id;
|
||||||
|
@ -851,13 +929,14 @@ delete_print(FpDevice *device)
|
||||||
|
|
||||||
g_object_get (print, "fp-data", &data, NULL);
|
g_object_get (print, "fp-data", &data, NULL);
|
||||||
g_debug ("data is %p", data);
|
g_debug ("data is %p", data);
|
||||||
if (!parse_print_data (data, &finger, &user_id, &user_id_len)) {
|
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
||||||
|
{
|
||||||
fpi_device_delete_complete (device,
|
fpi_device_delete_complete (device,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
payload = g_malloc0 (1 + user_id_len);
|
payload = g_malloc0 (1 + user_id_len);
|
||||||
payload[0] = finger;
|
payload[0] = finger;
|
||||||
|
@ -867,7 +946,7 @@ delete_print(FpDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_probe(FpDevice *device)
|
dev_probe (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
GUsbDevice *usb_dev;
|
GUsbDevice *usb_dev;
|
||||||
|
@ -879,21 +958,23 @@ dev_probe(FpDevice *device)
|
||||||
gboolean read_ok = TRUE;
|
gboolean read_ok = TRUE;
|
||||||
g_autofree gchar *serial = NULL;
|
g_autofree gchar *serial = NULL;
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
usb_dev = fpi_device_get_usb_device(device);
|
usb_dev = fpi_device_get_usb_device (device);
|
||||||
if (!g_usb_device_open (usb_dev, &error)) {
|
if (!g_usb_device_open (usb_dev, &error))
|
||||||
|
{
|
||||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error)) {
|
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
|
||||||
|
{
|
||||||
fpi_device_probe_complete (device, NULL, NULL, error);
|
fpi_device_probe_complete (device, NULL, NULL, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device(device), 0, 0, &error))
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
|
||||||
goto err_close;
|
goto err_close;
|
||||||
|
|
||||||
/* TODO: Do not do this synchronous. */
|
/* TODO: Do not do this synchronous. */
|
||||||
|
@ -913,12 +994,14 @@ dev_probe(FpDevice *device)
|
||||||
|
|
||||||
fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length);
|
fpi_byte_reader_init (&reader, transfer->buffer, transfer->actual_length);
|
||||||
|
|
||||||
if (!fpi_byte_reader_get_uint16_le (&reader, &status)) {
|
if (!fpi_byte_reader_get_uint16_le (&reader, &status))
|
||||||
|
{
|
||||||
g_warning ("Transfer in response to version query was too short");
|
g_warning ("Transfer in response to version query was too short");
|
||||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
if (status != 0) {
|
if (status != 0)
|
||||||
|
{
|
||||||
g_warning ("Device responded with error: %d", status);
|
g_warning ("Device responded with error: %d", status);
|
||||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||||
goto err_close;
|
goto err_close;
|
||||||
|
@ -935,25 +1018,26 @@ dev_probe(FpDevice *device)
|
||||||
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.formal_release);
|
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.formal_release);
|
||||||
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.platform);
|
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.platform);
|
||||||
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.patch);
|
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.patch);
|
||||||
if (fpi_byte_reader_get_data (&reader, sizeof(self->mis_version.serial_number), &data))
|
if (fpi_byte_reader_get_data (&reader, sizeof (self->mis_version.serial_number), &data))
|
||||||
memcpy (self->mis_version.serial_number, data, sizeof(self->mis_version.serial_number));
|
memcpy (self->mis_version.serial_number, data, sizeof (self->mis_version.serial_number));
|
||||||
else
|
else
|
||||||
read_ok = FALSE;
|
read_ok = FALSE;
|
||||||
read_ok &= fpi_byte_reader_get_uint16_le (&reader, &self->mis_version.security);
|
read_ok &= fpi_byte_reader_get_uint16_le (&reader, &self->mis_version.security);
|
||||||
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.iface);
|
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.iface);
|
||||||
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.device_type);
|
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.device_type);
|
||||||
|
|
||||||
if (!read_ok) {
|
if (!read_ok)
|
||||||
|
{
|
||||||
g_warning ("Transfer in response to verison query was too short");
|
g_warning ("Transfer in response to verison query was too short");
|
||||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("Build Time: %d", self->mis_version.build_time);
|
fp_dbg ("Build Time: %d", self->mis_version.build_time);
|
||||||
fp_dbg("Build Num: %d", self->mis_version.build_num);
|
fp_dbg ("Build Num: %d", self->mis_version.build_num);
|
||||||
fp_dbg("Version: %d.%d", self->mis_version.version_major, self->mis_version.version_minor);
|
fp_dbg ("Version: %d.%d", self->mis_version.version_major, self->mis_version.version_minor);
|
||||||
fp_dbg("Target: %d", self->mis_version.target);
|
fp_dbg ("Target: %d", self->mis_version.target);
|
||||||
fp_dbg("Product: %d", self->mis_version.product);
|
fp_dbg ("Product: %d", self->mis_version.product);
|
||||||
|
|
||||||
fpi_usb_transfer_unref (transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
|
||||||
|
@ -995,48 +1079,55 @@ err_close:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fps_init_msg_cb(FpiDeviceSynaptics *self,
|
fps_init_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
fpi_device_open_complete (FP_DEVICE (self), error);
|
fpi_device_open_complete (FP_DEVICE (self), error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BMKT_OPERATION_DENIED is returned if the sensor is already initialized */
|
/* BMKT_OPERATION_DENIED is returned if the sensor is already initialized */
|
||||||
if (resp->result == BMKT_SUCCESS || resp->result == BMKT_OPERATION_DENIED) {
|
if (resp->result == BMKT_SUCCESS || resp->result == BMKT_OPERATION_DENIED)
|
||||||
|
{
|
||||||
fpi_device_open_complete (FP_DEVICE (self), NULL);
|
fpi_device_open_complete (FP_DEVICE (self), NULL);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_warning ("Initializing fingerprint sensor failed with %d!", resp->result);
|
g_warning ("Initializing fingerprint sensor failed with %d!", resp->result);
|
||||||
fpi_device_open_complete (FP_DEVICE (self),
|
fpi_device_open_complete (FP_DEVICE (self),
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
fps_deinit_cb(FpiDeviceSynaptics *self,
|
fps_deinit_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE (self)), 0, 0, &error);
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)), 0, 0, &error);
|
||||||
|
|
||||||
g_clear_object (&self->interrupt_cancellable);
|
g_clear_object (&self->interrupt_cancellable);
|
||||||
|
|
||||||
if (!error) {
|
if (!error)
|
||||||
switch (resp->response_id) {
|
{
|
||||||
|
switch (resp->response_id)
|
||||||
|
{
|
||||||
case BMKT_RSP_POWER_DOWN_READY:
|
case BMKT_RSP_POWER_DOWN_READY:
|
||||||
fp_info("Fingerprint sensor ready to be powered down");
|
fp_info ("Fingerprint sensor ready to be powered down");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_POWER_DOWN_FAIL:
|
case BMKT_RSP_POWER_DOWN_FAIL:
|
||||||
fp_info("Failed to go to power down mode: %d", resp->result);
|
fp_info ("Failed to go to power down mode: %d", resp->result);
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||||
"Power down failed");
|
"Power down failed");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fpi_device_close_complete(FP_DEVICE (self), error);
|
fpi_device_close_complete (FP_DEVICE (self), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1045,7 +1136,7 @@ dev_init (FpDevice *device)
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->interrupt_cancellable = g_cancellable_new ();
|
self->interrupt_cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
@ -1065,19 +1156,19 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_exit(FpDevice *device)
|
dev_exit (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||||
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_POWER_DOWN_NOTIFY, NULL, 0, fps_deinit_cb);
|
synaptics_sensor_cmd (self, 0, BMKT_CMD_POWER_DOWN_NOTIFY, NULL, 0, fps_deinit_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cancel(FpDevice *dev)
|
cancel (FpDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS(dev);
|
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (dev);
|
||||||
|
|
||||||
/* We just send out a cancel command and hope for the best. */
|
/* We just send out a cancel command and hope for the best. */
|
||||||
synaptics_sensor_cmd (self, -1, BMKT_CMD_CANCEL_OP, NULL, 0, NULL);
|
synaptics_sensor_cmd (self, -1, BMKT_CMD_CANCEL_OP, NULL, 0, NULL);
|
||||||
|
@ -1091,12 +1182,14 @@ cancel(FpDevice *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_device_synaptics_init(FpiDeviceSynaptics *self) {
|
fpi_device_synaptics_init (FpiDeviceSynaptics *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fpi_device_synaptics_class_init(FpiDeviceSynapticsClass *klass) {
|
fpi_device_synaptics_class_init (FpiDeviceSynapticsClass *klass)
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
dev_class->id = FP_COMPONENT;
|
dev_class->id = FP_COMPONENT;
|
||||||
dev_class->full_name = SYNAPTICS_DRIVER_FULLNAME;
|
dev_class->full_name = SYNAPTICS_DRIVER_FULLNAME;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#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 */
|
||||||
|
@ -77,20 +77,18 @@ 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,
|
||||||
|
@ -100,7 +98,9 @@ typedef enum
|
||||||
} 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
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,9 +56,10 @@ static const uint16_t crc_table[256] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
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--)
|
while (size--)
|
||||||
crc = (uint16_t) ((crc << 8) ^
|
crc = (uint16_t) ((crc << 8) ^
|
||||||
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
||||||
|
|
|
@ -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
|
@ -27,7 +27,8 @@
|
||||||
#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 reg;
|
||||||
guint8 value;
|
guint8 value;
|
||||||
};
|
};
|
||||||
|
@ -71,7 +72,7 @@ static const struct sonly_regwrite awfsm_2016_writev_3[] = {
|
||||||
|
|
||||||
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 */
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
#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;
|
||||||
|
@ -40,18 +41,19 @@ struct _FpiDeviceUpektc {
|
||||||
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 ******/
|
||||||
|
|
||||||
|
@ -62,176 +64,194 @@ enum activate_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
|
||||||
|
write_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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)
|
if (self->setup_commands[self->init_idx].response_len)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
else
|
else
|
||||||
upektc_next_init_cmd(transfer->ssm, dev);
|
upektc_next_init_cmd (transfer->ssm, dev);
|
||||||
} else {
|
}
|
||||||
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
|
||||||
|
read_init_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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:
|
case READ_DATA:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer,
|
fpi_usb_transfer_fill_bulk (transfer,
|
||||||
self->ep_in,
|
self->ep_in,
|
||||||
self->setup_commands[self->init_idx].response_len);
|
self->setup_commands[self->init_idx].response_len);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
read_init_data_cb, NULL);
|
read_init_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
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
|
||||||
|
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
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 */
|
/* finger present, start capturing */
|
||||||
fpi_image_device_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_cmd_cb(FpiUsbTransfer *t, FpDevice *device,
|
static void
|
||||||
|
finger_det_cmd_cb (FpiUsbTransfer *t, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
||||||
|
fpi_image_device_session_error (dev, error);
|
||||||
return;
|
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);
|
|
||||||
|
if (self->deactivating)
|
||||||
|
{
|
||||||
|
complete_deactivation (dev, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
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);
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
|
||||||
finger_det_cmd_cb, NULL);
|
finger_det_cmd_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
@ -242,185 +262,209 @@ enum capture_states {
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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
|
||||||
|
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
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:
|
case CAPTURE_READ_DATA:
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk(transfer, self->ep_in,
|
fpi_usb_transfer_fill_bulk (transfer, self->ep_in,
|
||||||
IMAGE_SIZE);
|
IMAGE_SIZE);
|
||||||
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_read_data_cb, NULL);
|
capture_read_data_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
GError *error)
|
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);
|
{
|
||||||
|
complete_deactivation (dev, NULL);
|
||||||
return;
|
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;
|
self->init_idx = 0;
|
||||||
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)
|
||||||
{
|
{
|
||||||
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();
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
fpi_image_device_deactivate_complete(dev, error);
|
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);
|
{
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (driver_data) {
|
switch (driver_data)
|
||||||
|
{
|
||||||
case UPEKTC_2015:
|
case UPEKTC_2015:
|
||||||
self->ep_in = UPEKTC_EP_IN;
|
self->ep_in = UPEKTC_EP_IN;
|
||||||
self->ep_out = UPEKTC_EP_OUT;
|
self->ep_out = UPEKTC_EP_OUT;
|
||||||
self->setup_commands = upektc_setup_commands;
|
self->setup_commands = upektc_setup_commands;
|
||||||
self->setup_commands_len = G_N_ELEMENTS(upektc_setup_commands);
|
self->setup_commands_len = G_N_ELEMENTS (upektc_setup_commands);
|
||||||
self->sum_threshold = UPEKTC_SUM_THRESHOLD;
|
self->sum_threshold = UPEKTC_SUM_THRESHOLD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPEKTC_3001:
|
case UPEKTC_3001:
|
||||||
self->ep_in = UPEKET_EP_IN;
|
self->ep_in = UPEKET_EP_IN;
|
||||||
self->ep_out = UPEKET_EP_OUT;
|
self->ep_out = UPEKET_EP_OUT;
|
||||||
self->setup_commands = upeket_setup_commands;
|
self->setup_commands = upeket_setup_commands;
|
||||||
self->setup_commands_len = G_N_ELEMENTS(upeket_setup_commands);
|
self->setup_commands_len = G_N_ELEMENTS (upeket_setup_commands);
|
||||||
self->sum_threshold = UPEKET_SUM_THRESHOLD;
|
self->sum_threshold = UPEKET_SUM_THRESHOLD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Device variant %lu is not known\n", driver_data);
|
fp_err ("Device variant %lu is not known\n", driver_data);
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
fpi_image_device_open_complete(dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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)
|
||||||
{
|
{
|
||||||
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";
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
#define UPEKTC_SUM_THRESHOLD 10000
|
#define UPEKTC_SUM_THRESHOLD 10000
|
||||||
#define UPEKET_SUM_THRESHOLD 5000
|
#define UPEKET_SUM_THRESHOLD 5000
|
||||||
|
|
||||||
struct setup_cmd {
|
struct setup_cmd
|
||||||
|
{
|
||||||
unsigned char cmd[0x40];
|
unsigned char cmd[0x40];
|
||||||
int response_len;
|
int response_len;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#include "upek_proto.h"
|
#include "upek_proto.h"
|
||||||
#include "upektc_img.h"
|
#include "upektc_img.h"
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev);
|
static void start_capture (FpImageDevice *dev);
|
||||||
static void start_deactivation(FpImageDevice *dev);
|
static void start_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)
|
||||||
|
@ -39,7 +39,8 @@ static void start_deactivation(FpImageDevice *dev);
|
||||||
#define MAX_RESPONSE_SIZE 2052
|
#define MAX_RESPONSE_SIZE 2052
|
||||||
#define SHORT_RESPONSE_SIZE 64
|
#define SHORT_RESPONSE_SIZE 64
|
||||||
|
|
||||||
struct _FpiDeviceUpektcImg {
|
struct _FpiDeviceUpektcImg
|
||||||
|
{
|
||||||
FpImageDevice parent;
|
FpImageDevice parent;
|
||||||
|
|
||||||
unsigned char cmd[MAX_CMD_SIZE];
|
unsigned char cmd[MAX_CMD_SIZE];
|
||||||
|
@ -50,13 +51,14 @@ struct _FpiDeviceUpektcImg {
|
||||||
size_t response_rest;
|
size_t response_rest;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE(FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
|
||||||
DEVICE_UPEKTC_IMG, FpImageDevice);
|
DEVICE_UPEKTC_IMG, FpImageDevice);
|
||||||
G_DEFINE_TYPE(FpiDeviceUpektcImg, fpi_device_upektc_img, FP_TYPE_IMAGE_DEVICE);
|
G_DEFINE_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
/****** HELPERS ******/
|
/****** HELPERS ******/
|
||||||
|
|
||||||
static void upektc_img_cmd_fix_seq(unsigned char *cmd_buf, unsigned char seq)
|
static void
|
||||||
|
upektc_img_cmd_fix_seq (unsigned char *cmd_buf, unsigned char seq)
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
|
|
||||||
|
@ -66,58 +68,59 @@ static void upektc_img_cmd_fix_seq(unsigned char *cmd_buf, unsigned char seq)
|
||||||
cmd_buf[5] = byte;
|
cmd_buf[5] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void upektc_img_cmd_update_crc(unsigned char *cmd_buf, size_t size)
|
static void
|
||||||
|
upektc_img_cmd_update_crc (unsigned char *cmd_buf, size_t size)
|
||||||
{
|
{
|
||||||
/* CRC does not cover Ciao prefix (4 bytes) and CRC location (2 bytes) */
|
/* CRC does not cover Ciao prefix (4 bytes) and CRC location (2 bytes) */
|
||||||
uint16_t crc = udf_crc(cmd_buf + 4, size - 6);
|
uint16_t crc = udf_crc (cmd_buf + 4, size - 6);
|
||||||
|
|
||||||
cmd_buf[size - 2] = (crc & 0x00ff);
|
cmd_buf[size - 2] = (crc & 0x00ff);
|
||||||
cmd_buf[size - 1] = (crc & 0xff00) >> 8;
|
cmd_buf[size - 1] = (crc & 0xff00) >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
upektc_img_submit_req(FpiSsm *ssm,
|
upektc_img_submit_req (FpiSsm *ssm,
|
||||||
FpImageDevice *dev,
|
FpImageDevice *dev,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
size_t buf_size,
|
size_t buf_size,
|
||||||
unsigned char seq,
|
unsigned char seq,
|
||||||
FpiUsbTransferCallback cb)
|
FpiUsbTransferCallback cb)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
|
|
||||||
BUG_ON(buf_size > MAX_CMD_SIZE);
|
BUG_ON (buf_size > MAX_CMD_SIZE);
|
||||||
|
|
||||||
memcpy(self->cmd, buf, buf_size);
|
memcpy (self->cmd, buf, buf_size);
|
||||||
upektc_img_cmd_fix_seq(self->cmd, seq);
|
upektc_img_cmd_fix_seq (self->cmd, seq);
|
||||||
upektc_img_cmd_update_crc(self->cmd, buf_size);
|
upektc_img_cmd_update_crc (self->cmd, buf_size);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, self->cmd, buf_size,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, self->cmd, buf_size,
|
||||||
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, cb, NULL);
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
upektc_img_read_data(FpiSsm *ssm,
|
upektc_img_read_data (FpiSsm *ssm,
|
||||||
FpImageDevice *dev,
|
FpImageDevice *dev,
|
||||||
size_t buf_size,
|
size_t buf_size,
|
||||||
size_t buf_offset,
|
size_t buf_offset,
|
||||||
FpiUsbTransferCallback cb)
|
FpiUsbTransferCallback cb)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
|
|
||||||
BUG_ON(buf_offset + buf_size > MAX_RESPONSE_SIZE);
|
BUG_ON (buf_offset + buf_size > MAX_RESPONSE_SIZE);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN,
|
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN,
|
||||||
self->response + buf_offset, buf_size,
|
self->response + buf_offset, buf_size,
|
||||||
NULL);
|
NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL, cb, NULL);
|
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
@ -133,246 +136,281 @@ enum capture_states {
|
||||||
CAPTURE_NUM_STATES,
|
CAPTURE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capture_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (fpi_ssm_get_cur_state(transfer->ssm)) {
|
switch (fpi_ssm_get_cur_state (transfer->ssm))
|
||||||
|
{
|
||||||
case CAPTURE_ACK_00_28_TERM:
|
case CAPTURE_ACK_00_28_TERM:
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA_TERM);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA_TERM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int upektc_img_process_image_frame(unsigned char *image_buf, unsigned char *cmd_res)
|
static int
|
||||||
|
upektc_img_process_image_frame (unsigned char *image_buf, unsigned char *cmd_res)
|
||||||
{
|
{
|
||||||
int offset = 8;
|
int offset = 8;
|
||||||
int len = ((cmd_res[5] & 0x0f) << 8) | (cmd_res[6]);
|
int len = ((cmd_res[5] & 0x0f) << 8) | (cmd_res[6]);
|
||||||
|
|
||||||
len -= 1;
|
len -= 1;
|
||||||
if (cmd_res[7] == 0x2c) {
|
if (cmd_res[7] == 0x2c)
|
||||||
|
{
|
||||||
len -= 10;
|
len -= 10;
|
||||||
offset += 10;
|
offset += 10;
|
||||||
}
|
}
|
||||||
if (cmd_res[7] == 0x20) {
|
if (cmd_res[7] == 0x20)
|
||||||
len -= 4;
|
len -= 4;
|
||||||
}
|
memcpy (image_buf, cmd_res + offset, len);
|
||||||
memcpy(image_buf, cmd_res + offset, len);
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
unsigned char *data = self->response;
|
unsigned char *data = self->response;
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
size_t response_size;
|
size_t response_size;
|
||||||
|
|
||||||
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);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
fp_dbg("Deactivate requested\n");
|
{
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fp_dbg ("Deactivate requested\n");
|
||||||
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
return;
|
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 == 0) {
|
if (transfer->actual_length == 0)
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
{
|
||||||
fpi_ssm_get_cur_state(transfer->ssm));
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
|
fpi_ssm_get_cur_state (transfer->ssm));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fpi_ssm_get_cur_state(transfer->ssm) == CAPTURE_READ_DATA_TERM) {
|
if (fpi_ssm_get_cur_state (transfer->ssm) == CAPTURE_READ_DATA_TERM)
|
||||||
fp_dbg("Terminating SSM\n");
|
{
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fp_dbg ("Terminating SSM\n");
|
||||||
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->response_rest) {
|
if (!self->response_rest)
|
||||||
|
{
|
||||||
response_size = ((data[5] & 0x0f) << 8) + data[6];
|
response_size = ((data[5] & 0x0f) << 8) + data[6];
|
||||||
response_size += 9; /* 7 bytes for header, 2 for CRC */
|
response_size += 9; /* 7 bytes for header, 2 for CRC */
|
||||||
if (response_size > transfer->actual_length) {
|
if (response_size > transfer->actual_length)
|
||||||
fp_dbg("response_size is %lu, actual_length is %d\n",
|
{
|
||||||
response_size, (gint)transfer->actual_length);
|
fp_dbg ("response_size is %lu, actual_length is %d\n",
|
||||||
fp_dbg("Waiting for rest of transfer");
|
response_size, (gint) transfer->actual_length);
|
||||||
BUG_ON(self->response_rest);
|
fp_dbg ("Waiting for rest of transfer");
|
||||||
|
BUG_ON (self->response_rest);
|
||||||
self->response_rest = response_size - transfer->actual_length;
|
self->response_rest = response_size - transfer->actual_length;
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self->response_rest = 0;
|
self->response_rest = 0;
|
||||||
|
|
||||||
switch (data[4]) {
|
switch (data[4])
|
||||||
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
switch (data[7]) {
|
switch (data[7])
|
||||||
|
{
|
||||||
/* No finger */
|
/* No finger */
|
||||||
case 0x28:
|
case 0x28:
|
||||||
fp_dbg("18th byte is %.2x\n", data[18]);
|
fp_dbg ("18th byte is %.2x\n", data[18]);
|
||||||
switch (data[18]) {
|
switch (data[18])
|
||||||
|
{
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
/* no finger */
|
/* no finger */
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28);
|
CAPTURE_ACK_00_28);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* finger is present! */
|
/* finger is present! */
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28);
|
CAPTURE_ACK_00_28);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1e:
|
case 0x1e:
|
||||||
/* short scan */
|
/* short scan */
|
||||||
fp_err("short scan, aborting\n");
|
fp_err ("short scan, aborting\n");
|
||||||
fpi_image_device_retry_scan(dev,
|
fpi_image_device_retry_scan (dev,
|
||||||
FP_DEVICE_RETRY_TOO_SHORT);
|
FP_DEVICE_RETRY_TOO_SHORT);
|
||||||
fpi_image_device_report_finger_status(dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28_TERM);
|
CAPTURE_ACK_00_28_TERM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
/* too much horisontal movement */
|
/* too much horisontal movement */
|
||||||
fp_err("too much horisontal movement, aborting\n");
|
fp_err ("too much horisontal movement, aborting\n");
|
||||||
fpi_image_device_retry_scan(dev,
|
fpi_image_device_retry_scan (dev,
|
||||||
FP_DEVICE_RETRY_CENTER_FINGER);
|
FP_DEVICE_RETRY_CENTER_FINGER);
|
||||||
fpi_image_device_report_finger_status(dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28_TERM);
|
CAPTURE_ACK_00_28_TERM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* some error happened, cancel scan */
|
/* some error happened, cancel scan */
|
||||||
fp_err("something bad happened, stop scan\n");
|
fp_err ("something bad happened, stop scan\n");
|
||||||
fpi_image_device_retry_scan(dev,
|
fpi_image_device_retry_scan (dev,
|
||||||
FP_DEVICE_RETRY);
|
FP_DEVICE_RETRY);
|
||||||
fpi_image_device_report_finger_status(dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_00_28_TERM);
|
CAPTURE_ACK_00_28_TERM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Image frame with additional info */
|
/* Image frame with additional info */
|
||||||
case 0x2c:
|
case 0x2c:
|
||||||
fpi_image_device_report_finger_status(dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
/* Plain image frame */
|
/* Plain image frame */
|
||||||
case 0x24:
|
case 0x24:
|
||||||
self->image_size +=
|
self->image_size +=
|
||||||
upektc_img_process_image_frame(self->image_bits + self->image_size,
|
upektc_img_process_image_frame (self->image_bits + self->image_size,
|
||||||
data);
|
data);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
CAPTURE_ACK_FRAME);
|
CAPTURE_ACK_FRAME);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Last image frame */
|
/* Last image frame */
|
||||||
case 0x20:
|
case 0x20:
|
||||||
self->image_size +=
|
self->image_size +=
|
||||||
upektc_img_process_image_frame(self->image_bits + self->image_size,
|
upektc_img_process_image_frame (self->image_bits + self->image_size,
|
||||||
data);
|
data);
|
||||||
BUG_ON(self->image_size != IMAGE_SIZE);
|
BUG_ON (self->image_size != IMAGE_SIZE);
|
||||||
fp_dbg("Image size is %lu\n",
|
fp_dbg ("Image size is %lu\n",
|
||||||
self->image_size);
|
self->image_size);
|
||||||
img = fp_image_new(IMAGE_WIDTH, IMAGE_HEIGHT);
|
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||||
memcpy(img->data, self->image_bits,
|
memcpy (img->data, self->image_bits,
|
||||||
IMAGE_SIZE);
|
IMAGE_SIZE);
|
||||||
fpi_image_device_image_captured(dev, img);
|
fpi_image_device_image_captured (dev, img);
|
||||||
fpi_image_device_report_finger_status(dev,
|
fpi_image_device_report_finger_status (dev,
|
||||||
FALSE);
|
FALSE);
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Unknown response!\n");
|
fp_err ("Unknown response!\n");
|
||||||
fpi_ssm_mark_failed(transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08:
|
case 0x08:
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_ACK_08);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_ACK_08);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Not handled response!\n");
|
fp_err ("Not handled response!\n");
|
||||||
fpi_ssm_mark_failed(transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
static void
|
||||||
|
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(_dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case CAPTURE_INIT_CAPTURE:
|
case CAPTURE_INIT_CAPTURE:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_init_capture, sizeof(upek2020_init_capture),
|
upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture),
|
||||||
self->seq, capture_reqs_cb);
|
self->seq, capture_reqs_cb);
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
case CAPTURE_READ_DATA_TERM:
|
case CAPTURE_READ_DATA_TERM:
|
||||||
if (!self->response_rest)
|
if (!self->response_rest)
|
||||||
upektc_img_read_data(ssm, dev, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
|
upektc_img_read_data (ssm, dev, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
|
||||||
else
|
else
|
||||||
upektc_img_read_data(ssm, dev, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
|
upektc_img_read_data (ssm, dev, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
|
||||||
SHORT_RESPONSE_SIZE, capture_read_data_cb);
|
SHORT_RESPONSE_SIZE, capture_read_data_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_ACK_00_28:
|
case CAPTURE_ACK_00_28:
|
||||||
case CAPTURE_ACK_00_28_TERM:
|
case CAPTURE_ACK_00_28_TERM:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_00_28, sizeof(upek2020_ack_00_28),
|
upektc_img_submit_req (ssm, dev, upek2020_ack_00_28, sizeof (upek2020_ack_00_28),
|
||||||
self->seq, capture_reqs_cb);
|
self->seq, capture_reqs_cb);
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_ACK_08:
|
case CAPTURE_ACK_08:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_08, sizeof(upek2020_ack_08),
|
upektc_img_submit_req (ssm, dev, upek2020_ack_08, sizeof (upek2020_ack_08),
|
||||||
0, capture_reqs_cb);
|
0, capture_reqs_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_ACK_FRAME:
|
case CAPTURE_ACK_FRAME:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_ack_frame, sizeof(upek2020_ack_frame),
|
upektc_img_submit_req (ssm, dev, upek2020_ack_frame, sizeof (upek2020_ack_frame),
|
||||||
self->seq, capture_reqs_cb);
|
self->seq, capture_reqs_cb);
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data, GError *error_arg)
|
static void
|
||||||
|
capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data, GError *error_arg)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(_dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||||
|
|
||||||
g_autoptr(GError) error = error_arg;
|
g_autoptr(GError) error = error_arg;
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
|
|
||||||
/* Note: We assume that the error is a cancellation in the deactivation case */
|
/* Note: We assume that the error is a cancellation in the deactivation case */
|
||||||
if (self->deactivating)
|
if (self->deactivating)
|
||||||
start_deactivation(dev);
|
start_deactivation (dev);
|
||||||
else if (error)
|
else if (error)
|
||||||
fpi_image_device_session_error (dev, g_steal_pointer (&error));
|
fpi_image_device_session_error (dev, g_steal_pointer (&error));
|
||||||
else
|
else
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_capture(FpImageDevice *dev)
|
static void
|
||||||
|
start_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
self->image_size = 0;
|
self->image_size = 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);
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start (ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||||
|
@ -383,68 +421,74 @@ enum deactivate_states {
|
||||||
DEACTIVATE_NUM_STATES,
|
DEACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void deactivate_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
deactivate_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: process response properly */
|
/* TODO: process response properly */
|
||||||
static void deactivate_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
deactivate_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error)
|
||||||
fpi_ssm_mark_completed(transfer->ssm);
|
fpi_ssm_mark_completed (transfer->ssm);
|
||||||
} else {
|
else
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_run_state(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
deactivate_run_state (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(_dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case DEACTIVATE_DEINIT:
|
case DEACTIVATE_DEINIT:
|
||||||
upektc_img_submit_req(ssm, dev, upek2020_deinit, sizeof(upek2020_deinit),
|
upektc_img_submit_req (ssm, dev, upek2020_deinit, sizeof (upek2020_deinit),
|
||||||
self->seq, deactivate_reqs_cb);
|
self->seq, deactivate_reqs_cb);
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEACTIVATE_READ_DEINIT_DATA:
|
case DEACTIVATE_READ_DEINIT_DATA:
|
||||||
upektc_img_read_data(ssm, dev, SHORT_RESPONSE_SIZE, 0, deactivate_read_data_cb);
|
upektc_img_read_data (ssm, dev, SHORT_RESPONSE_SIZE, 0, deactivate_read_data_cb);
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
deactivate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(_dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||||
|
|
||||||
fp_dbg("Deactivate completed");
|
fp_dbg ("Deactivate completed");
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
|
|
||||||
self->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
fpi_image_device_deactivate_complete(dev, error);
|
fpi_image_device_deactivate_complete (dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_deactivation(FpImageDevice *dev)
|
static void
|
||||||
|
start_deactivation (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
FpiSsm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
self->image_size = 0;
|
self->image_size = 0;
|
||||||
|
|
||||||
ssm = fpi_ssm_new(FP_DEVICE(dev), deactivate_run_state,
|
ssm = fpi_ssm_new (FP_DEVICE (dev), deactivate_run_state,
|
||||||
DEACTIVATE_NUM_STATES, dev);
|
DEACTIVATE_NUM_STATES, dev);
|
||||||
fpi_ssm_start(ssm, deactivate_sm_complete);
|
fpi_ssm_start (ssm, deactivate_sm_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum activate_states {
|
enum activate_states {
|
||||||
|
@ -463,146 +507,161 @@ enum activate_states {
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init_reqs_ctrl_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
init_reqs_ctrl_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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: process response properly */
|
/* TODO: process response properly */
|
||||||
static void init_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
FpImageDevice *idev = user_data;
|
FpImageDevice *idev = user_data;
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case ACTIVATE_CONTROL_REQ_1:
|
case ACTIVATE_CONTROL_REQ_1:
|
||||||
case ACTIVATE_CONTROL_REQ_2:
|
case ACTIVATE_CONTROL_REQ_2:
|
||||||
{
|
{
|
||||||
transfer = fpi_usb_transfer_new(dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
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,
|
||||||
0x0c, 0x100, 0x0400, 1);
|
0x0c, 0x100, 0x0400, 1);
|
||||||
transfer->buffer[0] = '\0';
|
transfer->buffer[0] = '\0';
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
|
||||||
init_reqs_ctrl_cb, NULL);
|
init_reqs_ctrl_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_INIT_1:
|
case ACTIVATE_INIT_1:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_1, sizeof(upek2020_init_1),
|
upektc_img_submit_req (ssm, idev, upek2020_init_1, sizeof (upek2020_init_1),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_INIT_2:
|
case ACTIVATE_INIT_2:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_2, sizeof(upek2020_init_2),
|
upektc_img_submit_req (ssm, idev, upek2020_init_2, sizeof (upek2020_init_2),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_INIT_3:
|
case ACTIVATE_INIT_3:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_3, sizeof(upek2020_init_3),
|
upektc_img_submit_req (ssm, idev, upek2020_init_3, sizeof (upek2020_init_3),
|
||||||
0, init_reqs_cb);
|
0, init_reqs_cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_INIT_4:
|
case ACTIVATE_INIT_4:
|
||||||
upektc_img_submit_req(ssm, idev, upek2020_init_4, sizeof(upek2020_init_4),
|
upektc_img_submit_req (ssm, idev, upek2020_init_4, sizeof (upek2020_init_4),
|
||||||
self->seq, init_reqs_cb);
|
self->seq, init_reqs_cb);
|
||||||
/* Seq should be updated after 4th init */
|
/* Seq should be updated after 4th init */
|
||||||
self->seq++;
|
self->seq++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTIVATE_READ_CTRL_RESP_1:
|
case ACTIVATE_READ_CTRL_RESP_1:
|
||||||
case ACTIVATE_READ_CTRL_RESP_2:
|
case ACTIVATE_READ_CTRL_RESP_2:
|
||||||
case ACTIVATE_READ_INIT_1_RESP:
|
case ACTIVATE_READ_INIT_1_RESP:
|
||||||
case ACTIVATE_READ_INIT_2_RESP:
|
case ACTIVATE_READ_INIT_2_RESP:
|
||||||
case ACTIVATE_READ_INIT_3_RESP:
|
case ACTIVATE_READ_INIT_3_RESP:
|
||||||
case ACTIVATE_READ_INIT_4_RESP:
|
case ACTIVATE_READ_INIT_4_RESP:
|
||||||
upektc_img_read_data(ssm, idev, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
|
upektc_img_read_data (ssm, idev, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
static void
|
||||||
|
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
fpi_image_device_activate_complete(dev, error);
|
fpi_image_device_activate_complete (dev, error);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
start_capture(dev);
|
start_capture (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_activate(FpImageDevice *dev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (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->seq = 0;
|
self->seq = 0;
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
|
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_init(FpImageDevice *dev)
|
static void
|
||||||
|
dev_init (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* 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);
|
{
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->image_bits = g_malloc0 (IMAGE_SIZE * 2);
|
self->image_bits = g_malloc0 (IMAGE_SIZE * 2);
|
||||||
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)
|
||||||
{
|
{
|
||||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
|
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_clear_pointer (&self->image_bits, g_free);
|
g_clear_pointer (&self->image_bits, g_free);
|
||||||
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 int
|
static int
|
||||||
discover(GUsbDevice *usb_device)
|
discover (GUsbDevice *usb_device)
|
||||||
{
|
{
|
||||||
gint16 pid = g_usb_device_get_pid (usb_device);
|
gint16 pid = g_usb_device_get_pid (usb_device);
|
||||||
gint16 bcd = g_usb_device_get_release (usb_device);
|
gint16 bcd = g_usb_device_get_release (usb_device);
|
||||||
|
@ -615,19 +674,21 @@ discover(GUsbDevice *usb_device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{ .vid = 0x147e, .pid = 0x2016,
|
{ .vid = 0x147e, .pid = 0x2016, },
|
||||||
},
|
{ .vid = 0x147e, .pid = 0x2020, },
|
||||||
{ .vid = 0x147e, .pid = 0x2020,
|
|
||||||
},
|
|
||||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_upektc_img_init(FpiDeviceUpektcImg *self) {
|
static void
|
||||||
|
fpi_device_upektc_img_init (FpiDeviceUpektcImg *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_upektc_img_class_init(FpiDeviceUpektcImgClass *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_upektc_img_class_init (FpiDeviceUpektcImgClass *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_img";
|
dev_class->id = "upektc_img";
|
||||||
dev_class->full_name = "Upek TouchChip Fingerprint Coprocessor";
|
dev_class->full_name = "Upek TouchChip Fingerprint Coprocessor";
|
||||||
|
|
|
@ -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
|
@ -38,7 +38,8 @@
|
||||||
#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;
|
||||||
|
@ -46,9 +47,9 @@ struct _FpDeviceVcom5s {
|
||||||
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:
|
||||||
|
@ -75,62 +76,64 @@ enum v5s_cmd {
|
||||||
|
|
||||||
/***** REGISTER I/O *****/
|
/***** REGISTER I/O *****/
|
||||||
|
|
||||||
static void sm_write_reg_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
sm_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
else
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sm_exec_cmd (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
unsigned char cmd,
|
unsigned char cmd,
|
||||||
unsigned char param)
|
unsigned char param)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
fp_dbg("cmd %02x param %02x", cmd, param);
|
fp_dbg ("cmd %02x param %02x", cmd, param);
|
||||||
fpi_usb_transfer_fill_control(transfer,
|
fpi_usb_transfer_fill_control (transfer,
|
||||||
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
|
||||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||||
cmd, param, 0, 0);
|
cmd, param, 0, 0);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
|
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
|
||||||
NULL);
|
NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** FINGER DETECTION *****/
|
/***** FINGER DETECTION *****/
|
||||||
|
@ -145,12 +148,14 @@ 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);
|
unsigned char *rowdata = data + (row * IMG_WIDTH);
|
||||||
guint16 rowavg = 0;
|
guint16 rowavg = 0;
|
||||||
int col;
|
int col;
|
||||||
|
@ -161,51 +166,57 @@ static gboolean finger_is_present(unsigned char *data)
|
||||||
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
|
||||||
|
capture_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
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);
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++self->capture_iteration == NR_REQS) {
|
if (++self->capture_iteration == NR_REQS)
|
||||||
|
{
|
||||||
FpImage *img = self->capture_img;
|
FpImage *img = self->capture_img;
|
||||||
/* must clear this early, otherwise the call chain takes us into
|
/* must clear this early, otherwise the call chain takes us into
|
||||||
* loopsm_complete where we would free it, when in fact we are
|
* loopsm_complete where we would free it, when in fact we are
|
||||||
* supposed to be handing off this image */
|
* supposed to be handing off this image */
|
||||||
self->capture_img = NULL;
|
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;
|
||||||
|
@ -221,16 +232,16 @@ capture_iterate(FpiSsm *ssm,
|
||||||
|
|
||||||
|
|
||||||
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 *****/
|
||||||
|
@ -244,105 +255,127 @@ enum loop_states {
|
||||||
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:
|
case LOOP_SET_CONTRAST:
|
||||||
sm_write_reg(ssm, dev, REG_CONTRAST, 0x01);
|
sm_write_reg (ssm, dev, REG_CONTRAST, 0x01);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOOP_SET_GAIN:
|
case LOOP_SET_GAIN:
|
||||||
sm_write_reg(ssm, dev, REG_GAIN, 0x29);
|
sm_write_reg (ssm, dev, REG_GAIN, 0x29);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOOP_CMD_SCAN:
|
case LOOP_CMD_SCAN:
|
||||||
if (self->deactivating) {
|
if (self->deactivating)
|
||||||
fp_dbg("deactivating, marking completed");
|
{
|
||||||
fpi_ssm_mark_completed(ssm);
|
fp_dbg ("deactivating, marking completed");
|
||||||
} else
|
fpi_ssm_mark_completed (ssm);
|
||||||
sm_exec_cmd(ssm, dev, CMD_SCAN, 0x00);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sm_exec_cmd (ssm, dev, CMD_SCAN, 0x00);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOOP_CAPTURE:
|
case LOOP_CAPTURE:
|
||||||
sm_do_capture(ssm, dev);
|
sm_do_capture (ssm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOOP_CAPTURE_DONE:
|
case LOOP_CAPTURE_DONE:
|
||||||
fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
|
fpi_ssm_jump_to_state (ssm, LOOP_CMD_SCAN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loopsm_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
static void
|
||||||
|
loopsm_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||||
GError *error)
|
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;
|
self->deactivating = FALSE;
|
||||||
fpi_ssm_start(ssm, loopsm_complete);
|
fpi_ssm_start (ssm, loopsm_complete);
|
||||||
self->loop_running = TRUE;
|
self->loop_running = TRUE;
|
||||||
fpi_image_device_activate_complete(dev, NULL);
|
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)
|
if (self->loop_running)
|
||||||
self->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
else
|
else
|
||||||
fpi_image_device_deactivate_complete(dev, NULL);
|
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";
|
||||||
|
@ -358,4 +391,3 @@ static void fpi_device_vcom5s_class_init(FpDeviceVcom5sClass *klass) {
|
||||||
img_class->img_width = IMG_WIDTH;
|
img_class->img_width = IMG_WIDTH;
|
||||||
img_class->img_height = IMG_HEIGHT;
|
img_class->img_height = IMG_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,21 +27,23 @@ G_DEFINE_TYPE (FpDeviceVfs0050, fpi_device_vfs0050, FP_TYPE_IMAGE_DEVICE)
|
||||||
/* USB functions */
|
/* USB functions */
|
||||||
|
|
||||||
/* Callback for async_write */
|
/* Callback for async_write */
|
||||||
static void async_write_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
async_write_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
fp_err("USB write transfer: %s", error->message);
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fp_err ("USB write transfer: %s", error->message);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send data to EP1, the only out endpoint */
|
/* Send data to EP1, the only out endpoint */
|
||||||
static void
|
static void
|
||||||
async_write(FpiSsm *ssm,
|
async_write (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
void *data,
|
void *data,
|
||||||
int len)
|
int len)
|
||||||
|
@ -49,33 +51,35 @@ async_write(FpiSsm *ssm,
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, 0x01, data, len, NULL);
|
fpi_usb_transfer_fill_bulk_full (transfer, 0x01, data, len, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
||||||
async_write_callback, NULL);
|
async_write_callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for async_read */
|
/* Callback for async_read */
|
||||||
static void async_read_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
async_read_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
int ep = transfer->endpoint;
|
int ep = transfer->endpoint;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_err("USB read transfer on endpoint %d: %s", ep - 0x80,
|
{
|
||||||
|
fp_err ("USB read transfer on endpoint %d: %s", ep - 0x80,
|
||||||
error->message);
|
error->message);
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive data from the given ep and either discard or fill the given buffer */
|
/* Receive data from the given ep and either discard or fill the given buffer */
|
||||||
static void
|
static void
|
||||||
async_read(FpiSsm *ssm,
|
async_read (FpiSsm *ssm,
|
||||||
FpDevice *dev,
|
FpDevice *dev,
|
||||||
int ep,
|
int ep,
|
||||||
void *data,
|
void *data,
|
||||||
|
@ -90,52 +94,57 @@ async_read(FpiSsm *ssm,
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL)
|
||||||
|
{
|
||||||
data = g_malloc0 (len);
|
data = g_malloc0 (len);
|
||||||
free_func = g_free;
|
free_func = g_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0x83 is the only interrupt endpoint */
|
/* 0x83 is the only interrupt endpoint */
|
||||||
if (ep == EP3_IN)
|
if (ep == EP3_IN)
|
||||||
fpi_usb_transfer_fill_interrupt_full(transfer, ep, data, len, free_func);
|
fpi_usb_transfer_fill_interrupt_full (transfer, ep, data, len, free_func);
|
||||||
else
|
else
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, ep, data, len, free_func);
|
fpi_usb_transfer_fill_bulk_full (transfer, ep, data, len, free_func);
|
||||||
|
|
||||||
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
||||||
async_read_callback, NULL);
|
async_read_callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for async_abort */
|
/* Callback for async_abort */
|
||||||
static void async_abort_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
async_abort_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
int ep = transfer->endpoint;
|
int ep = transfer->endpoint;
|
||||||
|
|
||||||
/* In normal case endpoint is empty */
|
/* In normal case endpoint is empty */
|
||||||
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) {
|
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT))
|
||||||
|
{
|
||||||
g_free (error);
|
g_free (error);
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_err("USB write transfer: %s", error->message);
|
{
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fp_err ("USB write transfer: %s", error->message);
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't stop process, only print warning */
|
/* Don't stop process, only print warning */
|
||||||
fp_warn("Endpoint %d had extra %zd bytes readable", ep - 0x80,
|
fp_warn ("Endpoint %d had extra %zd bytes readable", ep - 0x80,
|
||||||
transfer->actual_length);
|
transfer->actual_length);
|
||||||
|
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
fpi_ssm_get_cur_state(transfer->ssm));
|
fpi_ssm_get_cur_state (transfer->ssm));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive data from the given ep; continues to the next state once no
|
/* Receive data from the given ep; continues to the next state once no
|
||||||
* more data is available. Otherwise the current state is repeated. */
|
* more data is available. Otherwise the current state is repeated. */
|
||||||
static void async_abort(FpDevice *dev, FpiSsm *ssm, int ep)
|
static void
|
||||||
|
async_abort (FpDevice *dev, FpiSsm *ssm, int ep)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
|
@ -149,31 +158,35 @@ static void async_abort(FpDevice *dev, FpiSsm *ssm, int ep)
|
||||||
else
|
else
|
||||||
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
|
||||||
|
|
||||||
fpi_usb_transfer_submit(transfer, VFS_USB_ABORT_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
|
||||||
async_abort_callback, NULL);
|
async_abort_callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image processing functions */
|
/* Image processing functions */
|
||||||
|
|
||||||
/* Pixel getter for fpi_assemble_lines */
|
/* Pixel getter for fpi_assemble_lines */
|
||||||
static unsigned char vfs0050_get_pixel(struct fpi_line_asmbl_ctx *ctx,
|
static unsigned char
|
||||||
|
vfs0050_get_pixel (struct fpi_line_asmbl_ctx *ctx,
|
||||||
GSList * line, unsigned int x)
|
GSList * line, unsigned int x)
|
||||||
{
|
{
|
||||||
return ((struct vfs_line *)line->data)->data[x];
|
return ((struct vfs_line *) line->data)->data[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deviation getter for fpi_assemble_lines */
|
/* Deviation getter for fpi_assemble_lines */
|
||||||
static int vfs0050_get_difference(struct fpi_line_asmbl_ctx *ctx,
|
static int
|
||||||
|
vfs0050_get_difference (struct fpi_line_asmbl_ctx *ctx,
|
||||||
GSList * line_list_1, GSList * line_list_2)
|
GSList * line_list_1, GSList * line_list_2)
|
||||||
{
|
{
|
||||||
struct vfs_line *line1 = line_list_1->data;
|
struct vfs_line *line1 = line_list_1->data;
|
||||||
struct vfs_line *line2 = line_list_2->data;
|
struct vfs_line *line2 = line_list_2->data;
|
||||||
const int shift = (VFS_IMAGE_WIDTH - VFS_NEXT_LINE_WIDTH) / 2 - 1;
|
const int shift = (VFS_IMAGE_WIDTH - VFS_NEXT_LINE_WIDTH) / 2 - 1;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
for (int i = 0; i < VFS_NEXT_LINE_WIDTH; ++i) {
|
|
||||||
|
for (int i = 0; i < VFS_NEXT_LINE_WIDTH; ++i)
|
||||||
|
{
|
||||||
int x =
|
int x =
|
||||||
(int)line1->next_line_part[i] - (int)line2->data[shift + i];
|
(int) line1->next_line_part[i] - (int) line2->data[shift + i];
|
||||||
res += x * x;
|
res += x * x;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -182,13 +195,15 @@ static int vfs0050_get_difference(struct fpi_line_asmbl_ctx *ctx,
|
||||||
#define VFS_NOISE_THRESHOLD 40
|
#define VFS_NOISE_THRESHOLD 40
|
||||||
|
|
||||||
/* Checks whether line is noise or not using hardware parameters */
|
/* Checks whether line is noise or not using hardware parameters */
|
||||||
static char is_noise(struct vfs_line *line)
|
static char
|
||||||
|
is_noise (struct vfs_line *line)
|
||||||
{
|
{
|
||||||
int val1 = line->noise_hash_1;
|
int val1 = line->noise_hash_1;
|
||||||
int val2 = line->noise_hash_2;
|
int val2 = line->noise_hash_2;
|
||||||
if (val1 > VFS_NOISE_THRESHOLD
|
|
||||||
&& val1 < 256 - VFS_NOISE_THRESHOLD
|
if (val1 > VFS_NOISE_THRESHOLD &&
|
||||||
&& val2 > VFS_NOISE_THRESHOLD && val2 < 256 - VFS_NOISE_THRESHOLD)
|
val1 < 256 - VFS_NOISE_THRESHOLD &&
|
||||||
|
val2 > VFS_NOISE_THRESHOLD && val2 < 256 - VFS_NOISE_THRESHOLD)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -205,15 +220,17 @@ static struct fpi_line_asmbl_ctx assembling_ctx = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Processes image before submitting */
|
/* Processes image before submitting */
|
||||||
static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
|
static FpImage *
|
||||||
|
prepare_image (FpDeviceVfs0050 *vdev)
|
||||||
{
|
{
|
||||||
int height = vdev->bytes / VFS_LINE_SIZE;
|
int height = vdev->bytes / VFS_LINE_SIZE;
|
||||||
|
|
||||||
/* Noise cleaning. IMHO, it works pretty well
|
/* Noise cleaning. IMHO, it works pretty well
|
||||||
I've not detected cases when it doesn't work or cuts a part of the finger
|
I've not detected cases when it doesn't work or cuts a part of the finger
|
||||||
Noise arises at the end of scan when some water remains on the scanner */
|
Noise arises at the end of scan when some water remains on the scanner */
|
||||||
while (height > 0) {
|
while (height > 0)
|
||||||
if (!is_noise(vdev->lines_buffer + height - 1))
|
{
|
||||||
|
if (!is_noise (vdev->lines_buffer + height - 1))
|
||||||
break;
|
break;
|
||||||
--height;
|
--height;
|
||||||
}
|
}
|
||||||
|
@ -227,274 +244,298 @@ static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
|
||||||
/* Building GSList */
|
/* Building GSList */
|
||||||
GSList *lines = NULL;
|
GSList *lines = NULL;
|
||||||
for (int i = height - 1; i >= 0; --i)
|
for (int i = height - 1; i >= 0; --i)
|
||||||
lines = g_slist_prepend(lines, vdev->lines_buffer + i);
|
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
|
||||||
|
|
||||||
/* Perform line assembling */
|
/* Perform line assembling */
|
||||||
FpImage *img = fpi_assemble_lines(&assembling_ctx, lines, height);
|
FpImage *img = fpi_assemble_lines (&assembling_ctx, lines, height);
|
||||||
|
|
||||||
g_slist_free(lines);
|
g_slist_free (lines);
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Processes and submits image after fingerprint received */
|
/* Processes and submits image after fingerprint received */
|
||||||
static void submit_image(FpDeviceVfs0050 *self)
|
static void
|
||||||
|
submit_image (FpDeviceVfs0050 *self)
|
||||||
{
|
{
|
||||||
FpImageDevice *idev = FP_IMAGE_DEVICE(self);
|
FpImageDevice *idev = FP_IMAGE_DEVICE (self);
|
||||||
|
|
||||||
/* We were not asked to submit image actually */
|
/* We were not asked to submit image actually */
|
||||||
if (!self->active)
|
if (!self->active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FpImage *img = prepare_image(self);
|
FpImage *img = prepare_image (self);
|
||||||
|
|
||||||
if (!img)
|
if (!img)
|
||||||
fpi_image_device_retry_scan(idev, FP_DEVICE_RETRY_TOO_SHORT);
|
fpi_image_device_retry_scan (idev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||||
else
|
else
|
||||||
fpi_image_device_image_captured(idev, img);
|
fpi_image_device_image_captured (idev, img);
|
||||||
|
|
||||||
/* Finger not on the scanner */
|
/* Finger not on the scanner */
|
||||||
fpi_image_device_report_finger_status(idev, FALSE);
|
fpi_image_device_report_finger_status (idev, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Proto functions */
|
/* Proto functions */
|
||||||
|
|
||||||
/* SSM loop for clear_ep2 */
|
/* SSM loop for clear_ep2 */
|
||||||
static void
|
static void
|
||||||
clear_ep2_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
clear_ep2_ssm (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
char command04 = 0x04;
|
char command04 = 0x04;
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case SUBSM1_COMMAND_04:
|
case SUBSM1_COMMAND_04:
|
||||||
async_write(ssm, dev, &command04, sizeof(command04));
|
async_write (ssm, dev, &command04, sizeof (command04));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM1_RETURN_CODE:
|
case SUBSM1_RETURN_CODE:
|
||||||
async_read(ssm, dev, 1, NULL, 2);
|
async_read (ssm, dev, 1, NULL, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM1_ABORT_2:
|
case SUBSM1_ABORT_2:
|
||||||
async_abort(dev, ssm, 2);
|
async_abort (dev, ssm, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Unknown SUBSM1 state");
|
fp_err ("Unknown SUBSM1 state");
|
||||||
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send command to clear EP2 */
|
/* Send command to clear EP2 */
|
||||||
static void
|
static void
|
||||||
clear_ep2(FpDevice *dev,
|
clear_ep2 (FpDevice *dev,
|
||||||
FpiSsm *ssm)
|
FpiSsm *ssm)
|
||||||
{
|
{
|
||||||
FpiSsm *subsm =
|
FpiSsm *subsm =
|
||||||
fpi_ssm_new(dev, clear_ep2_ssm, SUBSM1_STATES, NULL);
|
fpi_ssm_new (dev, clear_ep2_ssm, SUBSM1_STATES, NULL);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
|
||||||
|
fpi_ssm_start_subsm (ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_control_packet_ssm(FpiSsm *ssm, FpDevice *dev,
|
static void
|
||||||
|
send_control_packet_ssm (FpiSsm *ssm, FpDevice *dev,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(dev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case SUBSM2_SEND_CONTROL:
|
case SUBSM2_SEND_CONTROL:
|
||||||
async_write(ssm, dev, self->control_packet,
|
async_write (ssm, dev, self->control_packet,
|
||||||
VFS_CONTROL_PACKET_SIZE);
|
VFS_CONTROL_PACKET_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_RETURN_CODE:
|
case SUBSM2_RETURN_CODE:
|
||||||
async_read(ssm, dev, 1, NULL, 2);
|
async_read (ssm, dev, 1, NULL, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_SEND_COMMIT:
|
case SUBSM2_SEND_COMMIT:
|
||||||
/* next_receive_* packets could be sent only in pair */
|
/* next_receive_* packets could be sent only in pair */
|
||||||
if (self->control_packet == next_receive_1) {
|
if (self->control_packet == next_receive_1)
|
||||||
|
{
|
||||||
self->control_packet = next_receive_2;
|
self->control_packet = next_receive_2;
|
||||||
fpi_ssm_jump_to_state(ssm, SUBSM2_SEND_CONTROL);
|
fpi_ssm_jump_to_state (ssm, SUBSM2_SEND_CONTROL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* commit_out in Windows differs in each commit, but I send the same each time */
|
/* commit_out in Windows differs in each commit, but I send the same each time */
|
||||||
async_write(ssm, dev, commit_out, sizeof(commit_out));
|
async_write (ssm, dev, commit_out, sizeof (commit_out));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_COMMIT_RESPONSE:
|
case SUBSM2_COMMIT_RESPONSE:
|
||||||
async_read(ssm, dev, 1, NULL, VFS_COMMIT_RESPONSE_SIZE);
|
async_read (ssm, dev, 1, NULL, VFS_COMMIT_RESPONSE_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_READ_EMPTY_INTERRUPT:
|
case SUBSM2_READ_EMPTY_INTERRUPT:
|
||||||
/* I don't know how to check result, it could be different
|
/* I don't know how to check result, it could be different
|
||||||
* NOTE: I guess this comment relates to the above read. */
|
* NOTE: I guess this comment relates to the above read. */
|
||||||
async_read(ssm, dev, 3, self->interrupt, VFS_INTERRUPT_SIZE);
|
async_read (ssm, dev, 3, self->interrupt, VFS_INTERRUPT_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_ABORT_3:
|
case SUBSM2_ABORT_3:
|
||||||
/* Check that interrupt is empty */
|
/* Check that interrupt is empty */
|
||||||
if (memcmp
|
if (memcmp
|
||||||
(self->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE)) {
|
(self->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE))
|
||||||
fp_err("Unknown SUBSM2 state");
|
{
|
||||||
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fp_err ("Unknown SUBSM2 state");
|
||||||
|
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
async_abort(dev, ssm, 3);
|
async_abort (dev, ssm, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBSM2_CLEAR_EP2:
|
case SUBSM2_CLEAR_EP2:
|
||||||
/* After turn_on Windows doesn't clear EP2 */
|
/* After turn_on Windows doesn't clear EP2 */
|
||||||
if (self->control_packet != turn_on)
|
if (self->control_packet != turn_on)
|
||||||
clear_ep2(dev, ssm);
|
clear_ep2 (dev, ssm);
|
||||||
else
|
else
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Unknown SUBSM2 state");
|
fp_err ("Unknown SUBSM2 state");
|
||||||
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send device state control packet */
|
/* Send device state control packet */
|
||||||
static void
|
static void
|
||||||
send_control_packet(FpiSsm *ssm,
|
send_control_packet (FpiSsm *ssm,
|
||||||
FpDevice *dev)
|
FpDevice *dev)
|
||||||
{
|
{
|
||||||
FpiSsm *subsm =
|
FpiSsm *subsm =
|
||||||
fpi_ssm_new(dev, send_control_packet_ssm,
|
fpi_ssm_new (dev, send_control_packet_ssm,
|
||||||
SUBSM2_STATES, NULL);
|
SUBSM2_STATES, NULL);
|
||||||
fpi_ssm_start_subsm(ssm, subsm);
|
|
||||||
|
fpi_ssm_start_subsm (ssm, subsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clears all fprint data */
|
/* Clears all fprint data */
|
||||||
static void clear_data(FpDeviceVfs0050 *vdev)
|
static void
|
||||||
|
clear_data (FpDeviceVfs0050 *vdev)
|
||||||
{
|
{
|
||||||
g_free(vdev->lines_buffer);
|
g_free (vdev->lines_buffer);
|
||||||
vdev->lines_buffer = NULL;
|
vdev->lines_buffer = NULL;
|
||||||
vdev->memory = vdev->bytes = 0;
|
vdev->memory = vdev->bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After receiving interrupt from EP3 */
|
/* After receiving interrupt from EP3 */
|
||||||
static void interrupt_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
interrupt_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(device);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (device);
|
||||||
char *interrupt = transfer->buffer;
|
char *interrupt = transfer->buffer;
|
||||||
|
|
||||||
/* we expect a cancellation error when the device is deactivating
|
/* we expect a cancellation error when the device is deactivating
|
||||||
* go into the SSM_CLEAR_EP2 state in that case. */
|
* go into the SSM_CLEAR_EP2 state in that case. */
|
||||||
if (!self->active && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
if (!self->active && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
{
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
fpi_ssm_jump_to_state(transfer->ssm, SSM_CLEAR_EP2);
|
fpi_ssm_jump_to_state (transfer->ssm, SSM_CLEAR_EP2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
fp_err("USB read interrupt transfer: %s",
|
{
|
||||||
|
fp_err ("USB read interrupt transfer: %s",
|
||||||
error->message);
|
error->message);
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Standard interrupts */
|
/* Standard interrupts */
|
||||||
if (memcmp(interrupt, interrupt1, VFS_INTERRUPT_SIZE) == 0 ||
|
if (memcmp (interrupt, interrupt1, VFS_INTERRUPT_SIZE) == 0 ||
|
||||||
memcmp(interrupt, interrupt2, VFS_INTERRUPT_SIZE) == 0 ||
|
memcmp (interrupt, interrupt2, VFS_INTERRUPT_SIZE) == 0 ||
|
||||||
memcmp(interrupt, interrupt3, VFS_INTERRUPT_SIZE) == 0) {
|
memcmp (interrupt, interrupt3, VFS_INTERRUPT_SIZE) == 0)
|
||||||
|
{
|
||||||
/* Go to the next ssm stage */
|
/* Go to the next ssm stage */
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When finger is on the scanner before turn_on */
|
/* When finger is on the scanner before turn_on */
|
||||||
if (interrupt[0] == 0x01) {
|
if (interrupt[0] == 0x01)
|
||||||
fp_warn("Finger is already on the scanner");
|
{
|
||||||
|
fp_warn ("Finger is already on the scanner");
|
||||||
|
|
||||||
/* Go to the next ssm stage */
|
/* Go to the next ssm stage */
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unknown interrupt; abort the session */
|
/* Unknown interrupt; abort the session */
|
||||||
fp_err("Unknown interrupt '%02x:%02x:%02x:%02x:%02x'!",
|
fp_err ("Unknown interrupt '%02x:%02x:%02x:%02x:%02x'!",
|
||||||
interrupt[0] & 0xff, interrupt[1] & 0xff, interrupt[2] & 0xff,
|
interrupt[0] & 0xff, interrupt[1] & 0xff, interrupt[2] & 0xff,
|
||||||
interrupt[3] & 0xff, interrupt[4] & 0xff);
|
interrupt[3] & 0xff, interrupt[4] & 0xff);
|
||||||
|
|
||||||
/* Abort ssm */
|
/* Abort ssm */
|
||||||
fpi_ssm_mark_failed(transfer->ssm,
|
fpi_ssm_mark_failed (transfer->ssm,
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
static void
|
||||||
|
receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(device);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (device);
|
||||||
|
|
||||||
if (error && !g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) {
|
if (error && !g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT))
|
||||||
fp_err("USB read transfer: %s", error->message);
|
{
|
||||||
|
fp_err ("USB read transfer: %s", error->message);
|
||||||
|
|
||||||
fpi_ssm_mark_failed(transfer->ssm, error);
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
|
||||||
/* Check if fingerprint data is over */
|
/* Check if fingerprint data is over */
|
||||||
if (transfer->actual_length == 0) {
|
if (transfer->actual_length == 0)
|
||||||
fpi_ssm_next_state(transfer->ssm);
|
{
|
||||||
} else {
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
self->bytes += transfer->actual_length;
|
self->bytes += transfer->actual_length;
|
||||||
|
|
||||||
/* We need more data */
|
/* We need more data */
|
||||||
fpi_ssm_jump_to_state(transfer->ssm,
|
fpi_ssm_jump_to_state (transfer->ssm,
|
||||||
fpi_ssm_get_cur_state(transfer->ssm));
|
fpi_ssm_get_cur_state (transfer->ssm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SSM stub to prepare device to another scan after orange light was on */
|
/* SSM stub to prepare device to another scan after orange light was on */
|
||||||
static void
|
static void
|
||||||
another_scan(FpDevice *dev,
|
another_scan (FpDevice *dev,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = data;
|
FpiSsm *ssm = data;
|
||||||
fpi_ssm_jump_to_state(ssm, SSM_TURN_ON);
|
|
||||||
|
fpi_ssm_jump_to_state (ssm, SSM_TURN_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main SSM loop */
|
/* Main SSM loop */
|
||||||
static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
static void
|
||||||
|
activate_ssm (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
FpImageDevice *idev = FP_IMAGE_DEVICE (dev);
|
FpImageDevice *idev = FP_IMAGE_DEVICE (dev);
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(dev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (dev);
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
case SSM_INITIAL_ABORT_1:
|
case SSM_INITIAL_ABORT_1:
|
||||||
async_abort(dev, ssm, 1);
|
async_abort (dev, ssm, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_INITIAL_ABORT_2:
|
case SSM_INITIAL_ABORT_2:
|
||||||
async_abort(dev, ssm, 2);
|
async_abort (dev, ssm, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_INITIAL_ABORT_3:
|
case SSM_INITIAL_ABORT_3:
|
||||||
async_abort(dev, ssm, 3);
|
async_abort (dev, ssm, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_CLEAR_EP2:
|
case SSM_CLEAR_EP2:
|
||||||
clear_ep2(dev, ssm);
|
clear_ep2 (dev, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_TURN_OFF:
|
case SSM_TURN_OFF:
|
||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
self->control_packet = turn_off;
|
self->control_packet = turn_off;
|
||||||
|
|
||||||
send_control_packet(ssm, dev);
|
send_control_packet (ssm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_TURN_ON:
|
case SSM_TURN_ON:
|
||||||
if (!self->active) {
|
if (!self->active)
|
||||||
|
{
|
||||||
/* The only correct exit */
|
/* The only correct exit */
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed (ssm);
|
||||||
|
|
||||||
if (self->need_report) {
|
if (self->need_report)
|
||||||
fpi_image_device_deactivate_complete(idev,
|
{
|
||||||
|
fpi_image_device_deactivate_complete (idev,
|
||||||
NULL);
|
NULL);
|
||||||
self->need_report = 0;
|
self->need_report = 0;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +544,7 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
self->control_packet = turn_on;
|
self->control_packet = turn_on;
|
||||||
|
|
||||||
send_control_packet(ssm, dev);
|
send_control_packet (ssm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_ASK_INTERRUPT: {
|
case SSM_ASK_INTERRUPT: {
|
||||||
|
@ -511,8 +552,9 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
/* Activated, light must be blinking now */
|
/* Activated, light must be blinking now */
|
||||||
|
|
||||||
/* If we first time here, report that activate completed */
|
/* If we first time here, report that activate completed */
|
||||||
if (self->need_report) {
|
if (self->need_report)
|
||||||
fpi_image_device_activate_complete(idev, NULL);
|
{
|
||||||
|
fpi_image_device_activate_complete (idev, NULL);
|
||||||
self->need_report = 0;
|
self->need_report = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,11 +570,12 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
fpi_usb_transfer_unref (transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
|
|
||||||
/* I've put it here to be sure that data is cleared */
|
/* I've put it here to be sure that data is cleared */
|
||||||
clear_data(self);
|
clear_data (self);
|
||||||
|
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SSM_WAIT_INTERRUPT:
|
case SSM_WAIT_INTERRUPT:
|
||||||
/* TODO: This state is unused at this point. When we
|
/* TODO: This state is unused at this point. When we
|
||||||
* are in this state, then a user cancellation will
|
* are in this state, then a user cancellation will
|
||||||
|
@ -545,110 +588,119 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
case SSM_RECEIVE_FINGER: {
|
case SSM_RECEIVE_FINGER: {
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
if (self->memory == 0) {
|
if (self->memory == 0)
|
||||||
|
{
|
||||||
/* Initialize fingerprint buffer */
|
/* Initialize fingerprint buffer */
|
||||||
g_free(self->lines_buffer);
|
g_free (self->lines_buffer);
|
||||||
self->memory = VFS_USB_BUFFER_SIZE;
|
self->memory = VFS_USB_BUFFER_SIZE;
|
||||||
self->lines_buffer = g_malloc(self->memory);
|
self->lines_buffer = g_malloc (self->memory);
|
||||||
self->bytes = 0;
|
self->bytes = 0;
|
||||||
|
|
||||||
/* Finger is on the scanner */
|
/* Finger is on the scanner */
|
||||||
fpi_image_device_report_finger_status(idev, TRUE);
|
fpi_image_device_report_finger_status (idev, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increase buffer size while it's insufficient */
|
/* Increase buffer size while it's insufficient */
|
||||||
while (self->bytes + VFS_USB_BUFFER_SIZE > self->memory) {
|
while (self->bytes + VFS_USB_BUFFER_SIZE > self->memory)
|
||||||
|
{
|
||||||
self->memory <<= 1;
|
self->memory <<= 1;
|
||||||
self->lines_buffer =
|
self->lines_buffer =
|
||||||
(struct vfs_line *)g_realloc(self->lines_buffer,
|
(struct vfs_line *) g_realloc (self->lines_buffer,
|
||||||
self->memory);
|
self->memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive chunk of data */
|
/* Receive chunk of data */
|
||||||
transfer = fpi_usb_transfer_new (dev);
|
transfer = fpi_usb_transfer_new (dev);
|
||||||
fpi_usb_transfer_fill_bulk_full(transfer, 0x82,
|
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
|
||||||
(void *)self->lines_buffer + self->bytes,
|
(void *) self->lines_buffer + self->bytes,
|
||||||
VFS_USB_BUFFER_SIZE, NULL);
|
VFS_USB_BUFFER_SIZE, NULL);
|
||||||
transfer->ssm = ssm;
|
transfer->ssm = ssm;
|
||||||
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
||||||
receive_callback, NULL);
|
receive_callback, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SSM_SUBMIT_IMAGE:
|
case SSM_SUBMIT_IMAGE:
|
||||||
submit_image(self);
|
submit_image (self);
|
||||||
clear_data(self);
|
clear_data (self);
|
||||||
|
|
||||||
/* Wait for probable vdev->active changing */
|
/* Wait for probable vdev->active changing */
|
||||||
fpi_device_add_timeout(dev, VFS_SSM_TIMEOUT,
|
fpi_device_add_timeout (dev, VFS_SSM_TIMEOUT,
|
||||||
fpi_ssm_next_state_timeout_cb, ssm);
|
fpi_ssm_next_state_timeout_cb, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_NEXT_RECEIVE:
|
case SSM_NEXT_RECEIVE:
|
||||||
if (!self->active) {
|
if (!self->active)
|
||||||
|
{
|
||||||
/* It's the last scan */
|
/* It's the last scan */
|
||||||
fpi_ssm_jump_to_state(ssm, SSM_CLEAR_EP2);
|
fpi_ssm_jump_to_state (ssm, SSM_CLEAR_EP2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set control_packet argument */
|
/* Set control_packet argument */
|
||||||
self->control_packet = next_receive_1;
|
self->control_packet = next_receive_1;
|
||||||
|
|
||||||
send_control_packet(ssm, dev);
|
send_control_packet (ssm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_WAIT_ANOTHER_SCAN:
|
case SSM_WAIT_ANOTHER_SCAN:
|
||||||
/* Orange light is on now */
|
/* Orange light is on now */
|
||||||
fpi_device_add_timeout(dev, VFS_SSM_ORANGE_TIMEOUT,
|
fpi_device_add_timeout (dev, VFS_SSM_ORANGE_TIMEOUT,
|
||||||
another_scan, ssm);
|
another_scan, ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fp_err("Unknown state");
|
fp_err ("Unknown state");
|
||||||
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Driver functions */
|
/* Driver functions */
|
||||||
|
|
||||||
/* Callback for dev_activate ssm */
|
/* Callback for dev_activate ssm */
|
||||||
static void dev_activate_callback(FpiSsm *ssm, FpDevice *dev,
|
static void
|
||||||
|
dev_activate_callback (FpiSsm *ssm, FpDevice *dev,
|
||||||
void *user_data, GError *error)
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(dev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (dev);
|
||||||
|
|
||||||
self->ssm_active = 0;
|
self->ssm_active = 0;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_warning ("Unhandled device activation error: %s", error->message);
|
g_warning ("Unhandled device activation error: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate device */
|
/* Activate device */
|
||||||
static void dev_activate(FpImageDevice *idev)
|
static void
|
||||||
|
dev_activate (FpImageDevice *idev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||||
|
|
||||||
/* Initialize flags */
|
/* Initialize flags */
|
||||||
self->active = 1;
|
self->active = 1;
|
||||||
self->need_report = 1;
|
self->need_report = 1;
|
||||||
self->ssm_active = 1;
|
self->ssm_active = 1;
|
||||||
|
|
||||||
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(idev), activate_ssm, SSM_STATES,
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES,
|
||||||
idev);
|
idev);
|
||||||
fpi_ssm_start(ssm, dev_activate_callback);
|
fpi_ssm_start (ssm, dev_activate_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deactivate device */
|
/* Deactivate device */
|
||||||
static void dev_deactivate(FpImageDevice *idev)
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *idev)
|
||||||
{
|
{
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||||
|
|
||||||
if (!self->ssm_active) {
|
if (!self->ssm_active)
|
||||||
fpi_image_device_deactivate_complete(idev, NULL);
|
{
|
||||||
|
fpi_image_device_deactivate_complete (idev, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,58 +710,65 @@ static void dev_deactivate(FpImageDevice *idev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback for dev_open ssm */
|
/* Callback for dev_open ssm */
|
||||||
static void dev_open_callback(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
static void
|
||||||
|
dev_open_callback (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
/* Notify open complete */
|
/* Notify open complete */
|
||||||
fpi_image_device_open_complete(FP_IMAGE_DEVICE (dev), error);
|
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), error);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open device */
|
/* Open device */
|
||||||
static void dev_open(FpImageDevice *idev)
|
static void
|
||||||
|
dev_open (FpImageDevice *idev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* Claim usb interface */
|
/* Claim usb interface */
|
||||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device(FP_DEVICE(idev)), 0, 0, &error)) {
|
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (idev)), 0, 0, &error))
|
||||||
|
{
|
||||||
fpi_image_device_open_complete (idev, error);
|
fpi_image_device_open_complete (idev, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clearing previous device state */
|
/* Clearing previous device state */
|
||||||
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(idev), activate_ssm, SSM_STATES, NULL);
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES, NULL);
|
||||||
fpi_ssm_start(ssm, dev_open_callback);
|
fpi_ssm_start (ssm, dev_open_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close device */
|
/* Close device */
|
||||||
static void dev_close(FpImageDevice *idev)
|
static void
|
||||||
|
dev_close (FpImageDevice *idev)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
|
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||||
|
|
||||||
clear_data(self);
|
clear_data (self);
|
||||||
|
|
||||||
/* Release usb interface */
|
/* Release usb interface */
|
||||||
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(idev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (idev)),
|
||||||
0, 0, &error);
|
0, 0, &error);
|
||||||
|
|
||||||
/* Notify close complete */
|
/* Notify close complete */
|
||||||
fpi_image_device_close_complete(idev, error);
|
fpi_image_device_close_complete (idev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Usb id table of device */
|
/* Usb id table of device */
|
||||||
static const FpIdEntry id_table [ ] = {
|
static const FpIdEntry id_table[] = {
|
||||||
{.vid = 0x138a, .pid = 0x0050,
|
{.vid = 0x138a, .pid = 0x0050, },
|
||||||
},
|
|
||||||
{.vid = 0, .pid = 0, .driver_data = 0},
|
{.vid = 0, .pid = 0, .driver_data = 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fpi_device_vfs0050_init(FpDeviceVfs0050 *self) {
|
static void
|
||||||
|
fpi_device_vfs0050_init (FpDeviceVfs0050 *self)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
static void fpi_device_vfs0050_class_init(FpDeviceVfs0050Class *klass) {
|
static void
|
||||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
fpi_device_vfs0050_class_init (FpDeviceVfs0050Class *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 = "vfs0050";
|
dev_class->id = "vfs0050";
|
||||||
dev_class->full_name = "Validity VFS0050";
|
dev_class->full_name = "Validity VFS0050";
|
||||||
|
|
|
@ -51,7 +51,8 @@
|
||||||
#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 */
|
/* It must be always 0x01 */
|
||||||
unsigned char _0x01;
|
unsigned char _0x01;
|
||||||
/* It must be always 0xfe */
|
/* It must be always 0xfe */
|
||||||
|
@ -75,10 +76,11 @@ struct vfs_line {
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,36 +30,37 @@ 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);
|
{
|
||||||
|
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||||
return 0;
|
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,
|
||||||
|
@ -71,14 +72,13 @@ submit_image(FpiSsm *ssm,
|
||||||
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,
|
||||||
|
@ -93,172 +93,191 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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:
|
case M_REQUEST_PRINT:
|
||||||
vfs301_proto_request_fingerprint(self);
|
vfs301_proto_request_fingerprint (self);
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state (ssm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_WAIT_PRINT:
|
case M_WAIT_PRINT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
async_sleep(200, ssm, dev);
|
async_sleep (200, ssm, 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);
|
{
|
||||||
|
fpi_ssm_mark_completed (ssm);
|
||||||
/* NOTE: finger off is expected only after submitting image... */
|
/* NOTE: finger off is expected only after submitting image... */
|
||||||
fpi_image_device_report_finger_status(dev, FALSE);
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
} else {
|
}
|
||||||
fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
|
else
|
||||||
|
{
|
||||||
|
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
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
|
||||||
|
m_loop_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_warning ("State machine completed with an error: %s", error->message);
|
g_warning ("State machine completed with an error: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
/* Free sequential state machine */
|
/* Free sequential state machine */
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free (ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exec init sequential state machine */
|
/* Exec init sequential state machine */
|
||||||
static void m_init_state(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
|
||||||
|
m_init_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||||
GError *error)
|
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";
|
||||||
|
|
|
@ -35,7 +35,8 @@ enum {
|
||||||
#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 */
|
||||||
|
@ -85,7 +86,8 @@ enum {
|
||||||
* 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_0x01;
|
||||||
unsigned char sync_0xfe;
|
unsigned char sync_0xfe;
|
||||||
|
|
||||||
|
@ -99,7 +101,8 @@ typedef struct {
|
||||||
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_0x01;
|
||||||
unsigned char sync_0xfe;
|
unsigned char sync_0xfe;
|
||||||
|
|
||||||
|
@ -124,14 +127,16 @@ typedef struct {
|
||||||
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);
|
||||||
|
|
|
@ -41,29 +41,33 @@
|
||||||
/************************** USB STUFF *****************************************/
|
/************************** USB STUFF *****************************************/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void usb_print_packet(int dir, GError *error, const guint8 *data, int length)
|
static void
|
||||||
|
usb_print_packet (int dir, GError *error, const guint8 *data, int length)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s, error %s, len %d\n", dir ? "send" : "recv", error ? error->message : "-", length);
|
fprintf (stderr, "%s, error %s, len %d\n", dir ? "send" : "recv", error ? error->message : "-", length);
|
||||||
|
|
||||||
#ifdef PRINT_VERBOSE
|
#ifdef PRINT_VERBOSE
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MIN(length, 128); i++) {
|
for (i = 0; i < MIN (length, 128); i++)
|
||||||
fprintf(stderr, "%.2X ", data[i]);
|
{
|
||||||
|
fprintf (stderr, "%.2X ", data[i]);
|
||||||
if (i % 8 == 7)
|
if (i % 8 == 7)
|
||||||
fprintf(stderr, " ");
|
fprintf (stderr, " ");
|
||||||
if (i % 32 == 31)
|
if (i % 32 == 31)
|
||||||
fprintf(stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void usb_recv(FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsbTransfer **out, GError **error)
|
static void
|
||||||
|
usb_recv (FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsbTransfer **out, GError **error)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||||
|
|
||||||
/* XXX: This function swallows any transfer errors, that is obviously
|
/* XXX: This function swallows any transfer errors, that is obviously
|
||||||
|
@ -77,11 +81,12 @@ static void usb_recv(FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsb
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
usb_print_packet(0, err, transfer->buffer, transfer->actual_length);
|
usb_print_packet (0, err, transfer->buffer, transfer->actual_length);
|
||||||
#endif
|
#endif
|
||||||
if (err) {
|
if (err)
|
||||||
|
{
|
||||||
if (!error)
|
if (!error)
|
||||||
g_warning("Unhandled receive error: %s", err->message);
|
g_warning ("Unhandled receive error: %s", err->message);
|
||||||
g_propagate_error (error, err);
|
g_propagate_error (error, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +94,11 @@ static void usb_recv(FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsb
|
||||||
*out = g_steal_pointer (&transfer);
|
*out = g_steal_pointer (&transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GError **error)
|
static void
|
||||||
|
usb_send (FpDeviceVfs301 *dev, const guint8 *data, gssize length, GError **error)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||||
|
|
||||||
/* XXX: This function swallows any transfer errors, that is obviously
|
/* XXX: This function swallows any transfer errors, that is obviously
|
||||||
|
@ -99,15 +106,16 @@ static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GEr
|
||||||
|
|
||||||
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
transfer->short_is_error = TRUE;
|
transfer->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_fill_bulk_full (transfer, VFS301_SEND_ENDPOINT, (guint8*) data, length, g_free);
|
fpi_usb_transfer_fill_bulk_full (transfer, VFS301_SEND_ENDPOINT, (guint8 *) data, length, g_free);
|
||||||
|
|
||||||
fpi_usb_transfer_submit_sync (transfer, VFS301_DEFAULT_WAIT_TIMEOUT, &err);
|
fpi_usb_transfer_submit_sync (transfer, VFS301_DEFAULT_WAIT_TIMEOUT, &err);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
usb_print_packet(1, err, data, length);
|
usb_print_packet (1, err, data, length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (err) {
|
if (err)
|
||||||
|
{
|
||||||
g_warning ("Error while sending data, continuing anyway: %s", err->message);
|
g_warning ("Error while sending data, continuing anyway: %s", err->message);
|
||||||
g_propagate_error (error, err);
|
g_propagate_error (error, err);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +123,8 @@ static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GEr
|
||||||
|
|
||||||
/************************** OUT MESSAGES GENERATION ***************************/
|
/************************** OUT MESSAGES GENERATION ***************************/
|
||||||
|
|
||||||
static guint8 * vfs301_proto_generate_0B(int subtype, gssize *len)
|
static guint8 *
|
||||||
|
vfs301_proto_generate_0B (int subtype, gssize *len)
|
||||||
{
|
{
|
||||||
guint8 *res = g_malloc0 (39);
|
guint8 *res = g_malloc0 (39);
|
||||||
guint8 *data = res;
|
guint8 *data = res;
|
||||||
|
@ -128,16 +137,19 @@ static guint8 * vfs301_proto_generate_0B(int subtype, gssize *len)
|
||||||
|
|
||||||
data[20] = subtype;
|
data[20] = subtype;
|
||||||
|
|
||||||
switch (subtype) {
|
switch (subtype)
|
||||||
|
{
|
||||||
case 0x04:
|
case 0x04:
|
||||||
data[34] = 0x9F;
|
data[34] = 0x9F;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x05:
|
case 0x05:
|
||||||
data[34] = 0xAB;
|
data[34] = 0xAB;
|
||||||
/* NOTE: There was a len++ here, which could never do anything */
|
/* NOTE: There was a len++ here, which could never do anything */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +159,8 @@ static guint8 * vfs301_proto_generate_0B(int subtype, gssize *len)
|
||||||
#define HEX_TO_INT(c) \
|
#define HEX_TO_INT(c) \
|
||||||
(((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10))
|
(((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10))
|
||||||
|
|
||||||
static guint8 * translate_str(const char **srcL, gssize *len)
|
static guint8 *
|
||||||
|
translate_str (const char **srcL, gssize *len)
|
||||||
{
|
{
|
||||||
guint8 *res = NULL;
|
guint8 *res = NULL;
|
||||||
guint8 *dst;
|
guint8 *dst;
|
||||||
|
@ -155,11 +168,12 @@ static guint8 * translate_str(const char **srcL, gssize *len)
|
||||||
const char *src;
|
const char *src;
|
||||||
gssize src_len = 0;
|
gssize src_len = 0;
|
||||||
|
|
||||||
for (src_pos = srcL; *src_pos; src_pos++) {
|
for (src_pos = srcL; *src_pos; src_pos++)
|
||||||
|
{
|
||||||
gint tmp;
|
gint tmp;
|
||||||
|
|
||||||
src = *src_pos;
|
src = *src_pos;
|
||||||
tmp = strlen(src);
|
tmp = strlen (src);
|
||||||
g_assert (tmp % 2 == 0);
|
g_assert (tmp % 2 == 0);
|
||||||
src_len += tmp;
|
src_len += tmp;
|
||||||
}
|
}
|
||||||
|
@ -168,18 +182,18 @@ static guint8 * translate_str(const char **srcL, gssize *len)
|
||||||
res = g_malloc0 (*len);
|
res = g_malloc0 (*len);
|
||||||
dst = res;
|
dst = res;
|
||||||
|
|
||||||
for (src_pos = srcL; *src_pos; src_pos++) {
|
for (src_pos = srcL; *src_pos; src_pos++)
|
||||||
for (src = *src_pos; *src; src += 2, dst += 1) {
|
for (src = *src_pos; *src; src += 2, dst += 1)
|
||||||
*dst = (guint8) ((HEX_TO_INT (src[0]) << 4) | (HEX_TO_INT (src[1])));
|
*dst = (guint8) ((HEX_TO_INT (src[0]) << 4) | (HEX_TO_INT (src[1])));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
static guint8 *
|
||||||
|
vfs301_proto_generate (int type, int subtype, gssize *len)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type)
|
||||||
|
{
|
||||||
case 0x01:
|
case 0x01:
|
||||||
case 0x04:
|
case 0x04:
|
||||||
/* After cmd 0x04 is sent, a data is received on VALIDITY_RECEIVE_ENDPOINT_CTRL.
|
/* After cmd 0x04 is sent, a data is received on VALIDITY_RECEIVE_ENDPOINT_CTRL.
|
||||||
|
@ -199,9 +213,11 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
return vfs301_proto_generate_0B(subtype, len);
|
return vfs301_proto_generate_0B (subtype, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02D0:
|
case 0x02D0:
|
||||||
{
|
{
|
||||||
const char **dataLs[] = {
|
const char **dataLs[] = {
|
||||||
|
@ -213,55 +229,62 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
||||||
vfs301_02D0_06,
|
vfs301_02D0_06,
|
||||||
vfs301_02D0_07,
|
vfs301_02D0_07,
|
||||||
};
|
};
|
||||||
g_assert((int)subtype <= G_N_ELEMENTS (dataLs));
|
g_assert ((int) subtype <= G_N_ELEMENTS (dataLs));
|
||||||
return translate_str(dataLs[subtype - 1], len);
|
return translate_str (dataLs[subtype - 1], len);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0220:
|
case 0x0220:
|
||||||
switch (subtype) {
|
switch (subtype)
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return translate_str(vfs301_0220_01, len);
|
return translate_str (vfs301_0220_01, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return translate_str(vfs301_0220_02, len);
|
return translate_str (vfs301_0220_02, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
return translate_str(vfs301_0220_03, len);
|
return translate_str (vfs301_0220_03, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFA00:
|
case 0xFA00:
|
||||||
case 0x2C01:
|
case 0x2C01:
|
||||||
case 0x5E01: {
|
case 0x5E01: {
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint8 *field;
|
guint8 *field;
|
||||||
|
|
||||||
data = translate_str(vfs301_next_scan_template, len);
|
data = translate_str (vfs301_next_scan_template, len);
|
||||||
field = data + *len - (sizeof(S4_TAIL) - 1) / 2 - 4;
|
field = data + *len - (sizeof (S4_TAIL) - 1) / 2 - 4;
|
||||||
|
|
||||||
g_assert (field >= data && field < data + *len);
|
g_assert (field >= data && field < data + *len);
|
||||||
g_assert(field[0] == 0xDE);
|
g_assert (field[0] == 0xDE);
|
||||||
g_assert(field[1] == 0xAD);
|
g_assert (field[1] == 0xAD);
|
||||||
g_assert(field[2] == 0xDE);
|
g_assert (field[2] == 0xDE);
|
||||||
g_assert(field[3] == 0xAD);
|
g_assert (field[3] == 0xAD);
|
||||||
|
|
||||||
field[0] = (guint8)((subtype >> 8) & 0xFF);
|
field[0] = (guint8) ((subtype >> 8) & 0xFF);
|
||||||
field[1] = (guint8)(subtype & 0xFF);
|
field[1] = (guint8) (subtype & 0xFF);
|
||||||
field[2] = field[0];
|
field[2] = field[0];
|
||||||
field[3] = field[1];
|
field[3] = field[1];
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x06:
|
case 0x06:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_not_reached();
|
g_assert_not_reached ();
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -269,25 +292,27 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
||||||
/************************** SCAN IMAGE PROCESSING *****************************/
|
/************************** SCAN IMAGE PROCESSING *****************************/
|
||||||
|
|
||||||
#ifdef SCAN_FINISH_DETECTION
|
#ifdef SCAN_FINISH_DETECTION
|
||||||
static int img_is_finished_scan(fp_line_t *lines, int no_lines)
|
static int
|
||||||
|
img_is_finished_scan (fp_line_t *lines, int no_lines)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int rv = 1;
|
int rv = 1;
|
||||||
|
|
||||||
for (i = no_lines - VFS301_FP_SUM_LINES; i < no_lines; i++) {
|
for (i = no_lines - VFS301_FP_SUM_LINES; i < no_lines; i++)
|
||||||
|
{
|
||||||
/* check the line for fingerprint data */
|
/* check the line for fingerprint data */
|
||||||
for (j = 0; j < sizeof(lines[i].sum2); j++) {
|
for (j = 0; j < sizeof (lines[i].sum2); j++)
|
||||||
if (lines[i].sum2[j] > (VFS301_FP_SUM_MEDIAN + VFS301_FP_SUM_EMPTY_RANGE))
|
if (lines[i].sum2[j] > (VFS301_FP_SUM_MEDIAN + VFS301_FP_SUM_EMPTY_RANGE))
|
||||||
rv = 0;
|
rv = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int scanline_diff(const guint8 *scanlines, int prev, int cur)
|
static int
|
||||||
|
scanline_diff (const guint8 *scanlines, int prev, int cur)
|
||||||
{
|
{
|
||||||
const guint8 *line1 = scanlines + prev * VFS301_FP_OUTPUT_WIDTH;
|
const guint8 *line1 = scanlines + prev * VFS301_FP_OUTPUT_WIDTH;
|
||||||
const guint8 *line2 = scanlines + cur * VFS301_FP_OUTPUT_WIDTH;
|
const guint8 *line2 = scanlines + cur * VFS301_FP_OUTPUT_WIDTH;
|
||||||
|
@ -296,13 +321,14 @@ static int scanline_diff(const guint8 *scanlines, int prev, int cur)
|
||||||
|
|
||||||
#ifdef OUTPUT_RAW
|
#ifdef OUTPUT_RAW
|
||||||
/* We only need the image, not the surrounding stuff. */
|
/* We only need the image, not the surrounding stuff. */
|
||||||
line1 = ((vfs301_line_t*)line1)->scan;
|
line1 = ((vfs301_line_t *) line1)->scan;
|
||||||
line2 = ((vfs301_line_t*)line2)->scan;
|
line2 = ((vfs301_line_t *) line2)->scan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: This doesn't work too well when there are parallel lines in the
|
/* TODO: This doesn't work too well when there are parallel lines in the
|
||||||
* fingerprint. */
|
* fingerprint. */
|
||||||
for (diff = 0, i = 0; i < VFS301_FP_WIDTH; i++) {
|
for (diff = 0, i = 0; i < VFS301_FP_WIDTH; i++)
|
||||||
|
{
|
||||||
if (*line1 > *line2)
|
if (*line1 > *line2)
|
||||||
diff += *line1 - *line2;
|
diff += *line1 - *line2;
|
||||||
else
|
else
|
||||||
|
@ -312,21 +338,22 @@ static int scanline_diff(const guint8 *scanlines, int prev, int cur)
|
||||||
line2++;
|
line2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((diff / VFS301_FP_WIDTH) > VFS301_FP_LINE_DIFF_THRESHOLD);
|
return (diff / VFS301_FP_WIDTH) > VFS301_FP_LINE_DIFF_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Transform the input data to a normalized fingerprint scan */
|
/** Transform the input data to a normalized fingerprint scan */
|
||||||
void vfs301_extract_image(FpDeviceVfs301 *vfs, guint8 *output, int *output_height
|
void
|
||||||
)
|
vfs301_extract_image (FpDeviceVfs301 *vfs, guint8 *output, int *output_height
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const guint8 *scanlines = vfs->scanline_buf;
|
const guint8 *scanlines = vfs->scanline_buf;
|
||||||
int last_line;
|
int last_line;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_assert(vfs->scanline_count >= 1);
|
g_assert (vfs->scanline_count >= 1);
|
||||||
|
|
||||||
*output_height = 1;
|
*output_height = 1;
|
||||||
memcpy(output, scanlines, VFS301_FP_OUTPUT_WIDTH);
|
memcpy (output, scanlines, VFS301_FP_OUTPUT_WIDTH);
|
||||||
last_line = 0;
|
last_line = 0;
|
||||||
|
|
||||||
/* The following algorithm is quite trivial - it just picks lines that
|
/* The following algorithm is quite trivial - it just picks lines that
|
||||||
|
@ -335,9 +362,11 @@ void vfs301_extract_image(FpDeviceVfs301 *vfs, guint8 *output, int *output_heigh
|
||||||
* of bi/tri-linear resampling to get the output (so that we don't get so
|
* of bi/tri-linear resampling to get the output (so that we don't get so
|
||||||
* many false edges etc.).
|
* many false edges etc.).
|
||||||
*/
|
*/
|
||||||
for (i = 1; i < vfs->scanline_count; i++) {
|
for (i = 1; i < vfs->scanline_count; i++)
|
||||||
if (scanline_diff(scanlines, last_line, i)) {
|
{
|
||||||
memcpy(
|
if (scanline_diff (scanlines, last_line, i))
|
||||||
|
{
|
||||||
|
memcpy (
|
||||||
output + VFS301_FP_OUTPUT_WIDTH * (*output_height),
|
output + VFS301_FP_OUTPUT_WIDTH * (*output_height),
|
||||||
scanlines + VFS301_FP_OUTPUT_WIDTH * i,
|
scanlines + VFS301_FP_OUTPUT_WIDTH * i,
|
||||||
VFS301_FP_OUTPUT_WIDTH
|
VFS301_FP_OUTPUT_WIDTH
|
||||||
|
@ -348,41 +377,47 @@ void vfs301_extract_image(FpDeviceVfs301 *vfs, guint8 *output, int *output_heigh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int len)
|
static int
|
||||||
|
img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int len)
|
||||||
{
|
{
|
||||||
vfs301_line_t *lines = (vfs301_line_t*)buf;
|
vfs301_line_t *lines = (vfs301_line_t *) buf;
|
||||||
int no_lines = len / sizeof(vfs301_line_t);
|
int no_lines = len / sizeof (vfs301_line_t);
|
||||||
int i;
|
int i;
|
||||||
/*int no_nonempty;*/
|
/*int no_nonempty;*/
|
||||||
guint8 *cur_line;
|
guint8 *cur_line;
|
||||||
int last_img_height;
|
int last_img_height;
|
||||||
|
|
||||||
#ifdef SCAN_FINISH_DETECTION
|
#ifdef SCAN_FINISH_DETECTION
|
||||||
int finished_scan;
|
int finished_scan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (first_block) {
|
if (first_block)
|
||||||
|
{
|
||||||
last_img_height = 0;
|
last_img_height = 0;
|
||||||
dev->scanline_count = no_lines;
|
dev->scanline_count = no_lines;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
last_img_height = dev->scanline_count;
|
last_img_height = dev->scanline_count;
|
||||||
dev->scanline_count += no_lines;
|
dev->scanline_count += no_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->scanline_buf = g_realloc(dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH);
|
dev->scanline_buf = g_realloc (dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH);
|
||||||
|
|
||||||
for (cur_line = dev->scanline_buf + last_img_height * VFS301_FP_OUTPUT_WIDTH, i = 0;
|
for (cur_line = dev->scanline_buf + last_img_height * VFS301_FP_OUTPUT_WIDTH, i = 0;
|
||||||
i < no_lines;
|
i < no_lines;
|
||||||
i++, cur_line += VFS301_FP_OUTPUT_WIDTH
|
i++, cur_line += VFS301_FP_OUTPUT_WIDTH
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
#ifndef OUTPUT_RAW
|
#ifndef OUTPUT_RAW
|
||||||
memcpy(cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH);
|
memcpy (cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH);
|
||||||
#else
|
#else
|
||||||
memcpy(cur_line, &lines[i], VFS301_FP_OUTPUT_WIDTH);
|
memcpy (cur_line, &lines[i], VFS301_FP_OUTPUT_WIDTH);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCAN_FINISH_DETECTION
|
#ifdef SCAN_FINISH_DETECTION
|
||||||
finished_scan = img_is_finished_scan(lines, no_lines);
|
finished_scan = img_is_finished_scan (lines, no_lines);
|
||||||
|
|
||||||
return !finished_scan;
|
return !finished_scan;
|
||||||
#else /* SCAN_FINISH_DETECTION */
|
#else /* SCAN_FINISH_DETECTION */
|
||||||
|
@ -393,44 +428,47 @@ static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *
|
||||||
/************************** PROTOCOL STUFF ************************************/
|
/************************** PROTOCOL STUFF ************************************/
|
||||||
|
|
||||||
#define USB_RECV(from, len) \
|
#define USB_RECV(from, len) \
|
||||||
usb_recv(dev, from, len, NULL, NULL)
|
usb_recv (dev, from, len, NULL, NULL)
|
||||||
|
|
||||||
#define USB_SEND(type, subtype) \
|
#define USB_SEND(type, subtype) \
|
||||||
{ \
|
{ \
|
||||||
const guint8 *data; \
|
const guint8 *data; \
|
||||||
gssize len; \
|
gssize len; \
|
||||||
data = vfs301_proto_generate(type, subtype, &len); \
|
data = vfs301_proto_generate (type, subtype, &len); \
|
||||||
usb_send(dev, data, len, NULL); \
|
usb_send (dev, data, len, NULL); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAW_DATA(x) x, sizeof(x)
|
#define RAW_DATA(x) x, sizeof (x)
|
||||||
|
|
||||||
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))
|
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))
|
||||||
|
|
||||||
static int vfs301_proto_process_data(FpDeviceVfs301 *dev, int first_block, const guint8 *buf, gint len)
|
static int
|
||||||
|
vfs301_proto_process_data (FpDeviceVfs301 *dev, int first_block, const guint8 *buf, gint len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (first_block) {
|
if (first_block)
|
||||||
g_assert(len >= VFS301_FP_FRAME_SIZE);
|
{
|
||||||
|
g_assert (len >= VFS301_FP_FRAME_SIZE);
|
||||||
|
|
||||||
/* Skip bytes until start_sequence is found */
|
/* Skip bytes until start_sequence is found */
|
||||||
for (i = 0; i < VFS301_FP_FRAME_SIZE; i++, buf++, len--) {
|
for (i = 0; i < VFS301_FP_FRAME_SIZE; i++, buf++, len--)
|
||||||
if (IS_VFS301_FP_SEQ_START(buf))
|
if (IS_VFS301_FP_SEQ_START (buf))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return img_process_data(first_block, dev, buf, len);
|
return img_process_data (first_block, dev, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfs301_proto_request_fingerprint(FpDeviceVfs301 *dev)
|
void
|
||||||
|
vfs301_proto_request_fingerprint (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
USB_SEND(0x0220, 0xFA00);
|
USB_SEND (0x0220, 0xFA00);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 000000000000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 000000000000 */
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
|
int
|
||||||
|
vfs301_proto_peek_event (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||||
|
@ -438,19 +476,18 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
|
||||||
const char no_event[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
const char no_event[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00};
|
const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
USB_SEND(0x17, -1);
|
USB_SEND (0x17, -1);
|
||||||
usb_recv (dev, VFS301_RECEIVE_ENDPOINT_CTRL, 7, &transfer, &error);
|
usb_recv (dev, VFS301_RECEIVE_ENDPOINT_CTRL, 7, &transfer, &error);
|
||||||
|
|
||||||
/* XXX: This is obviously not a sane error handling! */
|
/* XXX: This is obviously not a sane error handling! */
|
||||||
g_assert (!error);
|
g_assert (!error);
|
||||||
|
|
||||||
if (memcmp(transfer->buffer, no_event, sizeof(no_event)) == 0) {
|
if (memcmp (transfer->buffer, no_event, sizeof (no_event)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else if (memcmp(transfer->buffer, got_event, sizeof(no_event)) == 0) {
|
else if (memcmp (transfer->buffer, got_event, sizeof (no_event)) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
else
|
||||||
g_assert_not_reached();
|
g_assert_not_reached ();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: We sometimes need to receive data on from two endpoints at the same
|
/* XXX: We sometimes need to receive data on from two endpoints at the same
|
||||||
|
@ -459,49 +496,57 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
|
||||||
*/
|
*/
|
||||||
#define PARALLEL_RECEIVE(e1, l1, e2, l2) \
|
#define PARALLEL_RECEIVE(e1, l1, e2, l2) \
|
||||||
{ \
|
{ \
|
||||||
g_autoptr(GError) error = NULL;\
|
g_autoptr(GError) error = NULL; \
|
||||||
usb_recv(dev, e1, l1, NULL, &error); \
|
usb_recv (dev, e1, l1, NULL, &error); \
|
||||||
usb_recv(dev, e2, l2, NULL, NULL); \
|
usb_recv (dev, e2, l2, NULL, NULL); \
|
||||||
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
|
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
|
||||||
usb_recv(dev, e1, l1, NULL, NULL); \
|
usb_recv(dev, e1, l1, NULL, NULL); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfs301_proto_process_event_cb(FpiUsbTransfer *transfer,
|
static void
|
||||||
|
vfs301_proto_process_event_cb (FpiUsbTransfer *transfer,
|
||||||
FpDevice *device,
|
FpDevice *device,
|
||||||
gpointer user_data, GError *error)
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpDeviceVfs301 *dev = user_data;
|
FpDeviceVfs301 *dev = user_data;
|
||||||
|
|
||||||
if (error) {
|
if (error)
|
||||||
|
{
|
||||||
g_warning ("Error receiving data: %s", error->message);
|
g_warning ("Error receiving data: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
dev->recv_progress = VFS301_FAILURE;
|
dev->recv_progress = VFS301_FAILURE;
|
||||||
return;
|
return;
|
||||||
} else if (transfer->actual_length < transfer->length) {
|
}
|
||||||
|
else if (transfer->actual_length < transfer->length)
|
||||||
|
{
|
||||||
/* TODO: process the data anyway? */
|
/* TODO: process the data anyway? */
|
||||||
dev->recv_progress = VFS301_ENDED;
|
dev->recv_progress = VFS301_ENDED;
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FpiUsbTransfer *new;
|
FpiUsbTransfer *new;
|
||||||
if (!vfs301_proto_process_data(dev,
|
if (!vfs301_proto_process_data (dev,
|
||||||
transfer->length == VFS301_FP_RECV_LEN_1,
|
transfer->length == VFS301_FP_RECV_LEN_1,
|
||||||
transfer->buffer,
|
transfer->buffer,
|
||||||
transfer->actual_length)) {
|
transfer->actual_length))
|
||||||
|
{
|
||||||
dev->recv_progress = VFS301_ENDED;
|
dev->recv_progress = VFS301_ENDED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = fpi_usb_transfer_new (device);
|
new = fpi_usb_transfer_new (device);
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk(new, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_2);
|
fpi_usb_transfer_fill_bulk (new, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_2);
|
||||||
fpi_usb_transfer_submit(new, VFS301_FP_RECV_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (new, VFS301_FP_RECV_TIMEOUT, NULL,
|
||||||
vfs301_proto_process_event_cb, NULL);
|
vfs301_proto_process_event_cb, NULL);
|
||||||
fpi_usb_transfer_unref (new);
|
fpi_usb_transfer_unref (new);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
|
void
|
||||||
|
vfs301_proto_process_event_start (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
|
|
||||||
|
@ -526,35 +571,36 @@ void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
|
||||||
* o FA00
|
* o FA00
|
||||||
* o 2C01
|
* o 2C01
|
||||||
*/
|
*/
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 64);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 64);
|
||||||
|
|
||||||
/* now read the fingerprint data, while there are some */
|
/* now read the fingerprint data, while there are some */
|
||||||
transfer = fpi_usb_transfer_new(FP_DEVICE (dev));
|
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
dev->recv_progress = VFS301_ONGOING;
|
dev->recv_progress = VFS301_ONGOING;
|
||||||
|
|
||||||
fpi_usb_transfer_fill_bulk (transfer, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_1);
|
fpi_usb_transfer_fill_bulk (transfer, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_1);
|
||||||
fpi_usb_transfer_submit(transfer, VFS301_FP_RECV_TIMEOUT, NULL,
|
fpi_usb_transfer_submit (transfer, VFS301_FP_RECV_TIMEOUT, NULL,
|
||||||
vfs301_proto_process_event_cb, NULL);
|
vfs301_proto_process_event_cb, NULL);
|
||||||
fpi_usb_transfer_unref(transfer);
|
fpi_usb_transfer_unref (transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev)
|
int
|
||||||
|
vfs301_proto_process_event_poll (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
if (dev->recv_progress != VFS301_ENDED)
|
if (dev->recv_progress != VFS301_ENDED)
|
||||||
return dev->recv_progress;
|
return dev->recv_progress;
|
||||||
|
|
||||||
/* Finish the scan process... */
|
/* Finish the scan process... */
|
||||||
|
|
||||||
USB_SEND(0x04, -1);
|
USB_SEND (0x04, -1);
|
||||||
/* the following may come in random order, data may not come at all, don't
|
/* the following may come in random order, data may not come at all, don't
|
||||||
* try for too long... */
|
* try for too long... */
|
||||||
PARALLEL_RECEIVE(
|
PARALLEL_RECEIVE (
|
||||||
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 1204 */
|
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 1204 */
|
||||||
VFS301_RECEIVE_ENDPOINT_DATA, 16384
|
VFS301_RECEIVE_ENDPOINT_DATA, 16384
|
||||||
);
|
);
|
||||||
|
|
||||||
USB_SEND(0x0220, 2);
|
USB_SEND (0x0220, 2);
|
||||||
PARALLEL_RECEIVE(
|
PARALLEL_RECEIVE (
|
||||||
VFS301_RECEIVE_ENDPOINT_DATA, 5760, /* seems to always come */
|
VFS301_RECEIVE_ENDPOINT_DATA, 5760, /* seems to always come */
|
||||||
VFS301_RECEIVE_ENDPOINT_CTRL, 2 /* 0000 */
|
VFS301_RECEIVE_ENDPOINT_CTRL, 2 /* 0000 */
|
||||||
);
|
);
|
||||||
|
@ -562,92 +608,94 @@ int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev)
|
||||||
return dev->recv_progress;
|
return dev->recv_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfs301_proto_init(FpDeviceVfs301 *dev)
|
void
|
||||||
|
vfs301_proto_init (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
USB_SEND(0x01, -1);
|
USB_SEND (0x01, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
||||||
USB_SEND(0x0B, 0x04);
|
USB_SEND (0x0B, 0x04);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 6); /* 000000000000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 6); /* 000000000000 */
|
||||||
USB_SEND(0x0B, 0x05);
|
USB_SEND (0x0B, 0x05);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7); /* 00000000000000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 7); /* 00000000000000 */
|
||||||
USB_SEND(0x19, -1);
|
USB_SEND (0x19, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 64);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 64);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 4); /* 6BB4D0BC */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 4); /* 6BB4D0BC */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_1), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_1), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
|
|
||||||
USB_SEND(0x01, -1);
|
USB_SEND (0x01, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
||||||
USB_SEND(0x1A, -1);
|
USB_SEND (0x1A, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_2), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_2), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_SEND(0x0220, 1);
|
USB_SEND (0x0220, 1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 256);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 256);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 32);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 32);
|
||||||
|
|
||||||
USB_SEND(0x1A, -1);
|
USB_SEND (0x1A, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_3), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_3), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
|
|
||||||
USB_SEND(0x01, -1);
|
USB_SEND (0x01, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
||||||
USB_SEND(0x02D0, 1);
|
USB_SEND (0x02D0, 1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 11648); /* 56 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 11648); /* 56 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 2);
|
USB_SEND (0x02D0, 2);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 53248); /* 2 * 128 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 53248); /* 2 * 128 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 3);
|
USB_SEND (0x02D0, 3);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 19968); /* 96 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 19968); /* 96 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 4);
|
USB_SEND (0x02D0, 4);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5824); /* 28 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 5824); /* 28 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 5);
|
USB_SEND (0x02D0, 5);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 6);
|
USB_SEND (0x02D0, 6);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
|
||||||
USB_SEND(0x02D0, 7);
|
USB_SEND (0x02D0, 7);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 832);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 832);
|
||||||
usb_send(dev, RAW_DATA(vfs301_12), NULL);
|
usb_send (dev, RAW_DATA (vfs301_12), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
|
|
||||||
USB_SEND(0x1A, -1);
|
USB_SEND (0x1A, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_2), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_2), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
USB_SEND(0x0220, 2);
|
USB_SEND (0x0220, 2);
|
||||||
PARALLEL_RECEIVE(
|
PARALLEL_RECEIVE (
|
||||||
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 0000 */
|
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 0000 */
|
||||||
VFS301_RECEIVE_ENDPOINT_DATA, 5760
|
VFS301_RECEIVE_ENDPOINT_DATA, 5760
|
||||||
);
|
);
|
||||||
|
|
||||||
USB_SEND(0x1A, -1);
|
USB_SEND (0x1A, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_1), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_1), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
|
|
||||||
USB_SEND(0x1A, -1);
|
USB_SEND (0x1A, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_06_4), NULL);
|
usb_send (dev, RAW_DATA (vfs301_06_4), NULL);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
usb_send(dev, RAW_DATA(vfs301_24), NULL); /* turns on white */
|
usb_send (dev, RAW_DATA (vfs301_24), NULL); /* turns on white */
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
|
||||||
|
|
||||||
USB_SEND(0x01, -1);
|
USB_SEND (0x01, -1);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
||||||
USB_SEND(0x0220, 3);
|
USB_SEND (0x0220, 3);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2368);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2368);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 36);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 36);
|
||||||
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5760);
|
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 5760);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfs301_proto_deinit(FpDeviceVfs301 *dev)
|
void
|
||||||
|
vfs301_proto_deinit (FpDeviceVfs301 *dev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -36,7 +36,8 @@
|
||||||
#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;
|
||||||
|
@ -54,7 +55,8 @@ G_DECLARE_FINAL_TYPE (FpDeviceVirtualImage, fpi_device_virtual_image, FPI, DEVIC
|
||||||
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,
|
||||||
|
@ -68,8 +70,10 @@ recv_image_img_recv_cb (GObject *source_object,
|
||||||
|
|
||||||
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) {
|
{
|
||||||
|
if (bytes < 0)
|
||||||
|
{
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
g_warning ("Error receiving header for image data: %s", error->message);
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
return;
|
return;
|
||||||
|
@ -89,7 +93,7 @@ recv_image_img_recv_cb (GObject *source_object,
|
||||||
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
|
||||||
|
@ -103,8 +107,10 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||||
|
|
||||||
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) {
|
{
|
||||||
|
if (bytes < 0)
|
||||||
|
{
|
||||||
g_warning ("Error receiving header for image data: %s", error->message);
|
g_warning ("Error receiving header for image data: %s", error->message);
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
return;
|
return;
|
||||||
|
@ -117,14 +123,17 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
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_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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]) {
|
{
|
||||||
|
switch (self->recv_img_hdr[0])
|
||||||
|
{
|
||||||
case -1:
|
case -1:
|
||||||
/* -1 is a retry error, just pass it through */
|
/* -1 is a retry error, just pass it through */
|
||||||
fpi_image_device_retry_scan (FP_IMAGE_DEVICE (self), self->recv_img_hdr[1]);
|
fpi_image_device_retry_scan (FP_IMAGE_DEVICE (self), self->recv_img_hdr[1]);
|
||||||
|
@ -143,14 +152,14 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
||||||
|
@ -163,7 +172,7 @@ 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,
|
||||||
|
@ -182,18 +191,20 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
|
||||||
res,
|
res,
|
||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);
|
||||||
if (!connection) {
|
if (!connection)
|
||||||
|
{
|
||||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
return;
|
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);
|
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +214,7 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
|
||||||
|
|
||||||
recv_image (dev, stream);
|
recv_image (dev, stream);
|
||||||
|
|
||||||
fp_dbg("Got a new connection!");
|
fp_dbg ("Got a new connection!");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -216,14 +227,14 @@ start_listen (FpDeviceVirtualImage *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;
|
||||||
|
|
||||||
|
@ -243,7 +254,8 @@ dev_init(FpImageDevice *dev)
|
||||||
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));
|
||||||
|
@ -259,18 +271,19 @@ dev_init(FpImageDevice *dev)
|
||||||
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
|
||||||
|
@ -297,4 +310,3 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
|
||||||
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,7 +26,8 @@
|
||||||
#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 x;
|
||||||
int y;
|
int y;
|
||||||
int ex;
|
int ex;
|
||||||
|
@ -42,7 +43,8 @@ struct fp_minutia {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fp_minutiae structure definition */
|
/* fp_minutiae structure definition */
|
||||||
struct fp_minutiae {
|
struct fp_minutiae
|
||||||
|
{
|
||||||
int alloc;
|
int alloc;
|
||||||
int num;
|
int num;
|
||||||
struct fp_minutia **list;
|
struct fp_minutia **list;
|
||||||
|
|
|
@ -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,7 +43,8 @@ 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);
|
g_type_class_unref (cls);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +55,8 @@ 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);
|
g_free (key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +72,8 @@ static GList *insert_drivers (GList *list)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GList *list, *l;
|
GList *list, *l;
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@ static const FpDeviceClass 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;
|
||||||
|
@ -56,21 +57,22 @@ static void print_driver (const FpDeviceClass *cls)
|
||||||
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;
|
const FpIdEntry *bl_entry;
|
||||||
char *key;
|
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)
|
if (bl_entry->vid != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
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);
|
g_free (key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -91,9 +93,10 @@ static void print_driver (const FpDeviceClass *cls)
|
||||||
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);
|
||||||
|
@ -102,11 +105,13 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
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);
|
GType driver = g_array_index (drivers, GType, i);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
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);
|
g_type_class_unref (cls);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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