Uncrustify everything except for nbis

This commit is contained in:
Marco Trevisan (Treviño) 2019-11-19 21:13:11 +01:00 committed by Benjamin Berg
parent fd5f511b33
commit d1fb1e26f3
60 changed files with 30386 additions and 28683 deletions

View file

@ -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,13 +99,15 @@ 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;
@ -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;
} }
@ -199,13 +205,16 @@ libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
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,9 +264,11 @@ 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;
@ -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 ();
} }
@ -490,18 +510,21 @@ 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;

View file

@ -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;
@ -40,6 +41,7 @@ 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;
@ -49,8 +51,10 @@ FpDevice *discover_device (GPtrArray *devices)
} }
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,25 +66,32 @@ 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"); g_debug ("Device has not storage, saving locally");
int r = print_data_save (print, FP_FINGER_RIGHT_INDEX); int r = print_data_save (print, FP_FINGER_RIGHT_INDEX);
if (r < 0) { if (r < 0)
{
g_warning ("Data save failed, code %d", r); g_warning ("Data save failed, code %d", r);
enroll_data->ret_value = EXIT_FAILURE; enroll_data->ret_value = EXIT_FAILURE;
} }
} }
} else { }
else
{
g_warning ("Enroll failed with error %s\n", error->message); g_warning ("Enroll failed with error %s\n", error->message);
} }
@ -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,7 +149,8 @@ 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;
@ -154,13 +168,15 @@ 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;
} }

View file

@ -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;
@ -162,7 +164,9 @@ on_print_deleted (FpDevice *dev,
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;
@ -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);

View file

@ -34,10 +34,13 @@ 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);
} }
@ -56,7 +59,8 @@ load_data(void)
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);
} }
@ -77,7 +81,8 @@ save_data(GVariant *data)
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;
} }
@ -92,6 +97,7 @@ 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(GError) error = NULL;
g_autoptr(GVariantDict) dict = NULL; g_autoptr(GVariantDict) dict = NULL;
g_autofree guchar *data = NULL; g_autofree guchar *data = NULL;
@ -102,7 +108,8 @@ print_data_save(FpPrint *print, FpFinger finger)
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;
} }
@ -118,6 +125,7 @@ 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(GVariant) val = NULL;
g_autoptr(GVariantDict) dict = NULL; g_autoptr(GVariantDict) dict = NULL;
g_autofree guchar *stored_data = NULL; g_autofree guchar *stored_data = NULL;
@ -126,7 +134,8 @@ print_data_load(FpDevice *dev, FpFinger finger)
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;
@ -171,21 +180,24 @@ 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); fclose (fd);
g_critical ("pgm header write failed, error %d", r); 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); fclose (fd);
g_critical ("short write (%d)", r); 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;

View file

@ -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 */

View file

@ -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;
@ -40,6 +41,7 @@ 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;
@ -49,8 +51,10 @@ FpDevice *discover_device (GPtrArray *devices)
} }
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,7 +219,8 @@ 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;
@ -209,13 +233,15 @@ 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;
} }

View file

@ -30,7 +30,8 @@
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;
@ -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,7 +118,8 @@ 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)
@ -120,10 +128,12 @@ static void generic_ignore_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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
@ -132,7 +142,8 @@ static void generic_write_regv_cb(FpImageDevice *dev, GError *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);
@ -177,7 +188,8 @@ static const struct aes_regwrite finger_det_reqs[] = {
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);
@ -185,7 +197,8 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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,24 +206,29 @@ 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;
} }
@ -223,11 +241,13 @@ static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
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;
} }
@ -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;
@ -435,12 +461,13 @@ static int adjust_gain(unsigned char *buffer, int status)
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--;
@ -495,7 +525,8 @@ static int adjust_gain(unsigned char *buffer, int status)
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,7 +564,8 @@ 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;
@ -541,7 +574,8 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
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,14 +584,13 @@ 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;
@ -567,7 +600,9 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
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? */
@ -582,7 +617,8 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
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",
@ -603,27 +639,33 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
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)
@ -632,6 +674,7 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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 = fpi_usb_transfer_new (_dev); FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
@ -642,34 +685,43 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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) { }
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)
{ {
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;
} }
@ -697,13 +749,15 @@ enum activate_states {
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);
@ -712,10 +766,12 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
/* 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)
@ -723,26 +779,32 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_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.
@ -756,12 +818,15 @@ static void complete_deactivation(FpImageDevice *dev)
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;
} }
@ -769,7 +834,8 @@ static void 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)
{ {
GError *error = NULL; GError *error = NULL;
@ -779,14 +845,17 @@ static void dev_deinit(FpImageDevice *dev)
} }
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
fpi_device_aes1610_class_init (FpiDeviceAes1610Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
@ -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;
} }

View file

@ -27,7 +27,8 @@
#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,
@ -62,9 +63,13 @@ 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
fpi_device_aes1660_class_init (FpiDeviceAes1660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass); FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);

View file

@ -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;
@ -83,17 +84,21 @@ 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;
@ -102,13 +107,15 @@ static void read_regs_data_cb(FpiUsbTransfer *transfer, FpDevice *dev,
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;
@ -122,7 +129,8 @@ static void read_regs_rq_cb(FpImageDevice *dev, GError *error, void *user_data)
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
@ -143,14 +151,17 @@ static void read_regs(FpImageDevice *dev, aes2501_read_regs_cb callback,
} }
/* 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,10 +171,12 @@ 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
@ -171,10 +184,12 @@ static void generic_write_regv_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 *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
@ -183,7 +198,8 @@ static void generic_ignore_data_cb(FpiUsbTransfer *transfer, FpDevice *dev,
/* 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;
@ -199,7 +215,8 @@ static void generic_read_ignore_data(FpiSsm *ssm, FpDevice *dev,
/****** 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;
@ -250,7 +267,8 @@ static const struct aes_regwrite finger_det_reqs[] = {
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);
@ -258,7 +276,8 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
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;
} }
@ -266,22 +285,27 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
/* 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;
} }
@ -294,12 +318,15 @@ static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
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 (); G_DEBUG_HERE ();
if (self->deactivating) { if (self->deactivating)
{
complete_deactivation (dev); complete_deactivation (dev);
return; return;
} }
@ -383,7 +410,8 @@ 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;
@ -394,32 +422,38 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
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;
@ -429,9 +463,11 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
/* 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);
@ -445,10 +481,14 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
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 { }
else
{
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP); fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
} }
} else { }
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));
@ -464,26 +504,32 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
} }
} }
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);
@ -491,6 +537,7 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *device, void *user_data)
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;
@ -503,10 +550,12 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *device, void *user_data)
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;
@ -514,23 +563,30 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
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) { }
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)
{ {
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;
} }
@ -649,15 +705,19 @@ 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); fpi_ssm_mark_failed (ssm, error);
} else { }
else
{
fp_dbg ("reg 0xaf = %x", regs[0x5f]); fp_dbg ("reg 0xaf = %x", regs[0x5f]);
if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13) if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13)
fpi_ssm_jump_to_state (ssm, WRITE_INIT_4); fpi_ssm_jump_to_state (ssm, WRITE_INIT_4);
@ -666,17 +726,20 @@ void activate_read_regs_cb(FpImageDevice *dev, GError *error,
} }
} }
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,30 +762,37 @@ 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);
@ -730,7 +800,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
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);
@ -740,26 +811,32 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *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.
@ -772,16 +849,19 @@ static void complete_deactivation(FpImageDevice *dev)
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;
@ -791,16 +871,18 @@ static void dev_deinit(FpImageDevice *dev)
} }
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
fpi_device_aes2501_class_init (FpiDeviceAes2501Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
@ -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;
} }

View file

@ -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;
@ -85,13 +86,15 @@ static unsigned char finger_det_reqs[] = {
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;
} }
@ -100,23 +103,28 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
(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;
} }
@ -129,13 +137,16 @@ static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
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 (); G_DEBUG_HERE ();
if (self->deactivating) { if (self->deactivating)
{
complete_deactivation (dev); complete_deactivation (dev);
return; return;
} }
@ -177,7 +188,8 @@ 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;
@ -185,14 +197,14 @@ static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *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];
@ -206,24 +218,26 @@ static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
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);
@ -235,7 +249,9 @@ static void capture_set_idle_reqs_cb(FpiUsbTransfer *transfer,
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 { }
else
{
if (error) if (error)
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
else else
@ -244,14 +260,16 @@ static void capture_set_idle_reqs_cb(FpiUsbTransfer *transfer,
} }
} }
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;
} }
@ -260,9 +278,11 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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"); fp_dbg ("Processing strip data failed");
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));
@ -271,21 +291,27 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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 { }
else
{
fpi_ssm_jump_to_state (transfer->ssm, 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);
@ -294,9 +320,11 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
} }
} }
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);
@ -310,6 +338,7 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -321,6 +350,7 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -336,10 +366,12 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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;
@ -347,23 +379,30 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
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) { }
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)
{ {
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;
} }
@ -399,41 +438,43 @@ 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);
@ -447,6 +488,7 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -458,6 +500,7 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -472,6 +515,7 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -486,7 +530,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
} }
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;
@ -498,23 +543,28 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_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;
@ -524,9 +574,11 @@ static void complete_deactivation(FpImageDevice *dev)
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);
@ -534,7 +586,8 @@ static void dev_init(FpImageDevice *dev)
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;
@ -544,16 +597,18 @@ static void dev_deinit(FpImageDevice *dev)
} }
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
fpi_device_aes2550_class_init (FpiDeviceAes2550Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -27,7 +27,8 @@
#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,
@ -63,10 +64,14 @@ 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
fpi_device_aes2660_class_init (FpiDeviceAes2660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass); FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);

View file

@ -115,7 +115,8 @@ 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,
@ -128,10 +129,14 @@ static const FpIdEntry id_table [ ] = {
{ .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
fpi_device_aes3500_class_init (FpiDeviceAes3500Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass); FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);

View file

@ -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;
@ -53,13 +54,16 @@ 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,10 +86,12 @@ 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)
@ -101,7 +108,8 @@ static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
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));
@ -121,7 +129,8 @@ static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
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);
@ -136,14 +145,16 @@ static void do_capture(FpImageDevice *dev)
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);
@ -153,7 +164,8 @@ static void aes3k_dev_activate(FpImageDevice *dev)
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);
@ -164,14 +176,18 @@ static void aes3k_dev_deactivate(FpImageDevice *dev)
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;
} }
@ -179,7 +195,8 @@ static void aes3k_dev_init(FpImageDevice *dev)
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;
@ -189,7 +206,9 @@ static void aes3k_dev_deinit(FpImageDevice *dev)
} }
static void fpi_device_aes3k_class_init(FpiDeviceAes3kClass *klass) { static void
fpi_device_aes3k_class_init (FpiDeviceAes3kClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -45,7 +45,8 @@ G_DECLARE_DERIVABLE_TYPE(FpiDeviceAes3k, fpi_device_aes3k, FPI,
#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 */

View file

@ -112,7 +112,8 @@ 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,
@ -125,10 +126,14 @@ static const FpIdEntry id_table [ ] = {
{ .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
fpi_device_aes4000_class_init (FpiDeviceAes4000Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass); FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);

View file

@ -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,25 +43,31 @@ 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); wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
g_free (wdata); g_free (wdata);
} else { }
else
{
continue_write_regv (FP_IMAGE_DEVICE (device), wdata); 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;
@ -71,7 +78,8 @@ static void do_write_regv(FpImageDevice *dev, struct write_regv_data *wdata, int
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;
@ -85,7 +93,8 @@ static void do_write_regv(FpImageDevice *dev, struct write_regv_data *wdata, int
/* 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,8 +103,10 @@ 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) { {
if (offset >= wdata->num_regs)
{
fp_dbg ("all registers written"); fp_dbg ("all registers written");
wdata->callback (dev, 0, wdata->user_data); wdata->callback (dev, 0, wdata->user_data);
g_free (wdata); g_free (wdata);
@ -114,7 +125,8 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
/* 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;
} }
@ -127,7 +139,8 @@ 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)
{ {
@ -143,7 +156,8 @@ void aes_write_regv(FpImageDevice *dev, const struct aes_regwrite *regs,
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)

View file

@ -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,11 +31,14 @@ 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,
@ -43,4 +47,3 @@ unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
unsigned int y); unsigned int y);
#endif #endif

View file

@ -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;
@ -102,28 +103,31 @@ aesX660_read_response(FpiSsm *ssm,
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]); fp_dbg ("Bogus calibrate response: %.2x\n", data[0]);
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,
@ -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,18 +157,21 @@ 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"); fp_dbg ("Failed to read FD data\n");
fpi_ssm_mark_failed (transfer->ssm, error); 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]); fp_dbg ("Bogus FD response: %.2x\n", data[0]);
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,
@ -171,28 +179,32 @@ static void finger_det_read_fd_data_cb(FpiUsbTransfer *transfer,
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 { }
else
{
fp_dbg ("Wait for finger returned %.2x as result\n", 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);
@ -203,32 +215,42 @@ static void finger_det_sm_complete(FpiSsm *ssm, FpDevice *_dev,
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) { }
else if (error)
{
fpi_image_device_session_error (dev, error); fpi_image_device_session_error (dev, error);
} else { }
else
{
fpi_image_device_report_finger_status (dev, TRUE); fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev); 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);
@ -236,13 +258,15 @@ static void finger_det_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
} }
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;
} }
@ -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,7 +296,8 @@ 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);
@ -288,19 +314,21 @@ static int process_stripe_data(FpiSsm *ssm, FpiDeviceAesX660 *self,
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,7 +336,8 @@ 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);
@ -320,12 +349,15 @@ static void capture_set_idle_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
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 { }
else
{
fpi_ssm_mark_failed (transfer->ssm, error); 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;
@ -383,34 +417,38 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
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),
@ -419,7 +457,8 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
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);
@ -428,24 +467,31 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *device, void *user_data,
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 { }
else
{
start_finger_detection (FP_IMAGE_DEVICE (device)); 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;
} }
@ -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,16 +524,20 @@ 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"); fp_dbg ("read_id cmd failed\n");
fpi_ssm_mark_failed (transfer->ssm, error); 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 { }
else
{
fp_dbg ("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]); fp_dbg ("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
fpi_ssm_mark_failed (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,
@ -494,7 +545,8 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
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];
@ -503,6 +555,7 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
/* 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];
@ -510,6 +563,7 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
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,
@ -519,7 +573,8 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
} }
} }
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);
@ -528,14 +583,16 @@ static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
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, fp_dbg ("read_init transfer status: %s, actual_len: %d\n", error->message,
(gint) transfer->actual_length); (gint) transfer->actual_length);
fpi_ssm_mark_failed (transfer->ssm, error); 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,
@ -544,7 +601,8 @@ static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
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);
@ -556,26 +614,31 @@ static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
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,
@ -585,21 +648,25 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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);
@ -609,14 +676,17 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
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,7 +694,8 @@ 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);
@ -637,7 +708,8 @@ static void aesX660_dev_init(FpImageDevice *dev)
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);
@ -652,7 +724,8 @@ static void aesX660_dev_deinit(FpImageDevice *dev)
} }
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);
@ -666,10 +739,14 @@ static void complete_deactivation(FpImageDevice *dev)
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
fpi_device_aes_x660_class_init (FpiDeviceAesX660Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -47,7 +47,8 @@ G_DECLARE_DERIVABLE_TYPE(FpiDeviceAesX660, fpi_device_aes_x660, FPI,
#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;
}; };
@ -107,4 +109,3 @@ static const guint8 calibrate_cmd[] = {
0x44, 0x02, 0x00, 0x04, 0x00, 0x44, 0x02, 0x00, 0x04, 0x00,
0x06, 0x06,
}; };

View file

@ -41,7 +41,8 @@
#include "drivers_api.h" #include "drivers_api.h"
#include "elan.h" #include "elan.h"
unsigned char elan_get_pixel(struct fpi_frame_asmbl_ctx *ctx, unsigned char
elan_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame, unsigned int x, struct fpi_frame *frame, unsigned int x,
unsigned int y) unsigned int y)
{ {
@ -55,13 +56,15 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
.get_pixel = elan_get_pixel, .get_pixel = elan_get_pixel,
}; };
struct _FpiDeviceElan { struct _FpiDeviceElan
{
FpImageDevice parent; FpImageDevice parent;
/* device config */ /* device config */
unsigned short dev_type; unsigned short dev_type;
unsigned short fw_ver; unsigned short fw_ver;
void (*process_frame) (unsigned short *raw_frame, GSList ** frames); void (*process_frame) (unsigned short *raw_frame,
GSList ** frames);
/* end device config */ /* end device config */
/* commands */ /* commands */
@ -88,12 +91,14 @@ G_DECLARE_FINAL_TYPE(FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
FpImageDevice); FpImageDevice);
G_DEFINE_TYPE (FpiDeviceElan, fpi_device_elan, FP_TYPE_IMAGE_DEVICE); G_DEFINE_TYPE (FpiDeviceElan, fpi_device_elan, FP_TYPE_IMAGE_DEVICE);
int cmp_short(const void *a, const void *b) int
cmp_short (const void *a, const void *b)
{ {
return (int) (*(short *) a - *(short *) b); return (int) (*(short *) a - *(short *) b);
} }
static void elan_dev_reset_state(FpiDeviceElan *elandev) static void
elan_dev_reset_state (FpiDeviceElan *elandev)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -110,7 +115,8 @@ static void elan_dev_reset_state(FpiDeviceElan *elandev)
elandev->num_frames = 0; elandev->num_frames = 0;
} }
static void elan_save_frame(FpiDeviceElan *self, unsigned short *frame) static void
elan_save_frame (FpiDeviceElan *self, unsigned short *frame)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -135,7 +141,8 @@ static void elan_save_frame(FpiDeviceElan *self, unsigned short *frame)
int frame_idx, raw_idx; int frame_idx, raw_idx;
for (int y = 0; y < frame_height; y++) for (int y = 0; y < frame_height; y++)
for (int x = 0; x < frame_width; x++) { for (int x = 0; x < frame_width; x++)
{
if (self->dev_type & ELAN_NOT_ROTATED) if (self->dev_type & ELAN_NOT_ROTATED)
raw_idx = x + (y + frame_margin) * frame_width; raw_idx = x + (y + frame_margin) * frame_width;
else else
@ -146,7 +153,8 @@ static void elan_save_frame(FpiDeviceElan *self, unsigned short *frame)
} }
} }
static void elan_save_background(FpiDeviceElan *elandev) static void
elan_save_background (FpiDeviceElan *elandev)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -192,7 +200,8 @@ static void elan_save_background(FpiDeviceElan *elandev)
* \ * \
* ======== 0 \___> ======== 0 * ======== 0 \___> ======== 0
*/ */
static int elan_save_img_frame(FpiDeviceElan *elandev) static int
elan_save_img_frame (FpiDeviceElan *elandev)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -201,7 +210,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
elan_save_frame (elandev, frame); elan_save_frame (elandev, frame);
unsigned int sum = 0; unsigned int sum = 0;
for (int i = 0; i < frame_size; i++) { for (int i = 0; i < frame_size; i++)
{
if (elandev->background[i] > frame[i]) if (elandev->background[i] > frame[i])
frame[i] = 0; frame[i] = 0;
else else
@ -209,7 +219,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
sum += frame[i]; sum += frame[i];
} }
if (sum == 0) { if (sum == 0)
{
fp_dbg fp_dbg
("frame darker than background; finger present during calibration?"); ("frame darker than background; finger present during calibration?");
return -1; return -1;
@ -220,7 +231,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
return 0; return 0;
} }
static void elan_process_frame_linear(unsigned short *raw_frame, static void
elan_process_frame_linear (unsigned short *raw_frame,
GSList ** frames) GSList ** frames)
{ {
unsigned int frame_size = unsigned int frame_size =
@ -231,7 +243,8 @@ static void elan_process_frame_linear(unsigned short *raw_frame,
G_DEBUG_HERE (); G_DEBUG_HERE ();
unsigned short min = 0xffff, max = 0; unsigned short min = 0xffff, max = 0;
for (int i = 0; i < frame_size; i++) { for (int i = 0; i < frame_size; i++)
{
if (raw_frame[i] < min) if (raw_frame[i] < min)
min = raw_frame[i]; min = raw_frame[i];
if (raw_frame[i] > max) if (raw_frame[i] > max)
@ -241,7 +254,8 @@ static void elan_process_frame_linear(unsigned short *raw_frame,
g_assert (max != min); g_assert (max != min);
unsigned short px; unsigned short px;
for (int i = 0; i < frame_size; i++) { for (int i = 0; i < frame_size; i++)
{
px = raw_frame[i]; px = raw_frame[i];
px = (px - min) * 0xff / (max - min); px = (px - min) * 0xff / (max - min);
frame->data[i] = (unsigned char) px; frame->data[i] = (unsigned char) px;
@ -250,7 +264,8 @@ static void elan_process_frame_linear(unsigned short *raw_frame,
*frames = g_slist_prepend (*frames, frame); *frames = g_slist_prepend (*frames, frame);
} }
static void elan_process_frame_thirds(unsigned short *raw_frame, static void
elan_process_frame_thirds (unsigned short *raw_frame,
GSList ** frames) GSList ** frames)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -271,7 +286,8 @@ static void elan_process_frame_thirds(unsigned short *raw_frame,
g_free (sorted); g_free (sorted);
unsigned short px; unsigned short px;
for (int i = 0; i < frame_size; i++) { for (int i = 0; i < frame_size; i++)
{
px = raw_frame[i]; px = raw_frame[i];
if (lvl0 <= px && px < lvl1) if (lvl0 <= px && px < lvl1)
px = (px - lvl0) * 99 / (lvl1 - lvl0); px = (px - lvl0) * 99 / (lvl1 - lvl0);
@ -285,7 +301,8 @@ static void elan_process_frame_thirds(unsigned short *raw_frame,
*frames = g_slist_prepend (*frames, frame); *frames = g_slist_prepend (*frames, frame);
} }
static void elan_submit_image(FpImageDevice *dev) static void
elan_submit_image (FpImageDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
GSList *raw_frames; GSList *raw_frames;
@ -306,13 +323,15 @@ static void elan_submit_image(FpImageDevice *dev)
fpi_image_device_image_captured (dev, img); fpi_image_device_image_captured (dev, img);
} }
static void elan_cmd_done(FpiSsm *ssm) static void
elan_cmd_done (FpiSsm *ssm)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
} }
static void elan_cmd_cb(FpiUsbTransfer *transfer, FpDevice *dev, static void
elan_cmd_cb (FpiUsbTransfer *transfer, FpDevice *dev,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
FpiSsm *ssm = transfer->ssm; FpiSsm *ssm = transfer->ssm;
@ -320,7 +339,8 @@ static void elan_cmd_cb(FpiUsbTransfer *transfer, FpDevice *dev,
G_DEBUG_HERE (); G_DEBUG_HERE ();
if (error) { if (error)
{
/* XXX: In the cancellation case we used to not /* XXX: In the cancellation case we used to not
* mark the SSM as failed?! */ * mark the SSM as failed?! */
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
@ -328,18 +348,22 @@ static void elan_cmd_cb(FpiUsbTransfer *transfer, FpDevice *dev,
} }
/* XXX: We used to reset the device in error cases! */ /* XXX: We used to reset the device in error cases! */
if (transfer->endpoint & FPI_USB_ENDPOINT_IN) { if (transfer->endpoint & FPI_USB_ENDPOINT_IN)
{
/* just finished receiving */ /* just finished receiving */
self->last_read = g_memdup (transfer->buffer, transfer->actual_length); self->last_read = g_memdup (transfer->buffer, transfer->actual_length);
elan_cmd_done (ssm); elan_cmd_done (ssm);
} else { }
else
{
/* just finished sending */ /* just finished sending */
G_DEBUG_HERE (); G_DEBUG_HERE ();
elan_cmd_read (ssm, dev); elan_cmd_read (ssm, dev);
} }
} }
static void elan_cmd_read(FpiSsm *ssm, FpDevice *dev) static void
elan_cmd_read (FpiSsm *ssm, FpDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
FpiUsbTransfer *transfer; FpiUsbTransfer *transfer;
@ -348,13 +372,15 @@ static void elan_cmd_read(FpiSsm *ssm, FpDevice *dev)
G_DEBUG_HERE (); G_DEBUG_HERE ();
if (self->cmd->response_len == ELAN_CMD_SKIP_READ) { if (self->cmd->response_len == ELAN_CMD_SKIP_READ)
{
fp_dbg ("skipping read, not expecting anything"); fp_dbg ("skipping read, not expecting anything");
elan_cmd_done (ssm); elan_cmd_done (ssm);
return; return;
} }
if (self->dev_type == ELAN_0C42) { if (self->dev_type == ELAN_0C42)
{
/* ELAN_0C42 sends an extra byte in one byte responses */ /* ELAN_0C42 sends an extra byte in one byte responses */
if (self->cmd->response_len == 1) if (self->cmd->response_len == 1)
response_len = 2; response_len = 2;
@ -396,7 +422,8 @@ elan_run_cmd(FpiSsm *ssm,
if (cmd_timeout != -1) if (cmd_timeout != -1)
self->cmd_timeout = cmd_timeout; self->cmd_timeout = cmd_timeout;
if (cmd->devices != ELAN_ALL_DEV && !(cmd->devices & self->dev_type)) { if (cmd->devices != ELAN_ALL_DEV && !(cmd->devices & self->dev_type))
{
fp_dbg ("skipping command 0x%x 0x%x for this device (for devices 0x%x but device is 0x%x)", fp_dbg ("skipping command 0x%x 0x%x for this device (for devices 0x%x but device is 0x%x)",
cmd->cmd[0], cmd->cmd[1], cmd->devices, self->dev_type); cmd->cmd[0], cmd->cmd[1], cmd->devices, self->dev_type);
elan_cmd_done (ssm); elan_cmd_done (ssm);
@ -429,12 +456,14 @@ enum stop_capture_states {
STOP_CAPTURE_NUM_STATES, STOP_CAPTURE_NUM_STATES,
}; };
static void stop_capture_run_state(FpiSsm *ssm, FpDevice *dev, static void
stop_capture_run_state (FpiSsm *ssm, FpDevice *dev,
void *user_data) void *user_data)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case STOP_CAPTURE: case STOP_CAPTURE:
elan_run_cmd (ssm, dev, &stop_cmd, elan_run_cmd (ssm, dev, &stop_cmd,
ELAN_CMD_TIMEOUT); ELAN_CMD_TIMEOUT);
@ -442,7 +471,8 @@ static void stop_capture_run_state(FpiSsm *ssm, FpDevice *dev,
} }
} }
static void stop_capture_complete(FpiSsm *ssm, FpDevice *_dev, static void
stop_capture_complete (FpiSsm *ssm, FpDevice *_dev,
void *user_data, GError *error) void *user_data, GError *error)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
@ -455,22 +485,23 @@ static void stop_capture_complete(FpiSsm *ssm, FpDevice *_dev,
/* The device is inactive at this point. */ /* The device is inactive at this point. */
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE; self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
if (self->deactivating) { if (self->deactivating)
{
/* Simply complete the pending deactivation. */ /* Simply complete the pending deactivation. */
self->deactivating = FALSE; self->deactivating = FALSE;
fpi_image_device_deactivate_complete (dev, error); fpi_image_device_deactivate_complete (dev, error);
return; return;
} }
if (!error) { if (!error)
fpi_image_device_report_finger_status (dev, FALSE); fpi_image_device_report_finger_status (dev, FALSE);
} else { else
/* NOTE: We cannot get a cancellation error here. */ /* NOTE: We cannot get a cancellation error here. */
fpi_image_device_session_error (dev, error); fpi_image_device_session_error (dev, error);
} }
}
static void elan_stop_capture(FpDevice *dev) static void
elan_stop_capture (FpDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
@ -492,47 +523,61 @@ enum capture_states {
CAPTURE_NUM_STATES, CAPTURE_NUM_STATES,
}; };
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 *idev = FP_IMAGE_DEVICE (dev); FpImageDevice *idev = FP_IMAGE_DEVICE (dev);
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
int r; int r;
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_LED_ON: case CAPTURE_LED_ON:
elan_run_cmd (ssm, dev, &led_on_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &led_on_cmd, ELAN_CMD_TIMEOUT);
break; break;
case CAPTURE_WAIT_FINGER: case CAPTURE_WAIT_FINGER:
elan_run_cmd (ssm, dev, &pre_scan_cmd, -1); elan_run_cmd (ssm, dev, &pre_scan_cmd, -1);
break; break;
case CAPTURE_READ_DATA: case CAPTURE_READ_DATA:
self->dev_state = FP_IMAGE_DEVICE_STATE_CAPTURE; self->dev_state = FP_IMAGE_DEVICE_STATE_CAPTURE;
/* 0x55 - finger present /* 0x55 - finger present
* 0xff - device not calibrated (probably) */ * 0xff - device not calibrated (probably) */
if (self->last_read && self->last_read[0] == 0x55) { if (self->last_read && self->last_read[0] == 0x55)
{
fpi_image_device_report_finger_status (idev, TRUE); fpi_image_device_report_finger_status (idev, TRUE);
elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT);
} else { }
else
{
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));
} }
break; break;
case CAPTURE_CHECK_ENOUGH_FRAMES: case CAPTURE_CHECK_ENOUGH_FRAMES:
r = elan_save_img_frame (self); r = elan_save_img_frame (self);
if (r < 0) if (r < 0)
{
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
else if (self->num_frames < ELAN_MAX_FRAMES) { }
else if (self->num_frames < ELAN_MAX_FRAMES)
{
/* quickly stop if finger is removed */ /* quickly stop if finger is removed */
self->cmd_timeout = ELAN_FINGER_TIMEOUT; self->cmd_timeout = ELAN_FINGER_TIMEOUT;
fpi_ssm_jump_to_state (ssm, CAPTURE_WAIT_FINGER); fpi_ssm_jump_to_state (ssm, CAPTURE_WAIT_FINGER);
} else { }
else
{
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
} }
break; break;
} }
} }
static void capture_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data, static void
capture_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
GError *error) GError *error)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
@ -545,23 +590,30 @@ static void capture_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
/* either max frames captured or timed out waiting for the next frame */ /* either max frames captured or timed out waiting for the next frame */
if (!error || if (!error ||
(g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) && (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) &&
fpi_ssm_get_cur_state(ssm) == CAPTURE_WAIT_FINGER)) { fpi_ssm_get_cur_state (ssm) == CAPTURE_WAIT_FINGER))
{
if (self->num_frames >= ELAN_MIN_FRAMES) if (self->num_frames >= ELAN_MIN_FRAMES)
{
elan_submit_image (dev); elan_submit_image (dev);
else { }
else
{
fp_dbg ("swipe too short: want >= %d frames, got %d", fp_dbg ("swipe too short: want >= %d frames, got %d",
ELAN_MIN_FRAMES, self->num_frames); ELAN_MIN_FRAMES, self->num_frames);
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT); fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
} }
g_clear_error (&error); g_clear_error (&error);
} else { }
else
{
fpi_image_device_session_error (dev, error); fpi_image_device_session_error (dev, error);
} }
fpi_ssm_free (ssm); fpi_ssm_free (ssm);
} }
static void elan_capture(FpDevice *dev) static void
elan_capture (FpDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
@ -576,7 +628,8 @@ static void elan_capture(FpDevice *dev)
/* this function needs to have elandev->background and elandev->last_read to be /* this function needs to have elandev->background and elandev->last_read to be
* the calibration mean */ * the calibration mean */
static int elan_need_calibration(FpiDeviceElan *elandev) static int
elan_need_calibration (FpiDeviceElan *elandev)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
@ -587,9 +640,11 @@ static int elan_need_calibration(FpiDeviceElan *elandev)
g_assert (frame_size != 0); g_assert (frame_size != 0);
if (elandev->dev_type == ELAN_0C42) { if (elandev->dev_type == ELAN_0C42)
{
if (calib_mean > 5500 || if (calib_mean > 5500 ||
calib_mean < 2500) { calib_mean < 2500)
{
fp_dbg ("Forcing needed recalibration"); fp_dbg ("Forcing needed recalibration");
return 1; return 1;
} }
@ -619,7 +674,8 @@ enum calibrate_states {
CALIBRATE_NUM_STATES, CALIBRATE_NUM_STATES,
}; };
static gboolean elan_supports_calibration(FpiDeviceElan *elandev) static gboolean
elan_supports_calibration (FpiDeviceElan *elandev)
{ {
if (elandev->dev_type == ELAN_0C42) if (elandev->dev_type == ELAN_0C42)
return TRUE; return TRUE;
@ -627,46 +683,64 @@ static gboolean elan_supports_calibration(FpiDeviceElan *elandev)
return elandev->fw_ver >= ELAN_MIN_CALIBRATION_FW; return elandev->fw_ver >= ELAN_MIN_CALIBRATION_FW;
} }
static void calibrate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data) static void
calibrate_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
G_DEBUG_HERE (); G_DEBUG_HERE ();
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case CALIBRATE_GET_BACKGROUND: case CALIBRATE_GET_BACKGROUND:
elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT);
break; break;
case CALIBRATE_SAVE_BACKGROUND: case CALIBRATE_SAVE_BACKGROUND:
elan_save_background (self); elan_save_background (self);
if (!elan_supports_calibration(self)) { if (!elan_supports_calibration (self))
{
fp_dbg ("FW does not support calibration"); fp_dbg ("FW does not support calibration");
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
} else }
else
{
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
}
break; break;
case CALIBRATE_GET_MEAN: case CALIBRATE_GET_MEAN:
elan_run_cmd (ssm, dev, &get_calib_mean_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &get_calib_mean_cmd, ELAN_CMD_TIMEOUT);
break; break;
case CALIBRATE_CHECK_NEEDED: case CALIBRATE_CHECK_NEEDED:
if (elan_need_calibration(self)) { if (elan_need_calibration (self))
{
self->calib_status = 0; self->calib_status = 0;
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
} else }
else
{
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
}
break; break;
case CALIBRATE_GET_STATUS: case CALIBRATE_GET_STATUS:
self->calib_atts_left -= 1; self->calib_atts_left -= 1;
if (self->calib_atts_left) if (self->calib_atts_left)
{
elan_run_cmd (ssm, dev, &get_calib_status_cmd, elan_run_cmd (ssm, dev, &get_calib_status_cmd,
ELAN_CMD_TIMEOUT); ELAN_CMD_TIMEOUT);
else { }
else
{
fp_dbg ("calibration failed"); fp_dbg ("calibration failed");
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Callibration failed!")); "Callibration failed!"));
} }
break; break;
case CALIBRATE_CHECK_STATUS: case CALIBRATE_CHECK_STATUS:
/* 0x01 - retry, 0x03 - ok /* 0x01 - retry, 0x03 - ok
* It appears that when reading the response soon after 0x4023 the device * It appears that when reading the response soon after 0x4023 the device
@ -675,15 +749,18 @@ static void calibrate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
* to 0x03. Because of this we don't just expect 0x03, we want to see 0x01 * to 0x03. Because of this we don't just expect 0x03, we want to see 0x01
* first. This is to make sure that a full calibration loop has completed */ * first. This is to make sure that a full calibration loop has completed */
fp_dbg ("calibration status: 0x%02x", self->last_read[0]); fp_dbg ("calibration status: 0x%02x", self->last_read[0]);
if (self->calib_status == 0x01 if (self->calib_status == 0x01 &&
&& self->last_read[0] == 0x03) { self->last_read[0] == 0x03)
{
self->calib_status = 0x03; self->calib_status = 0x03;
fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_BACKGROUND); fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_BACKGROUND);
} else { }
else
{
GSource *timeout; GSource *timeout;
if (self->calib_status == 0x00 if (self->calib_status == 0x00 &&
&& self->last_read[0] == 0x01) self->last_read[0] == 0x01)
self->calib_status = 0x01; self->calib_status = 0x01;
timeout = fpi_device_add_timeout (dev, 50, timeout = fpi_device_add_timeout (dev, 50,
fpi_ssm_next_state_timeout_cb, fpi_ssm_next_state_timeout_cb,
@ -691,23 +768,28 @@ static void calibrate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
g_source_set_name (timeout, "calibrate_run_state"); g_source_set_name (timeout, "calibrate_run_state");
} }
break; break;
case CALIBRATE_REPEAT_STATUS: case CALIBRATE_REPEAT_STATUS:
fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_STATUS); fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_STATUS);
break; break;
} }
} }
static void calibrate_complete(FpiSsm *ssm, FpDevice *dev, void *user_data, static void
calibrate_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
GError *error) GError *error)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
G_DEBUG_HERE (); G_DEBUG_HERE ();
if (error) { if (error)
{
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE; self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error); fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
} else { }
else
{
self->dev_state = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON; self->dev_state = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
elan_capture (dev); elan_capture (dev);
} }
@ -715,7 +797,8 @@ static void calibrate_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
fpi_ssm_free (ssm); fpi_ssm_free (ssm);
} }
static void elan_calibrate(FpDevice *dev) static void
elan_calibrate (FpDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
@ -738,32 +821,40 @@ enum activate_states {
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)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
G_DEBUG_HERE (); G_DEBUG_HERE ();
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case ACTIVATE_GET_FW_VER: case ACTIVATE_GET_FW_VER:
elan_run_cmd (ssm, dev, &get_fw_ver_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &get_fw_ver_cmd, ELAN_CMD_TIMEOUT);
break; break;
case ACTIVATE_SET_FW_VER: case ACTIVATE_SET_FW_VER:
self->fw_ver = self->fw_ver =
(self->last_read[0] << 8 | self->last_read[1]); (self->last_read[0] << 8 | self->last_read[1]);
fp_dbg ("FW ver 0x%04hx", self->fw_ver); fp_dbg ("FW ver 0x%04hx", self->fw_ver);
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case ACTIVATE_GET_SENSOR_DIM: case ACTIVATE_GET_SENSOR_DIM:
elan_run_cmd (ssm, dev, &get_sensor_dim_cmd, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &get_sensor_dim_cmd, ELAN_CMD_TIMEOUT);
break; break;
case ACTIVATE_SET_SENSOR_DIM: case ACTIVATE_SET_SENSOR_DIM:
/* see elan_save_frame for details */ /* see elan_save_frame for details */
if (self->dev_type & ELAN_NOT_ROTATED) { if (self->dev_type & ELAN_NOT_ROTATED)
{
self->frame_width = self->last_read[0]; self->frame_width = self->last_read[0];
self->frame_height = self->raw_frame_height = self->frame_height = self->raw_frame_height =
self->last_read[2]; self->last_read[2];
} else { }
else
{
self->frame_width = self->last_read[2]; self->frame_width = self->last_read[2];
self->frame_height = self->raw_frame_height = self->frame_height = self->raw_frame_height =
self->last_read[0]; self->last_read[0];
@ -771,7 +862,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
/* Work-around sensors returning the sizes as zero-based index /* Work-around sensors returning the sizes as zero-based index
* rather than the number of pixels. */ * rather than the number of pixels. */
if ((self->frame_width % 2 == 1) && if ((self->frame_width % 2 == 1) &&
(self->frame_height % 2 == 1)) { (self->frame_height % 2 == 1))
{
self->frame_width++; self->frame_width++;
self->frame_height++; self->frame_height++;
self->raw_frame_height = self->frame_height; self->raw_frame_height = self->frame_height;
@ -782,6 +874,7 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
self->raw_frame_height); self->raw_frame_height);
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case ACTIVATE_CMD_1: case ACTIVATE_CMD_1:
/* TODO: find out what this does, if we need it */ /* TODO: find out what this does, if we need it */
elan_run_cmd (ssm, dev, &activate_cmd_1, ELAN_CMD_TIMEOUT); elan_run_cmd (ssm, dev, &activate_cmd_1, ELAN_CMD_TIMEOUT);
@ -789,7 +882,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
} }
static void activate_complete(FpiSsm *ssm, FpDevice *dev, void *user_data, static void
activate_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
GError *error) GError *error)
{ {
FpImageDevice *idev = FP_IMAGE_DEVICE (dev); FpImageDevice *idev = FP_IMAGE_DEVICE (dev);
@ -801,7 +895,8 @@ static void activate_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
fpi_ssm_free (ssm); fpi_ssm_free (ssm);
} }
static void elan_activate(FpImageDevice *dev) static void
elan_activate (FpImageDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
@ -814,14 +909,16 @@ static void elan_activate(FpImageDevice *dev)
fpi_ssm_start (ssm, activate_complete); fpi_ssm_start (ssm, activate_complete);
} }
static void dev_init(FpImageDevice *dev) static void
dev_init (FpImageDevice *dev)
{ {
GError *error = NULL; GError *error = NULL;
FpiDeviceElan *self; FpiDeviceElan *self;
G_DEBUG_HERE (); G_DEBUG_HERE ();
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;
} }
@ -833,7 +930,8 @@ static void dev_init(FpImageDevice *dev)
self->background = NULL; self->background = NULL;
self->process_frame = elan_process_frame_thirds; self->process_frame = elan_process_frame_thirds;
switch (self->dev_type) { switch (self->dev_type)
{
case ELAN_0907: case ELAN_0907:
self->process_frame = elan_process_frame_linear; self->process_frame = elan_process_frame_linear;
break; break;
@ -842,7 +940,8 @@ static void 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)
{ {
GError *error = NULL; GError *error = NULL;
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
@ -856,34 +955,43 @@ static void dev_deinit(FpImageDevice *dev)
fpi_image_device_close_complete (dev, error); fpi_image_device_close_complete (dev, error);
} }
static void dev_activate(FpImageDevice *dev) static void
dev_activate (FpImageDevice *dev)
{ {
G_DEBUG_HERE (); G_DEBUG_HERE ();
elan_activate (dev); elan_activate (dev);
} }
static void elan_change_state(FpImageDevice *idev) static void
elan_change_state (FpImageDevice *idev)
{ {
FpDevice *dev = FP_DEVICE (idev); FpDevice *dev = FP_DEVICE (idev);
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
FpImageDeviceState next_state = self->dev_state_next; FpImageDeviceState next_state = self->dev_state_next;
if (self->dev_state == next_state) { if (self->dev_state == next_state)
{
fp_dbg ("already in %d", next_state); fp_dbg ("already in %d", next_state);
return; return;
} else { }
else
{
fp_dbg ("changing to %d", next_state); fp_dbg ("changing to %d", next_state);
} }
switch (next_state) { switch (next_state)
{
break; break;
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
/* activation completed or another enroll stage started */ /* activation completed or another enroll stage started */
elan_calibrate (dev); elan_calibrate (dev);
break; break;
case FP_IMAGE_DEVICE_STATE_CAPTURE: case FP_IMAGE_DEVICE_STATE_CAPTURE:
/* not used */ /* not used */
break; break;
case FP_IMAGE_DEVICE_STATE_INACTIVE: case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
if (self->dev_state != FP_IMAGE_DEVICE_STATE_INACTIVE || if (self->dev_state != FP_IMAGE_DEVICE_STATE_INACTIVE ||
@ -900,7 +1008,8 @@ elan_change_state_async(FpDevice *dev,
elan_change_state (FP_IMAGE_DEVICE (dev)); elan_change_state (FP_IMAGE_DEVICE (dev));
} }
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state) static void
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
GSource *timeout; GSource *timeout;
@ -911,11 +1020,11 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
if (state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF) if (state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
state = FP_IMAGE_DEVICE_STATE_INACTIVE; state = FP_IMAGE_DEVICE_STATE_INACTIVE;
if (self->dev_state_next == state) { if (self->dev_state_next == state)
fp_dbg ("change to state %d already queued", state); fp_dbg ("change to state %d already queued", state);
}
switch (state) { switch (state)
{
case FP_IMAGE_DEVICE_STATE_INACTIVE: case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: { case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: {
@ -934,25 +1043,32 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
break; break;
} }
case FP_IMAGE_DEVICE_STATE_CAPTURE: case FP_IMAGE_DEVICE_STATE_CAPTURE:
/* TODO MAYBE: split capture ssm into smaller ssms and use this state */ /* TODO MAYBE: split capture ssm into smaller ssms and use this state */
self->dev_state = state; self->dev_state = state;
self->dev_state_next = state; self->dev_state_next = state;
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }
} }
static void dev_deactivate(FpImageDevice *dev) static void
dev_deactivate (FpImageDevice *dev)
{ {
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev); FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
G_DEBUG_HERE (); G_DEBUG_HERE ();
if (self->dev_state == FP_IMAGE_DEVICE_STATE_INACTIVE) { if (self->dev_state == FP_IMAGE_DEVICE_STATE_INACTIVE)
{
/* The device is inactive already, complete the operation immediately. */ /* The device is inactive already, complete the operation immediately. */
fpi_image_device_deactivate_complete (dev, NULL); fpi_image_device_deactivate_complete (dev, NULL);
} else { }
else
{
/* The device is not yet inactive, flag that we are deactivating (and /* The device is not yet inactive, flag that we are deactivating (and
* need to signal back deactivation) and then ensure we will change * need to signal back deactivation) and then ensure we will change
* to the inactive state eventually. */ * to the inactive state eventually. */
@ -961,9 +1077,13 @@ static void dev_deactivate(FpImageDevice *dev)
} }
} }
static void fpi_device_elan_init(FpiDeviceElan *self) { static void
fpi_device_elan_init (FpiDeviceElan *self)
{
} }
static void fpi_device_elan_class_init(FpiDeviceElanClass *klass) { static void
fpi_device_elan_class_init (FpiDeviceElanClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -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;
@ -215,11 +216,13 @@ static const FpIdEntry elan_id_table [ ] = {
}; };
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

View file

@ -132,8 +132,7 @@ extern "C" {
* 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,
@ -148,8 +147,7 @@ typedef enum bmkt_mode
* 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,
@ -170,8 +168,7 @@ typedef enum bmkt_mode_level2
* 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;
@ -207,8 +204,7 @@ typedef struct bmkt_sensor_desc
* 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,

View file

@ -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,26 +38,24 @@ 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);
@ -63,15 +63,14 @@ static int parse_init_ok(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) 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);
@ -81,28 +80,26 @@ static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *res
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);
@ -110,14 +107,13 @@ static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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];
@ -126,43 +122,40 @@ static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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);
@ -176,15 +169,14 @@ static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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;
@ -198,16 +190,15 @@ static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_res
} }
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;
@ -221,30 +212,25 @@ static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_respo
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;
@ -256,15 +242,14 @@ static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *
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;
@ -277,29 +262,25 @@ int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq
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;
@ -386,17 +367,21 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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;
@ -405,6 +390,7 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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;

View file

@ -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_ */

View file

@ -378,8 +378,7 @@ typedef struct bmkt_get_db_capacity_resp
* 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,
@ -458,7 +457,8 @@ typedef struct bmkt_enrolled_fingers_resp
* 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;

View file

@ -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,
@ -67,14 +66,22 @@ typedef struct bmkt_sensor
} 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,
void *err_cb_ctx);
int bmkt_sensor_close (bmkt_sensor_t *sensor); 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_ */

View file

@ -46,7 +46,8 @@ 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;
@ -55,7 +56,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
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,10 +123,12 @@ 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. */
@ -125,7 +140,9 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
"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;
@ -188,9 +208,11 @@ synaptics_cmd_run_state(FpiSsm *ssm,
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");
} }
} }
@ -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);
@ -410,7 +449,8 @@ list_msg_cb(FpiDeviceSynaptics *self,
{ {
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,13 +461,16 @@ 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 { }
else
{
fp_info ("Failed to query enrolled users: %d", resp->result); 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),
@ -436,6 +479,7 @@ 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!");
@ -444,6 +488,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
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++)
@ -482,7 +527,8 @@ list_msg_cb(FpiDeviceSynaptics *self,
/* 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;
@ -547,12 +593,14 @@ verify_msg_cb(FpiDeviceSynaptics *self,
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,
@ -573,23 +621,30 @@ verify_msg_cb(FpiDeviceSynaptics *self,
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) { }
else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS)
{
fp_info ("Print is not in database"); 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 { }
else
{
fp_warn ("Verify has failed: %d", resp->result); 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);
} }
@ -608,6 +663,7 @@ 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,
@ -638,7 +695,8 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
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;
} }
@ -653,11 +711,13 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
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;
@ -671,41 +731,52 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
* 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;
@ -743,11 +814,14 @@ enroll(FpDevice *device)
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;
@ -807,7 +881,8 @@ delete_msg_cb(FpiDeviceSynaptics *self,
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;
} }
@ -820,6 +895,7 @@ delete_msg_cb(FpiDeviceSynaptics *self,
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)
@ -829,6 +905,7 @@ 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);
@ -841,6 +918,7 @@ 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,7 +929,8 @@ 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;
@ -883,12 +962,14 @@ dev_probe(FpDevice *device)
/* 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;
} }
@ -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;
@ -943,7 +1026,8 @@ dev_probe(FpDevice *device)
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;
@ -999,15 +1083,19 @@ 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));
@ -1023,11 +1111,14 @@ fps_deinit_cb(FpiDeviceSynaptics *self,
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,
@ -1091,11 +1182,13 @@ 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;

View file

@ -77,8 +77,7 @@ 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,
@ -89,8 +88,7 @@ typedef enum syna_state
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
{ {

View file

@ -59,6 +59,7 @@ 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++]);

View file

@ -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

View file

@ -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;
}; };

View file

@ -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;
@ -50,7 +51,8 @@ enum upektc_driver_data {
}; };
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,
GError *error);
static void start_finger_detection (FpImageDevice *dev); static void start_finger_detection (FpImageDevice *dev);
/****** INITIALIZATION/DEINITIALIZATION ******/ /****** INITIALIZATION/DEINITIALIZATION ******/
@ -74,23 +76,28 @@ upektc_next_init_cmd(FpiSsm *ssm,
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 { }
else
{
fpi_ssm_mark_failed (transfer->ssm, error); 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);
@ -101,11 +108,13 @@ static void read_init_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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);
@ -122,6 +131,7 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -138,7 +148,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
} }
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);
@ -153,52 +164,58 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
/****** 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); fp_dbg ("data transfer status %s\n", error->message);
fpi_image_device_session_error (dev, error); 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); fp_dbg ("req transfer status %s\n", error->message);
fpi_image_device_session_error (dev, error); fpi_image_device_session_error (dev, error);
return; return;
@ -213,13 +230,16 @@ static void finger_det_cmd_cb(FpiUsbTransfer *t, FpDevice *device,
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 (); G_DEBUG_HERE ();
if (self->deactivating) { if (self->deactivating)
{
complete_deactivation (dev, NULL); complete_deactivation (dev, NULL);
return; return;
} }
@ -242,23 +262,25 @@ 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); fp_dbg ("request is not completed, %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
@ -271,11 +293,13 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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);
@ -290,6 +314,7 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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);
@ -303,10 +328,12 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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;
@ -323,12 +350,14 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
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;
} }
@ -339,32 +368,38 @@ static void start_capture(FpImageDevice *dev)
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);
@ -372,12 +407,14 @@ static void dev_init(FpImageDevice *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;
@ -385,6 +422,7 @@ static void dev_init(FpImageDevice *dev)
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;
@ -392,6 +430,7 @@ static void dev_init(FpImageDevice *dev)
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 ();
@ -401,7 +440,8 @@ static void 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)
{ {
GError *error = NULL; GError *error = NULL;
@ -416,9 +456,13 @@ static const FpIdEntry id_table [ ] = {
{ .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
fpi_device_upektc_class_init (FpiDeviceUpektcClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -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;
}; };

View file

@ -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];
@ -56,7 +57,8 @@ 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,7 +68,8 @@ 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);
@ -133,42 +136,48 @@ 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);
@ -177,35 +186,41 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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); fp_dbg ("request is not completed, %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
} }
if (self->deactivating) { if (self->deactivating)
{
fp_dbg ("Deactivate requested\n"); fp_dbg ("Deactivate requested\n");
fpi_ssm_mark_completed (transfer->ssm); 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_jump_to_state (transfer->ssm,
fpi_ssm_get_cur_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"); fp_dbg ("Terminating SSM\n");
fpi_ssm_mark_completed (transfer->ssm); 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", fp_dbg ("response_size is %lu, actual_length is %d\n",
response_size, (gint) transfer->actual_length); response_size, (gint) transfer->actual_length);
fp_dbg ("Waiting for rest of transfer"); fp_dbg ("Waiting for rest of transfer");
@ -217,23 +232,28 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
} }
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");
@ -244,6 +264,7 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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");
@ -254,6 +275,7 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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");
@ -266,10 +288,12 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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 +=
@ -278,6 +302,7 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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 +=
@ -294,32 +319,38 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
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)
@ -328,28 +359,34 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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);
@ -363,7 +400,8 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data, GE
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;
@ -383,46 +421,51 @@ 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;
@ -435,7 +478,8 @@ static void deactivate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
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;
@ -463,44 +507,46 @@ 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:
{ {
@ -518,24 +564,29 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
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:
@ -547,7 +598,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
} }
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;
@ -559,29 +611,35 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
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;
} }
@ -590,7 +648,8 @@ static void 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)
{ {
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev); FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
GError *error = NULL; GError *error = NULL;
@ -616,16 +675,18 @@ discover(GUsbDevice *usb_device)
} }
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
fpi_device_upektc_img_class_init (FpiDeviceUpektcImgClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

File diff suppressed because it is too large Load diff

View file

@ -77,7 +77,8 @@ enum {
DP_URU4000B, DP_URU4000B,
}; };
static const struct uru4k_dev_profile { static const struct uru4k_dev_profile
{
const char *name; const char *name;
gboolean auth_cr; gboolean auth_cr;
gboolean encryption; gboolean encryption;
@ -115,7 +116,8 @@ typedef void (*irq_cb_fn)(FpImageDevice *dev,
void *user_data); void *user_data);
typedef void (*irqs_stopped_cb_fn)(FpImageDevice *dev); typedef void (*irqs_stopped_cb_fn)(FpImageDevice *dev);
struct _FpiDeviceUru4000 { struct _FpiDeviceUru4000
{
FpImageDevice parent; FpImageDevice parent;
const struct uru4k_dev_profile *profile; const struct uru4k_dev_profile *profile;
@ -162,7 +164,8 @@ static const unsigned char crkey[] = {
/***** REGISTER I/O *****/ /***** REGISTER I/O *****/
static void write_regs(FpImageDevice *dev, uint16_t first_reg, static void
write_regs (FpImageDevice *dev, uint16_t first_reg,
uint16_t num_regs, unsigned char *values, uint16_t num_regs, unsigned char *values,
FpiUsbTransferCallback callback, FpiUsbTransferCallback callback,
void *user_data) void *user_data)
@ -181,7 +184,8 @@ static void write_regs(FpImageDevice *dev, uint16_t first_reg,
fpi_usb_transfer_unref (transfer); fpi_usb_transfer_unref (transfer);
} }
static void write_reg(FpImageDevice *dev, uint16_t reg, static void
write_reg (FpImageDevice *dev, uint16_t reg,
unsigned char value, unsigned char value,
FpiUsbTransferCallback callback, FpiUsbTransferCallback callback,
void *user_data) void *user_data)
@ -189,7 +193,8 @@ static void write_reg(FpImageDevice *dev, uint16_t reg,
write_regs (dev, reg, 1, &value, callback, user_data); write_regs (dev, reg, 1, &value, callback, user_data);
} }
static void read_regs(FpImageDevice *dev, uint16_t first_reg, static void
read_regs (FpImageDevice *dev, uint16_t first_reg,
uint16_t num_regs, uint16_t num_regs,
FpiUsbTransferCallback callback, FpiUsbTransferCallback callback,
void *user_data) void *user_data)
@ -230,7 +235,8 @@ static void read_regs(FpImageDevice *dev, uint16_t first_reg,
* an interrupt to the host. Maybe? * an interrupt to the host. Maybe?
*/ */
static void response_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error) static void
response_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
{ {
/* NOTE: We could use the SSM function instead if we attached the ssm to the transfer! */ /* NOTE: We could use the SSM function instead if we attached the ssm to the transfer! */
FpiSsm *ssm = user_data; FpiSsm *ssm = user_data;
@ -241,7 +247,8 @@ static void response_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_data
fpi_ssm_mark_failed (ssm, error); fpi_ssm_mark_failed (ssm, error);
} }
static void challenge_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error) static void
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
{ {
FpiSsm *ssm = user_data; FpiSsm *ssm = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
@ -249,7 +256,8 @@ static void challenge_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_dat
PK11Context *ctx; PK11Context *ctx;
int outlen; int outlen;
if (error) { if (error)
{
fpi_ssm_mark_failed (ssm, error); fpi_ssm_mark_failed (ssm, error);
return; return;
} }
@ -258,8 +266,9 @@ static void challenge_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_dat
/* produce response from challenge */ /* produce response from challenge */
ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT, ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT,
self->symkey, self->param); self->symkey, self->param);
if (PK11_CipherOp(ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess ||
|| PK11_Finalize(ctx) != SECSuccess) { PK11_Finalize (ctx) != SECSuccess)
{
fp_err ("Failed to encrypt challenge data"); fp_err ("Failed to encrypt challenge data");
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data"); error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data");
} }
@ -290,7 +299,8 @@ sm_do_challenge_response(FpiSsm *ssm,
static void start_irq_handler (FpImageDevice *dev); static void start_irq_handler (FpImageDevice *dev);
static void irq_handler(FpiUsbTransfer *transfer, static void
irq_handler (FpiUsbTransfer *transfer,
FpDevice *dev, FpDevice *dev,
void *user_data, void *user_data,
GError *error) GError *error)
@ -302,16 +312,22 @@ static void irq_handler(FpiUsbTransfer *transfer,
g_clear_object (&urudev->irq_cancellable); g_clear_object (&urudev->irq_cancellable);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
fp_dbg ("cancelled"); fp_dbg ("cancelled");
if (urudev->irqs_stopped_cb) if (urudev->irqs_stopped_cb)
urudev->irqs_stopped_cb (imgdev); urudev->irqs_stopped_cb (imgdev);
urudev->irqs_stopped_cb = NULL; urudev->irqs_stopped_cb = NULL;
return; return;
} else if (error) { }
if (urudev->irq_cb) { else if (error)
{
if (urudev->irq_cb)
{
urudev->irq_cb (imgdev, error, 0, urudev->irq_cb_data); urudev->irq_cb (imgdev, error, 0, urudev->irq_cb_data);
} else { }
else
{
fp_dbg ("ignoring interrupt error: %s", error->message); fp_dbg ("ignoring interrupt error: %s", error->message);
g_clear_error (&error); g_clear_error (&error);
} }
@ -334,7 +350,8 @@ static void irq_handler(FpiUsbTransfer *transfer,
start_irq_handler (imgdev); start_irq_handler (imgdev);
} }
static void start_irq_handler(FpImageDevice *dev) static void
start_irq_handler (FpImageDevice *dev)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
FpiUsbTransfer *transfer; FpiUsbTransfer *transfer;
@ -351,11 +368,13 @@ static void start_irq_handler(FpImageDevice *dev)
fpi_usb_transfer_unref (transfer); fpi_usb_transfer_unref (transfer);
} }
static void stop_irq_handler(FpImageDevice *dev, irqs_stopped_cb_fn cb) static void
stop_irq_handler (FpImageDevice *dev, irqs_stopped_cb_fn cb)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (self->irq_cancellable) { if (self->irq_cancellable)
{
g_cancellable_cancel (self->irq_cancellable); g_cancellable_cancel (self->irq_cancellable);
self->irqs_stopped_cb = cb; self->irqs_stopped_cb = cb;
} }
@ -365,7 +384,8 @@ static void stop_irq_handler(FpImageDevice *dev, irqs_stopped_cb_fn cb)
static void execute_state_change (FpImageDevice *dev); static void execute_state_change (FpImageDevice *dev);
static void finger_presence_irq_cb(FpImageDevice *dev, static void
finger_presence_irq_cb (FpImageDevice *dev,
GError *error, GError *error,
uint16_t type, uint16_t type,
void *user_data) void *user_data)
@ -380,7 +400,8 @@ static void finger_presence_irq_cb(FpImageDevice *dev,
fp_warn ("ignoring unexpected interrupt %04x", type); fp_warn ("ignoring unexpected interrupt %04x", type);
} }
static void change_state_write_reg_cb(FpiUsbTransfer *transfer, static void
change_state_write_reg_cb (FpiUsbTransfer *transfer,
FpDevice *dev, FpDevice *dev,
void *user_data, void *user_data,
GError *error) GError *error)
@ -389,16 +410,19 @@ static void change_state_write_reg_cb(FpiUsbTransfer *transfer,
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error); fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
} }
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state) static void
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
switch (state) { switch (state)
{
case FP_IMAGE_DEVICE_STATE_INACTIVE: case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
case FP_IMAGE_DEVICE_STATE_CAPTURE: case FP_IMAGE_DEVICE_STATE_CAPTURE:
break; break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }
@ -412,7 +436,8 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
/***** GENERIC STATE MACHINE HELPER FUNCTIONS *****/ /***** GENERIC STATE MACHINE HELPER FUNCTIONS *****/
static void sm_write_reg_cb(FpiUsbTransfer *transfer, static void
sm_write_reg_cb (FpiUsbTransfer *transfer,
FpDevice *dev, FpDevice *dev,
void *user_data, void *user_data,
GError *error) GError *error)
@ -444,7 +469,8 @@ sm_write_reg(FpiSsm *ssm,
sm_write_regs (ssm, dev, reg, 1, &value); sm_write_regs (ssm, dev, reg, 1, &value);
} }
static void sm_read_reg_cb(FpiUsbTransfer *transfer, static void
sm_read_reg_cb (FpiUsbTransfer *transfer,
FpDevice *dev, FpDevice *dev,
void *user_data, void *user_data,
GError *error) GError *error)
@ -452,9 +478,12 @@ static void sm_read_reg_cb(FpiUsbTransfer *transfer,
FpiSsm *ssm = user_data; FpiSsm *ssm = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (error) { if (error)
{
fpi_ssm_mark_failed (ssm, error); fpi_ssm_mark_failed (ssm, error);
} else { }
else
{
memcpy (self->last_reg_rd, transfer->buffer, transfer->actual_length); memcpy (self->last_reg_rd, transfer->buffer, transfer->actual_length);
fp_dbg ("reg value %x", self->last_reg_rd[0]); fp_dbg ("reg value %x", self->last_reg_rd[0]);
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
@ -503,12 +532,14 @@ enum imaging_states {
IMAGING_NUM_STATES IMAGING_NUM_STATES
}; };
struct uru4k_image { struct uru4k_image
{
uint8_t unknown_00[4]; uint8_t unknown_00[4];
uint16_t num_lines; uint16_t num_lines;
uint8_t key_number; uint8_t key_number;
uint8_t unknown_07[9]; uint8_t unknown_07[9];
struct { struct
{
uint8_t flags; uint8_t flags;
uint8_t num_lines; uint8_t num_lines;
} block_info[15]; } block_info[15];
@ -516,16 +547,20 @@ struct uru4k_image {
uint8_t data[IMAGE_HEIGHT][IMAGE_WIDTH]; uint8_t data[IMAGE_HEIGHT][IMAGE_WIDTH];
}; };
static void image_transfer_cb(FpiUsbTransfer *transfer, FpDevice *dev, static void
image_transfer_cb (FpiUsbTransfer *transfer, FpDevice *dev,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
FpiSsm *ssm = transfer->ssm; FpiSsm *ssm = transfer->ssm;
if (error) { if (error)
{
fp_dbg ("error"); fp_dbg ("error");
fpi_ssm_mark_failed (ssm, error); fpi_ssm_mark_failed (ssm, error);
} else { }
else
{
self->img_data = g_memdup (transfer->buffer, sizeof (struct uru4k_image)); self->img_data = g_memdup (transfer->buffer, sizeof (struct uru4k_image));
self->img_data_actual_length = transfer->actual_length; self->img_data_actual_length = transfer->actual_length;
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
@ -539,11 +574,13 @@ enum {
BLOCKF_NOT_PRESENT = 0x01, BLOCKF_NOT_PRESENT = 0x01,
}; };
static uint32_t update_key(uint32_t key) static uint32_t
update_key (uint32_t key)
{ {
/* linear feedback shift register /* linear feedback shift register
* taps at bit positions 1 3 4 7 11 13 20 23 26 29 32 */ * taps at bit positions 1 3 4 7 11 13 20 23 26 29 32 */
uint32_t bit = key & 0x9248144d; uint32_t bit = key & 0x9248144d;
bit ^= bit << 16; bit ^= bit << 16;
bit ^= bit << 8; bit ^= bit << 8;
bit ^= bit << 4; bit ^= bit << 4;
@ -552,12 +589,14 @@ static uint32_t update_key(uint32_t key)
return (bit & 0x80000000) | (key >> 1); return (bit & 0x80000000) | (key >> 1);
} }
static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key) static uint32_t
do_decode (uint8_t *data, int num_bytes, uint32_t key)
{ {
uint8_t xorbyte; uint8_t xorbyte;
int i; int i;
for (i = 0; i < num_bytes - 1; i++) { for (i = 0; i < num_bytes - 1; i++)
{
/* calculate xor byte and update key */ /* calculate xor byte and update key */
xorbyte = ((key >> 4) & 1) << 0; xorbyte = ((key >> 4) & 1) << 0;
xorbyte |= ((key >> 8) & 1) << 1; xorbyte |= ((key >> 8) & 1) << 1;
@ -578,18 +617,21 @@ static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key)
return update_key (key); return update_key (key);
} }
static int calc_dev2(struct uru4k_image *img) static int
calc_dev2 (struct uru4k_image *img)
{ {
uint8_t *b[2] = { NULL, NULL }; uint8_t *b[2] = { NULL, NULL };
int res = 0, mean = 0, i, r, j, idx; int res = 0, mean = 0, i, r, j, idx;
for (i = r = idx = 0; i < G_N_ELEMENTS(img->block_info) && idx < 2; i++) { for (i = r = idx = 0; i < G_N_ELEMENTS (img->block_info) && idx < 2; i++)
{
if (img->block_info[i].flags & BLOCKF_NOT_PRESENT) if (img->block_info[i].flags & BLOCKF_NOT_PRESENT)
continue; continue;
for (j = 0; j < img->block_info[i].num_lines && idx < 2; j++) for (j = 0; j < img->block_info[i].num_lines && idx < 2; j++)
b[idx++] = img->data[r++]; b[idx++] = img->data[r++];
} }
if (!b[0] || !b[1]) { if (!b[0] || !b[1])
{
fp_dbg ("NULL! %p %p", b[0], b[1]); fp_dbg ("NULL! %p %p", b[0], b[1]);
return 0; return 0;
} }
@ -598,7 +640,8 @@ static int calc_dev2(struct uru4k_image *img)
mean /= IMAGE_WIDTH; mean /= IMAGE_WIDTH;
for (i = 0; i < IMAGE_WIDTH; i++) { for (i = 0; i < IMAGE_WIDTH; i++)
{
int dev = (int) b[0][i] + (int) b[1][i] - mean; int dev = (int) b[0][i] + (int) b[1][i] - mean;
res += dev * dev; res += dev * dev;
} }
@ -606,7 +649,8 @@ static int calc_dev2(struct uru4k_image *img)
return res / IMAGE_WIDTH; return res / IMAGE_WIDTH;
} }
static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
imaging_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
@ -617,18 +661,21 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
int i, r, to, dev2; int i, r, to, dev2;
unsigned char buf[5]; unsigned char buf[5];
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case IMAGING_CAPTURE: case IMAGING_CAPTURE:
self->img_lines_done = 0; self->img_lines_done = 0;
self->img_block = 0; self->img_block = 0;
fpi_usb_transfer_submit (self->img_transfer, 0, NULL, image_transfer_cb, NULL); fpi_usb_transfer_submit (self->img_transfer, 0, NULL, image_transfer_cb, NULL);
break; break;
case IMAGING_SEND_INDEX: case IMAGING_SEND_INDEX:
fp_dbg ("hw header lines %d", img->num_lines); fp_dbg ("hw header lines %d", img->num_lines);
if (img->num_lines >= IMAGE_HEIGHT || if (img->num_lines >= IMAGE_HEIGHT ||
self->img_data_actual_length < img->num_lines * IMAGE_WIDTH + 64) { self->img_data_actual_length < img->num_lines * IMAGE_WIDTH + 64)
{
fp_err ("bad captured image (%d lines) or size mismatch %d < %d", fp_err ("bad captured image (%d lines) or size mismatch %d < %d",
img->num_lines, img->num_lines,
self->img_data_actual_length, self->img_data_actual_length,
@ -636,10 +683,12 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE); fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE);
return; return;
} }
if (!self->profile->encryption) { if (!self->profile->encryption)
{
dev2 = calc_dev2 (img); dev2 = calc_dev2 (img);
fp_dbg ("dev2: %d", dev2); fp_dbg ("dev2: %d", dev2);
if (dev2 < ENC_THRESHOLD) { if (dev2 < ENC_THRESHOLD)
{
fpi_ssm_jump_to_state (ssm, IMAGING_REPORT_IMAGE); fpi_ssm_jump_to_state (ssm, IMAGING_REPORT_IMAGE);
return; return;
} }
@ -652,9 +701,11 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
buf[4] = self->img_enc_seed >> 24; buf[4] = self->img_enc_seed >> 24;
sm_write_regs (ssm, dev, REG_SCRAMBLE_DATA_INDEX, 5, buf); sm_write_regs (ssm, dev, REG_SCRAMBLE_DATA_INDEX, 5, buf);
break; break;
case IMAGING_READ_KEY: case IMAGING_READ_KEY:
sm_read_regs (ssm, dev, REG_SCRAMBLE_DATA_KEY, 4); sm_read_regs (ssm, dev, REG_SCRAMBLE_DATA_KEY, 4);
break; break;
case IMAGING_DECODE: case IMAGING_DECODE:
key = self->last_reg_rd[0]; key = self->last_reg_rd[0];
key |= self->last_reg_rd[1] << 8; key |= self->last_reg_rd[1] << 8;
@ -664,7 +715,8 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
fp_dbg ("encryption id %02x -> key %08x", img->key_number, key); fp_dbg ("encryption id %02x -> key %08x", img->key_number, key);
while (self->img_block < G_N_ELEMENTS (img->block_info) && while (self->img_block < G_N_ELEMENTS (img->block_info) &&
self->img_lines_done < img->num_lines) { self->img_lines_done < img->num_lines)
{
flags = img->block_info[self->img_block].flags; flags = img->block_info[self->img_block].flags;
num_lines = img->block_info[self->img_block].num_lines; num_lines = img->block_info[self->img_block].num_lines;
if (num_lines == 0) if (num_lines == 0)
@ -672,7 +724,8 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
fp_dbg ("%d %02x %d", self->img_block, flags, fp_dbg ("%d %02x %d", self->img_block, flags,
num_lines); num_lines);
if (flags & BLOCKF_CHANGE_KEY) { if (flags & BLOCKF_CHANGE_KEY)
{
fp_dbg ("changing encryption keys.\n"); fp_dbg ("changing encryption keys.\n");
img->block_info[self->img_block].flags &= ~BLOCKF_CHANGE_KEY; img->block_info[self->img_block].flags &= ~BLOCKF_CHANGE_KEY;
img->key_number++; img->key_number++;
@ -680,12 +733,14 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
fpi_ssm_jump_to_state (ssm, IMAGING_SEND_INDEX); fpi_ssm_jump_to_state (ssm, IMAGING_SEND_INDEX);
return; return;
} }
switch (flags & (BLOCKF_NO_KEY_UPDATE | BLOCKF_ENCRYPTED)) { switch (flags & (BLOCKF_NO_KEY_UPDATE | BLOCKF_ENCRYPTED))
{
case BLOCKF_ENCRYPTED: case BLOCKF_ENCRYPTED:
fp_dbg ("decoding %d lines", num_lines); fp_dbg ("decoding %d lines", num_lines);
key = do_decode (&img->data[self->img_lines_done][0], key = do_decode (&img->data[self->img_lines_done][0],
IMAGE_WIDTH * num_lines, key); IMAGE_WIDTH * num_lines, key);
break; break;
case 0: case 0:
fp_dbg ("skipping %d lines", num_lines); fp_dbg ("skipping %d lines", num_lines);
for (r = 0; r < IMAGE_WIDTH * num_lines; r++) for (r = 0; r < IMAGE_WIDTH * num_lines; r++)
@ -698,11 +753,13 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case IMAGING_REPORT_IMAGE: case IMAGING_REPORT_IMAGE:
fpimg = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT); fpimg = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
to = r = 0; to = r = 0;
for (i = 0; i < G_N_ELEMENTS(img->block_info) && r < img->num_lines; i++) { for (i = 0; i < G_N_ELEMENTS (img->block_info) && r < img->num_lines; i++)
{
flags = img->block_info[i].flags; flags = img->block_info[i].flags;
num_lines = img->block_info[i].num_lines; num_lines = img->block_info[i].num_lines;
if (num_lines == 0) if (num_lines == 0)
@ -727,10 +784,12 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
static void imaging_complete(FpiSsm *ssm, FpDevice *dev, void *user_data, static void
imaging_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
GError *error) GError *error)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
fpi_ssm_free (ssm); fpi_ssm_free (ssm);
/* Report error before exiting imaging loop - the error handler /* Report error before exiting imaging loop - the error handler
@ -782,29 +841,36 @@ rebootpwr_pause_cb(FpDevice *dev,
FpiSsm *ssm = data; FpiSsm *ssm = data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (!--self->rebootpwr_ctr) { if (!--self->rebootpwr_ctr)
{
fp_err ("could not reboot device power"); fp_err ("could not reboot device power");
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR, fpi_device_error_new_msg (FP_DEVICE_ERROR,
"Could not reboot device")); "Could not reboot device"));
} else { }
else
{
fpi_ssm_jump_to_state (ssm, REBOOTPWR_GET_HWSTAT); fpi_ssm_jump_to_state (ssm, REBOOTPWR_GET_HWSTAT);
} }
} }
static void rebootpwr_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
rebootpwr_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case REBOOTPWR_SET_HWSTAT: case REBOOTPWR_SET_HWSTAT:
self->rebootpwr_ctr = 100; self->rebootpwr_ctr = 100;
sm_set_hwstat (ssm, dev, self->last_hwstat & 0xf); sm_set_hwstat (ssm, dev, self->last_hwstat & 0xf);
break; break;
case REBOOTPWR_GET_HWSTAT: case REBOOTPWR_GET_HWSTAT:
sm_read_reg (ssm, dev, REG_HWSTAT); sm_read_reg (ssm, dev, REG_HWSTAT);
break; break;
case REBOOTPWR_CHECK_HWSTAT: case REBOOTPWR_CHECK_HWSTAT:
self->last_hwstat = self->last_reg_rd[0]; self->last_hwstat = self->last_reg_rd[0];
if (self->last_hwstat & 0x1) if (self->last_hwstat & 0x1)
@ -812,6 +878,7 @@ static void rebootpwr_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
else else
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case REBOOTPWR_PAUSE: case REBOOTPWR_PAUSE:
fpi_device_add_timeout (_dev, 10, rebootpwr_pause_cb, ssm); fpi_device_add_timeout (_dev, 10, rebootpwr_pause_cb, ssm);
break; break;
@ -861,35 +928,45 @@ powerup_pause_cb(FpDevice *dev,
FpiSsm *ssm = data; FpiSsm *ssm = data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (!--self->powerup_ctr) { if (!--self->powerup_ctr)
{
fp_err ("could not power device up"); fp_err ("could not power device up");
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"could not power device up")); "could not power device up"));
} else if (!self->profile->auth_cr) { }
else if (!self->profile->auth_cr)
{
fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT); fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT);
} else { }
else
{
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
} }
} }
static void powerup_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
powerup_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case POWERUP_INIT: case POWERUP_INIT:
self->powerup_ctr = 100; self->powerup_ctr = 100;
self->powerup_hwstat = self->last_hwstat & 0xf; self->powerup_hwstat = self->last_hwstat & 0xf;
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case POWERUP_SET_HWSTAT: case POWERUP_SET_HWSTAT:
sm_set_hwstat (ssm, dev, self->powerup_hwstat); sm_set_hwstat (ssm, dev, self->powerup_hwstat);
break; break;
case POWERUP_GET_HWSTAT: case POWERUP_GET_HWSTAT:
sm_read_reg (ssm, dev, REG_HWSTAT); sm_read_reg (ssm, dev, REG_HWSTAT);
break; break;
case POWERUP_CHECK_HWSTAT: case POWERUP_CHECK_HWSTAT:
self->last_hwstat = self->last_reg_rd[0]; self->last_hwstat = self->last_reg_rd[0];
if ((self->last_reg_rd[0] & 0x80) == 0) if ((self->last_reg_rd[0] & 0x80) == 0)
@ -897,12 +974,15 @@ static void powerup_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
else else
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case POWERUP_PAUSE: case POWERUP_PAUSE:
fpi_device_add_timeout (_dev, 10, powerup_pause_cb, ssm); fpi_device_add_timeout (_dev, 10, powerup_pause_cb, ssm);
break; break;
case POWERUP_CHALLENGE_RESPONSE: case POWERUP_CHALLENGE_RESPONSE:
sm_do_challenge_response (ssm, dev); sm_do_challenge_response (ssm, dev);
break; break;
case POWERUP_CHALLENGE_RESPONSE_SUCCESS: case POWERUP_CHALLENGE_RESPONSE_SUCCESS:
fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT); fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT);
break; break;
@ -940,20 +1020,28 @@ enum init_states {
INIT_NUM_STATES, INIT_NUM_STATES,
}; };
static void init_scanpwr_irq_cb(FpImageDevice *dev, GError *error, static void
init_scanpwr_irq_cb (FpImageDevice *dev, GError *error,
uint16_t type, void *user_data) uint16_t type, void *user_data)
{ {
FpiSsm *ssm = user_data; FpiSsm *ssm = user_data;
FpiDeviceUru4000 *urudev = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *urudev = FPI_DEVICE_URU4000 (dev);
if (error) if (error)
{
fpi_ssm_mark_failed (ssm, error); fpi_ssm_mark_failed (ssm, error);
}
else if (type != IRQDATA_SCANPWR_ON) else if (type != IRQDATA_SCANPWR_ON)
{
fp_dbg ("ignoring interrupt"); fp_dbg ("ignoring interrupt");
else if (fpi_ssm_get_cur_state(ssm) != INIT_AWAIT_SCAN_POWER) { }
else if (fpi_ssm_get_cur_state (ssm) != INIT_AWAIT_SCAN_POWER)
{
fp_dbg ("early scanpwr interrupt"); fp_dbg ("early scanpwr interrupt");
urudev->scanpwr_irq_timeouts = -1; urudev->scanpwr_irq_timeouts = -1;
} else { }
else
{
fp_dbg ("late scanpwr interrupt"); fp_dbg ("late scanpwr interrupt");
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
} }
@ -970,26 +1058,32 @@ init_scanpwr_timeout(FpDevice *dev,
self->irq_cb = NULL; self->irq_cb = NULL;
self->scanpwr_irq_timeout = NULL; self->scanpwr_irq_timeout = NULL;
if (++self->scanpwr_irq_timeouts >= 3) { if (++self->scanpwr_irq_timeouts >= 3)
{
fp_err ("powerup timed out 3 times, giving up"); fp_err ("powerup timed out 3 times, giving up");
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
g_error_new_literal (G_USB_DEVICE_ERROR, g_error_new_literal (G_USB_DEVICE_ERROR,
G_USB_DEVICE_ERROR_TIMED_OUT, G_USB_DEVICE_ERROR_TIMED_OUT,
"Powerup timed out 3 times, giving up")); "Powerup timed out 3 times, giving up"));
} else { }
else
{
fpi_ssm_jump_to_state (ssm, INIT_GET_HWSTAT); fpi_ssm_jump_to_state (ssm, INIT_GET_HWSTAT);
} }
} }
static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
init_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case INIT_GET_HWSTAT: case INIT_GET_HWSTAT:
sm_read_reg (ssm, dev, REG_HWSTAT); sm_read_reg (ssm, dev, REG_HWSTAT);
break; break;
case INIT_CHECK_HWSTAT_REBOOT: case INIT_CHECK_HWSTAT_REBOOT:
self->last_hwstat = self->last_reg_rd[0]; self->last_hwstat = self->last_reg_rd[0];
if ((self->last_hwstat & 0x84) == 0x84) if ((self->last_hwstat & 0x84) == 0x84)
@ -997,20 +1091,24 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
else else
fpi_ssm_jump_to_state (ssm, INIT_CHECK_HWSTAT_POWERDOWN); fpi_ssm_jump_to_state (ssm, INIT_CHECK_HWSTAT_POWERDOWN);
break; break;
case INIT_REBOOT_POWER:; case INIT_REBOOT_POWER:;
FpiSsm *rebootsm = fpi_ssm_new (FP_DEVICE (dev), FpiSsm *rebootsm = fpi_ssm_new (FP_DEVICE (dev),
rebootpwr_run_state, rebootpwr_run_state,
REBOOTPWR_NUM_STATES, dev); REBOOTPWR_NUM_STATES, dev);
fpi_ssm_start_subsm (ssm, rebootsm); fpi_ssm_start_subsm (ssm, rebootsm);
break; break;
case INIT_CHECK_HWSTAT_POWERDOWN: case INIT_CHECK_HWSTAT_POWERDOWN:
if ((self->last_hwstat & 0x80) == 0) if ((self->last_hwstat & 0x80) == 0)
sm_set_hwstat (ssm, dev, self->last_hwstat | 0x80); sm_set_hwstat (ssm, dev, self->last_hwstat | 0x80);
else else
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case INIT_POWERUP: case INIT_POWERUP:
if (!IRQ_HANDLER_IS_RUNNING(self)) { if (!IRQ_HANDLER_IS_RUNNING (self))
{
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"IRQ handler should be running but is not")); "IRQ handler should be running but is not"));
return; return;
@ -1023,8 +1121,10 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
POWERUP_NUM_STATES, dev); POWERUP_NUM_STATES, dev);
fpi_ssm_start_subsm (ssm, powerupsm); fpi_ssm_start_subsm (ssm, powerupsm);
break; break;
case INIT_AWAIT_SCAN_POWER: case INIT_AWAIT_SCAN_POWER:
if (self->scanpwr_irq_timeouts < 0) { if (self->scanpwr_irq_timeouts < 0)
{
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
} }
@ -1037,8 +1137,10 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
init_scanpwr_timeout, init_scanpwr_timeout,
ssm); ssm);
break; break;
case INIT_DONE: case INIT_DONE:
if (self->scanpwr_irq_timeout) { if (self->scanpwr_irq_timeout)
{
g_source_destroy (self->scanpwr_irq_timeout); g_source_destroy (self->scanpwr_irq_timeout);
self->scanpwr_irq_timeout = NULL; self->scanpwr_irq_timeout = NULL;
} }
@ -1046,9 +1148,11 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
self->irq_cb = NULL; self->irq_cb = NULL;
fpi_ssm_next_state (ssm); fpi_ssm_next_state (ssm);
break; break;
case INIT_GET_VERSION: case INIT_GET_VERSION:
sm_read_regs (ssm, dev, REG_DEVICE_INFO, 16); sm_read_regs (ssm, dev, REG_DEVICE_INFO, 16);
break; break;
case INIT_REPORT_VERSION: case INIT_REPORT_VERSION:
/* Likely hardware revision, and firmware version. /* Likely hardware revision, and firmware version.
* Not sure which is which. */ * Not sure which is which. */
@ -1060,13 +1164,15 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
static void activate_initsm_complete(FpiSsm *ssm, FpDevice *dev, static void
activate_initsm_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);
} }
static void dev_activate(FpImageDevice *dev) static void
dev_activate (FpImageDevice *dev)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
FpiSsm *ssm; FpiSsm *ssm;
@ -1080,28 +1186,33 @@ static void dev_activate(FpImageDevice *dev)
/***** DEINITIALIZATION *****/ /***** DEINITIALIZATION *****/
static void deactivate_irqs_stopped(FpImageDevice *dev) static void
deactivate_irqs_stopped (FpImageDevice *dev)
{ {
fpi_image_device_deactivate_complete (dev, NULL); fpi_image_device_deactivate_complete (dev, NULL);
} }
static void deactivate_write_reg_cb(FpiUsbTransfer *transfer, FpDevice *dev, static void
deactivate_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *dev,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
stop_irq_handler (FP_IMAGE_DEVICE (dev), deactivate_irqs_stopped); stop_irq_handler (FP_IMAGE_DEVICE (dev), deactivate_irqs_stopped);
} }
static void dev_deactivate(FpImageDevice *dev) static void
dev_deactivate (FpImageDevice *dev)
{ {
dev_change_state (dev, FP_IMAGE_DEVICE_STATE_INACTIVE); dev_change_state (dev, FP_IMAGE_DEVICE_STATE_INACTIVE);
} }
static void execute_state_change(FpImageDevice *dev) static void
execute_state_change (FpImageDevice *dev)
{ {
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
FpiSsm *ssm; FpiSsm *ssm;
switch (self->activate_state) { switch (self->activate_state)
{
case FP_IMAGE_DEVICE_STATE_INACTIVE: case FP_IMAGE_DEVICE_STATE_INACTIVE:
fp_dbg ("deactivating"); fp_dbg ("deactivating");
self->irq_cb = NULL; self->irq_cb = NULL;
@ -1112,7 +1223,8 @@ static void execute_state_change(FpImageDevice *dev)
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
fp_dbg ("wait finger on"); fp_dbg ("wait finger on");
if (!IRQ_HANDLER_IS_RUNNING(self)) { if (!IRQ_HANDLER_IS_RUNNING (self))
{
fpi_image_device_session_error (dev, fpi_image_device_session_error (dev,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"IRQ handler should be running but is not")); "IRQ handler should be running but is not"));
@ -1145,7 +1257,8 @@ static void execute_state_change(FpImageDevice *dev)
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
fp_dbg ("await finger off"); fp_dbg ("await finger off");
if (!IRQ_HANDLER_IS_RUNNING(self)) { if (!IRQ_HANDLER_IS_RUNNING (self))
{
fpi_image_device_session_error (dev, fpi_image_device_session_error (dev,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"IRQ handler should be running but is not")); "IRQ handler should be running but is not"));
@ -1160,10 +1273,12 @@ static void execute_state_change(FpImageDevice *dev)
/***** LIBRARY STUFF *****/ /***** LIBRARY STUFF *****/
static void dev_init(FpImageDevice *dev) static void
dev_init (FpImageDevice *dev)
{ {
GError *error = NULL; GError *error = NULL;
FpiDeviceUru4000 *self; FpiDeviceUru4000 *self;
g_autoptr(GPtrArray) interfaces = NULL; g_autoptr(GPtrArray) interfaces = NULL;
GUsbInterface *iface = NULL; GUsbInterface *iface = NULL;
guint64 driver_data; guint64 driver_data;
@ -1172,24 +1287,28 @@ static void dev_init(FpImageDevice *dev)
int i; int i;
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error); interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
if (error) { if (error)
{
fpi_image_device_open_complete (dev, error); fpi_image_device_open_complete (dev, error);
return; return;
} }
/* Find fingerprint interface; TODO: Move this into probe() */ /* Find fingerprint interface; TODO: Move this into probe() */
for (i = 0; i < interfaces->len; i++) { for (i = 0; i < interfaces->len; i++)
{
GUsbInterface *cur_iface = g_ptr_array_index (interfaces, i); GUsbInterface *cur_iface = g_ptr_array_index (interfaces, i);
if (g_usb_interface_get_class (cur_iface) == 255 && if (g_usb_interface_get_class (cur_iface) == 255 &&
g_usb_interface_get_subclass (cur_iface) == 255 && g_usb_interface_get_subclass (cur_iface) == 255 &&
g_usb_interface_get_protocol (cur_iface) == 255) { g_usb_interface_get_protocol (cur_iface) == 255)
{
iface = cur_iface; iface = cur_iface;
break; break;
} }
} }
if (iface == NULL) { if (iface == NULL)
{
fp_err ("could not find interface"); fp_err ("could not find interface");
fpi_image_device_open_complete (dev, fpi_image_device_open_complete (dev,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
@ -1199,25 +1318,28 @@ static void dev_init(FpImageDevice *dev)
/* TODO: Find/check endpoints; does not seem easily possible with GUsb unfortunately! */ /* TODO: Find/check endpoints; does not seem easily possible with GUsb unfortunately! */
#if 0 #if 0
if (iface_desc->bNumEndpoints != 2) { if (iface_desc->bNumEndpoints != 2)
{
fp_err ("found %d endpoints!?", iface_desc->bNumEndpoints); fp_err ("found %d endpoints!?", iface_desc->bNumEndpoints);
r = -ENODEV; r = -ENODEV;
goto out; goto out;
} }
ep = &iface_desc->endpoint[0]; ep = &iface_desc->endpoint[0];
if (ep->bEndpointAddress != EP_INTR if (ep->bEndpointAddress != EP_INTR ||
|| (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
LIBUSB_TRANSFER_TYPE_INTERRUPT) { LIBUSB_TRANSFER_TYPE_INTERRUPT)
{
fp_err ("unrecognised interrupt endpoint"); fp_err ("unrecognised interrupt endpoint");
r = -ENODEV; r = -ENODEV;
goto out; goto out;
} }
ep = &iface_desc->endpoint[1]; ep = &iface_desc->endpoint[1];
if (ep->bEndpointAddress != EP_DATA if (ep->bEndpointAddress != EP_DATA ||
|| (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
LIBUSB_TRANSFER_TYPE_BULK) { LIBUSB_TRANSFER_TYPE_BULK)
{
fp_err ("unrecognised bulk endpoint"); fp_err ("unrecognised bulk endpoint");
r = -ENODEV; r = -ENODEV;
goto out; goto out;
@ -1227,7 +1349,8 @@ static void dev_init(FpImageDevice *dev)
/* Device looks like a supported reader */ /* Device looks like a supported reader */
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
g_usb_interface_get_number (iface), 0, &error)) { g_usb_interface_get_number (iface), 0, &error))
{
fpi_image_device_open_complete (dev, error); fpi_image_device_open_complete (dev, error);
return; return;
} }
@ -1237,7 +1360,8 @@ static void dev_init(FpImageDevice *dev)
/* Initialise NSS early */ /* Initialise NSS early */
rv = NSS_NoDB_Init ("."); rv = NSS_NoDB_Init (".");
if (rv != SECSuccess) { if (rv != SECSuccess)
{
fp_err ("could not initialise NSS"); fp_err ("could not initialise NSS");
fpi_image_device_open_complete (dev, fpi_image_device_open_complete (dev,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
@ -1254,7 +1378,8 @@ static void dev_init(FpImageDevice *dev)
/* Set up encryption */ /* Set up encryption */
self->cipher = CKM_AES_ECB; self->cipher = CKM_AES_ECB;
self->slot = PK11_GetBestSlot (self->cipher, NULL); self->slot = PK11_GetBestSlot (self->cipher, NULL);
if (self->slot == NULL) { if (self->slot == NULL)
{
fp_err ("could not get encryption slot"); fp_err ("could not get encryption slot");
fpi_image_device_open_complete (dev, fpi_image_device_open_complete (dev,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
@ -1269,7 +1394,8 @@ static void dev_init(FpImageDevice *dev)
PK11_OriginUnwrap, PK11_OriginUnwrap,
CKA_ENCRYPT, CKA_ENCRYPT,
&item, NULL); &item, NULL);
if (self->symkey == NULL) { if (self->symkey == NULL)
{
fp_err ("failed to import key into NSS"); fp_err ("failed to import key into NSS");
PK11_FreeSlot (self->slot); PK11_FreeSlot (self->slot);
self->slot = NULL; self->slot = NULL;
@ -1283,10 +1409,12 @@ static void 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)
{ {
GError *error = NULL; GError *error = NULL;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (self->symkey) if (self->symkey)
PK11_FreeSymKey (self->symkey); PK11_FreeSymKey (self->symkey);
if (self->param) if (self->param)
@ -1324,10 +1452,14 @@ static const FpIdEntry id_table [ ] = {
{ .vid = 0, .pid = 0, .driver_data = 0 }, { .vid = 0, .pid = 0, .driver_data = 0 },
}; };
static void fpi_device_uru4000_init(FpiDeviceUru4000 *self) { static void
fpi_device_uru4000_init (FpiDeviceUru4000 *self)
{
} }
static void fpi_device_uru4000_class_init(FpiDeviceUru4000Class *klass) { static void
fpi_device_uru4000_class_init (FpiDeviceUru4000Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
@ -1346,4 +1478,3 @@ static void fpi_device_uru4000_class_init(FpiDeviceUru4000Class *klass) {
img_class->img_width = IMAGE_WIDTH; img_class->img_width = IMAGE_WIDTH;
img_class->img_height = IMAGE_HEIGHT; img_class->img_height = IMAGE_HEIGHT;
} }

View file

@ -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;
@ -75,7 +76,8 @@ 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)
@ -104,7 +106,8 @@ sm_write_reg(FpiSsm *ssm,
fpi_usb_transfer_unref (transfer); fpi_usb_transfer_unref (transfer);
} }
static void sm_exec_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
sm_exec_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
if (error) if (error)
@ -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;
@ -163,27 +168,31 @@ static gboolean finger_is_present(unsigned char *data)
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
@ -194,7 +203,9 @@ static void capture_cb(FpiUsbTransfer *transfer, FpDevice *device,
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 { }
else
{
capture_iterate (transfer->ssm, device); capture_iterate (transfer->ssm, device);
} }
} }
@ -244,36 +255,48 @@ 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"); fp_dbg ("deactivating, marking completed");
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
} else }
else
{
sm_exec_cmd (ssm, dev, CMD_SCAN, 0x00); sm_exec_cmd (ssm, 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);
@ -293,27 +316,32 @@ static void loopsm_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
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;
@ -322,7 +350,8 @@ static void dev_init(FpImageDevice *dev)
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;
@ -337,10 +366,14 @@ static const FpIdEntry id_table [ ] = {
{ .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
fpi_device_vcom5s_class_init (FpDeviceVcom5sClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
@ -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;
} }

View file

@ -27,10 +27,12 @@ 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); fp_err ("USB write transfer: %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
@ -58,12 +60,14 @@ async_write(FpiSsm *ssm,
} }
/* 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);
@ -90,7 +94,8 @@ 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;
} }
@ -107,19 +112,22 @@ async_read(FpiSsm *ssm,
} }
/* 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); fp_err ("USB write transfer: %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
@ -135,7 +143,8 @@ static void async_abort_callback(FpiUsbTransfer *transfer, FpDevice *device,
/* 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;
@ -157,21 +166,25 @@ static void async_abort(FpDevice *dev, FpiSsm *ssm, int ep)
/* 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;
@ -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,14 +220,16 @@ 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;
@ -237,7 +254,8 @@ static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
} }
/* 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);
@ -264,7 +282,8 @@ 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;
@ -290,15 +309,18 @@ clear_ep2(FpDevice *dev,
{ {
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);
@ -310,7 +332,8 @@ static void send_control_packet_ssm(FpiSsm *ssm, FpDevice *dev,
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;
@ -332,7 +355,8 @@ static void send_control_packet_ssm(FpiSsm *ssm, FpDevice *dev,
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"); 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));
break; break;
@ -362,11 +386,13 @@ send_control_packet(FpiSsm *ssm,
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;
@ -374,7 +400,8 @@ static void clear_data(FpDeviceVfs0050 *vdev)
} }
/* 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);
@ -382,13 +409,15 @@ static void interrupt_callback(FpiUsbTransfer *transfer, FpDevice *device,
/* 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);
@ -398,14 +427,16 @@ static void interrupt_callback(FpiUsbTransfer *transfer, FpDevice *device,
/* 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 */
@ -423,12 +454,14 @@ static void interrupt_callback(FpiUsbTransfer *transfer, FpDevice *device,
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);
@ -438,9 +471,12 @@ static void receive_callback(FpiUsbTransfer *transfer, FpDevice *device,
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); fpi_ssm_next_state (transfer->ssm);
} else { }
else
{
self->bytes += transfer->actual_length; self->bytes += transfer->actual_length;
/* We need more data */ /* We need more data */
@ -455,16 +491,19 @@ 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;
@ -489,11 +528,13 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
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;
@ -511,7 +552,8 @@ 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;
} }
@ -533,6 +575,7 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
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,7 +588,8 @@ 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;
@ -557,7 +601,8 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
} }
/* 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,
@ -575,6 +620,7 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
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);
@ -585,7 +631,8 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
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;
@ -612,14 +659,16 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
/* 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);
} }
@ -628,7 +677,8 @@ static void dev_activate_callback(FpiSsm *ssm, FpDevice *dev,
} }
/* 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);
@ -643,11 +693,13 @@ static void dev_activate(FpImageDevice *idev)
} }
/* 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,7 +710,8 @@ 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 */
@ -667,12 +720,14 @@ static void dev_open_callback(FpiSsm *ssm, FpDevice *dev, void *user_data,
} }
/* 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;
} }
@ -683,7 +738,8 @@ static void dev_open(FpImageDevice *idev)
} }
/* 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);
@ -700,14 +756,17 @@ static void dev_close(FpImageDevice *idev)
/* 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
fpi_device_vfs0050_class_init (FpDeviceVfs0050Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -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 */
@ -78,7 +79,8 @@ struct vfs_line {
} __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 */

View file

@ -85,7 +85,8 @@
#define VFS_VAL_IMG_EXPOSURE 0x21c0 #define VFS_VAL_IMG_EXPOSURE 0x21c0
/* Structure for Validity device */ /* Structure for Validity device */
struct _FpDeviceVfs101 { struct _FpDeviceVfs101
{
FpImageDevice parent; FpImageDevice parent;
/* Action state */ /* Action state */
@ -127,19 +128,22 @@ G_DECLARE_FINAL_TYPE(FpDeviceVfs101, fpi_device_vfs101, FPI, DEVICE_VFS101,
G_DEFINE_TYPE (FpDeviceVfs101, fpi_device_vfs101, FP_TYPE_IMAGE_DEVICE); G_DEFINE_TYPE (FpDeviceVfs101, fpi_device_vfs101, FP_TYPE_IMAGE_DEVICE);
/* Return byte at specified position */ /* Return byte at specified position */
static inline unsigned char byte(int position, int value) static inline unsigned char
byte (int position, int value)
{ {
return (value >> (position * 8)) & 0xff; return (value >> (position * 8)) & 0xff;
} }
/* Return sequential number */ /* Return sequential number */
static inline unsigned short get_seqnum(int h, int l) static inline unsigned short
get_seqnum (int h, int l)
{ {
return (h << 8) | l; return (h << 8) | l;
} }
/* Check sequential number */ /* Check sequential number */
static inline int check_seqnum(FpDeviceVfs101 *vdev) static inline int
check_seqnum (FpDeviceVfs101 *vdev)
{ {
if ((byte (0, vdev->seqnum) == vdev->buffer[0]) && if ((byte (0, vdev->seqnum) == vdev->buffer[0]) &&
(byte (1, vdev->seqnum) == vdev->buffer[1])) (byte (1, vdev->seqnum) == vdev->buffer[1]))
@ -149,8 +153,7 @@ static inline int check_seqnum(FpDeviceVfs101 *vdev)
} }
/* Internal result codes */ /* Internal result codes */
enum enum {
{
RESULT_RETRY, RESULT_RETRY,
RESULT_RETRY_SHORT, RESULT_RETRY_SHORT,
RESULT_RETRY_REMOVE, RESULT_RETRY_REMOVE,
@ -164,18 +167,23 @@ enum
) )
/* Callback of asynchronous send */ /* Callback of asynchronous send */
static void async_send_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
async_send_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);
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
/* Skip error check if ignore_error is set */ /* Skip error check if ignore_error is set */
if (error) { if (error)
if (!self->ignore_error) { {
if (!self->ignore_error)
{
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
} else { }
else
{
g_error_free (error); g_error_free (error);
fp_dbg ("Ignoring send error: %s", error->message); fp_dbg ("Ignoring send error: %s", error->message);
} }
@ -215,7 +223,8 @@ async_send(FpiSsm *ssm,
} }
/* Callback of asynchronous recv */ /* Callback of asynchronous recv */
static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
async_recv_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);
@ -276,10 +285,12 @@ async_recv(FpiSsm *ssm,
fpi_usb_transfer_unref (transfer); fpi_usb_transfer_unref (transfer);
} }
static void async_load(FpiSsm *ssm, FpImageDevice *dev); static void async_load (FpiSsm *ssm,
FpImageDevice *dev);
/* Callback of asynchronous load */ /* Callback of asynchronous load */
static void async_load_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
async_load_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);
@ -320,9 +331,11 @@ static void async_load_cb(FpiUsbTransfer *transfer, FpDevice *device,
return; return;
} }
else else
{
/* Image load not completed, submit another asynchronous load */ /* Image load not completed, submit another asynchronous load */
async_load (transfer->ssm, dev); async_load (transfer->ssm, dev);
} }
}
else else
{ {
/* Reset ignore_error flag */ /* Reset ignore_error flag */
@ -370,15 +383,15 @@ async_sleep(unsigned int msec,
} }
/* Swap ssm states */ /* Swap ssm states */
enum enum {
{
M_SWAP_SEND, M_SWAP_SEND,
M_SWAP_RECV, M_SWAP_RECV,
M_SWAP_NUM_STATES, M_SWAP_NUM_STATES,
}; };
/* Exec swap sequential state machine */ /* Exec swap sequential state machine */
static void m_swap_state(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
m_swap_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
switch (fpi_ssm_get_cur_state (ssm)) switch (fpi_ssm_get_cur_state (ssm))
{ {
@ -536,7 +549,8 @@ vfs_img_load(FpiSsm *ssm,
#define offset(x, y) ((x) + ((y) * VFS_FRAME_SIZE)) #define offset(x, y) ((x) + ((y) * VFS_FRAME_SIZE))
/* Screen image to remove noise and find bottom line and height of image */ /* Screen image to remove noise and find bottom line and height of image */
static void img_screen(FpDeviceVfs101 *vdev) static void
img_screen (FpDeviceVfs101 *vdev)
{ {
int y, x, count, top; int y, x, count, top;
long int level; long int level;
@ -564,8 +578,10 @@ static void img_screen(FpDeviceVfs101 *vdev)
{ {
/* Begin threshold satisfied */ /* Begin threshold satisfied */
if (count < VFS_IMG_SLT_LINES) if (count < VFS_IMG_SLT_LINES)
{
/* Increase count */ /* Increase count */
count++; count++;
}
else else
{ {
/* Found top fingerprint line */ /* Found top fingerprint line */
@ -578,8 +594,10 @@ static void img_screen(FpDeviceVfs101 *vdev)
{ {
/* End threshold satisfied */ /* End threshold satisfied */
if (count < VFS_IMG_SLT_LINES) if (count < VFS_IMG_SLT_LINES)
{
/* Increase count */ /* Increase count */
count++; count++;
}
else else
{ {
/* Found bottom fingerprint line */ /* Found bottom fingerprint line */
@ -588,9 +606,11 @@ static void img_screen(FpDeviceVfs101 *vdev)
} }
} }
else else
{
/* Not threshold satisfied, reset count */ /* Not threshold satisfied, reset count */
count = 0; count = 0;
} }
}
vdev->height = top - vdev->bottom + 1; vdev->height = top - vdev->bottom + 1;
@ -608,7 +628,8 @@ static void img_screen(FpDeviceVfs101 *vdev)
}; };
/* Copy image from reader buffer and put it into image data */ /* Copy image from reader buffer and put it into image data */
static void img_copy(FpDeviceVfs101 *self, FpImage *img) static void
img_copy (FpDeviceVfs101 *self, FpImage *img)
{ {
unsigned int line; unsigned int line;
unsigned char *img_buffer = img->data; unsigned char *img_buffer = img->data;
@ -661,15 +682,15 @@ img_extract(FpiSsm *ssm,
}; };
/* Finger states */ /* Finger states */
enum enum {
{
VFS_FINGER_EMPTY, VFS_FINGER_EMPTY,
VFS_FINGER_PRESENT, VFS_FINGER_PRESENT,
VFS_FINGER_UNKNOWN, VFS_FINGER_UNKNOWN,
}; };
/* Return finger state */ /* Return finger state */
static inline int vfs_finger_state(FpDeviceVfs101 *vdev) static inline int
vfs_finger_state (FpDeviceVfs101 *vdev)
{ {
/* Check finger state */ /* Check finger state */
switch (vdev->buffer[0x0a]) switch (vdev->buffer[0x0a])
@ -695,7 +716,8 @@ static inline int vfs_finger_state(FpDeviceVfs101 *vdev)
}; };
/* Check contrast of image */ /* Check contrast of image */
static void vfs_check_contrast(FpDeviceVfs101 *vdev) static void
vfs_check_contrast (FpDeviceVfs101 *vdev)
{ {
int y; int y;
long int count = 0; long int count = 0;
@ -723,8 +745,7 @@ static void vfs_check_contrast(FpDeviceVfs101 *vdev)
} }
/* Loop ssm states */ /* Loop ssm states */
enum enum {
{
/* Step 0 - Scan finger */ /* Step 0 - Scan finger */
M_LOOP_0_GET_PRINT, M_LOOP_0_GET_PRINT,
M_LOOP_0_SLEEP, M_LOOP_0_SLEEP,
@ -756,13 +777,15 @@ 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;
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev);
/* Complete if deactivation was requested */ /* Complete if deactivation was requested */
if (self->deactivate) { if (self->deactivate)
{
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
return; return;
} }
@ -926,7 +949,8 @@ static void m_loop_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
/* 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)
{ {
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
@ -942,8 +966,7 @@ static void m_loop_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
} }
/* Init ssm states */ /* Init ssm states */
enum enum {
{
/* Step 0 - Cleanup device buffer */ /* Step 0 - Cleanup device buffer */
M_INIT_0_RECV_DIRTY, M_INIT_0_RECV_DIRTY,
M_INIT_0_ABORT_PRINT, M_INIT_0_ABORT_PRINT,
@ -991,13 +1014,15 @@ enum
}; };
/* 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)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev);
/* Mark as cancelled when activation collides with deactivation. */ /* Mark as cancelled when activation collides with deactivation. */
if (self->deactivate) { if (self->deactivate)
{
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
g_error_new (G_IO_ERROR, g_error_new (G_IO_ERROR,
G_IO_ERROR_CANCELLED, G_IO_ERROR_CANCELLED,
@ -1088,8 +1113,10 @@ static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
/* Finger not present */ /* Finger not present */
if (self->counter == 0) if (self->counter == 0)
{
/* Continue */ /* Continue */
fpi_ssm_jump_to_state (ssm, M_INIT_3_SET_000E); fpi_ssm_jump_to_state (ssm, M_INIT_3_SET_000E);
}
else else
{ {
/* Finger removed, jump to abort */ /* Finger removed, jump to abort */
@ -1225,7 +1252,8 @@ static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
/* 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)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
@ -1233,7 +1261,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
/* Notify activate complete */ /* Notify activate complete */
fpi_image_device_activate_complete (dev, error); fpi_image_device_activate_complete (dev, error);
if (!error) { if (!error)
{
FpiSsm *ssm_loop; FpiSsm *ssm_loop;
/* Start loop ssm */ /* Start loop ssm */
@ -1247,7 +1276,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
} }
/* Activate device */ /* Activate device */
static void dev_activate(FpImageDevice *dev) static void
dev_activate (FpImageDevice *dev)
{ {
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
FpiSsm *ssm; FpiSsm *ssm;
@ -1272,12 +1302,14 @@ static void dev_activate(FpImageDevice *dev)
} }
/* Deactivate device */ /* Deactivate device */
static void dev_deactivate(FpImageDevice *dev) static void
dev_deactivate (FpImageDevice *dev)
{ {
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
/* Device already deactivated, likely due to an error */ /* Device already deactivated, likely due to an error */
if (!self->active) { if (!self->active)
{
fpi_image_device_deactivate_complete (dev, NULL); fpi_image_device_deactivate_complete (dev, NULL);
return; return;
} }
@ -1288,7 +1320,8 @@ static void dev_deactivate(FpImageDevice *dev)
} }
/* Open device */ /* Open device */
static void dev_open(FpImageDevice *dev) static void
dev_open (FpImageDevice *dev)
{ {
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
GError *error = NULL; GError *error = NULL;
@ -1305,7 +1338,8 @@ static void dev_open(FpImageDevice *dev)
} }
/* Close device */ /* Close device */
static void dev_close(FpImageDevice *dev) static void
dev_close (FpImageDevice *dev)
{ {
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev); FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
GError *error = NULL; GError *error = NULL;
@ -1326,10 +1360,14 @@ static const FpIdEntry id_table [ ] = {
{ .vid = 0, .pid = 0, .driver_data = 0 }, { .vid = 0, .pid = 0, .driver_data = 0 },
}; };
static void fpi_device_vfs101_init(FpDeviceVfs101 *self) { static void
fpi_device_vfs101_init (FpDeviceVfs101 *self)
{
} }
static void fpi_device_vfs101_class_init(FpDeviceVfs101Class *klass) { static void
fpi_device_vfs101_class_init (FpDeviceVfs101Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -49,7 +49,8 @@ submit_image(FpiSsm *ssm,
#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;
} }
@ -77,8 +78,7 @@ submit_image(FpiSsm *ssm,
} }
/* 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,12 +93,14 @@ 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);
@ -139,24 +141,30 @@ static void m_loop_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
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 { }
else
{
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT); 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);
} }
@ -165,7 +173,8 @@ static void m_loop_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
} }
/* 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);
@ -177,13 +186,15 @@ static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
/* 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 */
@ -197,7 +208,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
} }
/* Activate device */ /* Activate device */
static void dev_activate(FpImageDevice *dev) static void
dev_activate (FpImageDevice *dev)
{ {
FpiSsm *ssm; FpiSsm *ssm;
@ -207,7 +219,8 @@ static void dev_activate(FpImageDevice *dev)
} }
/* Deactivate device */ /* Deactivate device */
static void dev_deactivate(FpImageDevice *dev) static void
dev_deactivate (FpImageDevice *dev)
{ {
FpDeviceVfs301 *self; FpDeviceVfs301 *self;
@ -216,7 +229,8 @@ static void dev_deactivate(FpImageDevice *dev)
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;
@ -231,7 +245,8 @@ static void dev_open(FpImageDevice *dev)
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;
@ -254,9 +269,13 @@ static const FpIdEntry id_table [ ] = {
{ .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
fpi_device_vfs301_class_init (FpDeviceVfs301Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);

View file

@ -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;
@ -134,4 +137,6 @@ 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);

View file

@ -41,14 +41,16 @@
/************************** 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, " ");
@ -61,9 +63,11 @@ static void usb_print_packet(int dir, GError *error, const guint8 *data, int len
} }
#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
@ -79,7 +83,8 @@ 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
@ -107,7 +114,8 @@ static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GEr
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,14 +137,17 @@ 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,7 +168,8 @@ 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;
@ -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[] = {
@ -217,17 +233,22 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
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: {
@ -251,11 +272,13 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
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;
@ -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;
@ -302,7 +327,8 @@ static int scanline_diff(const guint8 *scanlines, int prev, int cur)
/* 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,11 +338,12 @@ 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;
@ -335,8 +362,10 @@ 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)) { {
if (scanline_diff (scanlines, last_line, i))
{
memcpy ( 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,
@ -348,7 +377,8 @@ 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);
@ -356,14 +386,18 @@ static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *
/*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;
} }
@ -373,7 +407,8 @@ static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *
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
@ -407,30 +442,33 @@ static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *
#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;
@ -444,14 +482,13 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
/* 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
* time. However, as this driver is currently all synchronous (yikes), * time. However, as this driver is currently all synchronous (yikes),
@ -466,27 +503,34 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
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;
} }
@ -501,7 +545,8 @@ static void vfs301_proto_process_event_cb(FpiUsbTransfer *transfer,
} }
} }
void vfs301_proto_process_event_start(FpDeviceVfs301 *dev) void
vfs301_proto_process_event_start (FpDeviceVfs301 *dev)
{ {
FpiUsbTransfer *transfer; FpiUsbTransfer *transfer;
@ -538,7 +583,8 @@ void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
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;
@ -562,7 +608,8 @@ 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);
@ -648,6 +695,7 @@ void vfs301_proto_init(FpDeviceVfs301 *dev)
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)
{ {
} }

View file

@ -30,7 +30,8 @@ enum {
ACTION_RECEIVE, ACTION_RECEIVE,
}; };
struct usb_action { struct usb_action
{
int type; int type;
const char *name; const char *name;
int endpoint; int endpoint;
@ -65,7 +66,8 @@ struct usb_action {
.correct_reply_size = sizeof (EXPECTED) \ .correct_reply_size = sizeof (EXPECTED) \
}, },
struct usbexchange_data { struct usbexchange_data
{
int stepcount; int stepcount;
FpImageDevice *device; FpImageDevice *device;
struct usb_action *actions; struct usb_action *actions;
@ -75,7 +77,8 @@ struct usbexchange_data {
static void start_scan (FpImageDevice *dev); static void start_scan (FpImageDevice *dev);
static void async_send_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
async_send_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
struct usbexchange_data *data = fpi_ssm_get_user_data (transfer->ssm); struct usbexchange_data *data = fpi_ssm_get_user_data (transfer->ssm);
@ -86,7 +89,8 @@ static void async_send_cb(FpiUsbTransfer *transfer, FpDevice *device,
action = &data->actions[fpi_ssm_get_cur_state (transfer->ssm)]; action = &data->actions[fpi_ssm_get_cur_state (transfer->ssm)];
g_assert (!(action->type != ACTION_SEND)); g_assert (!(action->type != ACTION_SEND));
if (error) { if (error)
{
/* Transfer not completed, return IO error */ /* Transfer not completed, return IO error */
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
@ -96,13 +100,15 @@ static void async_send_cb(FpiUsbTransfer *transfer, FpDevice *device,
fpi_ssm_next_state (transfer->ssm); fpi_ssm_next_state (transfer->ssm);
} }
static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device, static void
async_recv_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
struct usbexchange_data *data = fpi_ssm_get_user_data (transfer->ssm); struct usbexchange_data *data = fpi_ssm_get_user_data (transfer->ssm);
struct usb_action *action; struct usb_action *action;
if (error) { if (error)
{
/* Transfer not completed, return IO error */ /* Transfer not completed, return IO error */
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
return; return;
@ -113,8 +119,10 @@ static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device,
action = &data->actions[fpi_ssm_get_cur_state (transfer->ssm)]; action = &data->actions[fpi_ssm_get_cur_state (transfer->ssm)];
g_assert (!(action->type != ACTION_RECEIVE)); g_assert (!(action->type != ACTION_RECEIVE));
if (action->data != NULL) { if (action->data != NULL)
if (transfer->actual_length != action->correct_reply_size) { {
if (transfer->actual_length != action->correct_reply_size)
{
fp_err ("Got %d bytes instead of %d", fp_err ("Got %d bytes instead of %d",
(gint) transfer->actual_length, (gint) transfer->actual_length,
action->correct_reply_size); action->correct_reply_size);
@ -122,20 +130,25 @@ static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device,
return; return;
} }
if (memcmp (transfer->buffer, action->data, if (memcmp (transfer->buffer, action->data,
action->correct_reply_size) != 0) { action->correct_reply_size) != 0)
{
fp_dbg ("Wrong reply:"); fp_dbg ("Wrong reply:");
fpi_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));
return; return;
} }
} else }
else
{
fp_dbg ("Got %d bytes out of %d", fp_dbg ("Got %d bytes out of %d",
(gint) transfer->actual_length, (gint) transfer->actual_length,
(gint) transfer->length); (gint) transfer->length);
}
fpi_ssm_next_state (transfer->ssm); fpi_ssm_next_state (transfer->ssm);
} }
static void usbexchange_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
usbexchange_loop (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
struct usbexchange_data *data = user_data; struct usbexchange_data *data = user_data;
struct usb_action *action = &data->actions[fpi_ssm_get_cur_state (ssm)]; struct usb_action *action = &data->actions[fpi_ssm_get_cur_state (ssm)];
@ -143,7 +156,8 @@ static void usbexchange_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data)
g_assert (fpi_ssm_get_cur_state (ssm) < data->stepcount); g_assert (fpi_ssm_get_cur_state (ssm) < data->stepcount);
switch (action->type) { switch (action->type)
{
case ACTION_SEND: case ACTION_SEND:
fp_dbg ("Sending %s", action->name); fp_dbg ("Sending %s", action->name);
transfer = fpi_usb_transfer_new (_dev); transfer = fpi_usb_transfer_new (_dev);
@ -176,20 +190,23 @@ static void usbexchange_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
static void usb_exchange_async(FpiSsm *ssm, static void
usb_exchange_async (FpiSsm *ssm,
struct usbexchange_data *data) struct usbexchange_data *data)
{ {
FpiSsm *subsm = fpi_ssm_new (FP_DEVICE (data->device), FpiSsm *subsm = fpi_ssm_new (FP_DEVICE (data->device),
usbexchange_loop, usbexchange_loop,
data->stepcount, data->stepcount,
data); data);
fpi_ssm_start_subsm (ssm, subsm); fpi_ssm_start_subsm (ssm, subsm);
} }
/* ====================== utils ======================= */ /* ====================== utils ======================= */
/* Calculade squared standand deviation of sum of two lines */ /* Calculade squared standand deviation of sum of two lines */
static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1, GSList *row2) static int
vfs5011_get_deviation2 (struct fpi_line_asmbl_ctx *ctx, GSList *row1, GSList *row2)
{ {
unsigned char *buf1, *buf2; unsigned char *buf1, *buf2;
int res = 0, mean = 0, i; int res = 0, mean = 0, i;
@ -203,7 +220,8 @@ static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1,
mean /= size; mean /= size;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++)
{
int dev = (int) buf1[i] + (int) buf2[i] - mean; int dev = (int) buf1[i] + (int) buf2[i] - mean;
res += dev * dev; res += dev * dev;
} }
@ -211,7 +229,8 @@ static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1,
return res / size; return res / size;
} }
static unsigned char vfs5011_get_pixel(struct fpi_line_asmbl_ctx *ctx, static unsigned char
vfs5011_get_pixel (struct fpi_line_asmbl_ctx *ctx,
GSList *row, GSList *row,
unsigned x) unsigned x)
{ {
@ -238,7 +257,8 @@ static struct fpi_line_asmbl_ctx assembling_ctx = {
.get_pixel = vfs5011_get_pixel, .get_pixel = vfs5011_get_pixel,
}; };
struct _FpDeviceVfs5011 { struct _FpDeviceVfs5011
{
FpImageDevice parent; FpImageDevice parent;
unsigned char *total_buffer; unsigned char *total_buffer;
@ -272,7 +292,8 @@ enum {
DEV_OPEN_NUM_STATES DEV_OPEN_NUM_STATES
}; };
static void capture_init(FpDeviceVfs5011 *self, int max_captured, static void
capture_init (FpDeviceVfs5011 *self, int max_captured,
int max_recorded) int max_recorded)
{ {
fp_dbg ("capture_init"); fp_dbg ("capture_init");
@ -287,7 +308,8 @@ static void capture_init(FpDeviceVfs5011 *self, int max_captured,
self->max_lines_recorded = max_recorded; self->max_lines_recorded = max_recorded;
} }
static int process_chunk(FpDeviceVfs5011 *self, int transferred) static int
process_chunk (FpDeviceVfs5011 *self, int transferred)
{ {
enum { enum {
DEVIATION_THRESHOLD = 15 * 15, DEVIATION_THRESHOLD = 15 * 15,
@ -299,41 +321,50 @@ static int process_chunk(FpDeviceVfs5011 *self, int transferred)
int lines_captured = transferred / VFS5011_LINE_SIZE; int lines_captured = transferred / VFS5011_LINE_SIZE;
int i; int i;
for (i = 0; i < lines_captured; i++) { for (i = 0; i < lines_captured; i++)
{
unsigned char *linebuf = self->capture_buffer unsigned char *linebuf = self->capture_buffer
+ i * VFS5011_LINE_SIZE; + i * VFS5011_LINE_SIZE;
if (fpi_std_sq_dev (linebuf + 8, VFS5011_IMAGE_WIDTH) if (fpi_std_sq_dev (linebuf + 8, VFS5011_IMAGE_WIDTH)
< DEVIATION_THRESHOLD) { < DEVIATION_THRESHOLD)
{
if (self->lines_captured == 0) if (self->lines_captured == 0)
continue; continue;
else else
self->empty_lines++; self->empty_lines++;
} else }
else
{
self->empty_lines = 0; self->empty_lines = 0;
if (self->empty_lines >= STOP_CHECK_LINES) { }
if (self->empty_lines >= STOP_CHECK_LINES)
{
fp_dbg ("process_chunk: got %d empty lines, finishing", fp_dbg ("process_chunk: got %d empty lines, finishing",
self->empty_lines); self->empty_lines);
return 1; return 1;
} }
self->lines_captured++; self->lines_captured++;
if (self->lines_captured > self->max_lines_captured) { if (self->lines_captured > self->max_lines_captured)
{
fp_dbg ("process_chunk: captured %d lines, finishing", fp_dbg ("process_chunk: captured %d lines, finishing",
self->lines_captured); self->lines_captured);
return 1; return 1;
} }
if ((self->lastline == NULL) if ((self->lastline == NULL) ||
|| (fpi_mean_sq_diff_norm(self->lastline + 8, (fpi_mean_sq_diff_norm (self->lastline + 8,
linebuf + 8, linebuf + 8,
VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) { VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD))
{
self->lastline = g_malloc (VFS5011_LINE_SIZE); self->lastline = g_malloc (VFS5011_LINE_SIZE);
self->rows = g_slist_prepend (self->rows, self->rows = g_slist_prepend (self->rows,
self->lastline); self->lastline);
memmove (self->lastline, linebuf, VFS5011_LINE_SIZE); memmove (self->lastline, linebuf, VFS5011_LINE_SIZE);
self->lines_recorded++; self->lines_recorded++;
if (self->lines_recorded >= self->max_lines_recorded) { if (self->lines_recorded >= self->max_lines_recorded)
{
fp_dbg ("process_chunk: recorded %d lines, finishing", fp_dbg ("process_chunk: recorded %d lines, finishing",
self->lines_recorded); self->lines_recorded);
return 1; return 1;
@ -350,7 +381,8 @@ submit_image(FpiSsm *ssm,
{ {
FpImage *img; FpImage *img;
if (self->lines_recorded == 0) { if (self->lines_recorded == 0)
{
/* == FP_ENROLL_RETRY_TOO_SHORT */ /* == FP_ENROLL_RETRY_TOO_SHORT */
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT); fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
return; return;
@ -371,7 +403,8 @@ submit_image(FpiSsm *ssm,
fpi_image_device_image_captured (dev, img); fpi_image_device_image_captured (dev, img);
} }
static void chunk_capture_callback(FpiUsbTransfer *transfer, FpDevice *device, static void
chunk_capture_callback (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);
@ -380,7 +413,8 @@ static void chunk_capture_callback(FpiUsbTransfer *transfer, FpDevice *device,
self = FPI_DEVICE_VFS5011 (dev); self = FPI_DEVICE_VFS5011 (dev);
if (!error || if (!error ||
g_error_matches(error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) { g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT))
{
if (error) if (error)
g_error_free (error); g_error_free (error);
@ -393,22 +427,29 @@ static void chunk_capture_callback(FpiUsbTransfer *transfer, FpDevice *device,
else else
fpi_ssm_jump_to_state (transfer->ssm, fpi_ssm_jump_to_state (transfer->ssm,
DEV_ACTIVATE_READ_DATA); DEV_ACTIVATE_READ_DATA);
} else { }
if (!self->deactivating) { else
{
if (!self->deactivating)
{
fp_err ("Failed to capture data"); fp_err ("Failed to capture data");
fpi_ssm_mark_failed (transfer->ssm, error); fpi_ssm_mark_failed (transfer->ssm, error);
} else { }
else
{
g_error_free (error); g_error_free (error);
fpi_ssm_mark_completed (transfer->ssm); fpi_ssm_mark_completed (transfer->ssm);
} }
} }
} }
static void capture_chunk_async(FpDeviceVfs5011 *self, static void
capture_chunk_async (FpDeviceVfs5011 *self,
GUsbDevice *handle, int nline, GUsbDevice *handle, int nline,
int timeout, FpiSsm *ssm) int timeout, FpiSsm *ssm)
{ {
FpiUsbTransfer *transfer; FpiUsbTransfer *transfer;
fp_dbg ("capture_chunk_async: capture %d lines, already have %d", fp_dbg ("capture_chunk_async: capture %d lines, already have %d",
nline, self->lines_recorded); nline, self->lines_recorded);
enum { enum {
@ -616,7 +657,8 @@ struct usb_action vfs5011_initiate_capture[] = {
/* ====================== lifprint interface ======================= */ /* ====================== lifprint interface ======================= */
static void activate_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
activate_loop (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
enum {READ_TIMEOUT = 0}; enum {READ_TIMEOUT = 0};
@ -627,13 +669,15 @@ static void activate_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data)
fp_dbg ("main_loop: state %d", fpi_ssm_get_cur_state (ssm)); fp_dbg ("main_loop: state %d", fpi_ssm_get_cur_state (ssm));
if (self->deactivating) { if (self->deactivating)
{
fp_dbg ("deactivating, marking completed"); fp_dbg ("deactivating, marking completed");
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
return; return;
} }
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case DEV_ACTIVATE_REQUEST_FPRINT: case DEV_ACTIVATE_REQUEST_FPRINT:
self->init_sequence.stepcount = self->init_sequence.stepcount =
G_N_ELEMENTS (vfs5011_initiate_capture); G_N_ELEMENTS (vfs5011_initiate_capture);
@ -684,7 +728,8 @@ static void activate_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data)
} }
} }
static void activate_loop_complete(FpiSsm *ssm, FpDevice *_dev, static void
activate_loop_complete (FpiSsm *ssm, FpDevice *_dev,
void *user_data, GError *error) void *user_data, GError *error)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
@ -696,7 +741,8 @@ static void activate_loop_complete(FpiSsm *ssm, FpDevice *_dev,
if (self->init_sequence.receive_buf != NULL) if (self->init_sequence.receive_buf != NULL)
g_free (self->init_sequence.receive_buf); g_free (self->init_sequence.receive_buf);
self->init_sequence.receive_buf = NULL; self->init_sequence.receive_buf = NULL;
if (!self->deactivating && !error) { if (!self->deactivating && !error)
{
submit_image (ssm, self, dev); submit_image (ssm, self, dev);
fpi_image_device_report_finger_status (dev, FALSE); fpi_image_device_report_finger_status (dev, FALSE);
} }
@ -704,24 +750,25 @@ static void activate_loop_complete(FpiSsm *ssm, FpDevice *_dev,
self->loop_running = FALSE; self->loop_running = FALSE;
if (self->deactivating) { if (self->deactivating)
fpi_image_device_deactivate_complete (dev, error); fpi_image_device_deactivate_complete (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_scan (dev); start_scan (dev);
} }
}
static void open_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data) static void
open_loop (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
FpDeviceVfs5011 *self; FpDeviceVfs5011 *self;
self = FPI_DEVICE_VFS5011 (_dev); self = FPI_DEVICE_VFS5011 (_dev);
switch (fpi_ssm_get_cur_state(ssm)) { switch (fpi_ssm_get_cur_state (ssm))
{
case DEV_OPEN_START: case DEV_OPEN_START:
self->init_sequence.stepcount = self->init_sequence.stepcount =
G_N_ELEMENTS (vfs5011_initialization); G_N_ELEMENTS (vfs5011_initialization);
@ -732,10 +779,12 @@ static void open_loop(FpiSsm *ssm, FpDevice *_dev, void *user_data)
self->init_sequence.timeout = VFS5011_DEFAULT_WAIT_TIMEOUT; self->init_sequence.timeout = VFS5011_DEFAULT_WAIT_TIMEOUT;
usb_exchange_async (ssm, &self->init_sequence); usb_exchange_async (ssm, &self->init_sequence);
break; break;
}; }
;
} }
static void open_loop_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data, static void
open_loop_complete (FpiSsm *ssm, FpDevice *_dev, void *user_data,
GError *error) GError *error)
{ {
FpImageDevice *dev = user_data; FpImageDevice *dev = user_data;
@ -749,7 +798,8 @@ static void open_loop_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
fpi_ssm_free (ssm); fpi_ssm_free (ssm);
} }
static void dev_open(FpImageDevice *dev) static void
dev_open (FpImageDevice *dev)
{ {
FpiSsm *ssm; FpiSsm *ssm;
GError *error = NULL; GError *error = NULL;
@ -759,7 +809,8 @@ static void dev_open(FpImageDevice *dev)
self->capture_buffer = self->capture_buffer =
(unsigned char *) g_malloc0 (CAPTURE_LINES * VFS5011_LINE_SIZE); (unsigned char *) g_malloc0 (CAPTURE_LINES * VFS5011_LINE_SIZE);
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;
} }
@ -768,10 +819,13 @@ static void dev_open(FpImageDevice *dev)
fpi_ssm_start (ssm, open_loop_complete); fpi_ssm_start (ssm, open_loop_complete);
} }
static void dev_close(FpImageDevice *dev) static void
dev_close (FpImageDevice *dev)
{ {
GError *error = NULL; GError *error = NULL;
FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011(dev);; FpDeviceVfs5011 *self = FPI_DEVICE_VFS5011 (dev);
;
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);
@ -782,7 +836,8 @@ static void dev_close(FpImageDevice *dev)
fpi_image_device_close_complete (dev, error); fpi_image_device_close_complete (dev, error);
} }
static void start_scan(FpImageDevice *dev) static void
start_scan (FpImageDevice *dev)
{ {
FpDeviceVfs5011 *self; FpDeviceVfs5011 *self;
FpiSsm *ssm; FpiSsm *ssm;
@ -797,7 +852,8 @@ static void start_scan(FpImageDevice *dev)
fp_dbg ("ssm done, getting out"); fp_dbg ("ssm done, getting out");
} }
static void dev_activate(FpImageDevice *dev) static void
dev_activate (FpImageDevice *dev)
{ {
FpDeviceVfs5011 *self; FpDeviceVfs5011 *self;
@ -808,34 +864,34 @@ static void dev_activate(FpImageDevice *dev)
start_scan (dev); start_scan (dev);
} }
static void dev_deactivate(FpImageDevice *dev) static void
dev_deactivate (FpImageDevice *dev)
{ {
FpDeviceVfs5011 *self; FpDeviceVfs5011 *self;
self = FPI_DEVICE_VFS5011 (dev); self = FPI_DEVICE_VFS5011 (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 const FpIdEntry id_table[] = { static const FpIdEntry id_table[] = {
{ /* Validity device from some Toshiba laptops */ .vid = 0x138a, .pid = 0x0010, { /* Validity device from some Toshiba laptops */ .vid = 0x138a, .pid = 0x0010, },
}, { /* vfs5011 */ .vid = 0x138a, .pid = 0x0011, },
{ /* vfs5011 */ .vid = 0x138a, .pid = 0x0011, { /* Validity device from Lenovo Preferred Pro USB Fingerprint Keyboard KUF1256 */ .vid = 0x138a, .pid = 0x0015, },
}, { /* Validity device from Lenovo T440 laptops */ .vid = 0x138a, .pid = 0x0017, },
{ /* Validity device from Lenovo Preferred Pro USB Fingerprint Keyboard KUF1256 */ .vid = 0x138a, .pid = 0x0015, { /* one more Validity device */ .vid = 0x138a, .pid = 0x0018, },
},
{ /* Validity device from Lenovo T440 laptops */ .vid = 0x138a, .pid = 0x0017,
},
{ /* one more Validity device */ .vid = 0x138a, .pid = 0x0018,
},
{ .vid = 0, .pid = 0, .driver_data = 0 }, { .vid = 0, .pid = 0, .driver_data = 0 },
}; };
static void fpi_device_vfs5011_init(FpDeviceVfs5011 *self) { static void
fpi_device_vfs5011_init (FpDeviceVfs5011 *self)
{
} }
static void fpi_device_vfs5011_class_init(FpDeviceVfs5011Class *klass) { static void
fpi_device_vfs5011_class_init (FpDeviceVfs5011Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
@ -855,4 +911,3 @@ static void fpi_device_vfs5011_class_init(FpDeviceVfs5011Class *klass) {
img_class->img_width = VFS5011_IMAGE_WIDTH; img_class->img_width = VFS5011_IMAGE_WIDTH;
img_class->img_height = -1; img_class->img_height = -1;
} }

View file

@ -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;
@ -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]);
@ -182,7 +191,8 @@ 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;
@ -193,7 +203,8 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
/* 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;
} }
@ -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,7 +271,8 @@ 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);
@ -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;
} }

View file

@ -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;

View file

@ -28,7 +28,8 @@
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;
@ -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;

View file

@ -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,7 +93,8 @@ 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;
@ -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;
} }

View file

@ -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"

View file

@ -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