Uncrustify everything except for nbis
This commit is contained in:
parent
fd5f511b33
commit
d1fb1e26f3
60 changed files with 30386 additions and 28683 deletions
|
@ -33,7 +33,8 @@ typedef enum {
|
|||
IMAGE_DISPLAY_BINARY = 1 << 1
|
||||
} ImageDisplayFlags;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
GtkApplicationWindow parent_instance;
|
||||
|
||||
GtkWidget *header_bar;
|
||||
|
@ -79,7 +80,8 @@ img_to_rgbdata (const guint8 *imgdata,
|
|||
size_t i;
|
||||
size_t rgb_offset = 0;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
guint8 pixel = imgdata[i];
|
||||
|
||||
rgbdata[rgb_offset++] = pixel;
|
||||
|
@ -97,13 +99,15 @@ plot_minutiae (unsigned char *rgbdata,
|
|||
GPtrArray *minutiae)
|
||||
{
|
||||
int i;
|
||||
|
||||
#define write_pixel(num) do { \
|
||||
rgbdata[((num) * 3)] = 0xff; \
|
||||
rgbdata[((num) * 3) + 1] = 0; \
|
||||
rgbdata[((num) * 3) + 2] = 0; \
|
||||
} while(0)
|
||||
|
||||
for (i = 0; i < minutiae->len; i++) {
|
||||
for (i = 0; i < minutiae->len; i++)
|
||||
{
|
||||
struct fp_minutia *min = g_ptr_array_index (minutiae, i);
|
||||
int x, y;
|
||||
size_t pixel_offset;
|
||||
|
@ -149,7 +153,8 @@ img_to_pixbuf (FpImage *img,
|
|||
|
||||
rgbdata = img_to_rgbdata (data, width, height);
|
||||
|
||||
if (flags & IMAGE_DISPLAY_MINUTIAE) {
|
||||
if (flags & IMAGE_DISPLAY_MINUTIAE)
|
||||
{
|
||||
GPtrArray *minutiae;
|
||||
|
||||
minutiae = fp_image_get_minutiae (img);
|
||||
|
@ -167,7 +172,8 @@ update_image (LibfprintDemoWindow *win)
|
|||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
if (win->img == NULL) {
|
||||
if (win->img == NULL)
|
||||
{
|
||||
gtk_image_clear (GTK_IMAGE (win->capture_image));
|
||||
return;
|
||||
}
|
||||
|
@ -199,13 +205,16 @@ libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
|
|||
|
||||
scan_type = fp_device_get_scan_type (win->dev);
|
||||
|
||||
switch (scan_type) {
|
||||
switch (scan_type)
|
||||
{
|
||||
case FP_SCAN_TYPE_PRESS:
|
||||
message = "Place your finger on the fingerprint reader";
|
||||
break;
|
||||
|
||||
case FP_SCAN_TYPE_SWIPE:
|
||||
message = "Swipe your finger across the fingerprint reader";
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
@ -225,7 +234,8 @@ dev_capture_start_cb (FpDevice *dev,
|
|||
g_clear_object (&win->cancellable);
|
||||
|
||||
image = fp_device_capture_finish (dev, res, &error);
|
||||
if (!image) {
|
||||
if (!image)
|
||||
{
|
||||
g_warning ("Error capturing data: %s", error->message);
|
||||
if (error->domain == FP_DEVICE_RETRY ||
|
||||
g_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)
|
||||
{
|
||||
LibfprintDemoWindow *win = user_data;
|
||||
|
||||
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);
|
||||
libfprint_demo_set_mode (win, ERROR_MODE);
|
||||
return;
|
||||
|
@ -278,7 +290,8 @@ activate_capture (GSimpleAction *action,
|
|||
g_clear_object (&win->cancellable);
|
||||
win->cancellable = g_cancellable_new ();
|
||||
|
||||
if (win->opened) {
|
||||
if (win->opened)
|
||||
{
|
||||
dev_start_capture (win);
|
||||
return;
|
||||
}
|
||||
|
@ -411,19 +424,22 @@ libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
|||
{
|
||||
char *title;
|
||||
|
||||
switch (mode) {
|
||||
switch (mode)
|
||||
{
|
||||
case EMPTY_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "empty-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
case NOIMAGING_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "noimaging-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
case CAPTURE_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "capture-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
||||
|
@ -435,24 +451,28 @@ libfprint_demo_set_mode (LibfprintDemoWindow *win,
|
|||
|
||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
case SPINNER_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "spinner-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||
gtk_widget_set_sensitive (win->cancel_button, TRUE);
|
||||
gtk_spinner_start (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
case ERROR_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "error-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, FALSE);
|
||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
case RETRY_MODE:
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (win->mode_stack), "retry-mode");
|
||||
gtk_widget_set_sensitive (win->capture_button, TRUE);
|
||||
gtk_widget_set_sensitive (win->cancel_button, FALSE);
|
||||
gtk_spinner_stop (GTK_SPINNER (win->spinner));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
@ -490,18 +510,21 @@ libfprint_demo_window_init (LibfprintDemoWindow *window)
|
|||
ctx = fp_context_new ();
|
||||
|
||||
devices = fp_context_get_devices (ctx);
|
||||
if (!devices) {
|
||||
if (!devices)
|
||||
{
|
||||
libfprint_demo_set_mode (window, ERROR_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Empty list? */
|
||||
if (devices->len == 0) {
|
||||
if (devices->len == 0)
|
||||
{
|
||||
libfprint_demo_set_mode (window, EMPTY_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fp_device_supports_capture(g_ptr_array_index (devices, 0))) {
|
||||
if (!fp_device_supports_capture (g_ptr_array_index (devices, 0)))
|
||||
{
|
||||
libfprint_demo_set_mode (window, NOIMAGING_MODE);
|
||||
return;
|
||||
}
|
||||
|
@ -527,7 +550,8 @@ libfprint_demo_window_class_init (LibfprintDemoWindowClass *class)
|
|||
//FIXME setup dispose
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkApplication *app;
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#include "storage.h"
|
||||
|
||||
typedef struct _EnrollData {
|
||||
typedef struct _EnrollData
|
||||
{
|
||||
GMainLoop *loop;
|
||||
int ret_value;
|
||||
} EnrollData;
|
||||
|
@ -40,6 +41,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
|
|||
FpDevice *discover_device (GPtrArray * devices)
|
||||
{
|
||||
FpDevice *dev;
|
||||
|
||||
if (!devices->len)
|
||||
return NULL;
|
||||
|
||||
|
@ -49,8 +51,10 @@ FpDevice *discover_device (GPtrArray *devices)
|
|||
}
|
||||
|
||||
static void
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
EnrollData *enroll_data = user_data;
|
||||
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
fp_device_close_finish (dev, res, &error);
|
||||
|
@ -62,25 +66,32 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
|||
}
|
||||
|
||||
static void
|
||||
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
EnrollData *enroll_data = user_data;
|
||||
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
print = fp_device_enroll_finish (dev, res, &error);
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
enroll_data->ret_value = EXIT_SUCCESS;
|
||||
|
||||
if (!fp_device_has_storage (dev)) {
|
||||
if (!fp_device_has_storage (dev))
|
||||
{
|
||||
g_debug ("Device has not storage, saving locally");
|
||||
int r = print_data_save (print, FP_FINGER_RIGHT_INDEX);
|
||||
if (r < 0) {
|
||||
if (r < 0)
|
||||
{
|
||||
g_warning ("Data save failed, code %d", r);
|
||||
enroll_data->ret_value = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Enroll failed with error %s\n", error->message);
|
||||
}
|
||||
|
||||
|
@ -95,7 +106,8 @@ on_enroll_progress (FpDevice *device,
|
|||
gpointer user_data,
|
||||
GError *error)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Enroll stage %d of %d failed with error %s",
|
||||
completed_stages,
|
||||
fp_device_get_nr_enroll_stages (device),
|
||||
|
@ -104,9 +116,8 @@ on_enroll_progress (FpDevice *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 ("Enroll stage %d of %d passed. Yay!\n", completed_stages,
|
||||
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;
|
||||
FpPrint *print_template;
|
||||
|
||||
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_main_loop_quit (enroll_data->loop);
|
||||
return;
|
||||
|
@ -136,7 +149,8 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||
enroll_data);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
g_autoptr(FpContext) ctx = NULL;
|
||||
g_autoptr(EnrollData) enroll_data = NULL;
|
||||
|
@ -154,13 +168,15 @@ int main(void)
|
|||
ctx = fp_context_new ();
|
||||
|
||||
devices = fp_context_get_devices (ctx);
|
||||
if (!devices) {
|
||||
if (!devices)
|
||||
{
|
||||
g_warning ("Impossible to get devices");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dev = discover_device (devices);
|
||||
if (!dev) {
|
||||
if (!dev)
|
||||
{
|
||||
g_warning ("No devices detected.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
@ -122,8 +122,9 @@ delete_data_free (DeleteData *delete_data)
|
|||
}
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DeleteData, delete_data_free);
|
||||
|
||||
static void
|
||||
on_print_deleted (FpDevice *dev, GAsyncResult *res, gpointer user_data);
|
||||
static void on_print_deleted (FpDevice *dev,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
delete_next_print (FpDevice *dev,
|
||||
|
@ -145,6 +146,7 @@ on_print_deleted (FpDevice *dev,
|
|||
gpointer user_data)
|
||||
{
|
||||
ListData *list_data = user_data;
|
||||
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
GList *deleted_link;
|
||||
|
@ -162,7 +164,9 @@ on_print_deleted (FpDevice *dev,
|
|||
list_data->any_failed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Deleted print %s from device", fp_print_get_description (print));
|
||||
}
|
||||
|
||||
if (list_data->to_delete != NULL)
|
||||
{
|
||||
|
@ -184,6 +188,7 @@ on_list_completed (FpDevice *dev,
|
|||
gpointer user_data)
|
||||
{
|
||||
ListData *list_data = user_data;
|
||||
|
||||
g_autoptr(GPtrArray) prints = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
|
@ -247,11 +252,9 @@ on_list_completed (FpDevice *dev,
|
|||
if (list_data->to_delete)
|
||||
delete_next_print (dev, list_data);
|
||||
else
|
||||
{
|
||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||
list_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Getting prints failed with error %s", error->message);
|
||||
|
|
|
@ -34,10 +34,13 @@ get_print_data_descriptor (FpPrint *print, FpDevice *dev, FpFinger finger)
|
|||
const char *driver;
|
||||
const char *dev_id;
|
||||
|
||||
if (print) {
|
||||
if (print)
|
||||
{
|
||||
driver = fp_print_get_driver (print);
|
||||
dev_id = fp_print_get_device_id (print);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
driver = fp_device_get_driver (dev);
|
||||
dev_id = fp_device_get_device_id (dev);
|
||||
}
|
||||
|
@ -56,7 +59,8 @@ load_data(void)
|
|||
g_autofree gchar *contents = NULL;
|
||||
gssize length = 0;
|
||||
|
||||
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL)) {
|
||||
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL))
|
||||
{
|
||||
g_warning ("Error loading storage, assuming it is empty");
|
||||
return g_variant_dict_new (NULL);
|
||||
}
|
||||
|
@ -77,7 +81,8 @@ save_data(GVariant *data)
|
|||
length = g_variant_get_size (data);
|
||||
contents = (gchar *) g_variant_get_data (data);
|
||||
|
||||
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL)) {
|
||||
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL))
|
||||
{
|
||||
g_warning ("Error saving storage,!");
|
||||
return -1;
|
||||
}
|
||||
|
@ -92,6 +97,7 @@ int
|
|||
print_data_save (FpPrint *print, FpFinger finger)
|
||||
{
|
||||
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
|
||||
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GVariantDict) dict = NULL;
|
||||
g_autofree guchar *data = NULL;
|
||||
|
@ -102,7 +108,8 @@ print_data_save(FpPrint *print, FpFinger finger)
|
|||
dict = load_data ();
|
||||
|
||||
fp_print_serialize (print, &data, &size, &error);
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Error serializing data: %s", error->message);
|
||||
return -1;
|
||||
}
|
||||
|
@ -118,6 +125,7 @@ FpPrint *
|
|||
print_data_load (FpDevice *dev, FpFinger finger)
|
||||
{
|
||||
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
|
||||
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
g_autoptr(GVariantDict) dict = NULL;
|
||||
g_autofree guchar *stored_data = NULL;
|
||||
|
@ -126,7 +134,8 @@ print_data_load(FpDevice *dev, FpFinger finger)
|
|||
dict = load_data ();
|
||||
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
||||
|
||||
if (val) {
|
||||
if (val)
|
||||
{
|
||||
FpPrint *print;
|
||||
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);
|
||||
int r;
|
||||
|
||||
if (!fd) {
|
||||
if (!fd)
|
||||
{
|
||||
g_warning ("could not open '%s' for writing: %d", path, errno);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = fprintf (fd, "P5 %d %d 255\n",
|
||||
fp_image_get_width (img), fp_image_get_height (img));
|
||||
if (r < 0) {
|
||||
if (r < 0)
|
||||
{
|
||||
fclose (fd);
|
||||
g_critical ("pgm header write failed, error %d", r);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = fwrite (data, 1, write_size, fd);
|
||||
if (r < write_size) {
|
||||
if (r < write_size)
|
||||
{
|
||||
fclose (fd);
|
||||
g_critical ("short write (%d)", r);
|
||||
return FALSE;
|
||||
|
@ -197,7 +209,8 @@ save_image_to_pgm (FpImage *img, const char *path)
|
|||
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;
|
||||
|
||||
|
|
|
@ -22,9 +22,13 @@
|
|||
#define __STORAGE_H
|
||||
|
||||
|
||||
int print_data_save(FpPrint *print, FpFinger finger);
|
||||
FpPrint * print_data_load(FpDevice *dev, FpFinger finger);
|
||||
FpPrint * print_create_template(FpDevice *dev, FpFinger finger);
|
||||
gboolean print_image_save(FpPrint *print, const char *path);
|
||||
int print_data_save (FpPrint *print,
|
||||
FpFinger finger);
|
||||
FpPrint * print_data_load (FpDevice *dev,
|
||||
FpFinger finger);
|
||||
FpPrint * print_create_template (FpDevice *dev,
|
||||
FpFinger finger);
|
||||
gboolean print_image_save (FpPrint *print,
|
||||
const char *path);
|
||||
|
||||
#endif /* __STORAGE_H */
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#include "storage.h"
|
||||
|
||||
typedef struct _VerifyData {
|
||||
typedef struct _VerifyData
|
||||
{
|
||||
GMainLoop *loop;
|
||||
int ret_value;
|
||||
} VerifyData;
|
||||
|
@ -40,6 +41,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyData, verify_data_free)
|
|||
FpDevice *discover_device (GPtrArray * devices)
|
||||
{
|
||||
FpDevice *dev;
|
||||
|
||||
if (!devices->len)
|
||||
return NULL;
|
||||
|
||||
|
@ -49,8 +51,10 @@ FpDevice *discover_device (GPtrArray *devices)
|
|||
}
|
||||
|
||||
static void
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
VerifyData *verify_data = user_data;
|
||||
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void start_verification (FpDevice *dev, VerifyData *verify_data);
|
||||
static void start_verification (FpDevice *dev,
|
||||
VerifyData *verify_data);
|
||||
|
||||
static void
|
||||
on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
VerifyData *verify_data = user_data;
|
||||
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
char buffer[20];
|
||||
gboolean match;
|
||||
|
||||
if (!fp_device_verify_finish (dev, res, &match, &print, &error)) {
|
||||
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
|
||||
{
|
||||
g_warning ("Failed to verify print: %s", error->message);
|
||||
g_main_loop_quit (verify_data->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
if (match)
|
||||
{
|
||||
g_print ("MATCH!\n");
|
||||
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");
|
||||
}
|
||||
|
||||
verify_data->ret_value = EXIT_SUCCESS;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("NO MATCH!\n");
|
||||
verify_data->ret_value = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
g_print ("Verify again? [Y/n]? ");
|
||||
if (fgets (buffer, sizeof (buffer), stdin) &&
|
||||
(buffer[0] == 'Y' || buffer[0] == 'y')) {
|
||||
(buffer[0] == 'Y' || buffer[0] == 'y'))
|
||||
{
|
||||
start_verification (dev, verify_data);
|
||||
return;
|
||||
}
|
||||
|
@ -106,23 +116,27 @@ static void
|
|||
on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
VerifyData *verify_data = user_data;
|
||||
|
||||
g_autoptr(GPtrArray) prints = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
prints = fp_device_list_prints_finish (dev, res, &error);
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
FpPrint *verify_print = NULL;
|
||||
guint i;
|
||||
|
||||
if (!prints->len)
|
||||
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];
|
||||
|
||||
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 ||
|
||||
(g_date_compare (fp_print_get_enroll_date (print),
|
||||
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 "
|
||||
"finger first?");
|
||||
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,
|
||||
(GAsyncReadyCallback) on_verify_completed,
|
||||
verify_data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Loading prints failed with error %s", error->message);
|
||||
g_main_loop_quit (verify_data->loop);
|
||||
}
|
||||
|
@ -153,18 +170,22 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
|||
static void
|
||||
start_verification (FpDevice *dev, VerifyData *verify_data)
|
||||
{
|
||||
if (fp_device_has_storage (dev)) {
|
||||
if (fp_device_has_storage (dev))
|
||||
{
|
||||
g_print ("Creating finger template, using device storage...\n");
|
||||
fp_device_list_prints (dev, NULL,
|
||||
(GAsyncReadyCallback) on_list_completed,
|
||||
verify_data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("Loading previously enrolled right index finger data...\n");
|
||||
g_autoptr(FpPrint) verify_print;
|
||||
|
||||
verify_print = print_data_load (dev, FP_FINGER_RIGHT_INDEX);
|
||||
|
||||
if (!verify_print) {
|
||||
if (!verify_print)
|
||||
{
|
||||
g_warning ("Failed to load fingerprint data");
|
||||
g_warning ("Did you remember to enroll your right index "
|
||||
"finger first?");
|
||||
|
@ -183,9 +204,11 @@ static void
|
|||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
VerifyData *verify_data = user_data;
|
||||
|
||||
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_main_loop_quit (verify_data->loop);
|
||||
return;
|
||||
|
@ -196,7 +219,8 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||
start_verification (dev, verify_data);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
g_autoptr(FpContext) ctx = NULL;
|
||||
g_autoptr(VerifyData) verify_data = NULL;
|
||||
|
@ -209,13 +233,15 @@ int main(void)
|
|||
ctx = fp_context_new ();
|
||||
|
||||
devices = fp_context_get_devices (ctx);
|
||||
if (!devices) {
|
||||
if (!devices)
|
||||
{
|
||||
g_warning ("Impossible to get devices");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dev = discover_device (devices);
|
||||
if (!dev) {
|
||||
if (!dev)
|
||||
{
|
||||
g_warning ("No devices detected.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -231,5 +257,3 @@ int main(void)
|
|||
|
||||
return verify_data->ret_value;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
static void start_capture (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 LAST_AES1610_REG 0xFF
|
||||
|
@ -69,7 +70,8 @@ static int adjust_gain(unsigned char *buffer, int status);
|
|||
|
||||
/****** GENERAL FUNCTIONS ******/
|
||||
|
||||
struct _FpiDeviceAes1610 {
|
||||
struct _FpiDeviceAes1610
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
guint8 read_regs_retry_count;
|
||||
|
@ -89,10 +91,13 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
|||
.get_pixel = aes_get_pixel,
|
||||
};
|
||||
|
||||
typedef void (*aes1610_read_regs_cb)(FpImageDevice *dev, int status,
|
||||
unsigned char *regs, void *user_data);
|
||||
typedef void (*aes1610_read_regs_cb)(FpImageDevice *dev,
|
||||
int status,
|
||||
unsigned char *regs,
|
||||
void *user_data);
|
||||
|
||||
struct aes1610_read_regs {
|
||||
struct aes1610_read_regs
|
||||
{
|
||||
FpImageDevice *dev;
|
||||
aes1610_read_regs_cb callback;
|
||||
struct aes_regwrite *regwrite;
|
||||
|
@ -100,10 +105,12 @@ struct aes1610_read_regs {
|
|||
};
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_warn ("Error stopping capture: %s", error->message);
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
if (error)
|
||||
|
@ -120,10 +128,12 @@ static void generic_ignore_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
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)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
|
||||
if (!error)
|
||||
fpi_ssm_next_state (ssm);
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
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 finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||
static void
|
||||
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -185,7 +197,8 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
int i;
|
||||
int sum = 0;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -193,24 +206,29 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
/* examine histogram to determine finger presence */
|
||||
for (i = 3; i < 17; i++)
|
||||
sum += (data[i] & 0xf) + (data[i] >> 4);
|
||||
if (sum > 20) {
|
||||
if (sum > 20)
|
||||
{
|
||||
/* reset default gain */
|
||||
adjust_gain (data, GAIN_STATUS_FIRST);
|
||||
/* finger present, start capturing */
|
||||
fpi_image_device_report_finger_status (dev, TRUE);
|
||||
start_capture (dev);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no finger, poll for a new histogram */
|
||||
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)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -223,11 +241,13 @@ static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
|
|||
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);
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -393,7 +413,8 @@ static unsigned char list_BD_values[10] = {
|
|||
* 0xbd, 0xbe, 0x29 and 0x2A registers are affected
|
||||
* Returns 0 if no problem occurred
|
||||
* 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
|
||||
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)
|
||||
// We adjust strip_scan_reqs for future strips and capture_reqs that is sent just after this step
|
||||
if (status == GAIN_STATUS_FIRST) {
|
||||
if (buffer[1] > 0x78) { // maximum gain needed
|
||||
if (status == GAIN_STATUS_FIRST)
|
||||
{
|
||||
if (buffer[1] > 0x78) // maximum gain needed
|
||||
{
|
||||
strip_scan_reqs[0].value = 0x6B;
|
||||
strip_scan_reqs[1].value = 0x06;
|
||||
strip_scan_reqs[2].value = 0x35;
|
||||
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[1].value = 0x15;
|
||||
strip_scan_reqs[2].value = 0x35;
|
||||
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[1].value = 0x13;
|
||||
strip_scan_reqs[2].value = 0x35;
|
||||
strip_scan_reqs[3].value = 0x30;
|
||||
}
|
||||
else { // minimum gain needed
|
||||
else // minimum gain needed
|
||||
{
|
||||
strip_scan_reqs[0].value = 0x23;
|
||||
strip_scan_reqs[1].value = 0x07;
|
||||
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);
|
||||
}
|
||||
|
||||
// Every 2/3 strips
|
||||
// We try to soften big changes of the gain (at least for 0xBE and 0xBD
|
||||
// FIXME: This softenning will need testing and tweaking too
|
||||
else if (status == GAIN_STATUS_NORMAL) {
|
||||
if (buffer[514] > 0x78) { // maximum gain needed
|
||||
else if (status == GAIN_STATUS_NORMAL)
|
||||
{
|
||||
if (buffer[514] > 0x78) // maximum gain needed
|
||||
{
|
||||
if (pos_list_BE < 7)
|
||||
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[2].value = 0x35;
|
||||
}
|
||||
else if (buffer[514] > 0x55) {
|
||||
else if (buffer[514] > 0x55)
|
||||
{
|
||||
if (pos_list_BE < 2)
|
||||
pos_list_BE++;
|
||||
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[2].value = 0x35;
|
||||
}
|
||||
else if (buffer[514] > 0x40 || buffer[529] > 0x19) {
|
||||
else if (buffer[514] > 0x40 || buffer[529] > 0x19)
|
||||
{
|
||||
if (pos_list_BE < 1)
|
||||
pos_list_BE++;
|
||||
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[2].value = 0x35;
|
||||
}
|
||||
else { // minimum gain needed
|
||||
else // minimum gain needed
|
||||
{
|
||||
if (pos_list_BE > 0)
|
||||
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);
|
||||
}
|
||||
// Unknown status
|
||||
else {
|
||||
else
|
||||
{
|
||||
fp_err ("Unexpected gain status.");
|
||||
return 1;
|
||||
}
|
||||
|
@ -505,7 +536,8 @@ static int adjust_gain(unsigned char *buffer, int status)
|
|||
|
||||
/*
|
||||
* 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[1].value = 0x04;
|
||||
|
@ -532,7 +564,8 @@ enum capture_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)
|
||||
{
|
||||
unsigned char *stripdata;
|
||||
|
@ -541,7 +574,8 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
unsigned char *data = transfer->buffer;
|
||||
gint sum, i;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
@ -550,14 +584,13 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
|
||||
sum = 0;
|
||||
for (i = 516; i < 530; i++)
|
||||
{
|
||||
/* histogram[i] = number of pixels of value i
|
||||
Only the pixel values from 10 to 15 are used to detect finger. */
|
||||
sum += data[i];
|
||||
}
|
||||
|
||||
fp_dbg ("sum=%d", sum);
|
||||
if (sum > 0) {
|
||||
if (sum > 0)
|
||||
{
|
||||
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
||||
struct fpi_frame *stripe = g_malloc (FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof (struct fpi_frame));
|
||||
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_len++;
|
||||
self->blanks_count = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: 0 might be too low as a threshold */
|
||||
/* FIXME: sometimes we get 0 in the middle of a scan, should we wait for
|
||||
* a few consecutive zeroes? */
|
||||
|
@ -582,7 +617,8 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
adjust_gain (data, GAIN_STATUS_NORMAL);
|
||||
|
||||
/* 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;
|
||||
|
||||
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);
|
||||
/* Acquisition finished: restore default gain values */
|
||||
restore_gain ();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* obtain next 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;
|
||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case CAPTURE_WRITE_REQS:
|
||||
fp_dbg ("write reqs");
|
||||
aes_write_regv (dev, capture_reqs, G_N_ELEMENTS (capture_reqs),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA:
|
||||
fp_dbg ("read data");
|
||||
generic_read_ignore_data (ssm, _dev, STRIP_CAPTURE_LEN);
|
||||
break;
|
||||
|
||||
case CAPTURE_REQUEST_STRIP:
|
||||
fp_dbg ("request strip");
|
||||
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),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_STRIP:;
|
||||
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);
|
||||
fpi_usb_transfer_unref (transfer);
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
start_finger_detection (dev);
|
||||
}
|
||||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -697,13 +749,15 @@ enum activate_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;
|
||||
|
||||
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
||||
/* verify there's anything missing here */
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case WRITE_INIT:
|
||||
fp_dbg ("write init");
|
||||
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 */
|
||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
||||
static void
|
||||
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||
void *user_data, GError *error)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
||||
fpi_image_device_activate_complete (dev, error);
|
||||
|
||||
if (!error)
|
||||
|
@ -723,26 +779,32 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
self->read_regs_retry_count = 0;
|
||||
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);
|
||||
|
||||
/* FIXME: audit cancellation points, probably need more, specifically
|
||||
* in error handling paths? */
|
||||
self->deactivating = TRUE;
|
||||
}
|
||||
|
||||
static void complete_deactivation(FpImageDevice *dev)
|
||||
static void
|
||||
complete_deactivation (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* 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);
|
||||
return;
|
||||
}
|
||||
|
@ -769,7 +834,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -779,14 +845,17 @@ static void dev_deinit(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x08ff, .pid = 0x1600,
|
||||
}, /* AES1600 */
|
||||
{ .vid = 0x08ff, .pid = 0x1600, },/* AES1600 */
|
||||
{ .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);
|
||||
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_height = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#define FRAME_WIDTH 128
|
||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||
|
||||
struct _FpiDeviceAes1660 {
|
||||
struct _FpiDeviceAes1660
|
||||
{
|
||||
FpiDeviceAesX660 parent;
|
||||
};
|
||||
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 },
|
||||
};
|
||||
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||
|
|
|
@ -63,7 +63,8 @@ static void complete_deactivation(FpImageDevice *dev);
|
|||
|
||||
/****** GENERAL FUNCTIONS ******/
|
||||
|
||||
struct _FpiDeviceAes2501 {
|
||||
struct _FpiDeviceAes2501
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
guint8 read_regs_retry_count;
|
||||
|
@ -83,17 +84,21 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
|||
.get_pixel = aes_get_pixel,
|
||||
};
|
||||
|
||||
typedef void (*aes2501_read_regs_cb)(FpImageDevice *dev, GError *error,
|
||||
unsigned char *regs, void *user_data);
|
||||
typedef void (*aes2501_read_regs_cb)(FpImageDevice *dev,
|
||||
GError *error,
|
||||
unsigned char *regs,
|
||||
void *user_data);
|
||||
|
||||
struct aes2501_read_regs {
|
||||
struct aes2501_read_regs
|
||||
{
|
||||
FpImageDevice *dev;
|
||||
aes2501_read_regs_cb callback;
|
||||
struct aes_regwrite *regwrite;
|
||||
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)
|
||||
{
|
||||
struct aes2501_read_regs *rdata = user_data;
|
||||
|
@ -102,13 +107,15 @@ static void read_regs_data_cb(FpiUsbTransfer *transfer, FpDevice *dev,
|
|||
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;
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
g_free (rdata->regwrite);
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
rdata->callback (dev, error, NULL, rdata->user_data);
|
||||
g_free (rdata);
|
||||
return;
|
||||
|
@ -122,7 +129,8 @@ static void read_regs_rq_cb(FpImageDevice *dev, GError *error, void *user_data)
|
|||
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)
|
||||
{
|
||||
/* 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 */
|
||||
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");
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
@ -160,10 +171,12 @@ static int regval_from_dump(unsigned char *data, guint8 target)
|
|||
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)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
|
||||
if (!error)
|
||||
fpi_ssm_next_state (ssm);
|
||||
else
|
||||
|
@ -171,10 +184,12 @@ static void generic_write_regv_cb(FpImageDevice *dev, GError *error,
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
FpiSsm *ssm = transfer->ssm;
|
||||
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
|
@ -199,7 +215,8 @@ static void generic_read_ignore_data(FpiSsm *ssm, FpDevice *dev,
|
|||
|
||||
/****** 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 i;
|
||||
|
@ -250,7 +267,8 @@ static const struct aes_regwrite finger_det_reqs[] = {
|
|||
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||
|
@ -258,7 +276,8 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
|
|||
int i;
|
||||
int sum = 0;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -266,22 +285,27 @@ static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
|
|||
/* examine histogram to determine finger presence */
|
||||
for (i = 1; i < 9; i++)
|
||||
sum += (data[i] & 0xf) + (data[i] >> 4);
|
||||
if (sum > 20) {
|
||||
if (sum > 20)
|
||||
{
|
||||
/* finger present, start capturing */
|
||||
fpi_image_device_report_finger_status (dev, TRUE);
|
||||
start_capture (dev);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no finger, poll for a new histogram */
|
||||
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)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -294,12 +318,15 @@ static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
|
|||
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);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -383,7 +410,8 @@ enum capture_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)
|
||||
{
|
||||
FpiSsm *ssm = transfer->ssm;
|
||||
|
@ -394,32 +422,38 @@ static void capture_read_strip_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
|
|||
int sum;
|
||||
int threshold;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
threshold = regval_from_dump (data + 1 + 192 * 8 + 1 + 16 * 2 + 1 + 8,
|
||||
AES2501_REG_DATFMT);
|
||||
if (threshold < 0) {
|
||||
if (threshold < 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
return;
|
||||
}
|
||||
|
||||
sum = sum_histogram_values (data + 1 + 192 * 8, threshold & 0x0f);
|
||||
if (sum < 0) {
|
||||
if (sum < 0)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
return;
|
||||
}
|
||||
fp_dbg ("sum=%d", sum);
|
||||
|
||||
if (sum < AES2501_SUM_LOW_THRESH) {
|
||||
if (sum < AES2501_SUM_LOW_THRESH)
|
||||
{
|
||||
strip_scan_reqs[4].value -= 0x8;
|
||||
if (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;
|
||||
if (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
|
||||
* to ensure
|
||||
*/
|
||||
if (sum == 0) {
|
||||
if (sum == 0)
|
||||
{
|
||||
self->no_finger_cnt++;
|
||||
if (self->no_finger_cnt == 3) {
|
||||
if (self->no_finger_cnt == 3)
|
||||
{
|
||||
FpImage *img;
|
||||
|
||||
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);
|
||||
/* marking machine complete will re-trigger finger detection loop */
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* obtain next strip */
|
||||
/* FIXME: would preallocating strip buffers be a decent optimization? */
|
||||
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;
|
||||
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:
|
||||
aes_write_regv (dev, capture_reqs_1, G_N_ELEMENTS (capture_reqs_1),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA_1:
|
||||
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
|
||||
break;
|
||||
|
||||
case CAPTURE_WRITE_REQS_2:
|
||||
aes_write_regv (dev, capture_reqs_2, G_N_ELEMENTS (capture_reqs_2),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA_2:
|
||||
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
|
||||
break;
|
||||
|
||||
case CAPTURE_REQUEST_STRIP:
|
||||
if (self->deactivating)
|
||||
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),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_STRIP: {
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
|
@ -503,10 +550,12 @@ static void capture_run_state(FpiSsm *ssm, FpDevice *device, void *user_data)
|
|||
fpi_usb_transfer_unref (transfer);
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -514,23 +563,30 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
g_clear_pointer (&error, g_error_free);
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
start_finger_detection (dev);
|
||||
}
|
||||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -649,15 +705,19 @@ enum activate_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)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("reg 0xaf = %x", regs[0x5f]);
|
||||
if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13)
|
||||
fpi_ssm_jump_to_state (ssm, WRITE_INIT_4);
|
||||
|
@ -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)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
|
||||
if (!error)
|
||||
fpi_ssm_jump_to_state (ssm, READ_REGS);
|
||||
else
|
||||
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;
|
||||
|
||||
|
@ -699,30 +762,37 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
aes_write_regv(init_4);
|
||||
*/
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case WRITE_INIT_1:
|
||||
aes_write_regv (dev, init_1, G_N_ELEMENTS (init_1),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case READ_DATA_1:
|
||||
fp_dbg ("read data 1");
|
||||
generic_read_ignore_data (ssm, _dev, FINGER_DETECTION_LEN);
|
||||
break;
|
||||
|
||||
case WRITE_INIT_2:
|
||||
aes_write_regv (dev, init_2, G_N_ELEMENTS (init_2),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case READ_REGS:
|
||||
read_regs (dev, activate_read_regs_cb, ssm);
|
||||
break;
|
||||
|
||||
case WRITE_INIT_3:
|
||||
aes_write_regv (dev, init_3, G_N_ELEMENTS (init_3),
|
||||
activate_init3_cb, ssm);
|
||||
break;
|
||||
|
||||
case WRITE_INIT_4:
|
||||
aes_write_regv (dev, init_4, G_N_ELEMENTS (init_4),
|
||||
generic_write_regv_cb, ssm);
|
||||
break;
|
||||
|
||||
case WRITE_INIT_5:
|
||||
aes_write_regv (dev, init_5, G_N_ELEMENTS (init_5),
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
self->read_regs_retry_count = 0;
|
||||
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);
|
||||
|
||||
/* FIXME: audit cancellation points, probably need more, specifically
|
||||
* in error handling paths? */
|
||||
self->deactivating = TRUE;
|
||||
}
|
||||
|
||||
static void complete_deactivation(FpImageDevice *dev)
|
||||
static void
|
||||
complete_deactivation (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* FIXME check endpoints */
|
||||
|
||||
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||
fpi_image_device_open_complete (dev, error);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -791,16 +871,18 @@ static void dev_deinit(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x08ff, .pid = 0x2500,
|
||||
}, /* AES2500 */
|
||||
{ .vid = 0x08ff, .pid = 0x2580,
|
||||
}, /* AES2501 */
|
||||
{ .vid = 0x08ff, .pid = 0x2500, },/* AES2500 */
|
||||
{ .vid = 0x08ff, .pid = 0x2580, },/* AES2501 */
|
||||
{ .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);
|
||||
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_height = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ static void complete_deactivation(FpImageDevice *dev);
|
|||
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||
|
||||
struct _FpiDeviceAes2550 {
|
||||
struct _FpiDeviceAes2550
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
GSList *strips;
|
||||
|
@ -85,13 +86,15 @@ static unsigned char finger_det_reqs[] = {
|
|||
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
unsigned char *data = transfer->buffer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
||||
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]);
|
||||
|
||||
/* Check if we got 2 bytes, reg address 0x83 and its value */
|
||||
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT)) {
|
||||
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT))
|
||||
{
|
||||
/* finger present, start capturing */
|
||||
fpi_image_device_report_finger_status (dev, TRUE);
|
||||
start_capture (dev);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no finger, poll for a new histogram */
|
||||
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)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
FpImageDevice *dev = user_data;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -129,13 +137,16 @@ static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
|
|||
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);
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -177,7 +188,8 @@ enum capture_states {
|
|||
};
|
||||
|
||||
/* 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 *stripdata;
|
||||
|
@ -185,14 +197,14 @@ static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
|
|||
struct fpi_frame *stripe;
|
||||
int len;
|
||||
|
||||
if (data[0] != AES2550_EDATA_MAGIC) {
|
||||
if (data[0] != AES2550_EDATA_MAGIC)
|
||||
{
|
||||
fp_dbg ("Bogus magic: %.2x\n", (int) (data[0]));
|
||||
return FALSE;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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_y = -(int8_t) data[7];
|
||||
|
@ -206,24 +218,26 @@ static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
|
|||
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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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,
|
||||
GError *error)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||
|
||||
if (!error && self->strips_len) {
|
||||
if (!error && self->strips_len)
|
||||
{
|
||||
FpImage *img;
|
||||
|
||||
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);
|
||||
/* marking machine complete will re-trigger finger detection loop */
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||
unsigned char *data = transfer->buffer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
@ -260,9 +278,11 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
if (transfer->actual_length >= 2)
|
||||
fp_dbg ("data: %.2x %.2x", (int) data[0], (int) data[1]);
|
||||
|
||||
switch (transfer->actual_length) {
|
||||
switch (transfer->actual_length)
|
||||
{
|
||||
case AES2550_STRIP_SIZE:
|
||||
if (!process_strip_data(transfer->ssm, dev, data)) {
|
||||
if (!process_strip_data (transfer->ssm, dev, data))
|
||||
{
|
||||
fp_dbg ("Processing strip data failed");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
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;
|
||||
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||
break;
|
||||
|
||||
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 */
|
||||
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,
|
||||
* assemble image and submit it to the library */
|
||||
fp_dbg ("Got 3 heartbeats => finger removed");
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
CAPTURE_READ_DATA);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fp_dbg ("Short frame %d, skip",
|
||||
(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:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_SET_IDLE:
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -347,23 +379,30 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
|
||||
fp_dbg ("Capture completed");
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
g_clear_pointer (&error, g_error_free);
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
start_finger_detection (dev);
|
||||
}
|
||||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -399,41 +438,43 @@ enum activate_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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: use calibration table, datasheet is rather terse on that
|
||||
* 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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case READ_DATA:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIBRATE:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case READ_CALIB_TABLE:
|
||||
{
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -498,23 +543,28 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
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,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
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);
|
||||
|
||||
self->deactivating = TRUE;
|
||||
}
|
||||
|
||||
static void complete_deactivation(FpImageDevice *dev)
|
||||
static void
|
||||
complete_deactivation (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
self->deactivating = FALSE;
|
||||
|
@ -524,9 +574,11 @@ static void complete_deactivation(FpImageDevice *dev)
|
|||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* TODO check that device has endpoints we're using */
|
||||
|
||||
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||
|
@ -534,7 +586,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, error);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -544,16 +597,18 @@ static void dev_deinit(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x08ff, .pid = 0x2550,
|
||||
}, /* AES2550 */
|
||||
{ .vid = 0x08ff, .pid = 0x2810,
|
||||
}, /* AES2810 */
|
||||
{ .vid = 0x08ff, .pid = 0x2550, },/* AES2550 */
|
||||
{ .vid = 0x08ff, .pid = 0x2810, },/* AES2810 */
|
||||
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||
};
|
||||
|
||||
static void fpi_device_aes2550_init(FpiDeviceAes2550 *self) {
|
||||
static void
|
||||
fpi_device_aes2550_init (FpiDeviceAes2550 *self)
|
||||
{
|
||||
}
|
||||
static void fpi_device_aes2550_class_init(FpiDeviceAes2550Class *klass) {
|
||||
static void
|
||||
fpi_device_aes2550_class_init (FpiDeviceAes2550Class *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#define FRAME_WIDTH 192
|
||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||
|
||||
struct _FpiDeviceAes2660 {
|
||||
struct _FpiDeviceAes2660
|
||||
{
|
||||
FpiDeviceAesX660 parent;
|
||||
};
|
||||
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 },
|
||||
};
|
||||
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
FpiDeviceAesX660Class *aes_class = FPI_DEVICE_AES_X660_CLASS (klass);
|
||||
|
|
|
@ -115,7 +115,8 @@ static struct aes_regwrite init_reqs[] = {
|
|||
{ 0x81, 0x00 },
|
||||
};
|
||||
|
||||
struct _FpiDeviceAes3500 {
|
||||
struct _FpiDeviceAes3500
|
||||
{
|
||||
FpiDeviceAes3k parent;
|
||||
};
|
||||
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 },
|
||||
};
|
||||
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
#include "aeslib.h"
|
||||
#include "aes3k.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
FpiUsbTransfer *img_trf;
|
||||
gboolean deactivating;
|
||||
} 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);
|
||||
|
||||
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)
|
||||
{
|
||||
size_t row, column;
|
||||
|
||||
for (column = 0; column < width; column++) {
|
||||
for (row = 0; row < height; row += 2) {
|
||||
for (column = 0; column < width; column++)
|
||||
{
|
||||
for (row = 0; row < height; row += 2)
|
||||
{
|
||||
output[width * row + column] = (*input & 0x0f) * 17;
|
||||
output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -81,10 +86,12 @@ static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
|
||||
priv->img_trf = NULL;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED)) {
|
||||
G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
/* Deactivation was completed. */
|
||||
g_error_free (error);
|
||||
if (priv->deactivating)
|
||||
|
@ -101,7 +108,8 @@ static void img_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
tmp->width = cls->frame_width;
|
||||
tmp->height = cls->frame_width;
|
||||
tmp->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
|
||||
for (i = 0; i < cls->frame_number; i++) {
|
||||
for (i = 0; i < cls->frame_number; i++)
|
||||
{
|
||||
fp_dbg ("frame header byte %02x", *ptr);
|
||||
ptr++;
|
||||
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);
|
||||
}
|
||||
|
||||
static void do_capture(FpImageDevice *dev)
|
||||
static void
|
||||
do_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!result)
|
||||
do_capture (dev);
|
||||
}
|
||||
|
||||
static void aes3k_dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
aes3k_dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||
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);
|
||||
}
|
||||
|
||||
static void aes3k_dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
aes3k_dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
|
||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
|
||||
{
|
||||
fpi_image_device_open_complete (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -179,7 +195,8 @@ static void aes3k_dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void aes3k_dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
aes3k_dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ G_DECLARE_DERIVABLE_TYPE(FpiDeviceAes3k, fpi_device_aes3k, FPI,
|
|||
|
||||
#define FPI_TYPE_DEVICE_AES3K (fpi_device_aes3k_get_type ())
|
||||
|
||||
struct _FpiDeviceAes3kClass {
|
||||
struct _FpiDeviceAes3kClass
|
||||
{
|
||||
FpImageDeviceClass parent;
|
||||
|
||||
gsize frame_width; /* image size = frame_width x frame_width */
|
||||
|
|
|
@ -112,7 +112,8 @@ static struct aes_regwrite init_reqs[] = {
|
|||
{ 0x81, 0x00 },
|
||||
};
|
||||
|
||||
struct _FpiDeviceAes4000 {
|
||||
struct _FpiDeviceAes4000
|
||||
{
|
||||
FpiDeviceAes3k parent;
|
||||
};
|
||||
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 },
|
||||
};
|
||||
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
FpiDeviceAes3kClass *aes_class = FPI_DEVICE_AES3K_CLASS (klass);
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||
|
||||
struct write_regv_data {
|
||||
struct write_regv_data
|
||||
{
|
||||
unsigned int num_regs;
|
||||
const struct aes_regwrite *regs;
|
||||
unsigned int offset;
|
||||
|
@ -42,25 +43,31 @@ struct write_regv_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
|
||||
* 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)
|
||||
{
|
||||
struct write_regv_data *wdata = user_data;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
|
||||
g_free (wdata);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
continue_write_regv (FP_IMAGE_DEVICE (device), wdata);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 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);
|
||||
|
||||
for (i = offset; i < offset + num; i++) {
|
||||
for (i = offset; i < offset + num; i++)
|
||||
{
|
||||
const struct aes_regwrite *regwrite = &wdata->regs[i];
|
||||
transfer->buffer[data_offset++] = regwrite->reg;
|
||||
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,
|
||||
* 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 regs_remaining;
|
||||
|
@ -94,8 +103,10 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
|
|||
int i;
|
||||
|
||||
/* skip all zeros and ensure there is still work to do */
|
||||
while (TRUE) {
|
||||
if (offset >= wdata->num_regs) {
|
||||
while (TRUE)
|
||||
{
|
||||
if (offset >= wdata->num_regs)
|
||||
{
|
||||
fp_dbg ("all registers written");
|
||||
wdata->callback (dev, 0, wdata->user_data);
|
||||
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
|
||||
* is a zero dividing things up */
|
||||
for (i = offset; i <= upper_bound; i++)
|
||||
if (!wdata->regs[i].reg) {
|
||||
if (!wdata->regs[i].reg)
|
||||
{
|
||||
upper_bound = i - 1;
|
||||
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
|
||||
* 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. */
|
||||
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,
|
||||
void *user_data)
|
||||
{
|
||||
|
@ -143,7 +156,8 @@ void aes_write_regv(FpImageDevice *dev, const struct aes_regwrite *regs,
|
|||
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,
|
||||
unsigned int x,
|
||||
unsigned int y)
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
#include <fprint.h>
|
||||
|
||||
struct aes_regwrite {
|
||||
struct aes_regwrite
|
||||
{
|
||||
unsigned char reg;
|
||||
unsigned char value;
|
||||
};
|
||||
|
@ -30,11 +31,14 @@ struct aes_regwrite {
|
|||
struct fpi_frame;
|
||||
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 aes_write_regv(FpImageDevice *dev, const struct aes_regwrite *regs,
|
||||
unsigned int num_regs, aes_write_regv_cb callback,
|
||||
void aes_write_regv (FpImageDevice *dev,
|
||||
const struct aes_regwrite *regs,
|
||||
unsigned int num_regs,
|
||||
aes_write_regv_cb callback,
|
||||
void *user_data);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#include "aeslib.h"
|
||||
#include "aesx660.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
GByteArray *stripe_packet;
|
||||
GSList *strips;
|
||||
size_t strips_len;
|
||||
|
@ -102,28 +103,31 @@ aesX660_read_response(FpiSsm *ssm,
|
|||
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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
unsigned char *data = transfer->buffer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
/* Calibrate response was read correctly? */
|
||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
|
||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE)
|
||||
{
|
||||
fp_dbg ("Bogus calibrate response: %.2x\n", data[0]);
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
|
@ -144,7 +148,8 @@ enum finger_det_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,
|
||||
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);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("Failed to read FD data\n");
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
|
||||
if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE)
|
||||
{
|
||||
fp_dbg ("Bogus FD response: %.2x\n", data[0]);
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
|
@ -171,28 +179,32 @@ static void finger_det_read_fd_data_cb(FpiUsbTransfer *transfer,
|
|||
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... */
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("Wait for finger returned %.2x as result\n",
|
||||
data[AESX660_FINGER_PRESENT_OFFSET]);
|
||||
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,
|
||||
GError *error)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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)
|
||||
{
|
||||
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_ssm_free (ssm);
|
||||
|
||||
if (priv->deactivating) {
|
||||
if (priv->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_image_device_report_finger_status (dev, TRUE);
|
||||
start_capture (dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void finger_det_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||
static void
|
||||
finger_det_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||
{
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
case FINGER_DET_SEND_LED_CMD:
|
||||
aesX660_send_cmd (ssm, dev, led_blink_cmd, sizeof (led_blink_cmd),
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case FINGER_DET_SEND_FD_CMD:
|
||||
aesX660_send_cmd_timeout (ssm, dev, wait_for_finger_cmd, sizeof (wait_for_finger_cmd),
|
||||
aesX660_send_cmd_cb, 0);
|
||||
break;
|
||||
|
||||
case FINGER_DET_READ_FD_DATA:
|
||||
aesX660_read_response (ssm, dev, TRUE, TRUE, FINGER_DET_DATA_LEN, finger_det_read_fd_data_cb);
|
||||
break;
|
||||
|
||||
case FINGER_DET_SET_IDLE:
|
||||
aesX660_send_cmd (ssm, dev, set_idle_cmd, sizeof (set_idle_cmd),
|
||||
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);
|
||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (priv->deactivating) {
|
||||
if (priv->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -263,7 +287,8 @@ enum capture_states {
|
|||
};
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
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!",
|
||||
length,
|
||||
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];
|
||||
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);
|
||||
|
||||
priv->strips = g_slist_prepend (priv->strips, stripe);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
FpiDeviceAesX660Class *cls = FPI_DEVICE_AES_X660_GET_CLASS (self);
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
FpImage *img;
|
||||
|
||||
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_report_finger_status (dev, FALSE);
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
||||
static void
|
||||
capture_read_stripe_data_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device, gpointer user_data,
|
||||
GError *error)
|
||||
{
|
||||
|
@ -335,14 +367,16 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
|
|||
int finger_missing = 0;
|
||||
size_t actual_length = transfer->actual_length;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_byte_array_set_size (priv->stripe_packet, 0);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fp_dbg ("Got %lu bytes of data", actual_length);
|
||||
while (actual_length) {
|
||||
while (actual_length)
|
||||
{
|
||||
gssize payload_length;
|
||||
gssize still_needed_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");
|
||||
|
||||
if (finger_missing) {
|
||||
if (finger_missing)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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);
|
||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (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:
|
||||
aesX660_send_cmd (ssm, _dev, led_solid_cmd, sizeof (led_solid_cmd),
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case CAPTURE_SEND_CAPTURE_CMD:
|
||||
g_byte_array_set_size (priv->stripe_packet, 0);
|
||||
aesX660_send_cmd (ssm, _dev, cls->start_imaging_cmd,
|
||||
cls->start_imaging_cmd_len,
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_STRIPE_DATA:
|
||||
aesX660_read_response (ssm, _dev, FALSE, FALSE, AESX660_BULK_TRANSFER_SIZE,
|
||||
capture_read_stripe_data_cb);
|
||||
break;
|
||||
|
||||
case CAPTURE_SET_IDLE:
|
||||
fp_dbg ("Got %lu frames\n", priv->strips_len);
|
||||
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)
|
||||
{
|
||||
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");
|
||||
fpi_ssm_free (ssm);
|
||||
|
||||
if (priv->deactivating) {
|
||||
if (priv->deactivating)
|
||||
{
|
||||
complete_deactivation (FP_IMAGE_DEVICE (device));
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
start_finger_detection (FP_IMAGE_DEVICE (device));
|
||||
}
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (priv->deactivating) {
|
||||
if (priv->deactivating)
|
||||
{
|
||||
complete_deactivation (dev);
|
||||
return;
|
||||
}
|
||||
|
@ -469,7 +515,8 @@ enum activate_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)
|
||||
{
|
||||
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);
|
||||
unsigned char *data = transfer->buffer;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("read_id cmd failed\n");
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
/* 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",
|
||||
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]);
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
|
@ -494,7 +545,8 @@ static void activate_read_id_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
return;
|
||||
}
|
||||
|
||||
switch (priv->init_seq_idx) {
|
||||
switch (priv->init_seq_idx)
|
||||
{
|
||||
case 0:
|
||||
priv->init_seq = cls->init_seqs[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 */
|
||||
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
priv->init_seq = cls->init_seqs[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;
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
break;
|
||||
|
||||
default:
|
||||
fp_dbg ("Failed to init device! init status: %.2x\n", data[7]);
|
||||
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)
|
||||
{
|
||||
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");
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("read_init transfer status: %s, actual_len: %d\n", error->message,
|
||||
(gint) transfer->actual_length);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
/* 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],
|
||||
data[3]);
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
|
@ -544,7 +601,8 @@ static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
return;
|
||||
}
|
||||
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)
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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:
|
||||
priv->init_seq_idx = 0;
|
||||
fp_dbg ("Activate: set idle\n");
|
||||
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_SEND_READ_ID_CMD:
|
||||
fp_dbg ("Activate: read ID\n");
|
||||
aesX660_send_cmd (ssm, _dev, read_id_cmd, sizeof (read_id_cmd),
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_READ_ID:
|
||||
aesX660_read_response (ssm, _dev, TRUE, FALSE, ID_LEN, activate_read_id_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_SEND_INIT_CMD:
|
||||
fp_dbg ("Activate: send init seq #%d cmd #%d\n",
|
||||
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,
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_READ_INIT_RESPONSE:
|
||||
fp_dbg ("Activate: read init response\n");
|
||||
aesX660_read_response (ssm, _dev, TRUE, FALSE, INIT_LEN, activate_read_init_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_SEND_CALIBRATE_CMD:
|
||||
aesX660_send_cmd (ssm, _dev, calibrate_cmd, sizeof (calibrate_cmd),
|
||||
aesX660_send_cmd_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_READ_CALIBRATE_DATA:
|
||||
aesX660_read_response (ssm, _dev, TRUE, FALSE, CALIBRATE_DATA_LEN, aesX660_read_calibrate_data_cb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
||||
static void
|
||||
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||
void *user_data, GError *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));
|
||||
}
|
||||
|
||||
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,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
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);
|
||||
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
|
||||
|
@ -624,7 +694,8 @@ static void aesX660_dev_deactivate(FpImageDevice *dev)
|
|||
priv->deactivating = TRUE;
|
||||
}
|
||||
|
||||
static void aesX660_dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
aesX660_dev_init (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||
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);
|
||||
}
|
||||
|
||||
static void aesX660_dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
aesX660_dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -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 ())
|
||||
|
||||
struct _FpiDeviceAesX660Class {
|
||||
struct _FpiDeviceAesX660Class
|
||||
{
|
||||
FpImageDeviceClass parent;
|
||||
|
||||
struct aesX660_cmd *init_seqs[2];
|
||||
|
@ -57,7 +58,8 @@ struct _FpiDeviceAesX660Class {
|
|||
struct fpi_frame_asmbl_ctx *assembling_ctx;
|
||||
};
|
||||
|
||||
struct aesX660_cmd {
|
||||
struct aesX660_cmd
|
||||
{
|
||||
const guint8 *cmd;
|
||||
gsize len;
|
||||
};
|
||||
|
@ -107,4 +109,3 @@ static const guint8 calibrate_cmd[] = {
|
|||
0x44, 0x02, 0x00, 0x04, 0x00,
|
||||
0x06,
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
#include "drivers_api.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,
|
||||
unsigned int y)
|
||||
{
|
||||
|
@ -55,13 +56,15 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
|||
.get_pixel = elan_get_pixel,
|
||||
};
|
||||
|
||||
struct _FpiDeviceElan {
|
||||
struct _FpiDeviceElan
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
/* device config */
|
||||
unsigned short dev_type;
|
||||
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 */
|
||||
|
||||
/* commands */
|
||||
|
@ -88,12 +91,14 @@ G_DECLARE_FINAL_TYPE(FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
|
|||
FpImageDevice);
|
||||
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);
|
||||
}
|
||||
|
||||
static void elan_dev_reset_state(FpiDeviceElan *elandev)
|
||||
static void
|
||||
elan_dev_reset_state (FpiDeviceElan *elandev)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
|
@ -110,7 +115,8 @@ static void elan_dev_reset_state(FpiDeviceElan *elandev)
|
|||
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 ();
|
||||
|
||||
|
@ -135,7 +141,8 @@ static void elan_save_frame(FpiDeviceElan *self, unsigned short *frame)
|
|||
int frame_idx, raw_idx;
|
||||
|
||||
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)
|
||||
raw_idx = x + (y + frame_margin) * frame_width;
|
||||
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 ();
|
||||
|
||||
|
@ -192,7 +200,8 @@ static void elan_save_background(FpiDeviceElan *elandev)
|
|||
* \
|
||||
* ======== 0 \___> ======== 0
|
||||
*/
|
||||
static int elan_save_img_frame(FpiDeviceElan *elandev)
|
||||
static int
|
||||
elan_save_img_frame (FpiDeviceElan *elandev)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
|
@ -201,7 +210,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
|
|||
elan_save_frame (elandev, frame);
|
||||
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])
|
||||
frame[i] = 0;
|
||||
else
|
||||
|
@ -209,7 +219,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
|
|||
sum += frame[i];
|
||||
}
|
||||
|
||||
if (sum == 0) {
|
||||
if (sum == 0)
|
||||
{
|
||||
fp_dbg
|
||||
("frame darker than background; finger present during calibration?");
|
||||
return -1;
|
||||
|
@ -220,7 +231,8 @@ static int elan_save_img_frame(FpiDeviceElan *elandev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void elan_process_frame_linear(unsigned short *raw_frame,
|
||||
static void
|
||||
elan_process_frame_linear (unsigned short *raw_frame,
|
||||
GSList ** frames)
|
||||
{
|
||||
unsigned int frame_size =
|
||||
|
@ -231,7 +243,8 @@ static void elan_process_frame_linear(unsigned short *raw_frame,
|
|||
G_DEBUG_HERE ();
|
||||
|
||||
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)
|
||||
min = raw_frame[i];
|
||||
if (raw_frame[i] > max)
|
||||
|
@ -241,7 +254,8 @@ static void elan_process_frame_linear(unsigned short *raw_frame,
|
|||
g_assert (max != min);
|
||||
|
||||
unsigned short px;
|
||||
for (int i = 0; i < frame_size; i++) {
|
||||
for (int i = 0; i < frame_size; i++)
|
||||
{
|
||||
px = raw_frame[i];
|
||||
px = (px - min) * 0xff / (max - min);
|
||||
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);
|
||||
}
|
||||
|
||||
static void elan_process_frame_thirds(unsigned short *raw_frame,
|
||||
static void
|
||||
elan_process_frame_thirds (unsigned short *raw_frame,
|
||||
GSList ** frames)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
|
@ -271,7 +286,8 @@ static void elan_process_frame_thirds(unsigned short *raw_frame,
|
|||
g_free (sorted);
|
||||
|
||||
unsigned short px;
|
||||
for (int i = 0; i < frame_size; i++) {
|
||||
for (int i = 0; i < frame_size; i++)
|
||||
{
|
||||
px = raw_frame[i];
|
||||
if (lvl0 <= px && px < lvl1)
|
||||
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);
|
||||
}
|
||||
|
||||
static void elan_submit_image(FpImageDevice *dev)
|
||||
static void
|
||||
elan_submit_image (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
GSList *raw_frames;
|
||||
|
@ -306,13 +323,15 @@ static void elan_submit_image(FpImageDevice *dev)
|
|||
fpi_image_device_image_captured (dev, img);
|
||||
}
|
||||
|
||||
static void elan_cmd_done(FpiSsm *ssm)
|
||||
static void
|
||||
elan_cmd_done (FpiSsm *ssm)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
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)
|
||||
{
|
||||
FpiSsm *ssm = transfer->ssm;
|
||||
|
@ -320,7 +339,8 @@ static void elan_cmd_cb(FpiUsbTransfer *transfer, FpDevice *dev,
|
|||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
/* XXX: In the cancellation case we used to not
|
||||
* mark the SSM as failed?! */
|
||||
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! */
|
||||
if (transfer->endpoint & FPI_USB_ENDPOINT_IN) {
|
||||
if (transfer->endpoint & FPI_USB_ENDPOINT_IN)
|
||||
{
|
||||
/* just finished receiving */
|
||||
self->last_read = g_memdup (transfer->buffer, transfer->actual_length);
|
||||
elan_cmd_done (ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* just finished sending */
|
||||
G_DEBUG_HERE ();
|
||||
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);
|
||||
FpiUsbTransfer *transfer;
|
||||
|
@ -348,13 +372,15 @@ static void elan_cmd_read(FpiSsm *ssm, FpDevice *dev)
|
|||
|
||||
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");
|
||||
elan_cmd_done (ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->dev_type == ELAN_0C42) {
|
||||
if (self->dev_type == ELAN_0C42)
|
||||
{
|
||||
/* ELAN_0C42 sends an extra byte in one byte responses */
|
||||
if (self->cmd->response_len == 1)
|
||||
response_len = 2;
|
||||
|
@ -396,7 +422,8 @@ elan_run_cmd(FpiSsm *ssm,
|
|||
if (cmd_timeout != -1)
|
||||
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)",
|
||||
cmd->cmd[0], cmd->cmd[1], cmd->devices, self->dev_type);
|
||||
elan_cmd_done (ssm);
|
||||
|
@ -429,12 +456,14 @@ enum stop_capture_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)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case STOP_CAPTURE:
|
||||
elan_run_cmd (ssm, dev, &stop_cmd,
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -455,22 +485,23 @@ static void stop_capture_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
/* The device is inactive at this point. */
|
||||
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
/* Simply complete the pending deactivation. */
|
||||
self->deactivating = FALSE;
|
||||
fpi_image_device_deactivate_complete (dev, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_image_device_report_finger_status (dev, FALSE);
|
||||
} else {
|
||||
else
|
||||
/* NOTE: We cannot get a cancellation error here. */
|
||||
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);
|
||||
|
||||
|
@ -492,47 +523,61 @@ enum capture_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);
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
int r;
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case CAPTURE_LED_ON:
|
||||
elan_run_cmd (ssm, dev, &led_on_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
|
||||
case CAPTURE_WAIT_FINGER:
|
||||
elan_run_cmd (ssm, dev, &pre_scan_cmd, -1);
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA:
|
||||
self->dev_state = FP_IMAGE_DEVICE_STATE_CAPTURE;
|
||||
|
||||
/* 0x55 - finger present
|
||||
* 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);
|
||||
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));
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_CHECK_ENOUGH_FRAMES:
|
||||
r = elan_save_img_frame (self);
|
||||
if (r < 0)
|
||||
{
|
||||
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 */
|
||||
self->cmd_timeout = ELAN_FINGER_TIMEOUT;
|
||||
fpi_ssm_jump_to_state (ssm, CAPTURE_WAIT_FINGER);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if (!error ||
|
||||
(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)
|
||||
{
|
||||
elan_submit_image (dev);
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("swipe too short: want >= %d frames, got %d",
|
||||
ELAN_MIN_FRAMES, self->num_frames);
|
||||
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_image_device_session_error (dev, error);
|
||||
}
|
||||
|
||||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void elan_capture(FpDevice *dev)
|
||||
static void
|
||||
elan_capture (FpDevice *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
|
||||
* the calibration mean */
|
||||
static int elan_need_calibration(FpiDeviceElan *elandev)
|
||||
static int
|
||||
elan_need_calibration (FpiDeviceElan *elandev)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
|
@ -587,9 +640,11 @@ static int elan_need_calibration(FpiDeviceElan *elandev)
|
|||
|
||||
g_assert (frame_size != 0);
|
||||
|
||||
if (elandev->dev_type == ELAN_0C42) {
|
||||
if (elandev->dev_type == ELAN_0C42)
|
||||
{
|
||||
if (calib_mean > 5500 ||
|
||||
calib_mean < 2500) {
|
||||
calib_mean < 2500)
|
||||
{
|
||||
fp_dbg ("Forcing needed recalibration");
|
||||
return 1;
|
||||
}
|
||||
|
@ -619,7 +674,8 @@ enum calibrate_states {
|
|||
CALIBRATE_NUM_STATES,
|
||||
};
|
||||
|
||||
static gboolean elan_supports_calibration(FpiDeviceElan *elandev)
|
||||
static gboolean
|
||||
elan_supports_calibration (FpiDeviceElan *elandev)
|
||||
{
|
||||
if (elandev->dev_type == ELAN_0C42)
|
||||
return TRUE;
|
||||
|
@ -627,46 +683,64 @@ static gboolean elan_supports_calibration(FpiDeviceElan *elandev)
|
|||
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);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case CALIBRATE_GET_BACKGROUND:
|
||||
elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
|
||||
case CALIBRATE_SAVE_BACKGROUND:
|
||||
elan_save_background (self);
|
||||
if (!elan_supports_calibration(self)) {
|
||||
if (!elan_supports_calibration (self))
|
||||
{
|
||||
fp_dbg ("FW does not support calibration");
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIBRATE_GET_MEAN:
|
||||
elan_run_cmd (ssm, dev, &get_calib_mean_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
|
||||
case CALIBRATE_CHECK_NEEDED:
|
||||
if (elan_need_calibration(self)) {
|
||||
if (elan_need_calibration (self))
|
||||
{
|
||||
self->calib_status = 0;
|
||||
fpi_ssm_next_state (ssm);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIBRATE_GET_STATUS:
|
||||
self->calib_atts_left -= 1;
|
||||
if (self->calib_atts_left)
|
||||
{
|
||||
elan_run_cmd (ssm, dev, &get_calib_status_cmd,
|
||||
ELAN_CMD_TIMEOUT);
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("calibration failed");
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Callibration failed!"));
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIBRATE_CHECK_STATUS:
|
||||
/* 0x01 - retry, 0x03 - ok
|
||||
* 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
|
||||
* first. This is to make sure that a full calibration loop has completed */
|
||||
fp_dbg ("calibration status: 0x%02x", self->last_read[0]);
|
||||
if (self->calib_status == 0x01
|
||||
&& self->last_read[0] == 0x03) {
|
||||
if (self->calib_status == 0x01 &&
|
||||
self->last_read[0] == 0x03)
|
||||
{
|
||||
self->calib_status = 0x03;
|
||||
fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_BACKGROUND);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
GSource *timeout;
|
||||
|
||||
if (self->calib_status == 0x00
|
||||
&& self->last_read[0] == 0x01)
|
||||
if (self->calib_status == 0x00 &&
|
||||
self->last_read[0] == 0x01)
|
||||
self->calib_status = 0x01;
|
||||
timeout = fpi_device_add_timeout (dev, 50,
|
||||
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");
|
||||
}
|
||||
break;
|
||||
|
||||
case CALIBRATE_REPEAT_STATUS:
|
||||
fpi_ssm_jump_to_state (ssm, CALIBRATE_GET_STATUS);
|
||||
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)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
|
||||
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->dev_state = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
|
||||
elan_capture (dev);
|
||||
}
|
||||
|
@ -715,7 +797,8 @@ static void calibrate_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
|||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void elan_calibrate(FpDevice *dev)
|
||||
static void
|
||||
elan_calibrate (FpDevice *dev)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
|
||||
|
@ -738,32 +821,40 @@ enum activate_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);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case ACTIVATE_GET_FW_VER:
|
||||
elan_run_cmd (ssm, dev, &get_fw_ver_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
|
||||
case ACTIVATE_SET_FW_VER:
|
||||
self->fw_ver =
|
||||
(self->last_read[0] << 8 | self->last_read[1]);
|
||||
fp_dbg ("FW ver 0x%04hx", self->fw_ver);
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case ACTIVATE_GET_SENSOR_DIM:
|
||||
elan_run_cmd (ssm, dev, &get_sensor_dim_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
|
||||
case ACTIVATE_SET_SENSOR_DIM:
|
||||
/* 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_height = self->raw_frame_height =
|
||||
self->last_read[2];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->frame_width = self->last_read[2];
|
||||
self->frame_height = self->raw_frame_height =
|
||||
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
|
||||
* rather than the number of pixels. */
|
||||
if ((self->frame_width % 2 == 1) &&
|
||||
(self->frame_height % 2 == 1)) {
|
||||
(self->frame_height % 2 == 1))
|
||||
{
|
||||
self->frame_width++;
|
||||
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);
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case ACTIVATE_CMD_1:
|
||||
/* TODO: find out what this does, if we need it */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void elan_activate(FpImageDevice *dev)
|
||||
static void
|
||||
elan_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
|
||||
|
@ -814,14 +909,16 @@ static void elan_activate(FpImageDevice *dev)
|
|||
fpi_ssm_start (ssm, activate_complete);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
FpiDeviceElan *self;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -833,7 +930,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
self->background = NULL;
|
||||
self->process_frame = elan_process_frame_thirds;
|
||||
|
||||
switch (self->dev_type) {
|
||||
switch (self->dev_type)
|
||||
{
|
||||
case ELAN_0907:
|
||||
self->process_frame = elan_process_frame_linear;
|
||||
break;
|
||||
|
@ -842,7 +940,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
|
@ -856,34 +955,43 @@ static void dev_deinit(FpImageDevice *dev)
|
|||
fpi_image_device_close_complete (dev, error);
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
elan_activate (dev);
|
||||
}
|
||||
|
||||
static void elan_change_state(FpImageDevice *idev)
|
||||
static void
|
||||
elan_change_state (FpImageDevice *idev)
|
||||
{
|
||||
FpDevice *dev = FP_DEVICE (idev);
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
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);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("changing to %d", next_state);
|
||||
}
|
||||
|
||||
switch (next_state) {
|
||||
switch (next_state)
|
||||
{
|
||||
break;
|
||||
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||
/* activation completed or another enroll stage started */
|
||||
elan_calibrate (dev);
|
||||
break;
|
||||
|
||||
case FP_IMAGE_DEVICE_STATE_CAPTURE:
|
||||
/* not used */
|
||||
break;
|
||||
|
||||
case FP_IMAGE_DEVICE_STATE_INACTIVE:
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||
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));
|
||||
}
|
||||
|
||||
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
|
||||
static void
|
||||
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
GSource *timeout;
|
||||
|
@ -911,11 +1020,11 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
|
|||
if (state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
|
||||
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);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
switch (state)
|
||||
{
|
||||
case FP_IMAGE_DEVICE_STATE_INACTIVE:
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: {
|
||||
|
@ -934,25 +1043,32 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case FP_IMAGE_DEVICE_STATE_CAPTURE:
|
||||
/* TODO MAYBE: split capture ssm into smaller ssms and use this state */
|
||||
self->dev_state = state;
|
||||
self->dev_state_next = state;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
|
||||
|
||||
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. */
|
||||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The device is not yet inactive, flag that we are deactivating (and
|
||||
* need to signal back deactivation) and then ensure we will change
|
||||
* 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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@
|
|||
#define ELAN_CMD_TIMEOUT 10000
|
||||
#define ELAN_FINGER_TIMEOUT 200
|
||||
|
||||
struct elan_cmd {
|
||||
struct elan_cmd
|
||||
{
|
||||
unsigned char cmd[ELAN_CMD_LEN];
|
||||
int response_len;
|
||||
int response_in;
|
||||
|
@ -215,11 +216,13 @@ static const FpIdEntry elan_id_table [ ] = {
|
|||
};
|
||||
|
||||
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_capture (FpDevice *dev);
|
||||
|
||||
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state);
|
||||
static void dev_change_state (FpImageDevice *dev,
|
||||
FpImageDeviceState state);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -132,8 +132,7 @@ extern "C" {
|
|||
* bmkt_mode:
|
||||
* Fingerprint system operational mode values level 1
|
||||
*/
|
||||
typedef enum bmkt_mode
|
||||
{
|
||||
typedef enum bmkt_mode {
|
||||
BMKT_STATE_UNINIT = 0xFF,
|
||||
BMKT_STATE_IDLE = 0x00,
|
||||
BMKT_STATE_ENROLL = 0x10,
|
||||
|
@ -148,8 +147,7 @@ typedef enum bmkt_mode
|
|||
* bmkt_mode_level2:
|
||||
* 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_STARTING = 0x11,
|
||||
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
|
||||
|
@ -170,8 +168,7 @@ typedef enum bmkt_mode_level2
|
|||
* bmkt_transport_type:
|
||||
* Fingerprint system transport types
|
||||
*/
|
||||
typedef enum bmkt_transport_type
|
||||
{
|
||||
typedef enum bmkt_transport_type {
|
||||
BMKT_TRANSPORT_TYPE_USB = 0,
|
||||
} bmkt_transport_type_t;
|
||||
|
||||
|
@ -207,8 +204,7 @@ typedef struct bmkt_sensor_desc
|
|||
* bmkt_finger_state_t:
|
||||
* Finger state representation values.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
BMKT_FINGER_STATE_UNKNOWN = 0,
|
||||
BMKT_FINGER_STATE_ON_SENSOR,
|
||||
BMKT_FINGER_STATE_NOT_ON_SENSOR,
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
#include "bmkt_response.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;
|
||||
int off = 0;
|
||||
|
||||
if (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)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_init_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
static int
|
||||
parse_init_ok (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_init_resp_t *init_resp = &resp->response.init_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
init_resp->finger_presence = extract8 (msg_resp->payload, NULL);
|
||||
|
||||
|
@ -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;
|
||||
bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
|
||||
|
||||
if (msg_resp->payload_len != sizeof (bmkt_fps_mode_resp_t))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
fps_mode_resp->mode = extract8 (msg_resp->payload, &offset);
|
||||
fps_mode_resp->level2_mode = extract8 (msg_resp->payload, &offset);
|
||||
|
@ -81,28 +80,26 @@ static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *res
|
|||
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;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
enroll_resp->progress = extract8 (msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
static int
|
||||
parse_enroll_ok (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
||||
|
||||
if (msg_resp->payload_len < 1 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 1))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
enroll_resp->finger_id = msg_resp->payload[0];
|
||||
memcpy (enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
|
||||
|
@ -110,14 +107,13 @@ static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|||
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;
|
||||
|
||||
if (msg_resp->payload_len < 3 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 3))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
id_resp->match_result = (double) msg_resp->payload[0] + 0.01 * (double) msg_resp->payload[1];
|
||||
id_resp->finger_id = msg_resp->payload[2];
|
||||
|
@ -126,43 +122,40 @@ static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|||
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;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
sec_level_resp->sec_level = extract8 (msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_del_all_users_progress_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
static int
|
||||
parse_del_all_users_progress_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_del_all_users_resp_t *del_all_users_resp = &resp->response.del_all_users_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
del_all_users_resp->progress = extract8 (msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
static int
|
||||
parse_db_cap_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_get_db_capacity_resp_t *db_cap_resp = &resp->response.db_cap_resp;
|
||||
int offset = 0;
|
||||
|
||||
if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
db_cap_resp->total = extract8 (msg_resp->payload, &offset);
|
||||
db_cap_resp->empty = extract8 (msg_resp->payload, &offset);
|
||||
|
@ -176,15 +169,14 @@ static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
|||
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 i = 0;
|
||||
|
||||
if (msg_resp->payload_len < 2)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
/* 2 bytes per finger so calculate the total number of fingers to process*/
|
||||
int num_fingers = (msg_resp->payload_len) / 2;
|
||||
|
||||
|
@ -198,16 +190,15 @@ static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_res
|
|||
}
|
||||
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 i = 0;
|
||||
|
||||
/* the payload is 2 bytes + template data */
|
||||
if (msg_resp->payload_len < 2)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
|
||||
|
||||
|
@ -221,30 +212,25 @@ static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_respo
|
|||
break;
|
||||
get_enroll_templates_resp->templates[n].user_id_len = extract8 (msg_resp->payload, &offset) - 2;
|
||||
if(get_enroll_templates_resp->templates[n].user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
get_enroll_templates_resp->templates[n].template_status = extract8 (msg_resp->payload, &offset);
|
||||
get_enroll_templates_resp->templates[n].finger_id = extract8 (msg_resp->payload, &offset);
|
||||
for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
|
||||
{
|
||||
get_enroll_templates_resp->templates[n].user_id[i] = extract8 (msg_resp->payload, &offset);
|
||||
}
|
||||
get_enroll_templates_resp->templates[n].user_id[i] = '\0';
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
static int
|
||||
parse_get_version_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_get_version_resp_t *get_version_resp = &resp->response.get_version_resp;
|
||||
int offset = 0;
|
||||
|
||||
if (msg_resp->payload_len != 15)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
memcpy (get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
|
||||
offset += BMKT_PART_NUM_LEN;
|
||||
|
@ -256,15 +242,14 @@ static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *
|
|||
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)
|
||||
{
|
||||
int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
|
||||
|
||||
if (*cmd_len < message_len)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
|
||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
||||
|
@ -277,29 +262,25 @@ int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq
|
|||
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)
|
||||
{
|
||||
return BMKT_CORRUPT_MESSAGE;
|
||||
}
|
||||
|
||||
msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
|
||||
msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
|
||||
msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
|
||||
if (msg_resp->payload_len > 0)
|
||||
{
|
||||
msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_resp->payload = NULL;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
int
|
||||
bmkt_parse_message_payload (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
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);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||
ret = parse_get_enrolled_fingers_report (msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
||||
resp->complete = 1;
|
||||
ret = parse_db_cap_report (msg_resp, resp);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||
ret = parse_get_enrolled_users_report (msg_resp, resp);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
@ -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);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_POWER_DOWN_READY:
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
|
|
@ -78,9 +78,16 @@ typedef struct bmkt_msg_resp
|
|||
int result;
|
||||
} bmkt_msg_resp_t;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp);
|
||||
int bmkt_parse_message_header (uint8_t *resp_buf,
|
||||
int resp_len,
|
||||
bmkt_msg_resp_t *msg_resp);
|
||||
int bmkt_parse_message_payload (bmkt_msg_resp_t *msg_resp,
|
||||
bmkt_response_t *resp);
|
||||
#endif /* BMKT_MESSAGE_H_ */
|
||||
|
|
|
@ -378,8 +378,7 @@ typedef struct bmkt_get_db_capacity_resp
|
|||
* bmkt_sec_level:
|
||||
* Security level values.
|
||||
*/
|
||||
typedef enum bmkt_sec_level
|
||||
{
|
||||
typedef enum bmkt_sec_level {
|
||||
BMKT_SECURITY_LEVEL_LOW = 0x10,
|
||||
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
|
||||
BMKT_SECURITY_LEVEL_HIGH = 0x60,
|
||||
|
@ -458,7 +457,8 @@ typedef struct bmkt_enrolled_fingers_resp
|
|||
* bmkt_response_data_t:
|
||||
* Union combining all response payload data types.
|
||||
*/
|
||||
typedef union {
|
||||
typedef union
|
||||
{
|
||||
bmkt_init_resp_t init_resp;
|
||||
bmkt_enroll_resp_t enroll_resp;
|
||||
bmkt_verify_resp_t verify_resp;
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
#include "usb_transport.h"
|
||||
#define BMKT_MAX_PENDING_SESSIONS 2
|
||||
|
||||
typedef enum bmkt_sensor_state
|
||||
{
|
||||
typedef enum bmkt_sensor_state {
|
||||
BMKT_SENSOR_STATE_UNINIT = 0,
|
||||
BMKT_SENSOR_STATE_IDLE,
|
||||
BMKT_SENSOR_STATE_INIT,
|
||||
|
@ -67,14 +66,22 @@ typedef struct bmkt_sensor
|
|||
} bmkt_sensor_t;
|
||||
|
||||
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_init_fps (bmkt_sensor_t *sensor);
|
||||
|
||||
int bmkt_sensor_send_message(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *resp_data);
|
||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
||||
int bmkt_sensor_send_message (bmkt_sensor_t *sensor,
|
||||
uint8_t msg_id,
|
||||
uint8_t payload_size,
|
||||
uint8_t *payload,
|
||||
bmkt_resp_cb_t resp_cb,
|
||||
void *resp_data);
|
||||
int bmkt_sensor_handle_response (bmkt_sensor_t *sensor,
|
||||
uint8_t *resp_buf,
|
||||
int resp_len,
|
||||
bmkt_msg_resp_t *msg_resp);
|
||||
|
||||
int bmkt_sensor_send_async_read_command (bmkt_sensor_t *sensor);
|
||||
#endif /* _SENSOR_H_ */
|
||||
|
|
|
@ -46,7 +46,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
bmkt_msg_resp_t msg_resp;
|
||||
bmkt_response_t resp;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
/* NOTE: assumes timeout should never happen for receiving. */
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
|
@ -55,7 +56,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
res = bmkt_parse_message_header (&transfer->buffer[SENSOR_FW_REPLY_HEADER_LEN],
|
||||
transfer->actual_length - SENSOR_FW_REPLY_HEADER_LEN,
|
||||
&msg_resp);
|
||||
if (res != BMKT_SUCCESS) {
|
||||
if (res != BMKT_SUCCESS)
|
||||
{
|
||||
g_warning ("Corrupted message received");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
|
@ -63,19 +65,25 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
}
|
||||
|
||||
/* Special case events */
|
||||
if (msg_resp.msg_id == BMKT_EVT_FINGER_REPORT) {
|
||||
if (msg_resp.payload_len != 1) {
|
||||
if (msg_resp.msg_id == BMKT_EVT_FINGER_REPORT)
|
||||
{
|
||||
if (msg_resp.payload_len != 1)
|
||||
{
|
||||
g_warning ("Corrupted finger report received");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_resp.payload[0] == 0x01) {
|
||||
if (msg_resp.payload[0] == 0x01)
|
||||
{
|
||||
self->finger_on_sensor = TRUE;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->finger_on_sensor = FALSE;
|
||||
if (self->cmd_complete_on_removal) {
|
||||
if (self->cmd_complete_on_removal)
|
||||
{
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
@ -87,7 +95,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
}
|
||||
|
||||
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);
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
|
@ -95,14 +104,18 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
}
|
||||
|
||||
/* 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) {
|
||||
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)
|
||||
{
|
||||
fp_dbg ("Received cancellation success resonse");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
g_error_new_literal (G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED,
|
||||
"Device reported cancellation of operation"));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("Cancellation failed, this should not happen");
|
||||
fpi_ssm_mark_failed (transfer->ssm,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
|
@ -110,10 +123,12 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
return;
|
||||
}
|
||||
|
||||
if (msg_resp.seq_num == 0) {
|
||||
if (msg_resp.seq_num == 0)
|
||||
{
|
||||
/* XXX: Should we really abort the command on general error?
|
||||
* 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;
|
||||
|
||||
/* XXX: It is weird that this is big endian. */
|
||||
|
@ -125,7 +140,9 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
|
|||
"Received general error from device"));
|
||||
//fpi_ssm_jump_to_state (transfer->ssm, fpi_ssm_get_cur_state (transfer->ssm));
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("Received message with 0 sequence number 0x%02x, ignoring!",
|
||||
msg_resp.msg_id);
|
||||
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
|
||||
* 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",
|
||||
msg_resp.seq_num,
|
||||
self->cmd_seq_num);
|
||||
|
@ -162,8 +180,10 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
|
|||
GError *error)
|
||||
{
|
||||
g_debug ("interrupt transfer done");
|
||||
if (error) {
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_error_free (error);
|
||||
fpi_ssm_jump_to_state (transfer->ssm, SYNAPTICS_CMD_GET_RESP);
|
||||
return;
|
||||
|
@ -188,9 +208,11 @@ synaptics_cmd_run_state(FpiSsm *ssm,
|
|||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||
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:
|
||||
if (self->cmd_pending_transfer) {
|
||||
if (self->cmd_pending_transfer)
|
||||
{
|
||||
self->cmd_pending_transfer->ssm = ssm;
|
||||
fpi_usb_transfer_submit (self->cmd_pending_transfer,
|
||||
1000,
|
||||
|
@ -198,7 +220,9 @@ synaptics_cmd_run_state(FpiSsm *ssm,
|
|||
fpi_ssm_usb_transfer_cb,
|
||||
NULL);
|
||||
g_clear_pointer (&self->cmd_pending_transfer, fpi_usb_transfer_unref);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
break;
|
||||
|
@ -258,9 +282,12 @@ cmd_ssm_done (FpiSsm *ssm,
|
|||
self->cmd_ssm = NULL;
|
||||
|
||||
/* Notify about the SSM failure from here instead. */
|
||||
if (error) {
|
||||
if (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);
|
||||
self->cmd_complete_error = NULL;
|
||||
}
|
||||
|
@ -275,10 +302,13 @@ cmd_forget_cb (FpiUsbTransfer *transfer,
|
|||
gpointer user_data,
|
||||
GError *error)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Async command sending failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
* sequence number should not be udpated (i.e. second async command which
|
||||
* 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);
|
||||
real_seq_num = self->last_seq_num;
|
||||
if (seq_num == 0)
|
||||
self->cmd_seq_num = self->last_seq_num;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
real_seq_num = 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
|
||||
* cancellation). */
|
||||
if (seq_num == -1) {
|
||||
if (seq_num == -1)
|
||||
{
|
||||
g_assert (callback == NULL);
|
||||
|
||||
/* We just send and forget here. */
|
||||
fpi_usb_transfer_submit (transfer, 1000, NULL, cmd_forget_cb, NULL);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Command should be send using the state machine. */
|
||||
g_assert (self->cmd_pending_transfer == NULL);
|
||||
|
||||
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.
|
||||
* There is nothing to do in this case, the command will be
|
||||
* sent automatically. */
|
||||
g_assert (callback == NULL);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Start of a new command, create the state machine. */
|
||||
g_assert (callback != NULL);
|
||||
|
||||
|
@ -410,7 +449,8 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
|||
{
|
||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
||||
fpi_device_list_complete (FP_DEVICE (self), NULL, error);
|
||||
return;
|
||||
|
@ -421,13 +461,16 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
|||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_QUERY_FAIL:
|
||||
if (resp->result == BMKT_FP_DATABASE_EMPTY) {
|
||||
if (resp->result == BMKT_FP_DATABASE_EMPTY)
|
||||
{
|
||||
fp_info ("Database is empty");
|
||||
|
||||
fpi_device_list_complete (FP_DEVICE (self),
|
||||
g_steal_pointer (&self->list_result),
|
||||
NULL);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_info ("Failed to query enrolled users: %d", resp->result);
|
||||
g_clear_pointer (&self->list_result, g_ptr_array_free);
|
||||
fpi_device_list_complete (FP_DEVICE (self),
|
||||
|
@ -436,6 +479,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
|||
"Failed to query enrolled users"));
|
||||
}
|
||||
break;
|
||||
|
||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||
fp_info ("Query complete!");
|
||||
|
||||
|
@ -444,6 +488,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
|
|||
NULL);
|
||||
|
||||
break;
|
||||
|
||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||
|
||||
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 */
|
||||
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);
|
||||
gint32 date_ymd;
|
||||
GDate *date = NULL;
|
||||
|
@ -547,12 +593,14 @@ verify_msg_cb(FpiDeviceSynaptics *self,
|
|||
FpDevice *device = FP_DEVICE (self);
|
||||
bmkt_verify_resp_t *verify_resp;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resp == NULL && self->cmd_complete_on_removal) {
|
||||
if (resp == NULL && self->cmd_complete_on_removal)
|
||||
{
|
||||
fpi_device_verify_complete (device,
|
||||
GPOINTER_TO_INT (self->cmd_complete_data),
|
||||
NULL,
|
||||
|
@ -573,23 +621,30 @@ verify_msg_cb(FpiDeviceSynaptics *self,
|
|||
break;
|
||||
|
||||
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!");
|
||||
self->cmd_complete_on_removal = TRUE;
|
||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_ERROR);
|
||||
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!");
|
||||
self->cmd_complete_on_removal = TRUE;
|
||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_FAIL);
|
||||
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");
|
||||
fpi_device_verify_complete (device,
|
||||
FPI_MATCH_ERROR,
|
||||
NULL,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_warn ("Verify has failed: %d", resp->result);
|
||||
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
|
||||
}
|
||||
|
@ -608,6 +663,7 @@ verify(FpDevice *device)
|
|||
{
|
||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||
FpPrint *print = NULL;
|
||||
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
guint8 finger;
|
||||
const guint8 *user_id;
|
||||
|
@ -617,7 +673,8 @@ verify(FpDevice *device)
|
|||
|
||||
g_object_get (print, "fp-data", &data, NULL);
|
||||
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_MATCH_ERROR,
|
||||
NULL,
|
||||
|
@ -638,7 +695,8 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
|
|||
FpDevice *device = FP_DEVICE (self);
|
||||
bmkt_enroll_resp_t *enroll_resp;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_device_enroll_complete (device, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
@ -653,11 +711,13 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
|
|||
fp_info ("Place Finger on the Sensor!");
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||
{
|
||||
fp_info ("Fingerprint image capture complete!");
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ENROLL_REPORT:
|
||||
{
|
||||
gint done_stages;
|
||||
|
@ -671,41 +731,52 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
|
|||
* progress. Some firmware revisions report more required
|
||||
* touches. */
|
||||
if (self->enroll_stage == done_stages)
|
||||
{
|
||||
fpi_device_enroll_progress (device,
|
||||
done_stages,
|
||||
NULL,
|
||||
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||
}
|
||||
|
||||
while (self->enroll_stage < done_stages) {
|
||||
while (self->enroll_stage < done_stages)
|
||||
{
|
||||
self->enroll_stage += 1;
|
||||
fpi_device_enroll_progress (device, self->enroll_stage, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ENROLL_PAUSED:
|
||||
{
|
||||
fp_info ("Enrollment has been paused!");
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ENROLL_RESUMED:
|
||||
{
|
||||
fp_info ("Enrollment has been resumed!");
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ENROLL_FAIL:
|
||||
{
|
||||
fp_info ("Enrollment has failed!: %d", resp->result);
|
||||
if (resp->result == BMKT_FP_DATABASE_FULL)
|
||||
{
|
||||
fpi_device_enroll_complete (device,
|
||||
NULL,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_FULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_device_enroll_complete (device,
|
||||
NULL,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Enrollment failed"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BMKT_RSP_ENROLL_OK:
|
||||
{
|
||||
FpPrint *print = NULL;
|
||||
|
@ -743,11 +814,14 @@ enroll(FpDevice *device)
|
|||
G_DEBUG_HERE ();
|
||||
|
||||
date = fp_print_get_enroll_date (print);
|
||||
if (date && g_date_valid (date)) {
|
||||
if (date && g_date_valid (date))
|
||||
{
|
||||
y = date->year;
|
||||
m = date->month;
|
||||
d = date->day;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
y = 0;
|
||||
m = 0;
|
||||
d = 0;
|
||||
|
@ -807,7 +881,8 @@ delete_msg_cb(FpiDeviceSynaptics *self,
|
|||
FpDevice *device = FP_DEVICE (self);
|
||||
bmkt_del_user_resp_t *del_user_resp;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_device_delete_complete (device, error);
|
||||
return;
|
||||
}
|
||||
|
@ -820,6 +895,7 @@ delete_msg_cb(FpiDeviceSynaptics *self,
|
|||
fp_info ("Deleting Enrolled Users is %d%% complete",
|
||||
del_user_resp->progress);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||
fp_info ("Failed to delete enrolled user: %d", resp->result);
|
||||
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_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||
break;
|
||||
|
||||
case BMKT_RSP_DEL_USER_FP_OK:
|
||||
fp_info ("Successfully deleted enrolled user");
|
||||
fpi_device_delete_complete (device, NULL);
|
||||
|
@ -841,6 +918,7 @@ delete_print(FpDevice *device)
|
|||
{
|
||||
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
|
||||
FpPrint *print = NULL;
|
||||
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
guint8 finger;
|
||||
const guint8 *user_id;
|
||||
|
@ -851,7 +929,8 @@ delete_print(FpDevice *device)
|
|||
|
||||
g_object_get (print, "fp-data", &data, NULL);
|
||||
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_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||
return;
|
||||
|
@ -883,12 +962,14 @@ dev_probe(FpDevice *device)
|
|||
|
||||
/* Claim usb interface */
|
||||
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);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -913,12 +994,14 @@ dev_probe(FpDevice *device)
|
|||
|
||||
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");
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||
goto err_close;
|
||||
}
|
||||
if (status != 0) {
|
||||
if (status != 0)
|
||||
{
|
||||
g_warning ("Device responded with error: %d", status);
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||
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.device_type);
|
||||
|
||||
if (!read_ok) {
|
||||
if (!read_ok)
|
||||
{
|
||||
g_warning ("Transfer in response to verison query was too short");
|
||||
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
|
||||
goto err_close;
|
||||
|
@ -999,15 +1083,19 @@ fps_init_msg_cb(FpiDeviceSynaptics *self,
|
|||
bmkt_response_t *resp,
|
||||
GError *error)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_device_open_complete (FP_DEVICE (self), error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Initializing fingerprint sensor failed with %d!", resp->result);
|
||||
fpi_device_open_complete (FP_DEVICE (self),
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||
|
@ -1023,11 +1111,14 @@ fps_deinit_cb(FpiDeviceSynaptics *self,
|
|||
|
||||
g_clear_object (&self->interrupt_cancellable);
|
||||
|
||||
if (!error) {
|
||||
switch (resp->response_id) {
|
||||
if (!error)
|
||||
{
|
||||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_POWER_DOWN_READY:
|
||||
fp_info ("Fingerprint sensor ready to be powered down");
|
||||
break;
|
||||
|
||||
case BMKT_RSP_POWER_DOWN_FAIL:
|
||||
fp_info ("Failed to go to power down mode: %d", resp->result);
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
|
@ -1091,11 +1182,13 @@ cancel(FpDevice *dev)
|
|||
}
|
||||
|
||||
static void
|
||||
fpi_device_synaptics_init(FpiDeviceSynaptics *self) {
|
||||
fpi_device_synaptics_init (FpiDeviceSynaptics *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_synaptics_class_init(FpiDeviceSynapticsClass *klass) {
|
||||
fpi_device_synaptics_class_init (FpiDeviceSynapticsClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
|
|
|
@ -77,8 +77,7 @@ struct syna_enroll_resp_data
|
|||
{
|
||||
int progress;
|
||||
};
|
||||
typedef enum syna_state
|
||||
{
|
||||
typedef enum syna_state {
|
||||
SYNA_STATE_UNINIT = 0,
|
||||
SYNA_STATE_IDLE,
|
||||
SYNA_STATE_ENROLL,
|
||||
|
@ -89,8 +88,7 @@ typedef enum syna_state
|
|||
SYNA_STATE_DELETE,
|
||||
} syna_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
SYNAPTICS_CMD_SEND_PENDING = 0,
|
||||
SYNAPTICS_CMD_GET_RESP,
|
||||
SYNAPTICS_CMD_WAIT_INTERRUPT,
|
||||
|
@ -100,7 +98,9 @@ typedef enum
|
|||
} 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
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ uint16_t
|
|||
udf_crc (unsigned char *buffer, size_t size)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
|
||||
while (size--)
|
||||
crc = (uint16_t) ((crc << 8) ^
|
||||
crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
|
||||
|
|
|
@ -21,4 +21,5 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
uint16_t udf_crc(unsigned char *buffer, size_t size);
|
||||
uint16_t udf_crc (unsigned char *buffer,
|
||||
size_t size);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,7 +27,8 @@
|
|||
#define IMG_WIDTH_1000 288
|
||||
#define IMG_WIDTH_1001 216
|
||||
|
||||
struct sonly_regwrite {
|
||||
struct sonly_regwrite
|
||||
{
|
||||
guint8 reg;
|
||||
guint8 value;
|
||||
};
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
#define UPEKET_EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||
#define BULK_TIMEOUT 4000
|
||||
|
||||
struct _FpiDeviceUpektc {
|
||||
struct _FpiDeviceUpektc
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
gboolean deactivating;
|
||||
|
@ -50,7 +51,8 @@ enum upektc_driver_data {
|
|||
};
|
||||
|
||||
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);
|
||||
|
||||
/****** INITIALIZATION/DEINITIALIZATION ******/
|
||||
|
@ -74,23 +76,28 @@ upektc_next_init_cmd(FpiSsm *ssm,
|
|||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
if (self->setup_commands[self->init_idx].response_len)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
else
|
||||
upektc_next_init_cmd (transfer->ssm, dev);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_init_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||
static void
|
||||
read_init_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case WRITE_INIT:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case READ_DATA:
|
||||
{
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||
|
@ -153,52 +164,58 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
|
||||
/****** 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;
|
||||
|
||||
sum = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (img[i] < 160) {
|
||||
for (i = 0; i < len; i++)
|
||||
if (img[i] < 160)
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
|
||||
fp_dbg ("finger_present: sum is %d\n", sum);
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("data transfer status %s\n", error->message);
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (finger_present(transfer->buffer, IMAGE_SIZE, self->sum_threshold)) {
|
||||
if (finger_present (transfer->buffer, IMAGE_SIZE, self->sum_threshold))
|
||||
{
|
||||
/* finger present, start capturing */
|
||||
fpi_image_device_report_finger_status (dev, TRUE);
|
||||
start_capture (dev);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no finger, poll for a new histogram */
|
||||
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)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("req transfer status %s\n", error->message);
|
||||
fpi_image_device_session_error (dev, error);
|
||||
return;
|
||||
|
@ -213,13 +230,16 @@ static void finger_det_cmd_cb(FpiUsbTransfer *t, FpDevice *device,
|
|||
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);
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -242,23 +262,25 @@ enum capture_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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpImage *img;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("request is not completed, %s", error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
|
@ -271,11 +293,13 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
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);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case CAPTURE_WRITE_CMD:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA:
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -323,12 +350,14 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
complete_deactivation (dev, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -339,32 +368,38 @@ static void start_capture(FpImageDevice *dev)
|
|||
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);
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
self->init_idx = 0;
|
||||
fpi_ssm_start (ssm, activate_sm_complete);
|
||||
}
|
||||
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
|
||||
|
||||
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);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
self->deactivating = FALSE;
|
||||
fpi_image_device_deactivate_complete (dev, error);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
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 */
|
||||
|
||||
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
|
||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
|
||||
{
|
||||
fpi_image_device_open_complete (dev, error);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (driver_data) {
|
||||
switch (driver_data)
|
||||
{
|
||||
case UPEKTC_2015:
|
||||
self->ep_in = UPEKTC_EP_IN;
|
||||
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->sum_threshold = UPEKTC_SUM_THRESHOLD;
|
||||
break;
|
||||
|
||||
case UPEKTC_3001:
|
||||
self->ep_in = UPEKET_EP_IN;
|
||||
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->sum_threshold = UPEKET_SUM_THRESHOLD;
|
||||
break;
|
||||
|
||||
default:
|
||||
fp_err ("Device variant %lu is not known\n", driver_data);
|
||||
g_assert_not_reached ();
|
||||
|
@ -401,7 +440,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -416,9 +456,13 @@ static const FpIdEntry id_table [ ] = {
|
|||
{ .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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
#define UPEKTC_SUM_THRESHOLD 10000
|
||||
#define UPEKET_SUM_THRESHOLD 5000
|
||||
|
||||
struct setup_cmd {
|
||||
struct setup_cmd
|
||||
{
|
||||
unsigned char cmd[0x40];
|
||||
int response_len;
|
||||
};
|
||||
|
|
|
@ -39,7 +39,8 @@ static void start_deactivation(FpImageDevice *dev);
|
|||
#define MAX_RESPONSE_SIZE 2052
|
||||
#define SHORT_RESPONSE_SIZE 64
|
||||
|
||||
struct _FpiDeviceUpektcImg {
|
||||
struct _FpiDeviceUpektcImg
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
unsigned char cmd[MAX_CMD_SIZE];
|
||||
|
@ -56,7 +57,8 @@ G_DEFINE_TYPE(FpiDeviceUpektcImg, fpi_device_upektc_img, FP_TYPE_IMAGE_DEVICE);
|
|||
|
||||
/****** 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;
|
||||
|
||||
|
@ -66,7 +68,8 @@ static void upektc_img_cmd_fix_seq(unsigned char *cmd_buf, unsigned char seq)
|
|||
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) */
|
||||
uint16_t crc = udf_crc (cmd_buf + 4, size - 6);
|
||||
|
@ -133,42 +136,48 @@ enum capture_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)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
switch (fpi_ssm_get_cur_state(transfer->ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (transfer->ssm))
|
||||
{
|
||||
case CAPTURE_ACK_00_28_TERM:
|
||||
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA_TERM);
|
||||
break;
|
||||
|
||||
default:
|
||||
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||
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 len = ((cmd_res[5] & 0x0f) << 8) | (cmd_res[6]);
|
||||
|
||||
len -= 1;
|
||||
if (cmd_res[7] == 0x2c) {
|
||||
if (cmd_res[7] == 0x2c)
|
||||
{
|
||||
len -= 10;
|
||||
offset += 10;
|
||||
}
|
||||
if (cmd_res[7] == 0x20) {
|
||||
if (cmd_res[7] == 0x20)
|
||||
len -= 4;
|
||||
}
|
||||
memcpy (image_buf, cmd_res + offset, 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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -177,35 +186,41 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
FpImage *img;
|
||||
size_t response_size;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("request is not completed, %s", error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
fp_dbg ("Deactivate requested\n");
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
fp_dbg ("request completed, len: %.4x", (gint) transfer->actual_length);
|
||||
if (transfer->actual_length == 0) {
|
||||
if (transfer->actual_length == 0)
|
||||
{
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
fpi_ssm_get_cur_state (transfer->ssm));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fpi_ssm_get_cur_state(transfer->ssm) == CAPTURE_READ_DATA_TERM) {
|
||||
if (fpi_ssm_get_cur_state (transfer->ssm) == CAPTURE_READ_DATA_TERM)
|
||||
{
|
||||
fp_dbg ("Terminating SSM\n");
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->response_rest) {
|
||||
if (!self->response_rest)
|
||||
{
|
||||
response_size = ((data[5] & 0x0f) << 8) + data[6];
|
||||
response_size += 9; /* 7 bytes for header, 2 for CRC */
|
||||
if (response_size > transfer->actual_length) {
|
||||
if (response_size > transfer->actual_length)
|
||||
{
|
||||
fp_dbg ("response_size is %lu, actual_length is %d\n",
|
||||
response_size, (gint) transfer->actual_length);
|
||||
fp_dbg ("Waiting for rest of transfer");
|
||||
|
@ -217,23 +232,28 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
}
|
||||
self->response_rest = 0;
|
||||
|
||||
switch (data[4]) {
|
||||
switch (data[4])
|
||||
{
|
||||
case 0x00:
|
||||
switch (data[7]) {
|
||||
switch (data[7])
|
||||
{
|
||||
/* No finger */
|
||||
case 0x28:
|
||||
fp_dbg ("18th byte is %.2x\n", data[18]);
|
||||
switch (data[18]) {
|
||||
switch (data[18])
|
||||
{
|
||||
case 0x0c:
|
||||
/* no finger */
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
CAPTURE_ACK_00_28);
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
/* finger is present! */
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
CAPTURE_ACK_00_28);
|
||||
break;
|
||||
|
||||
case 0x1e:
|
||||
/* short scan */
|
||||
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,
|
||||
CAPTURE_ACK_00_28_TERM);
|
||||
break;
|
||||
|
||||
case 0x1d:
|
||||
/* too much horisontal movement */
|
||||
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,
|
||||
CAPTURE_ACK_00_28_TERM);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* some error happened, cancel scan */
|
||||
fp_err ("something bad happened, stop scan\n");
|
||||
|
@ -266,10 +288,12 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Image frame with additional info */
|
||||
case 0x2c:
|
||||
fpi_image_device_report_finger_status (dev,
|
||||
TRUE);
|
||||
|
||||
/* Plain image frame */
|
||||
case 0x24:
|
||||
self->image_size +=
|
||||
|
@ -278,6 +302,7 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
CAPTURE_ACK_FRAME);
|
||||
break;
|
||||
|
||||
/* Last image frame */
|
||||
case 0x20:
|
||||
self->image_size +=
|
||||
|
@ -294,32 +319,38 @@ static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
FALSE);
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
break;
|
||||
|
||||
default:
|
||||
fp_err ("Unknown response!\n");
|
||||
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_ACK_08);
|
||||
break;
|
||||
|
||||
default:
|
||||
fp_err ("Not handled response!\n");
|
||||
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;
|
||||
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:
|
||||
upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture),
|
||||
self->seq, capture_reqs_cb);
|
||||
self->seq++;
|
||||
break;
|
||||
|
||||
case CAPTURE_READ_DATA:
|
||||
case CAPTURE_READ_DATA_TERM:
|
||||
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,
|
||||
SHORT_RESPONSE_SIZE, capture_read_data_cb);
|
||||
break;
|
||||
|
||||
case CAPTURE_ACK_00_28:
|
||||
case CAPTURE_ACK_00_28_TERM:
|
||||
upektc_img_submit_req (ssm, dev, upek2020_ack_00_28, sizeof (upek2020_ack_00_28),
|
||||
self->seq, capture_reqs_cb);
|
||||
self->seq++;
|
||||
break;
|
||||
|
||||
case CAPTURE_ACK_08:
|
||||
upektc_img_submit_req (ssm, dev, upek2020_ack_08, sizeof (upek2020_ack_08),
|
||||
0, capture_reqs_cb);
|
||||
break;
|
||||
|
||||
case CAPTURE_ACK_FRAME:
|
||||
upektc_img_submit_req (ssm, dev, upek2020_ack_frame, sizeof (upek2020_ack_frame),
|
||||
self->seq, capture_reqs_cb);
|
||||
self->seq++;
|
||||
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;
|
||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||
|
||||
g_autoptr(GError) error = error_arg;
|
||||
|
||||
fpi_ssm_free (ssm);
|
||||
|
@ -363,7 +400,8 @@ static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data, GE
|
|||
start_capture (dev);
|
||||
}
|
||||
|
||||
static void start_capture(FpImageDevice *dev)
|
||||
static void
|
||||
start_capture (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||
FpiSsm *ssm;
|
||||
|
@ -383,46 +421,51 @@ enum deactivate_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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
|
||||
} else {
|
||||
else
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case DEACTIVATE_DEINIT:
|
||||
upektc_img_submit_req (ssm, dev, upek2020_deinit, sizeof (upek2020_deinit),
|
||||
self->seq, deactivate_reqs_cb);
|
||||
self->seq++;
|
||||
break;
|
||||
|
||||
case DEACTIVATE_READ_DEINIT_DATA:
|
||||
upektc_img_read_data (ssm, dev, SHORT_RESPONSE_SIZE, 0, deactivate_read_data_cb);
|
||||
break;
|
||||
};
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
static void deactivate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
||||
static void
|
||||
deactivate_sm_complete (FpiSsm *ssm, FpDevice *_dev,
|
||||
void *user_data, GError *error)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -435,7 +478,8 @@ static void deactivate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
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);
|
||||
FpiSsm *ssm;
|
||||
|
@ -463,44 +507,46 @@ enum activate_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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (!error) {
|
||||
if (!error)
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
else
|
||||
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;
|
||||
FpImageDevice *idev = user_data;
|
||||
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_2:
|
||||
{
|
||||
|
@ -518,24 +564,29 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
fpi_usb_transfer_unref (transfer);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVATE_INIT_1:
|
||||
upektc_img_submit_req (ssm, idev, upek2020_init_1, sizeof (upek2020_init_1),
|
||||
0, init_reqs_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_INIT_2:
|
||||
upektc_img_submit_req (ssm, idev, upek2020_init_2, sizeof (upek2020_init_2),
|
||||
0, init_reqs_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_INIT_3:
|
||||
upektc_img_submit_req (ssm, idev, upek2020_init_3, sizeof (upek2020_init_3),
|
||||
0, init_reqs_cb);
|
||||
break;
|
||||
|
||||
case ACTIVATE_INIT_4:
|
||||
upektc_img_submit_req (ssm, idev, upek2020_init_4, sizeof (upek2020_init_4),
|
||||
self->seq, init_reqs_cb);
|
||||
/* Seq should be updated after 4th init */
|
||||
self->seq++;
|
||||
break;
|
||||
|
||||
case ACTIVATE_READ_CTRL_RESP_1:
|
||||
case ACTIVATE_READ_CTRL_RESP_2:
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -559,29 +611,35 @@ static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
start_capture (dev);
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
self->seq = 0;
|
||||
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);
|
||||
|
||||
self->deactivating = TRUE;
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
|
||||
GError *error = NULL;
|
||||
|
||||
/* TODO check that device has endpoints we're using */
|
||||
|
||||
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
|
||||
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
|
||||
{
|
||||
fpi_image_device_open_complete (dev, error);
|
||||
return;
|
||||
}
|
||||
|
@ -590,7 +648,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
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);
|
||||
GError *error = NULL;
|
||||
|
@ -616,16 +675,18 @@ discover(GUsbDevice *usb_device)
|
|||
}
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ .vid = 0x147e, .pid = 0x2016,
|
||||
},
|
||||
{ .vid = 0x147e, .pid = 0x2020,
|
||||
},
|
||||
{ .vid = 0x147e, .pid = 0x2016, },
|
||||
{ .vid = 0x147e, .pid = 0x2020, },
|
||||
{ .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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -77,7 +77,8 @@ enum {
|
|||
DP_URU4000B,
|
||||
};
|
||||
|
||||
static const struct uru4k_dev_profile {
|
||||
static const struct uru4k_dev_profile
|
||||
{
|
||||
const char *name;
|
||||
gboolean auth_cr;
|
||||
gboolean encryption;
|
||||
|
@ -115,7 +116,8 @@ typedef void (*irq_cb_fn)(FpImageDevice *dev,
|
|||
void *user_data);
|
||||
typedef void (*irqs_stopped_cb_fn)(FpImageDevice *dev);
|
||||
|
||||
struct _FpiDeviceUru4000 {
|
||||
struct _FpiDeviceUru4000
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
const struct uru4k_dev_profile *profile;
|
||||
|
@ -162,7 +164,8 @@ static const unsigned char crkey[] = {
|
|||
|
||||
/***** 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,
|
||||
FpiUsbTransferCallback callback,
|
||||
void *user_data)
|
||||
|
@ -181,7 +184,8 @@ static void write_regs(FpImageDevice *dev, uint16_t first_reg,
|
|||
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,
|
||||
FpiUsbTransferCallback callback,
|
||||
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);
|
||||
}
|
||||
|
||||
static void read_regs(FpImageDevice *dev, uint16_t first_reg,
|
||||
static void
|
||||
read_regs (FpImageDevice *dev, uint16_t first_reg,
|
||||
uint16_t num_regs,
|
||||
FpiUsbTransferCallback callback,
|
||||
void *user_data)
|
||||
|
@ -230,7 +235,8 @@ static void read_regs(FpImageDevice *dev, uint16_t first_reg,
|
|||
* 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! */
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
@ -249,7 +256,8 @@ static void challenge_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_dat
|
|||
PK11Context *ctx;
|
||||
int outlen;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
return;
|
||||
}
|
||||
|
@ -258,8 +266,9 @@ static void challenge_cb(FpiUsbTransfer *transfer, FpDevice *dev, void *user_dat
|
|||
/* produce response from challenge */
|
||||
ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT,
|
||||
self->symkey, self->param);
|
||||
if (PK11_CipherOp(ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess
|
||||
|| PK11_Finalize(ctx) != SECSuccess) {
|
||||
if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess ||
|
||||
PK11_Finalize (ctx) != SECSuccess)
|
||||
{
|
||||
fp_err ("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 irq_handler(FpiUsbTransfer *transfer,
|
||||
static void
|
||||
irq_handler (FpiUsbTransfer *transfer,
|
||||
FpDevice *dev,
|
||||
void *user_data,
|
||||
GError *error)
|
||||
|
@ -302,16 +312,22 @@ static void irq_handler(FpiUsbTransfer *transfer,
|
|||
|
||||
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");
|
||||
if (urudev->irqs_stopped_cb)
|
||||
urudev->irqs_stopped_cb (imgdev);
|
||||
urudev->irqs_stopped_cb = NULL;
|
||||
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);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("ignoring interrupt error: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
@ -334,7 +350,8 @@ static void irq_handler(FpiUsbTransfer *transfer,
|
|||
start_irq_handler (imgdev);
|
||||
}
|
||||
|
||||
static void start_irq_handler(FpImageDevice *dev)
|
||||
static void
|
||||
start_irq_handler (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
FpiUsbTransfer *transfer;
|
||||
|
@ -351,11 +368,13 @@ static void start_irq_handler(FpImageDevice *dev)
|
|||
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);
|
||||
|
||||
if (self->irq_cancellable) {
|
||||
if (self->irq_cancellable)
|
||||
{
|
||||
g_cancellable_cancel (self->irq_cancellable);
|
||||
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 finger_presence_irq_cb(FpImageDevice *dev,
|
||||
static void
|
||||
finger_presence_irq_cb (FpImageDevice *dev,
|
||||
GError *error,
|
||||
uint16_t type,
|
||||
void *user_data)
|
||||
|
@ -380,7 +400,8 @@ static void finger_presence_irq_cb(FpImageDevice *dev,
|
|||
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,
|
||||
void *user_data,
|
||||
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);
|
||||
}
|
||||
|
||||
static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
|
||||
static void
|
||||
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
|
||||
{
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
switch (state) {
|
||||
switch (state)
|
||||
{
|
||||
case FP_IMAGE_DEVICE_STATE_INACTIVE:
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
|
||||
case FP_IMAGE_DEVICE_STATE_CAPTURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
@ -412,7 +436,8 @@ static void dev_change_state(FpImageDevice *dev, FpImageDeviceState state)
|
|||
|
||||
/***** GENERIC STATE MACHINE HELPER FUNCTIONS *****/
|
||||
|
||||
static void sm_write_reg_cb(FpiUsbTransfer *transfer,
|
||||
static void
|
||||
sm_write_reg_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *dev,
|
||||
void *user_data,
|
||||
GError *error)
|
||||
|
@ -444,7 +469,8 @@ sm_write_reg(FpiSsm *ssm,
|
|||
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,
|
||||
void *user_data,
|
||||
GError *error)
|
||||
|
@ -452,9 +478,12 @@ static void sm_read_reg_cb(FpiUsbTransfer *transfer,
|
|||
FpiSsm *ssm = user_data;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (self->last_reg_rd, transfer->buffer, transfer->actual_length);
|
||||
fp_dbg ("reg value %x", self->last_reg_rd[0]);
|
||||
fpi_ssm_next_state (ssm);
|
||||
|
@ -503,12 +532,14 @@ enum imaging_states {
|
|||
IMAGING_NUM_STATES
|
||||
};
|
||||
|
||||
struct uru4k_image {
|
||||
struct uru4k_image
|
||||
{
|
||||
uint8_t unknown_00[4];
|
||||
uint16_t num_lines;
|
||||
uint8_t key_number;
|
||||
uint8_t unknown_07[9];
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint8_t flags;
|
||||
uint8_t num_lines;
|
||||
} block_info[15];
|
||||
|
@ -516,16 +547,20 @@ struct uru4k_image {
|
|||
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)
|
||||
{
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
FpiSsm *ssm = transfer->ssm;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("error");
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->img_data = g_memdup (transfer->buffer, sizeof (struct uru4k_image));
|
||||
self->img_data_actual_length = transfer->actual_length;
|
||||
fpi_ssm_next_state (ssm);
|
||||
|
@ -539,11 +574,13 @@ enum {
|
|||
BLOCKF_NOT_PRESENT = 0x01,
|
||||
};
|
||||
|
||||
static uint32_t update_key(uint32_t key)
|
||||
static uint32_t
|
||||
update_key (uint32_t key)
|
||||
{
|
||||
/* linear feedback shift register
|
||||
* taps at bit positions 1 3 4 7 11 13 20 23 26 29 32 */
|
||||
uint32_t bit = key & 0x9248144d;
|
||||
|
||||
bit ^= bit << 16;
|
||||
bit ^= bit << 8;
|
||||
bit ^= bit << 4;
|
||||
|
@ -552,12 +589,14 @@ static uint32_t update_key(uint32_t key)
|
|||
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;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_bytes - 1; i++) {
|
||||
for (i = 0; i < num_bytes - 1; i++)
|
||||
{
|
||||
/* calculate xor byte and update key */
|
||||
xorbyte = ((key >> 4) & 1) << 0;
|
||||
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);
|
||||
}
|
||||
|
||||
static int calc_dev2(struct uru4k_image *img)
|
||||
static int
|
||||
calc_dev2 (struct uru4k_image *img)
|
||||
{
|
||||
uint8_t *b[2] = { NULL, NULL };
|
||||
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)
|
||||
continue;
|
||||
for (j = 0; j < img->block_info[i].num_lines && idx < 2; j++)
|
||||
b[idx++] = img->data[r++];
|
||||
}
|
||||
if (!b[0] || !b[1]) {
|
||||
if (!b[0] || !b[1])
|
||||
{
|
||||
fp_dbg ("NULL! %p %p", b[0], b[1]);
|
||||
return 0;
|
||||
}
|
||||
|
@ -598,7 +640,8 @@ static int calc_dev2(struct uru4k_image *img)
|
|||
|
||||
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;
|
||||
res += dev * dev;
|
||||
}
|
||||
|
@ -606,7 +649,8 @@ static int calc_dev2(struct uru4k_image *img)
|
|||
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;
|
||||
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;
|
||||
unsigned char buf[5];
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case IMAGING_CAPTURE:
|
||||
self->img_lines_done = 0;
|
||||
self->img_block = 0;
|
||||
fpi_usb_transfer_submit (self->img_transfer, 0, NULL, image_transfer_cb, NULL);
|
||||
|
||||
break;
|
||||
|
||||
case IMAGING_SEND_INDEX:
|
||||
fp_dbg ("hw header lines %d", img->num_lines);
|
||||
|
||||
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",
|
||||
img->num_lines,
|
||||
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);
|
||||
return;
|
||||
}
|
||||
if (!self->profile->encryption) {
|
||||
if (!self->profile->encryption)
|
||||
{
|
||||
dev2 = calc_dev2 (img);
|
||||
fp_dbg ("dev2: %d", dev2);
|
||||
if (dev2 < ENC_THRESHOLD) {
|
||||
if (dev2 < ENC_THRESHOLD)
|
||||
{
|
||||
fpi_ssm_jump_to_state (ssm, IMAGING_REPORT_IMAGE);
|
||||
return;
|
||||
}
|
||||
|
@ -652,9 +701,11 @@ static void imaging_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
buf[4] = self->img_enc_seed >> 24;
|
||||
sm_write_regs (ssm, dev, REG_SCRAMBLE_DATA_INDEX, 5, buf);
|
||||
break;
|
||||
|
||||
case IMAGING_READ_KEY:
|
||||
sm_read_regs (ssm, dev, REG_SCRAMBLE_DATA_KEY, 4);
|
||||
break;
|
||||
|
||||
case IMAGING_DECODE:
|
||||
key = self->last_reg_rd[0];
|
||||
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);
|
||||
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;
|
||||
num_lines = img->block_info[self->img_block].num_lines;
|
||||
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,
|
||||
num_lines);
|
||||
if (flags & BLOCKF_CHANGE_KEY) {
|
||||
if (flags & BLOCKF_CHANGE_KEY)
|
||||
{
|
||||
fp_dbg ("changing encryption keys.\n");
|
||||
img->block_info[self->img_block].flags &= ~BLOCKF_CHANGE_KEY;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
switch (flags & (BLOCKF_NO_KEY_UPDATE | BLOCKF_ENCRYPTED)) {
|
||||
switch (flags & (BLOCKF_NO_KEY_UPDATE | BLOCKF_ENCRYPTED))
|
||||
{
|
||||
case BLOCKF_ENCRYPTED:
|
||||
fp_dbg ("decoding %d lines", num_lines);
|
||||
key = do_decode (&img->data[self->img_lines_done][0],
|
||||
IMAGE_WIDTH * num_lines, key);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
fp_dbg ("skipping %d lines", num_lines);
|
||||
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);
|
||||
break;
|
||||
|
||||
case IMAGING_REPORT_IMAGE:
|
||||
fpimg = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
|
||||
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;
|
||||
num_lines = img->block_info[i].num_lines;
|
||||
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)
|
||||
{
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
fpi_ssm_free (ssm);
|
||||
|
||||
/* Report error before exiting imaging loop - the error handler
|
||||
|
@ -782,29 +841,36 @@ rebootpwr_pause_cb(FpDevice *dev,
|
|||
FpiSsm *ssm = data;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (!--self->rebootpwr_ctr) {
|
||||
if (!--self->rebootpwr_ctr)
|
||||
{
|
||||
fp_err ("could not reboot device power");
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR,
|
||||
"Could not reboot device"));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case REBOOTPWR_SET_HWSTAT:
|
||||
self->rebootpwr_ctr = 100;
|
||||
sm_set_hwstat (ssm, dev, self->last_hwstat & 0xf);
|
||||
break;
|
||||
|
||||
case REBOOTPWR_GET_HWSTAT:
|
||||
sm_read_reg (ssm, dev, REG_HWSTAT);
|
||||
break;
|
||||
|
||||
case REBOOTPWR_CHECK_HWSTAT:
|
||||
self->last_hwstat = self->last_reg_rd[0];
|
||||
if (self->last_hwstat & 0x1)
|
||||
|
@ -812,6 +878,7 @@ static void rebootpwr_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
else
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case REBOOTPWR_PAUSE:
|
||||
fpi_device_add_timeout (_dev, 10, rebootpwr_pause_cb, ssm);
|
||||
break;
|
||||
|
@ -861,35 +928,45 @@ powerup_pause_cb(FpDevice *dev,
|
|||
FpiSsm *ssm = data;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (!--self->powerup_ctr) {
|
||||
if (!--self->powerup_ctr)
|
||||
{
|
||||
fp_err ("could not power device up");
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"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);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case POWERUP_INIT:
|
||||
self->powerup_ctr = 100;
|
||||
self->powerup_hwstat = self->last_hwstat & 0xf;
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case POWERUP_SET_HWSTAT:
|
||||
sm_set_hwstat (ssm, dev, self->powerup_hwstat);
|
||||
break;
|
||||
|
||||
case POWERUP_GET_HWSTAT:
|
||||
sm_read_reg (ssm, dev, REG_HWSTAT);
|
||||
break;
|
||||
|
||||
case POWERUP_CHECK_HWSTAT:
|
||||
self->last_hwstat = self->last_reg_rd[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
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case POWERUP_PAUSE:
|
||||
fpi_device_add_timeout (_dev, 10, powerup_pause_cb, ssm);
|
||||
break;
|
||||
|
||||
case POWERUP_CHALLENGE_RESPONSE:
|
||||
sm_do_challenge_response (ssm, dev);
|
||||
break;
|
||||
|
||||
case POWERUP_CHALLENGE_RESPONSE_SUCCESS:
|
||||
fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT);
|
||||
break;
|
||||
|
@ -940,20 +1020,28 @@ enum init_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)
|
||||
{
|
||||
FpiSsm *ssm = user_data;
|
||||
FpiDeviceUru4000 *urudev = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm, error);
|
||||
}
|
||||
else if (type != IRQDATA_SCANPWR_ON)
|
||||
{
|
||||
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");
|
||||
urudev->scanpwr_irq_timeouts = -1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("late scanpwr interrupt");
|
||||
fpi_ssm_next_state (ssm);
|
||||
}
|
||||
|
@ -970,26 +1058,32 @@ init_scanpwr_timeout(FpDevice *dev,
|
|||
self->irq_cb = 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");
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
g_error_new_literal (G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_TIMED_OUT,
|
||||
"Powerup timed out 3 times, giving up"));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case INIT_GET_HWSTAT:
|
||||
sm_read_reg (ssm, dev, REG_HWSTAT);
|
||||
break;
|
||||
|
||||
case INIT_CHECK_HWSTAT_REBOOT:
|
||||
self->last_hwstat = self->last_reg_rd[0];
|
||||
if ((self->last_hwstat & 0x84) == 0x84)
|
||||
|
@ -997,20 +1091,24 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
else
|
||||
fpi_ssm_jump_to_state (ssm, INIT_CHECK_HWSTAT_POWERDOWN);
|
||||
break;
|
||||
|
||||
case INIT_REBOOT_POWER:;
|
||||
FpiSsm *rebootsm = fpi_ssm_new (FP_DEVICE (dev),
|
||||
rebootpwr_run_state,
|
||||
REBOOTPWR_NUM_STATES, dev);
|
||||
fpi_ssm_start_subsm (ssm, rebootsm);
|
||||
break;
|
||||
|
||||
case INIT_CHECK_HWSTAT_POWERDOWN:
|
||||
if ((self->last_hwstat & 0x80) == 0)
|
||||
sm_set_hwstat (ssm, dev, self->last_hwstat | 0x80);
|
||||
else
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
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,
|
||||
"IRQ handler should be running but is not"));
|
||||
return;
|
||||
|
@ -1023,8 +1121,10 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
POWERUP_NUM_STATES, dev);
|
||||
fpi_ssm_start_subsm (ssm, powerupsm);
|
||||
break;
|
||||
|
||||
case INIT_AWAIT_SCAN_POWER:
|
||||
if (self->scanpwr_irq_timeouts < 0) {
|
||||
if (self->scanpwr_irq_timeouts < 0)
|
||||
{
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
}
|
||||
|
@ -1037,8 +1137,10 @@ static void init_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
init_scanpwr_timeout,
|
||||
ssm);
|
||||
break;
|
||||
|
||||
case INIT_DONE:
|
||||
if (self->scanpwr_irq_timeout) {
|
||||
if (self->scanpwr_irq_timeout)
|
||||
{
|
||||
g_source_destroy (self->scanpwr_irq_timeout);
|
||||
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;
|
||||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
|
||||
case INIT_GET_VERSION:
|
||||
sm_read_regs (ssm, dev, REG_DEVICE_INFO, 16);
|
||||
break;
|
||||
|
||||
case INIT_REPORT_VERSION:
|
||||
/* Likely hardware revision, and firmware version.
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
FpiSsm *ssm;
|
||||
|
@ -1080,28 +1186,33 @@ static void dev_activate(FpImageDevice *dev)
|
|||
|
||||
/***** DEINITIALIZATION *****/
|
||||
|
||||
static void deactivate_irqs_stopped(FpImageDevice *dev)
|
||||
static void
|
||||
deactivate_irqs_stopped (FpImageDevice *dev)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void execute_state_change(FpImageDevice *dev)
|
||||
static void
|
||||
execute_state_change (FpImageDevice *dev)
|
||||
{
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
FpiSsm *ssm;
|
||||
|
||||
switch (self->activate_state) {
|
||||
switch (self->activate_state)
|
||||
{
|
||||
case FP_IMAGE_DEVICE_STATE_INACTIVE:
|
||||
fp_dbg ("deactivating");
|
||||
self->irq_cb = NULL;
|
||||
|
@ -1112,7 +1223,8 @@ static void execute_state_change(FpImageDevice *dev)
|
|||
|
||||
case FP_IMAGE_DEVICE_STATE_AWAIT_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_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"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:
|
||||
fp_dbg ("await finger off");
|
||||
if (!IRQ_HANDLER_IS_RUNNING(self)) {
|
||||
if (!IRQ_HANDLER_IS_RUNNING (self))
|
||||
{
|
||||
fpi_image_device_session_error (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"IRQ handler should be running but is not"));
|
||||
|
@ -1160,10 +1273,12 @@ static void execute_state_change(FpImageDevice *dev)
|
|||
|
||||
/***** LIBRARY STUFF *****/
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
FpiDeviceUru4000 *self;
|
||||
|
||||
g_autoptr(GPtrArray) interfaces = NULL;
|
||||
GUsbInterface *iface = NULL;
|
||||
guint64 driver_data;
|
||||
|
@ -1172,24 +1287,28 @@ static void dev_init(FpImageDevice *dev)
|
|||
int i;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
if (g_usb_interface_get_class (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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iface == NULL) {
|
||||
if (iface == NULL)
|
||||
{
|
||||
fp_err ("could not find interface");
|
||||
fpi_image_device_open_complete (dev,
|
||||
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! */
|
||||
#if 0
|
||||
if (iface_desc->bNumEndpoints != 2) {
|
||||
if (iface_desc->bNumEndpoints != 2)
|
||||
{
|
||||
fp_err ("found %d endpoints!?", iface_desc->bNumEndpoints);
|
||||
r = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ep = &iface_desc->endpoint[0];
|
||||
if (ep->bEndpointAddress != EP_INTR
|
||||
|| (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
|
||||
LIBUSB_TRANSFER_TYPE_INTERRUPT) {
|
||||
if (ep->bEndpointAddress != EP_INTR ||
|
||||
(ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
|
||||
LIBUSB_TRANSFER_TYPE_INTERRUPT)
|
||||
{
|
||||
fp_err ("unrecognised interrupt endpoint");
|
||||
r = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ep = &iface_desc->endpoint[1];
|
||||
if (ep->bEndpointAddress != EP_DATA
|
||||
|| (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
|
||||
LIBUSB_TRANSFER_TYPE_BULK) {
|
||||
if (ep->bEndpointAddress != EP_DATA ||
|
||||
(ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
|
||||
LIBUSB_TRANSFER_TYPE_BULK)
|
||||
{
|
||||
fp_err ("unrecognised bulk endpoint");
|
||||
r = -ENODEV;
|
||||
goto out;
|
||||
|
@ -1227,7 +1349,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
/* Device looks like a supported reader */
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -1237,7 +1360,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
|
||||
/* Initialise NSS early */
|
||||
rv = NSS_NoDB_Init (".");
|
||||
if (rv != SECSuccess) {
|
||||
if (rv != SECSuccess)
|
||||
{
|
||||
fp_err ("could not initialise NSS");
|
||||
fpi_image_device_open_complete (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
|
@ -1254,7 +1378,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
/* Set up encryption */
|
||||
self->cipher = CKM_AES_ECB;
|
||||
self->slot = PK11_GetBestSlot (self->cipher, NULL);
|
||||
if (self->slot == NULL) {
|
||||
if (self->slot == NULL)
|
||||
{
|
||||
fp_err ("could not get encryption slot");
|
||||
fpi_image_device_open_complete (dev,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
|
@ -1269,7 +1394,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
PK11_OriginUnwrap,
|
||||
CKA_ENCRYPT,
|
||||
&item, NULL);
|
||||
if (self->symkey == NULL) {
|
||||
if (self->symkey == NULL)
|
||||
{
|
||||
fp_err ("failed to import key into NSS");
|
||||
PK11_FreeSlot (self->slot);
|
||||
self->slot = NULL;
|
||||
|
@ -1283,10 +1409,12 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||
|
||||
if (self->symkey)
|
||||
PK11_FreeSymKey (self->symkey);
|
||||
if (self->param)
|
||||
|
@ -1324,10 +1452,14 @@ static const FpIdEntry id_table [ ] = {
|
|||
{ .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);
|
||||
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_height = IMAGE_HEIGHT;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
#define RQ_SIZE (IMG_WIDTH * ROWS_PER_RQ)
|
||||
#define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT)
|
||||
|
||||
struct _FpDeviceVcom5s {
|
||||
struct _FpDeviceVcom5s
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
int capture_iteration;
|
||||
|
@ -75,7 +76,8 @@ enum v5s_cmd {
|
|||
|
||||
/***** 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)
|
||||
{
|
||||
if (error)
|
||||
|
@ -104,7 +106,8 @@ sm_write_reg(FpiSsm *ssm,
|
|||
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)
|
||||
{
|
||||
if (error)
|
||||
|
@ -145,12 +148,14 @@ sm_exec_cmd(FpiSsm *ssm,
|
|||
#define DETBOX_COL_END (DETBOX_COL_START + DETBOX_COLS)
|
||||
#define FINGER_PRESENCE_THRESHOLD 100
|
||||
|
||||
static gboolean finger_is_present(unsigned char *data)
|
||||
static gboolean
|
||||
finger_is_present (unsigned char *data)
|
||||
{
|
||||
int row;
|
||||
guint16 imgavg = 0;
|
||||
|
||||
for (row = DETBOX_ROW_START; row < DETBOX_ROW_END; row++) {
|
||||
for (row = DETBOX_ROW_START; row < DETBOX_ROW_END; row++)
|
||||
{
|
||||
unsigned char *rowdata = data + (row * IMG_WIDTH);
|
||||
guint16 rowavg = 0;
|
||||
int col;
|
||||
|
@ -163,27 +168,31 @@ static gboolean finger_is_present(unsigned char *data)
|
|||
imgavg /= DETBOX_ROWS;
|
||||
fp_dbg ("img avg %d", imgavg);
|
||||
|
||||
return (imgavg <= FINGER_PRESENCE_THRESHOLD);
|
||||
return imgavg <= FINGER_PRESENCE_THRESHOLD;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***** 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)
|
||||
{
|
||||
FpImageDevice *imgdev = FP_IMAGE_DEVICE (device);
|
||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (device);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (++self->capture_iteration == NR_REQS) {
|
||||
if (++self->capture_iteration == NR_REQS)
|
||||
{
|
||||
FpImage *img = self->capture_img;
|
||||
/* must clear this early, otherwise the call chain takes us into
|
||||
* 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));
|
||||
fpi_image_device_image_captured (imgdev, img);
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
capture_iterate (transfer->ssm, device);
|
||||
}
|
||||
}
|
||||
|
@ -244,36 +255,48 @@ enum loop_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);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case LOOP_SET_CONTRAST:
|
||||
sm_write_reg (ssm, dev, REG_CONTRAST, 0x01);
|
||||
break;
|
||||
|
||||
case LOOP_SET_GAIN:
|
||||
sm_write_reg (ssm, dev, REG_GAIN, 0x29);
|
||||
break;
|
||||
|
||||
case LOOP_CMD_SCAN:
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
fp_dbg ("deactivating, marking completed");
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
sm_exec_cmd (ssm, dev, CMD_SCAN, 0x00);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOOP_CAPTURE:
|
||||
sm_do_capture (ssm, dev);
|
||||
break;
|
||||
|
||||
case LOOP_CAPTURE_DONE:
|
||||
fpi_ssm_jump_to_state (ssm, LOOP_CMD_SCAN);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void loopsm_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||
static void
|
||||
loopsm_complete (FpiSsm *ssm, FpDevice *dev, void *user_data,
|
||||
GError *error)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), loop_run_state,
|
||||
LOOP_NUM_STATES, dev);
|
||||
|
||||
self->deactivating = FALSE;
|
||||
fpi_ssm_start (ssm, loopsm_complete);
|
||||
self->loop_running = TRUE;
|
||||
fpi_image_device_activate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
|
||||
|
||||
if (self->loop_running)
|
||||
self->deactivating = TRUE;
|
||||
else
|
||||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void dev_init(FpImageDevice *dev)
|
||||
static void
|
||||
dev_init (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -322,7 +350,8 @@ static void dev_init(FpImageDevice *dev)
|
|||
fpi_image_device_open_complete (dev, error);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *dev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -337,10 +366,14 @@ static const FpIdEntry id_table [ ] = {
|
|||
{ .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);
|
||||
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_height = IMG_HEIGHT;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,12 @@ G_DEFINE_TYPE (FpDeviceVfs0050, fpi_device_vfs0050, FP_TYPE_IMAGE_DEVICE)
|
|||
/* USB functions */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_err ("USB write transfer: %s", error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
|
@ -58,12 +60,14 @@ async_write(FpiSsm *ssm,
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int ep = transfer->endpoint;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_err ("USB read transfer on endpoint %d: %s", ep - 0x80,
|
||||
error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
|
@ -90,7 +94,8 @@ async_read(FpiSsm *ssm,
|
|||
transfer->ssm = ssm;
|
||||
transfer->short_is_error = TRUE;
|
||||
|
||||
if (data == NULL) {
|
||||
if (data == NULL)
|
||||
{
|
||||
data = g_malloc0 (len);
|
||||
free_func = g_free;
|
||||
}
|
||||
|
@ -107,19 +112,22 @@ async_read(FpiSsm *ssm,
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int ep = transfer->endpoint;
|
||||
|
||||
/* 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);
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_err ("USB write transfer: %s", error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
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
|
||||
* 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;
|
||||
|
||||
|
@ -157,21 +166,25 @@ static void async_abort(FpDevice *dev, FpiSsm *ssm, int ep)
|
|||
/* Image processing functions */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return ((struct vfs_line *) line->data)->data[x];
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct vfs_line *line1 = line_list_1->data;
|
||||
struct vfs_line *line2 = line_list_2->data;
|
||||
const int shift = (VFS_IMAGE_WIDTH - VFS_NEXT_LINE_WIDTH) / 2 - 1;
|
||||
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) line1->next_line_part[i] - (int) line2->data[shift + i];
|
||||
res += x * x;
|
||||
|
@ -182,13 +195,15 @@ static int vfs0050_get_difference(struct fpi_line_asmbl_ctx *ctx,
|
|||
#define VFS_NOISE_THRESHOLD 40
|
||||
|
||||
/* 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 val2 = line->noise_hash_2;
|
||||
if (val1 > VFS_NOISE_THRESHOLD
|
||||
&& val1 < 256 - VFS_NOISE_THRESHOLD
|
||||
&& val2 > VFS_NOISE_THRESHOLD && val2 < 256 - VFS_NOISE_THRESHOLD)
|
||||
|
||||
if (val1 > VFS_NOISE_THRESHOLD &&
|
||||
val1 < 256 - VFS_NOISE_THRESHOLD &&
|
||||
val2 > VFS_NOISE_THRESHOLD && val2 < 256 - VFS_NOISE_THRESHOLD)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -205,14 +220,16 @@ static struct fpi_line_asmbl_ctx assembling_ctx = {
|
|||
};
|
||||
|
||||
/* Processes image before submitting */
|
||||
static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
|
||||
static FpImage *
|
||||
prepare_image (FpDeviceVfs0050 *vdev)
|
||||
{
|
||||
int height = vdev->bytes / VFS_LINE_SIZE;
|
||||
|
||||
/* Noise cleaning. IMHO, it works pretty well
|
||||
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 */
|
||||
while (height > 0) {
|
||||
while (height > 0)
|
||||
{
|
||||
if (!is_noise (vdev->lines_buffer + height - 1))
|
||||
break;
|
||||
--height;
|
||||
|
@ -237,7 +254,8 @@ static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@ -264,7 +282,8 @@ clear_ep2_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
{
|
||||
char command04 = 0x04;
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case SUBSM1_COMMAND_04:
|
||||
async_write (ssm, dev, &command04, sizeof (command04));
|
||||
break;
|
||||
|
@ -290,15 +309,18 @@ clear_ep2(FpDevice *dev,
|
|||
{
|
||||
FpiSsm *subsm =
|
||||
fpi_ssm_new (dev, clear_ep2_ssm, SUBSM1_STATES, NULL);
|
||||
|
||||
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)
|
||||
{
|
||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case SUBSM2_SEND_CONTROL:
|
||||
async_write (ssm, dev, self->control_packet,
|
||||
VFS_CONTROL_PACKET_SIZE);
|
||||
|
@ -310,7 +332,8 @@ static void send_control_packet_ssm(FpiSsm *ssm, FpDevice *dev,
|
|||
|
||||
case SUBSM2_SEND_COMMIT:
|
||||
/* 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;
|
||||
fpi_ssm_jump_to_state (ssm, SUBSM2_SEND_CONTROL);
|
||||
break;
|
||||
|
@ -332,7 +355,8 @@ static void send_control_packet_ssm(FpiSsm *ssm, FpDevice *dev,
|
|||
case SUBSM2_ABORT_3:
|
||||
/* Check that interrupt is empty */
|
||||
if (memcmp
|
||||
(self->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE)) {
|
||||
(self->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE))
|
||||
{
|
||||
fp_err ("Unknown SUBSM2 state");
|
||||
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||
break;
|
||||
|
@ -362,11 +386,13 @@ send_control_packet(FpiSsm *ssm,
|
|||
FpiSsm *subsm =
|
||||
fpi_ssm_new (dev, send_control_packet_ssm,
|
||||
SUBSM2_STATES, NULL);
|
||||
|
||||
fpi_ssm_start_subsm (ssm, subsm);
|
||||
}
|
||||
|
||||
/* Clears all fprint data */
|
||||
static void clear_data(FpDeviceVfs0050 *vdev)
|
||||
static void
|
||||
clear_data (FpDeviceVfs0050 *vdev)
|
||||
{
|
||||
g_free (vdev->lines_buffer);
|
||||
vdev->lines_buffer = NULL;
|
||||
|
@ -374,7 +400,8 @@ static void clear_data(FpDeviceVfs0050 *vdev)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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
|
||||
* 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);
|
||||
fpi_ssm_jump_to_state (transfer->ssm, SSM_CLEAR_EP2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
fp_err ("USB read interrupt transfer: %s",
|
||||
error->message);
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
|
@ -398,14 +427,16 @@ static void interrupt_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
/* Standard interrupts */
|
||||
if (memcmp (interrupt, interrupt1, 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 */
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
|
||||
/* 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));
|
||||
}
|
||||
|
||||
static void receive_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
||||
static void
|
||||
receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
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);
|
||||
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
|
@ -438,9 +471,12 @@ static void receive_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
g_error_free (error);
|
||||
|
||||
/* Check if fingerprint data is over */
|
||||
if (transfer->actual_length == 0) {
|
||||
if (transfer->actual_length == 0)
|
||||
{
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self->bytes += transfer->actual_length;
|
||||
|
||||
/* We need more data */
|
||||
|
@ -455,16 +491,19 @@ another_scan(FpDevice *dev,
|
|||
void *data)
|
||||
{
|
||||
FpiSsm *ssm = data;
|
||||
|
||||
fpi_ssm_jump_to_state (ssm, SSM_TURN_ON);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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:
|
||||
async_abort (dev, ssm, 1);
|
||||
break;
|
||||
|
@ -489,11 +528,13 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
break;
|
||||
|
||||
case SSM_TURN_ON:
|
||||
if (!self->active) {
|
||||
if (!self->active)
|
||||
{
|
||||
/* The only correct exit */
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
|
||||
if (self->need_report) {
|
||||
if (self->need_report)
|
||||
{
|
||||
fpi_image_device_deactivate_complete (idev,
|
||||
NULL);
|
||||
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 */
|
||||
|
||||
/* If we first time here, report that activate completed */
|
||||
if (self->need_report) {
|
||||
if (self->need_report)
|
||||
{
|
||||
fpi_image_device_activate_complete (idev, NULL);
|
||||
self->need_report = 0;
|
||||
}
|
||||
|
@ -533,6 +575,7 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
fpi_ssm_next_state (ssm);
|
||||
break;
|
||||
}
|
||||
|
||||
case SSM_WAIT_INTERRUPT:
|
||||
/* TODO: This state is unused at this point. When we
|
||||
* 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: {
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
if (self->memory == 0) {
|
||||
if (self->memory == 0)
|
||||
{
|
||||
/* Initialize fingerprint buffer */
|
||||
g_free (self->lines_buffer);
|
||||
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 */
|
||||
while (self->bytes + VFS_USB_BUFFER_SIZE > self->memory) {
|
||||
while (self->bytes + VFS_USB_BUFFER_SIZE > self->memory)
|
||||
{
|
||||
self->memory <<= 1;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
case SSM_SUBMIT_IMAGE:
|
||||
submit_image (self);
|
||||
clear_data (self);
|
||||
|
@ -585,7 +631,8 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
break;
|
||||
|
||||
case SSM_NEXT_RECEIVE:
|
||||
if (!self->active) {
|
||||
if (!self->active)
|
||||
{
|
||||
/* It's the last scan */
|
||||
fpi_ssm_jump_to_state (ssm, SSM_CLEAR_EP2);
|
||||
break;
|
||||
|
@ -612,14 +659,16 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
|||
/* Driver functions */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (dev);
|
||||
|
||||
self->ssm_active = 0;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Unhandled device activation error: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
@ -628,7 +677,8 @@ static void dev_activate_callback(FpiSsm *ssm, FpDevice *dev,
|
|||
}
|
||||
|
||||
/* Activate device */
|
||||
static void dev_activate(FpImageDevice *idev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *idev)
|
||||
{
|
||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||
|
||||
|
@ -643,11 +693,13 @@ static void dev_activate(FpImageDevice *idev)
|
|||
}
|
||||
|
||||
/* Deactivate device */
|
||||
static void dev_deactivate(FpImageDevice *idev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *idev)
|
||||
{
|
||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||
|
||||
if (!self->ssm_active) {
|
||||
if (!self->ssm_active)
|
||||
{
|
||||
fpi_image_device_deactivate_complete (idev, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -658,7 +710,8 @@ static void dev_deactivate(FpImageDevice *idev)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* Notify open complete */
|
||||
|
@ -667,12 +720,14 @@ static void dev_open_callback(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
|||
}
|
||||
|
||||
/* Open device */
|
||||
static void dev_open(FpImageDevice *idev)
|
||||
static void
|
||||
dev_open (FpImageDevice *idev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* 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);
|
||||
return;
|
||||
}
|
||||
|
@ -683,7 +738,8 @@ static void dev_open(FpImageDevice *idev)
|
|||
}
|
||||
|
||||
/* Close device */
|
||||
static void dev_close(FpImageDevice *idev)
|
||||
static void
|
||||
dev_close (FpImageDevice *idev)
|
||||
{
|
||||
GError *error = NULL;
|
||||
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
|
||||
|
@ -700,14 +756,17 @@ static void dev_close(FpImageDevice *idev)
|
|||
|
||||
/* Usb id table of device */
|
||||
static const FpIdEntry id_table[] = {
|
||||
{.vid = 0x138a, .pid = 0x0050,
|
||||
},
|
||||
{.vid = 0x138a, .pid = 0x0050, },
|
||||
{.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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@
|
|||
#define EP3_IN 0x83
|
||||
|
||||
/* Fingerprint horizontal line */
|
||||
struct vfs_line {
|
||||
struct vfs_line
|
||||
{
|
||||
/* It must be always 0x01 */
|
||||
unsigned char _0x01;
|
||||
/* It must be always 0xfe */
|
||||
|
@ -78,7 +79,8 @@ struct vfs_line {
|
|||
} __attribute__((__packed__));
|
||||
|
||||
/* The main driver structure */
|
||||
struct _FpDeviceVfs0050 {
|
||||
struct _FpDeviceVfs0050
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
/* One if we were asked to read fingerprint, zero otherwise */
|
||||
|
|
|
@ -85,7 +85,8 @@
|
|||
#define VFS_VAL_IMG_EXPOSURE 0x21c0
|
||||
|
||||
/* Structure for Validity device */
|
||||
struct _FpDeviceVfs101 {
|
||||
struct _FpDeviceVfs101
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
||||
/* 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]) &&
|
||||
(byte (1, vdev->seqnum) == vdev->buffer[1]))
|
||||
|
@ -149,8 +153,7 @@ static inline int check_seqnum(FpDeviceVfs101 *vdev)
|
|||
}
|
||||
|
||||
/* Internal result codes */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
RESULT_RETRY,
|
||||
RESULT_RETRY_SHORT,
|
||||
RESULT_RETRY_REMOVE,
|
||||
|
@ -164,18 +167,23 @@ enum
|
|||
)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
|
||||
|
||||
/* Skip error check if ignore_error is set */
|
||||
if (error) {
|
||||
if (!self->ignore_error) {
|
||||
if (error)
|
||||
{
|
||||
if (!self->ignore_error)
|
||||
{
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error_free (error);
|
||||
fp_dbg ("Ignoring send error: %s", error->message);
|
||||
}
|
||||
|
@ -215,7 +223,8 @@ async_send(FpiSsm *ssm,
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -276,10 +285,12 @@ async_recv(FpiSsm *ssm,
|
|||
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 */
|
||||
static void async_load_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||
static void
|
||||
async_load_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -320,9 +331,11 @@ static void async_load_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Image load not completed, submit another asynchronous load */
|
||||
async_load (transfer->ssm, dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset ignore_error flag */
|
||||
|
@ -370,15 +383,15 @@ async_sleep(unsigned int msec,
|
|||
}
|
||||
|
||||
/* Swap ssm states */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
M_SWAP_SEND,
|
||||
M_SWAP_RECV,
|
||||
M_SWAP_NUM_STATES,
|
||||
};
|
||||
|
||||
/* 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))
|
||||
{
|
||||
|
@ -536,7 +549,8 @@ vfs_img_load(FpiSsm *ssm,
|
|||
#define offset(x, y) ((x) + ((y) * VFS_FRAME_SIZE))
|
||||
|
||||
/* 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;
|
||||
long int level;
|
||||
|
@ -564,8 +578,10 @@ static void img_screen(FpDeviceVfs101 *vdev)
|
|||
{
|
||||
/* Begin threshold satisfied */
|
||||
if (count < VFS_IMG_SLT_LINES)
|
||||
{
|
||||
/* Increase count */
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Found top fingerprint line */
|
||||
|
@ -578,8 +594,10 @@ static void img_screen(FpDeviceVfs101 *vdev)
|
|||
{
|
||||
/* End threshold satisfied */
|
||||
if (count < VFS_IMG_SLT_LINES)
|
||||
{
|
||||
/* Increase count */
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Found bottom fingerprint line */
|
||||
|
@ -588,9 +606,11 @@ static void img_screen(FpDeviceVfs101 *vdev)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not threshold satisfied, reset count */
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
static void img_copy(FpDeviceVfs101 *self, FpImage *img)
|
||||
static void
|
||||
img_copy (FpDeviceVfs101 *self, FpImage *img)
|
||||
{
|
||||
unsigned int line;
|
||||
unsigned char *img_buffer = img->data;
|
||||
|
@ -661,15 +682,15 @@ img_extract(FpiSsm *ssm,
|
|||
};
|
||||
|
||||
/* Finger states */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
VFS_FINGER_EMPTY,
|
||||
VFS_FINGER_PRESENT,
|
||||
VFS_FINGER_UNKNOWN,
|
||||
};
|
||||
|
||||
/* Return finger state */
|
||||
static inline int vfs_finger_state(FpDeviceVfs101 *vdev)
|
||||
static inline int
|
||||
vfs_finger_state (FpDeviceVfs101 *vdev)
|
||||
{
|
||||
/* Check finger state */
|
||||
switch (vdev->buffer[0x0a])
|
||||
|
@ -695,7 +716,8 @@ static inline int vfs_finger_state(FpDeviceVfs101 *vdev)
|
|||
};
|
||||
|
||||
/* Check contrast of image */
|
||||
static void vfs_check_contrast(FpDeviceVfs101 *vdev)
|
||||
static void
|
||||
vfs_check_contrast (FpDeviceVfs101 *vdev)
|
||||
{
|
||||
int y;
|
||||
long int count = 0;
|
||||
|
@ -723,8 +745,7 @@ static void vfs_check_contrast(FpDeviceVfs101 *vdev)
|
|||
}
|
||||
|
||||
/* Loop ssm states */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
/* Step 0 - Scan finger */
|
||||
M_LOOP_0_GET_PRINT,
|
||||
M_LOOP_0_SLEEP,
|
||||
|
@ -756,13 +777,15 @@ enum
|
|||
};
|
||||
|
||||
/* 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;
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev);
|
||||
|
||||
/* Complete if deactivation was requested */
|
||||
if (self->deactivate) {
|
||||
if (self->deactivate)
|
||||
{
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
return;
|
||||
}
|
||||
|
@ -926,7 +949,8 @@ static void m_loop_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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 */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
/* Step 0 - Cleanup device buffer */
|
||||
M_INIT_0_RECV_DIRTY,
|
||||
M_INIT_0_ABORT_PRINT,
|
||||
|
@ -991,13 +1014,15 @@ enum
|
|||
};
|
||||
|
||||
/* 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;
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (_dev);
|
||||
|
||||
/* Mark as cancelled when activation collides with deactivation. */
|
||||
if (self->deactivate) {
|
||||
if (self->deactivate)
|
||||
{
|
||||
fpi_ssm_mark_failed (ssm,
|
||||
g_error_new (G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED,
|
||||
|
@ -1088,8 +1113,10 @@ static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
{
|
||||
/* Finger not present */
|
||||
if (self->counter == 0)
|
||||
{
|
||||
/* Continue */
|
||||
fpi_ssm_jump_to_state (ssm, M_INIT_3_SET_000E);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 */
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -1233,7 +1261,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
/* Notify activate complete */
|
||||
fpi_image_device_activate_complete (dev, error);
|
||||
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
FpiSsm *ssm_loop;
|
||||
|
||||
/* Start loop ssm */
|
||||
|
@ -1247,7 +1276,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
}
|
||||
|
||||
/* Activate device */
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
|
||||
FpiSsm *ssm;
|
||||
|
@ -1272,12 +1302,14 @@ static void dev_activate(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
/* Deactivate device */
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
|
||||
|
||||
/* Device already deactivated, likely due to an error */
|
||||
if (!self->active) {
|
||||
if (!self->active)
|
||||
{
|
||||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -1288,7 +1320,8 @@ static void dev_deactivate(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
/* Open device */
|
||||
static void dev_open(FpImageDevice *dev)
|
||||
static void
|
||||
dev_open (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
|
||||
GError *error = NULL;
|
||||
|
@ -1305,7 +1338,8 @@ static void dev_open(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
/* Close device */
|
||||
static void dev_close(FpImageDevice *dev)
|
||||
static void
|
||||
dev_close (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs101 *self = FPI_DEVICE_VFS101 (dev);
|
||||
GError *error = NULL;
|
||||
|
@ -1326,10 +1360,14 @@ static const FpIdEntry id_table [ ] = {
|
|||
{ .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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ submit_image(FpiSsm *ssm,
|
|||
|
||||
#if 0
|
||||
/* XXX: This is probably handled by libfprint automagically? */
|
||||
if (vdev->scanline_count < 20) {
|
||||
if (vdev->scanline_count < 20)
|
||||
{
|
||||
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||
return 0;
|
||||
}
|
||||
|
@ -77,8 +78,7 @@ submit_image(FpiSsm *ssm,
|
|||
}
|
||||
|
||||
/* Loop ssm states */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
/* Step 0 - Scan finger */
|
||||
M_REQUEST_PRINT,
|
||||
M_WAIT_PRINT,
|
||||
|
@ -93,12 +93,14 @@ enum
|
|||
};
|
||||
|
||||
/* 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;
|
||||
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case M_REQUEST_PRINT:
|
||||
vfs301_proto_request_fingerprint (self);
|
||||
fpi_ssm_next_state (ssm);
|
||||
|
@ -139,24 +141,30 @@ static void m_loop_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
break;
|
||||
|
||||
case M_SUBMIT_PRINT:
|
||||
if (submit_image(ssm, dev)) {
|
||||
if (submit_image (ssm, dev))
|
||||
{
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
/* NOTE: finger off is expected only after submitting image... */
|
||||
fpi_image_device_report_finger_status (dev, FALSE);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("State machine completed with an error: %s", error->message);
|
||||
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 */
|
||||
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);
|
||||
|
||||
|
@ -177,13 +186,15 @@ static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
FpiSsm *ssm_loop;
|
||||
|
||||
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
|
||||
if (!error) {
|
||||
if (!error)
|
||||
{
|
||||
/* Notify activate complete */
|
||||
|
||||
/* Start loop ssm */
|
||||
|
@ -197,7 +208,8 @@ static void m_init_complete(FpiSsm *ssm, FpDevice *dev, void *user_data,
|
|||
}
|
||||
|
||||
/* Activate device */
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpiSsm *ssm;
|
||||
|
||||
|
@ -207,7 +219,8 @@ static void dev_activate(FpImageDevice *dev)
|
|||
}
|
||||
|
||||
/* Deactivate device */
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs301 *self;
|
||||
|
||||
|
@ -216,7 +229,8 @@ static void dev_deactivate(FpImageDevice *dev)
|
|||
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);
|
||||
GError *error = NULL;
|
||||
|
@ -231,7 +245,8 @@ static void dev_open(FpImageDevice *dev)
|
|||
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);
|
||||
GError *error = NULL;
|
||||
|
@ -254,9 +269,13 @@ static const FpIdEntry id_table [ ] = {
|
|||
{ .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);
|
||||
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ enum {
|
|||
#define VFS301_FP_RECV_LEN_1 (84032)
|
||||
#define VFS301_FP_RECV_LEN_2 (84096)
|
||||
|
||||
struct _FpDeviceVfs301 {
|
||||
struct _FpDeviceVfs301
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
/* buffer to hold raw scanlines */
|
||||
|
@ -85,7 +86,8 @@ enum {
|
|||
* to the 0x02D0 messages.
|
||||
* It seems to be always the same - what is it for? Some kind of confirmation?
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
unsigned char sync_0x01;
|
||||
unsigned char sync_0xfe;
|
||||
|
||||
|
@ -99,7 +101,8 @@ typedef struct {
|
|||
unsigned char scan[VFS301_FP_WIDTH];
|
||||
} vfs301_init_line_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
unsigned char sync_0x01;
|
||||
unsigned char sync_0xfe;
|
||||
|
||||
|
@ -134,4 +137,6 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev);
|
|||
void vfs301_proto_process_event_start (FpDeviceVfs301 *dev);
|
||||
int vfs301_proto_process_event_poll (FpDeviceVfs301 *dev);
|
||||
|
||||
void vfs301_extract_image(FpDeviceVfs301 *vfs, unsigned char *output, int *output_height);
|
||||
void vfs301_extract_image (FpDeviceVfs301 *vfs,
|
||||
unsigned char *output,
|
||||
int *output_height);
|
||||
|
|
|
@ -41,14 +41,16 @@
|
|||
/************************** USB STUFF *****************************************/
|
||||
|
||||
#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);
|
||||
|
||||
#ifdef PRINT_VERBOSE
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MIN(length, 128); i++) {
|
||||
for (i = 0; i < MIN (length, 128); i++)
|
||||
{
|
||||
fprintf (stderr, "%.2X ", data[i]);
|
||||
if (i % 8 == 7)
|
||||
fprintf (stderr, " ");
|
||||
|
@ -61,9 +63,11 @@ static void usb_print_packet(int dir, GError *error, const guint8 *data, int len
|
|||
}
|
||||
#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;
|
||||
|
||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||
|
||||
/* 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
|
||||
usb_print_packet (0, err, transfer->buffer, transfer->actual_length);
|
||||
#endif
|
||||
if (err) {
|
||||
if (err)
|
||||
{
|
||||
if (!error)
|
||||
g_warning ("Unhandled receive error: %s", err->message);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
g_autoptr(FpiUsbTransfer) transfer = NULL;
|
||||
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
if (err) {
|
||||
if (err)
|
||||
{
|
||||
g_warning ("Error while sending data, continuing anyway: %s", err->message);
|
||||
g_propagate_error (error, err);
|
||||
}
|
||||
|
@ -115,7 +123,8 @@ static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GEr
|
|||
|
||||
/************************** 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 *data = res;
|
||||
|
@ -128,14 +137,17 @@ static guint8 * vfs301_proto_generate_0B(int subtype, gssize *len)
|
|||
|
||||
data[20] = subtype;
|
||||
|
||||
switch (subtype) {
|
||||
switch (subtype)
|
||||
{
|
||||
case 0x04:
|
||||
data[34] = 0x9F;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
data[34] = 0xAB;
|
||||
/* NOTE: There was a len++ here, which could never do anything */
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
@ -147,7 +159,8 @@ static guint8 * vfs301_proto_generate_0B(int subtype, gssize *len)
|
|||
#define HEX_TO_INT(c) \
|
||||
(((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 *dst;
|
||||
|
@ -155,7 +168,8 @@ static guint8 * translate_str(const char **srcL, gssize *len)
|
|||
const char *src;
|
||||
gssize src_len = 0;
|
||||
|
||||
for (src_pos = srcL; *src_pos; src_pos++) {
|
||||
for (src_pos = srcL; *src_pos; src_pos++)
|
||||
{
|
||||
gint tmp;
|
||||
|
||||
src = *src_pos;
|
||||
|
@ -168,18 +182,18 @@ static guint8 * translate_str(const char **srcL, gssize *len)
|
|||
res = g_malloc0 (*len);
|
||||
dst = res;
|
||||
|
||||
for (src_pos = srcL; *src_pos; src_pos++) {
|
||||
for (src = *src_pos; *src; src += 2, dst += 1) {
|
||||
for (src_pos = srcL; *src_pos; src_pos++)
|
||||
for (src = *src_pos; *src; src += 2, dst += 1)
|
||||
*dst = (guint8) ((HEX_TO_INT (src[0]) << 4) | (HEX_TO_INT (src[1])));
|
||||
}
|
||||
}
|
||||
|
||||
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 0x04:
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0B:
|
||||
return vfs301_proto_generate_0B (subtype, len);
|
||||
break;
|
||||
|
||||
case 0x02D0:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0220:
|
||||
switch (subtype) {
|
||||
switch (subtype)
|
||||
{
|
||||
case 1:
|
||||
return translate_str (vfs301_0220_01, len);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return translate_str (vfs301_0220_02, len);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return translate_str (vfs301_0220_03, len);
|
||||
break;
|
||||
|
||||
case 0xFA00:
|
||||
case 0x2C01:
|
||||
case 0x5E01: {
|
||||
|
@ -251,11 +272,13 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
|||
return data;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
default:
|
||||
break;
|
||||
|
@ -269,25 +292,27 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
|
|||
/************************** SCAN IMAGE PROCESSING *****************************/
|
||||
|
||||
#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 j;
|
||||
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 */
|
||||
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))
|
||||
rv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#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 *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
|
||||
* fingerprint. */
|
||||
for (diff = 0, i = 0; i < VFS301_FP_WIDTH; i++) {
|
||||
for (diff = 0, i = 0; i < VFS301_FP_WIDTH; i++)
|
||||
{
|
||||
if (*line1 > *line2)
|
||||
diff += *line1 - *line2;
|
||||
else
|
||||
|
@ -312,11 +338,12 @@ static int scanline_diff(const guint8 *scanlines, int prev, int cur)
|
|||
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 */
|
||||
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;
|
||||
|
@ -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
|
||||
* many false edges etc.).
|
||||
*/
|
||||
for (i = 1; i < vfs->scanline_count; i++) {
|
||||
if (scanline_diff(scanlines, last_line, i)) {
|
||||
for (i = 1; i < vfs->scanline_count; i++)
|
||||
{
|
||||
if (scanline_diff (scanlines, last_line, i))
|
||||
{
|
||||
memcpy (
|
||||
output + VFS301_FP_OUTPUT_WIDTH * (*output_height),
|
||||
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;
|
||||
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;*/
|
||||
guint8 *cur_line;
|
||||
int last_img_height;
|
||||
|
||||
#ifdef SCAN_FINISH_DETECTION
|
||||
int finished_scan;
|
||||
#endif
|
||||
|
||||
if (first_block) {
|
||||
if (first_block)
|
||||
{
|
||||
last_img_height = 0;
|
||||
dev->scanline_count = no_lines;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
last_img_height = dev->scanline_count;
|
||||
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;
|
||||
i < no_lines;
|
||||
i++, cur_line += VFS301_FP_OUTPUT_WIDTH
|
||||
) {
|
||||
)
|
||||
{
|
||||
#ifndef OUTPUT_RAW
|
||||
memcpy (cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH);
|
||||
#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))
|
||||
|
||||
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;
|
||||
|
||||
if (first_block) {
|
||||
if (first_block)
|
||||
{
|
||||
g_assert (len >= VFS301_FP_FRAME_SIZE);
|
||||
|
||||
/* 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))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_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(FpiUsbTransfer) transfer = NULL;
|
||||
|
@ -444,14 +482,13 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
|
|||
/* XXX: This is obviously not a sane error handling! */
|
||||
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;
|
||||
} else if (memcmp(transfer->buffer, got_event, sizeof(no_event)) == 0) {
|
||||
else if (memcmp (transfer->buffer, got_event, sizeof (no_event)) == 0)
|
||||
return 1;
|
||||
} else {
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: We sometimes need to receive data on from two endpoints at the same
|
||||
* 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); \
|
||||
}
|
||||
|
||||
static void vfs301_proto_process_event_cb(FpiUsbTransfer *transfer,
|
||||
static void
|
||||
vfs301_proto_process_event_cb (FpiUsbTransfer *transfer,
|
||||
FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
FpDeviceVfs301 *dev = user_data;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Error receiving data: %s", error->message);
|
||||
g_error_free (error);
|
||||
dev->recv_progress = VFS301_FAILURE;
|
||||
return;
|
||||
} else if (transfer->actual_length < transfer->length) {
|
||||
}
|
||||
else if (transfer->actual_length < transfer->length)
|
||||
{
|
||||
/* TODO: process the data anyway? */
|
||||
dev->recv_progress = VFS301_ENDED;
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
FpiUsbTransfer *new;
|
||||
if (!vfs301_proto_process_data (dev,
|
||||
transfer->length == VFS301_FP_RECV_LEN_1,
|
||||
transfer->buffer,
|
||||
transfer->actual_length)) {
|
||||
transfer->actual_length))
|
||||
{
|
||||
dev->recv_progress = VFS301_ENDED;
|
||||
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;
|
||||
|
||||
|
@ -538,7 +583,8 @@ void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
|
|||
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)
|
||||
return dev->recv_progress;
|
||||
|
@ -562,7 +608,8 @@ int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev)
|
|||
return dev->recv_progress;
|
||||
}
|
||||
|
||||
void vfs301_proto_init(FpDeviceVfs301 *dev)
|
||||
void
|
||||
vfs301_proto_init (FpDeviceVfs301 *dev)
|
||||
{
|
||||
USB_SEND (0x01, -1);
|
||||
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
|
||||
|
@ -648,6 +695,7 @@ void vfs301_proto_init(FpDeviceVfs301 *dev)
|
|||
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 5760);
|
||||
}
|
||||
|
||||
void vfs301_proto_deinit(FpDeviceVfs301 *dev)
|
||||
void
|
||||
vfs301_proto_deinit (FpDeviceVfs301 *dev)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ enum {
|
|||
ACTION_RECEIVE,
|
||||
};
|
||||
|
||||
struct usb_action {
|
||||
struct usb_action
|
||||
{
|
||||
int type;
|
||||
const char *name;
|
||||
int endpoint;
|
||||
|
@ -65,7 +66,8 @@ struct usb_action {
|
|||
.correct_reply_size = sizeof (EXPECTED) \
|
||||
},
|
||||
|
||||
struct usbexchange_data {
|
||||
struct usbexchange_data
|
||||
{
|
||||
int stepcount;
|
||||
FpImageDevice *device;
|
||||
struct usb_action *actions;
|
||||
|
@ -75,7 +77,8 @@ struct usbexchange_data {
|
|||
|
||||
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)
|
||||
{
|
||||
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)];
|
||||
g_assert (!(action->type != ACTION_SEND));
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
/* Transfer not completed, return IO error */
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
|
@ -96,13 +100,15 @@ static void async_send_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
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)
|
||||
{
|
||||
struct usbexchange_data *data = fpi_ssm_get_user_data (transfer->ssm);
|
||||
struct usb_action *action;
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
/* Transfer not completed, return IO error */
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
return;
|
||||
|
@ -113,8 +119,10 @@ static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
action = &data->actions[fpi_ssm_get_cur_state (transfer->ssm)];
|
||||
g_assert (!(action->type != ACTION_RECEIVE));
|
||||
|
||||
if (action->data != NULL) {
|
||||
if (transfer->actual_length != action->correct_reply_size) {
|
||||
if (action->data != NULL)
|
||||
{
|
||||
if (transfer->actual_length != action->correct_reply_size)
|
||||
{
|
||||
fp_err ("Got %d bytes instead of %d",
|
||||
(gint) transfer->actual_length,
|
||||
action->correct_reply_size);
|
||||
|
@ -122,20 +130,25 @@ static void async_recv_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
return;
|
||||
}
|
||||
if (memcmp (transfer->buffer, action->data,
|
||||
action->correct_reply_size) != 0) {
|
||||
action->correct_reply_size) != 0)
|
||||
{
|
||||
fp_dbg ("Wrong reply:");
|
||||
fpi_ssm_mark_failed (transfer->ssm, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||
return;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_dbg ("Got %d bytes out of %d",
|
||||
(gint) transfer->actual_length,
|
||||
(gint) transfer->length);
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
switch (action->type) {
|
||||
switch (action->type)
|
||||
{
|
||||
case ACTION_SEND:
|
||||
fp_dbg ("Sending %s", action->name);
|
||||
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)
|
||||
{
|
||||
FpiSsm *subsm = fpi_ssm_new (FP_DEVICE (data->device),
|
||||
usbexchange_loop,
|
||||
data->stepcount,
|
||||
data);
|
||||
|
||||
fpi_ssm_start_subsm (ssm, subsm);
|
||||
}
|
||||
|
||||
/* ====================== utils ======================= */
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int dev = (int) buf1[i] + (int) buf2[i] - mean;
|
||||
res += dev * dev;
|
||||
}
|
||||
|
@ -211,7 +229,8 @@ static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1,
|
|||
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,
|
||||
unsigned x)
|
||||
{
|
||||
|
@ -238,7 +257,8 @@ static struct fpi_line_asmbl_ctx assembling_ctx = {
|
|||
.get_pixel = vfs5011_get_pixel,
|
||||
};
|
||||
|
||||
struct _FpDeviceVfs5011 {
|
||||
struct _FpDeviceVfs5011
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
unsigned char *total_buffer;
|
||||
|
@ -272,7 +292,8 @@ enum {
|
|||
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)
|
||||
{
|
||||
fp_dbg ("capture_init");
|
||||
|
@ -287,7 +308,8 @@ static void capture_init(FpDeviceVfs5011 *self, int max_captured,
|
|||
self->max_lines_recorded = max_recorded;
|
||||
}
|
||||
|
||||
static int process_chunk(FpDeviceVfs5011 *self, int transferred)
|
||||
static int
|
||||
process_chunk (FpDeviceVfs5011 *self, int transferred)
|
||||
{
|
||||
enum {
|
||||
DEVIATION_THRESHOLD = 15 * 15,
|
||||
|
@ -299,41 +321,50 @@ static int process_chunk(FpDeviceVfs5011 *self, int transferred)
|
|||
int lines_captured = transferred / VFS5011_LINE_SIZE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lines_captured; i++) {
|
||||
for (i = 0; i < lines_captured; i++)
|
||||
{
|
||||
unsigned char *linebuf = self->capture_buffer
|
||||
+ i * VFS5011_LINE_SIZE;
|
||||
|
||||
if (fpi_std_sq_dev (linebuf + 8, VFS5011_IMAGE_WIDTH)
|
||||
< DEVIATION_THRESHOLD) {
|
||||
< DEVIATION_THRESHOLD)
|
||||
{
|
||||
if (self->lines_captured == 0)
|
||||
continue;
|
||||
else
|
||||
self->empty_lines++;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
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",
|
||||
self->empty_lines);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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",
|
||||
self->lines_captured);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((self->lastline == NULL)
|
||||
|| (fpi_mean_sq_diff_norm(self->lastline + 8,
|
||||
if ((self->lastline == NULL) ||
|
||||
(fpi_mean_sq_diff_norm (self->lastline + 8,
|
||||
linebuf + 8,
|
||||
VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) {
|
||||
VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD))
|
||||
{
|
||||
self->lastline = g_malloc (VFS5011_LINE_SIZE);
|
||||
self->rows = g_slist_prepend (self->rows,
|
||||
self->lastline);
|
||||
memmove (self->lastline, linebuf, VFS5011_LINE_SIZE);
|
||||
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",
|
||||
self->lines_recorded);
|
||||
return 1;
|
||||
|
@ -350,7 +381,8 @@ submit_image(FpiSsm *ssm,
|
|||
{
|
||||
FpImage *img;
|
||||
|
||||
if (self->lines_recorded == 0) {
|
||||
if (self->lines_recorded == 0)
|
||||
{
|
||||
/* == FP_ENROLL_RETRY_TOO_SHORT */
|
||||
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
return;
|
||||
|
@ -371,7 +403,8 @@ submit_image(FpiSsm *ssm,
|
|||
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)
|
||||
{
|
||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||
|
@ -380,7 +413,8 @@ static void chunk_capture_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
self = FPI_DEVICE_VFS5011 (dev);
|
||||
|
||||
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)
|
||||
g_error_free (error);
|
||||
|
||||
|
@ -393,22 +427,29 @@ static void chunk_capture_callback(FpiUsbTransfer *transfer, FpDevice *device,
|
|||
else
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
DEV_ACTIVATE_READ_DATA);
|
||||
} else {
|
||||
if (!self->deactivating) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!self->deactivating)
|
||||
{
|
||||
fp_err ("Failed to capture data");
|
||||
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error_free (error);
|
||||
fpi_ssm_mark_completed (transfer->ssm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void capture_chunk_async(FpDeviceVfs5011 *self,
|
||||
static void
|
||||
capture_chunk_async (FpDeviceVfs5011 *self,
|
||||
GUsbDevice *handle, int nline,
|
||||
int timeout, FpiSsm *ssm)
|
||||
{
|
||||
FpiUsbTransfer *transfer;
|
||||
|
||||
fp_dbg ("capture_chunk_async: capture %d lines, already have %d",
|
||||
nline, self->lines_recorded);
|
||||
enum {
|
||||
|
@ -616,7 +657,8 @@ struct usb_action vfs5011_initiate_capture[] = {
|
|||
|
||||
/* ====================== 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};
|
||||
|
||||
|
@ -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));
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
{
|
||||
fp_dbg ("deactivating, marking completed");
|
||||
fpi_ssm_mark_completed (ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case DEV_ACTIVATE_REQUEST_FPRINT:
|
||||
self->init_sequence.stepcount =
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -696,7 +741,8 @@ static void activate_loop_complete(FpiSsm *ssm, FpDevice *_dev,
|
|||
if (self->init_sequence.receive_buf != NULL)
|
||||
g_free (self->init_sequence.receive_buf);
|
||||
self->init_sequence.receive_buf = NULL;
|
||||
if (!self->deactivating && !error) {
|
||||
if (!self->deactivating && !error)
|
||||
{
|
||||
submit_image (ssm, self, dev);
|
||||
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;
|
||||
|
||||
if (self->deactivating) {
|
||||
if (self->deactivating)
|
||||
fpi_image_device_deactivate_complete (dev, error);
|
||||
} else if (error) {
|
||||
else if (error)
|
||||
fpi_image_device_session_error (dev, error);
|
||||
} else {
|
||||
else
|
||||
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;
|
||||
FpDeviceVfs5011 *self;
|
||||
|
||||
self = FPI_DEVICE_VFS5011 (_dev);
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
switch (fpi_ssm_get_cur_state (ssm))
|
||||
{
|
||||
case DEV_OPEN_START:
|
||||
self->init_sequence.stepcount =
|
||||
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;
|
||||
usb_exchange_async (ssm, &self->init_sequence);
|
||||
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)
|
||||
{
|
||||
FpImageDevice *dev = user_data;
|
||||
|
@ -749,7 +798,8 @@ static void open_loop_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
|||
fpi_ssm_free (ssm);
|
||||
}
|
||||
|
||||
static void dev_open(FpImageDevice *dev)
|
||||
static void
|
||||
dev_open (FpImageDevice *dev)
|
||||
{
|
||||
FpiSsm *ssm;
|
||||
GError *error = NULL;
|
||||
|
@ -759,7 +809,8 @@ static void dev_open(FpImageDevice *dev)
|
|||
self->capture_buffer =
|
||||
(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);
|
||||
return;
|
||||
}
|
||||
|
@ -768,10 +819,13 @@ static void dev_open(FpImageDevice *dev)
|
|||
fpi_ssm_start (ssm, open_loop_complete);
|
||||
}
|
||||
|
||||
static void dev_close(FpImageDevice *dev)
|
||||
static void
|
||||
dev_close (FpImageDevice *dev)
|
||||
{
|
||||
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)),
|
||||
0, 0, &error);
|
||||
|
@ -782,7 +836,8 @@ static void dev_close(FpImageDevice *dev)
|
|||
fpi_image_device_close_complete (dev, error);
|
||||
}
|
||||
|
||||
static void start_scan(FpImageDevice *dev)
|
||||
static void
|
||||
start_scan (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs5011 *self;
|
||||
FpiSsm *ssm;
|
||||
|
@ -797,7 +852,8 @@ static void start_scan(FpImageDevice *dev)
|
|||
fp_dbg ("ssm done, getting out");
|
||||
}
|
||||
|
||||
static void dev_activate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_activate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs5011 *self;
|
||||
|
||||
|
@ -808,34 +864,34 @@ static void dev_activate(FpImageDevice *dev)
|
|||
start_scan (dev);
|
||||
}
|
||||
|
||||
static void dev_deactivate(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deactivate (FpImageDevice *dev)
|
||||
{
|
||||
FpDeviceVfs5011 *self;
|
||||
|
||||
self = FPI_DEVICE_VFS5011 (dev);
|
||||
if (self->loop_running) {
|
||||
if (self->loop_running)
|
||||
self->deactivating = TRUE;
|
||||
} else
|
||||
else
|
||||
fpi_image_device_deactivate_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static const FpIdEntry id_table[] = {
|
||||
{ /* Validity device from some Toshiba laptops */ .vid = 0x138a, .pid = 0x0010,
|
||||
},
|
||||
{ /* 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,
|
||||
},
|
||||
{ /* one more Validity device */ .vid = 0x138a, .pid = 0x0018,
|
||||
},
|
||||
{ /* Validity device from some Toshiba laptops */ .vid = 0x138a, .pid = 0x0010, },
|
||||
{ /* 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, },
|
||||
{ /* one more Validity device */ .vid = 0x138a, .pid = 0x0018, },
|
||||
{ .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);
|
||||
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_height = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#include <gio/gio.h>
|
||||
#include <gio/gunixsocketaddress.h>
|
||||
|
||||
struct _FpDeviceVirtualImage {
|
||||
struct _FpDeviceVirtualImage
|
||||
{
|
||||
FpImageDevice parent;
|
||||
|
||||
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)
|
||||
|
||||
static void start_listen (FpDeviceVirtualImage *dev);
|
||||
static void recv_image (FpDeviceVirtualImage *dev, GInputStream *stream);
|
||||
static void recv_image (FpDeviceVirtualImage *dev,
|
||||
GInputStream *stream);
|
||||
|
||||
static void
|
||||
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);
|
||||
|
||||
if (bytes <= 0) {
|
||||
if (bytes < 0) {
|
||||
if (bytes <= 0)
|
||||
{
|
||||
if (bytes < 0)
|
||||
{
|
||||
g_warning ("Error receiving header for image data: %s", error->message);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
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);
|
||||
|
||||
if (bytes <= 0) {
|
||||
if (bytes < 0) {
|
||||
if (bytes <= 0)
|
||||
{
|
||||
if (bytes < 0)
|
||||
{
|
||||
g_warning ("Error receiving header for image data: %s", error->message);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
@ -117,14 +123,17 @@ recv_image_hdr_recv_cb (GObject *source_object,
|
|||
}
|
||||
|
||||
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
|
||||
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000) {
|
||||
if (self->recv_img_hdr[0] > 5000 || self->recv_img_hdr[1] > 5000)
|
||||
{
|
||||
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
self->connection = NULL;
|
||||
}
|
||||
|
||||
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0) {
|
||||
switch (self->recv_img_hdr[0]) {
|
||||
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
|
||||
{
|
||||
switch (self->recv_img_hdr[0])
|
||||
{
|
||||
case -1:
|
||||
/* -1 is a retry error, just pass it through */
|
||||
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,
|
||||
NULL,
|
||||
&error);
|
||||
if (!connection) {
|
||||
if (!connection)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
|
@ -193,7 +203,8 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
|
|||
/* Always further connections (but we disconnect them immediately
|
||||
* if we already have a connection). */
|
||||
start_listen (dev);
|
||||
if (dev->connection) {
|
||||
if (dev->connection)
|
||||
{
|
||||
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -243,7 +254,8 @@ dev_init(FpImageDevice *dev)
|
|||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
&error)) {
|
||||
&error))
|
||||
{
|
||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void dev_deinit(FpImageDevice *dev)
|
||||
static void
|
||||
dev_deinit (FpImageDevice *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_close = dev_deinit;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
#include "fpi-image-device.h"
|
||||
|
||||
/* fp_minutia structure definition */
|
||||
struct fp_minutia {
|
||||
struct fp_minutia
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int ex;
|
||||
|
@ -42,7 +43,8 @@ struct fp_minutia {
|
|||
};
|
||||
|
||||
/* fp_minutiae structure definition */
|
||||
struct fp_minutiae {
|
||||
struct fp_minutiae
|
||||
{
|
||||
int alloc;
|
||||
int num;
|
||||
struct fp_minutia **list;
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
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));
|
||||
gint i;
|
||||
|
@ -42,7 +43,8 @@ static GList *insert_drivers (GList *list)
|
|||
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
||||
const FpIdEntry *entry;
|
||||
|
||||
if (cls->type != FP_DEVICE_TYPE_USB) {
|
||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
{
|
||||
g_type_class_unref (cls);
|
||||
continue;
|
||||
}
|
||||
|
@ -53,7 +55,8 @@ static GList *insert_drivers (GList *list)
|
|||
|
||||
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
||||
|
||||
if (g_hash_table_lookup (printed, key) != NULL) {
|
||||
if (g_hash_table_lookup (printed, key) != NULL)
|
||||
{
|
||||
g_free (key);
|
||||
continue;
|
||||
}
|
||||
|
@ -69,7 +72,8 @@ static GList *insert_drivers (GList *list)
|
|||
return list;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GList *list, *l;
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ static const FpDeviceClass whitelist = {
|
|||
|
||||
GHashTable *printed = NULL;
|
||||
|
||||
static void print_driver (const FpDeviceClass *cls)
|
||||
static void
|
||||
print_driver (const FpDeviceClass *cls)
|
||||
{
|
||||
const FpIdEntry *entry;
|
||||
gint num_printed = 0;
|
||||
|
@ -56,21 +57,22 @@ static void print_driver (const FpDeviceClass *cls)
|
|||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
return;
|
||||
|
||||
for (entry = cls->id_table; entry->vid != 0; entry++) {
|
||||
for (entry = cls->id_table; entry->vid != 0; entry++)
|
||||
{
|
||||
const FpIdEntry *bl_entry;
|
||||
char *key;
|
||||
|
||||
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++) {
|
||||
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid) {
|
||||
for (bl_entry = blacklist_id_table; bl_entry->vid != 0; bl_entry++)
|
||||
if (entry->vid == bl_entry->vid && entry->pid == bl_entry->pid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bl_entry->vid != 0)
|
||||
continue;
|
||||
|
||||
key = g_strdup_printf ("%04x:%04x", entry->vid, entry->pid);
|
||||
|
||||
if (g_hash_table_lookup (printed, key) != NULL) {
|
||||
if (g_hash_table_lookup (printed, key) != NULL)
|
||||
{
|
||||
g_free (key);
|
||||
continue;
|
||||
}
|
||||
|
@ -91,7 +93,8 @@ static void print_driver (const FpDeviceClass *cls)
|
|||
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));
|
||||
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);
|
||||
|
||||
for (i = 0; i < drivers->len; i++) {
|
||||
for (i = 0; i < drivers->len; i++)
|
||||
{
|
||||
GType driver = g_array_index (drivers, GType, i);
|
||||
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
|
||||
|
||||
if (cls->type != FP_DEVICE_TYPE_USB) {
|
||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
{
|
||||
g_type_class_unref (cls);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -22,4 +22,3 @@
|
|||
#include "fp-context.h"
|
||||
#include "fp-device.h"
|
||||
#include "fp-image.h"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ case "$1" in
|
|||
esac
|
||||
|
||||
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=$?
|
||||
popd
|
||||
exit $RES
|
Loading…
Reference in a new issue