Uncrustify everything except for nbis

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

View file

@ -33,7 +33,8 @@ typedef enum {
IMAGE_DISPLAY_BINARY = 1 << 1
} 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,33 +99,35 @@ 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;
fp_minutia_get_coords(min, &x, &y);
fp_minutia_get_coords (min, &x, &y);
pixel_offset = (y * width) + x;
write_pixel(pixel_offset - 2);
write_pixel(pixel_offset - 1);
write_pixel(pixel_offset);
write_pixel(pixel_offset + 1);
write_pixel(pixel_offset + 2);
write_pixel (pixel_offset - 2);
write_pixel (pixel_offset - 1);
write_pixel (pixel_offset);
write_pixel (pixel_offset + 1);
write_pixel (pixel_offset + 2);
write_pixel(pixel_offset - (width * 2));
write_pixel(pixel_offset - (width * 1) - 1);
write_pixel(pixel_offset - (width * 1));
write_pixel(pixel_offset - (width * 1) + 1);
write_pixel(pixel_offset + (width * 1) - 1);
write_pixel(pixel_offset + (width * 1));
write_pixel(pixel_offset + (width * 1) + 1);
write_pixel(pixel_offset + (width * 2));
write_pixel (pixel_offset - (width * 2));
write_pixel (pixel_offset - (width * 1) - 1);
write_pixel (pixel_offset - (width * 1));
write_pixel (pixel_offset - (width * 1) + 1);
write_pixel (pixel_offset + (width * 1) - 1);
write_pixel (pixel_offset + (width * 1));
write_pixel (pixel_offset + (width * 1) + 1);
write_pixel (pixel_offset + (width * 2));
}
}
@ -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;
}
@ -197,15 +203,18 @@ libfprint_demo_set_capture_label (LibfprintDemoWindow *win)
FpScanType scan_type;
const char *message;
scan_type = fp_device_get_scan_type(win->dev);
scan_type = fp_device_get_scan_type (win->dev);
switch (scan_type) {
switch (scan_type)
{
case FP_SCAN_TYPE_PRESS:
message = "Place your finger on the fingerprint reader";
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,15 +264,17 @@ 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;
}
dev_start_capture(win);
dev_start_capture (win);
}
static void
@ -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 ();
}
@ -489,19 +509,22 @@ libfprint_demo_window_init (LibfprintDemoWindow *window)
ctx = fp_context_new ();
devices = fp_context_get_devices(ctx);
if (!devices) {
devices = fp_context_get_devices (ctx);
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;

View file

@ -24,7 +24,8 @@
#include "storage.h"
typedef struct _EnrollData {
typedef struct _EnrollData
{
GMainLoop *loop;
int ret_value;
} EnrollData;
@ -37,20 +38,23 @@ enroll_data_free (EnrollData *enroll_data)
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
FpDevice *discover_device (GPtrArray *devices)
FpDevice *discover_device (GPtrArray * devices)
{
FpDevice *dev;
if (!devices->len)
return NULL;
dev = g_ptr_array_index (devices, 0);
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
return dev;
}
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,26 +66,33 @@ 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)) {
g_debug("Device has not storage, saving locally");
int r = print_data_save(print, FP_FINGER_RIGHT_INDEX);
if (r < 0) {
g_warning("Data save failed, code %d", r);
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)
{
g_warning ("Data save failed, code %d", r);
enroll_data->ret_value = EXIT_FAILURE;
}
}
} else {
g_warning("Enroll failed with error %s\n", error->message);
}
else
{
g_warning ("Enroll failed with error %s\n", error->message);
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
@ -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,32 +149,35 @@ 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;
g_autoptr(FpContext) ctx = NULL;
g_autoptr(EnrollData) enroll_data = NULL;
GPtrArray *devices;
FpDevice *dev;
printf("This program will enroll your right index finger, "
printf ("This program will enroll your right index finger, "
"unconditionally overwriting any right-index print that was enrolled "
"previously. If you want to continue, press enter, otherwise hit "
"Ctrl+C\n");
getchar();
getchar ();
setenv ("G_MESSAGES_DEBUG", "all", 0);
ctx = fp_context_new ();
devices = fp_context_get_devices (ctx);
if (!devices) {
g_warning("Impossible to get devices");
if (!devices)
{
g_warning ("Impossible to get devices");
return EXIT_FAILURE;
}
dev = discover_device (devices);
if (!dev) {
g_warning("No devices detected.");
if (!dev)
{
g_warning ("No devices detected.");
return EXIT_FAILURE;
}

View file

@ -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;
@ -157,12 +159,14 @@ on_print_deleted (FpDevice *dev,
if (error)
{
g_warning("Failed to remove print %s: %s",
g_warning ("Failed to remove print %s: %s",
fp_print_get_description (print), error->message);
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;
@ -198,7 +203,7 @@ on_list_completed (FpDevice *dev,
for (i = 0; i < prints->len; ++i)
{
FpPrint* print = prints->pdata[i];
FpPrint * print = prints->pdata[i];
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d",
fp_print_get_enroll_date (print));
@ -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);

View file

@ -34,103 +34,112 @@ 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);
}
return g_strdup_printf("%s/%s/%x",
return g_strdup_printf ("%s/%s/%x",
driver,
dev_id,
finger);
}
static GVariantDict *
load_data(void)
load_data (void)
{
GVariantDict *res;
GVariant *var;
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);
return g_variant_dict_new (NULL);
}
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL);
res = g_variant_dict_new(var);
g_variant_unref(var);
res = g_variant_dict_new (var);
g_variant_unref (var);
return res;
}
static int
save_data(GVariant *data)
save_data (GVariant *data)
{
const gchar *contents = NULL;
gsize length;
length = g_variant_get_size(data);
contents = (gchar*) g_variant_get_data (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;
}
g_variant_ref_sink(data);
g_variant_unref(data);
g_variant_ref_sink (data);
g_variant_unref (data);
return 0;
}
int
print_data_save(FpPrint *print, FpFinger finger)
print_data_save (FpPrint *print, FpFinger finger)
{
g_autofree gchar *descr = get_print_data_descriptor (print, NULL, finger);
g_autoptr (GError) error = NULL;
g_autoptr (GVariantDict) dict = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GVariantDict) dict = NULL;
g_autofree guchar *data = NULL;
GVariant *val;
gsize size;
int res;
dict = load_data();
dict = load_data ();
fp_print_serialize (print, &data, &size, &error);
if (error) {
if (error)
{
g_warning ("Error serializing data: %s", error->message);
return -1;
}
val = g_variant_new_fixed_array (G_VARIANT_TYPE("y"), data, size, 1);
val = g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), data, size, 1);
g_variant_dict_insert_value (dict, descr, val);
res = save_data(g_variant_dict_end(dict));
res = save_data (g_variant_dict_end (dict));
return res;
}
FpPrint *
print_data_load(FpDevice *dev, FpFinger finger)
print_data_load (FpDevice *dev, FpFinger finger)
{
g_autofree gchar *descr = get_print_data_descriptor (NULL, dev, finger);
g_autoptr (GVariant) val = NULL;
g_autoptr (GVariantDict) dict = NULL;
g_autoptr(GVariant) val = NULL;
g_autoptr(GVariantDict) dict = NULL;
g_autofree guchar *stored_data = NULL;
gsize stored_len;
dict = load_data();
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;
g_autoptr(GError) error = NULL;
stored_data = (guchar*) g_variant_get_fixed_array (val, &stored_len, 1);
stored_data = (guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
print = fp_print_deserialize (stored_data, stored_len, &error);
if (error)
@ -171,23 +180,26 @@ save_image_to_pgm (FpImage *img, const char *path)
const guchar *data = fp_image_get_data (img, &write_size);
int r;
if (!fd) {
g_warning("could not open '%s' for writing: %d", path, errno);
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) {
fclose(fd);
g_critical("pgm header write failed, error %d", r);
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) {
fclose(fd);
g_critical("short write (%d)", r);
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;

View file

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

View file

@ -24,7 +24,8 @@
#include "storage.h"
typedef struct _VerifyData {
typedef struct _VerifyData
{
GMainLoop *loop;
int ret_value;
} VerifyData;
@ -37,20 +38,23 @@ verify_data_free (VerifyData *verify_data)
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyData, verify_data_free)
FpDevice *discover_device (GPtrArray *devices)
FpDevice *discover_device (GPtrArray * devices)
{
FpDevice *dev;
if (!devices->len)
return NULL;
dev = g_ptr_array_index (devices, 0);
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
printf ("Found device claimed by %s driver\n", fp_device_get_driver (dev));
return dev;
}
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")) {
g_print("Print image saved as 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,10 +219,11 @@ 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;
g_autoptr(FpContext) ctx = NULL;
g_autoptr(VerifyData) verify_data = NULL;
GPtrArray *devices;
FpDevice *dev;
@ -209,14 +233,16 @@ int main(void)
ctx = fp_context_new ();
devices = fp_context_get_devices (ctx);
if (!devices) {
g_warning("Impossible to get devices");
if (!devices)
{
g_warning ("Impossible to get devices");
return EXIT_FAILURE;
}
dev = discover_device (devices);
if (!dev) {
g_warning("No devices detected.");
if (!dev)
{
g_warning ("No devices detected.");
return EXIT_FAILURE;
}
@ -231,5 +257,3 @@ int main(void)
return verify_data->ret_value;
}

View file

@ -28,9 +28,10 @@
#include "drivers_api.h"
#include "aeslib.h"
static void start_capture(FpImageDevice *dev);
static void complete_deactivation(FpImageDevice *dev);
static int adjust_gain(unsigned char *buffer, int status);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
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;
@ -78,9 +80,9 @@ struct _FpiDeviceAes1610 {
gboolean deactivating;
guint8 blanks_count;
};
G_DECLARE_FINAL_TYPE(FpiDeviceAes1610, fpi_device_aes1610, FPI, DEVICE_AES1610,
G_DECLARE_FINAL_TYPE (FpiDeviceAes1610, fpi_device_aes1610, FPI, DEVICE_AES1610,
FpImageDevice);
G_DEFINE_TYPE(FpiDeviceAes1610, fpi_device_aes1610, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpiDeviceAes1610, fpi_device_aes1610, FP_TYPE_IMAGE_DEVICE);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
@ -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,40 +118,44 @@ 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)
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
}
static void generic_write_regv_cb(FpImageDevice *dev, GError *error,
static void
generic_write_regv_cb (FpImageDevice *dev, GError *error,
void *user_data)
{
FpiSsm *ssm = user_data;
if (!error)
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
else
fpi_ssm_mark_failed(ssm, error);
fpi_ssm_mark_failed (ssm, error);
}
/* read the specified number of bytes from the IN endpoint but throw them
* 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);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
unsigned char *data;
data = g_malloc(bytes);
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN, data, bytes, NULL);
data = g_malloc (bytes);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
generic_ignore_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/****** FINGER PRESENCE DETECTION ******/
@ -175,17 +186,19 @@ static const struct aes_regwrite finger_det_reqs[] = {
{ 0x81, 0x04 }
};
static void start_finger_detection(FpImageDevice *dev);
static void start_finger_detection (FpImageDevice *dev);
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
static void
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
unsigned char *data = transfer->buffer;
int i;
int sum = 0;
if (error) {
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
@ -193,46 +206,53 @@ 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);
adjust_gain (data, GAIN_STATUS_FIRST);
/* finger present, start capturing */
fpi_image_device_report_finger_status(dev, TRUE);
start_capture(dev);
} else {
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
else
{
/* no finger, poll for a new histogram */
start_finger_detection(dev);
start_finger_detection (dev);
}
}
static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
static void
finger_det_reqs_cb (FpImageDevice *dev, GError *error,
void *user_data)
{
FpiUsbTransfer *transfer;
if (error) {
fpi_image_device_session_error(dev, error);
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
static void start_finger_detection(FpImageDevice *dev)
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs), finger_det_reqs_cb, NULL);
aes_write_regv (dev, finger_det_reqs, G_N_ELEMENTS (finger_det_reqs), finger_det_reqs_cb, NULL);
}
@ -373,7 +393,7 @@ static struct aes_regwrite strip_scan_reqs[] = {
};
static const struct aes_regwrite capture_stop[] = {
{ 0x81,0x00 }
{ 0x81, 0x00 }
};
/*
@ -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;
@ -433,14 +459,15 @@ static int adjust_gain(unsigned char *buffer, int status)
capture_reqs[10].value = strip_scan_reqs[2].value;
capture_reqs[21].value = strip_scan_reqs[3].value;
fp_dbg("first gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
fp_dbg ("first gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
}
// Every 2/3 strips
// 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--;
@ -492,11 +522,12 @@ static int adjust_gain(unsigned char *buffer, int status)
strip_scan_reqs[0].value = list_BE_values[pos_list_BE];
strip_scan_reqs[3].value = list_BD_values[pos_list_BD];
fp_dbg("gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
fp_dbg ("gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value);
}
// Unknown status
else {
fp_err("Unexpected gain status.");
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,16 +564,18 @@ 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;
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
unsigned char *data = transfer->buffer;
gint sum, i;
if (error) {
if (error)
{
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
@ -550,134 +584,152 @@ 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) {
fp_dbg ("sum=%d", sum);
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));
struct fpi_frame *stripe = g_malloc (FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof (struct fpi_frame));
stripe->delta_x = 0;
stripe->delta_y = 0;
stripdata = stripe->data;
memcpy(stripdata, data + 1, FRAME_WIDTH * (FRAME_HEIGHT / 2));
self->strips = g_slist_prepend(self->strips, stripe);
memcpy (stripdata, data + 1, FRAME_WIDTH * (FRAME_HEIGHT / 2));
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? */
/* sum cannot be negative, so is 0 */
self->blanks_count++;
fp_dbg("got blank frame");
fp_dbg ("got blank frame");
}
/* use histogram data above for gain calibration (0xbd, 0xbe, 0x29 and 0x2A ) */
adjust_gain(data, GAIN_STATUS_NORMAL);
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",
self->blanks_count, g_slist_length(self->strips));
fp_dbg ("sending stop capture.... blanks=%d frames=%d",
self->blanks_count, g_slist_length (self->strips));
/* send stop capture bits */
aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL);
self->strips = g_slist_reverse(self->strips);
fpi_do_movement_estimation(&assembling_ctx, self->strips);
img = fpi_assemble_frames(&assembling_ctx, self->strips);
aes_write_regv (dev, capture_stop, G_N_ELEMENTS (capture_stop), stub_capture_stop_cb, NULL);
self->strips = g_slist_reverse (self->strips);
fpi_do_movement_estimation (&assembling_ctx, self->strips);
img = fpi_assemble_frames (&assembling_ctx, self->strips);
g_slist_free_full(self->strips, g_free);
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;
self->blanks_count = 0;
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev, FALSE);
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
/* marking machine complete will re-trigger finger detection loop */
fpi_ssm_mark_completed(transfer->ssm);
fpi_ssm_mark_completed (transfer->ssm);
/* Acquisition finished: restore default gain values */
restore_gain();
} else {
restore_gain ();
}
else
{
/* obtain next strip */
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_REQUEST_STRIP);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_REQUEST_STRIP);
}
}
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
static void
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{
FpImageDevice *dev = user_data;
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(_dev);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
switch (fpi_ssm_get_cur_state(ssm)) {
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_WRITE_REQS:
fp_dbg("write reqs");
aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_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);
fp_dbg ("read data");
generic_read_ignore_data (ssm, _dev, STRIP_CAPTURE_LEN);
break;
case CAPTURE_REQUEST_STRIP:
fp_dbg("request strip");
fp_dbg ("request strip");
if (self->deactivating)
fpi_ssm_mark_completed(ssm);
fpi_ssm_mark_completed (ssm);
else
aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
aes_write_regv (dev, strip_scan_reqs, G_N_ELEMENTS (strip_scan_reqs),
generic_write_regv_cb, ssm);
break;
case CAPTURE_READ_STRIP: ;
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
case CAPTURE_READ_STRIP:;
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_strip_cb, NULL);
fpi_usb_transfer_unref(transfer);
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);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (_dev);
G_DEBUG_HERE();
if (self->deactivating) {
complete_deactivation(dev);
G_DEBUG_HERE ();
if (self->deactivating)
{
complete_deactivation (dev);
if (error)
g_error_free (error);
} else if (error) {
fpi_image_device_session_error(dev, error);
} else {
start_finger_detection(dev);
}
fpi_ssm_free(ssm);
else if (error)
{
fpi_image_device_session_error (dev, error);
}
else
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
FpiSsm *ssm;
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
G_DEBUG_HERE();
fpi_ssm_start(ssm, capture_sm_complete);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -687,108 +739,125 @@ static const struct aes_regwrite init[] = {
};
/*
static const struct aes_regwrite stop_reader[] = {
static const struct aes_regwrite stop_reader[] = {
{ 0xFF, 0x00 }
};
*/
};
*/
enum activate_states {
WRITE_INIT,
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);
fp_dbg ("write init");
aes_write_regv (dev, init, G_N_ELEMENTS (init), generic_write_regv_cb, ssm);
break;
}
}
/* 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);
fpi_image_device_activate_complete (dev, error);
if (!error)
start_finger_detection(dev);
fpi_ssm_free(ssm);
start_finger_detection (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,
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);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610(dev);
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
/* FIXME: audit cancellation points, probably need more, specifically
* 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();
FpiDeviceAes1610 *self = FPI_DEVICE_AES1610 (dev);
G_DEBUG_HERE ();
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
* maybe we can do this with a master reset, unconditionally? */
self->deactivating = FALSE;
g_slist_free(self->strips);
g_slist_free (self->strips);
self->strips = NULL;
self->strips_len = 0;
self->blanks_count = 0;
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
/* FIXME check endpoints */
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
fpi_image_device_open_complete(dev, error);
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
{
fpi_image_device_open_complete (dev, error);
return;
}
fpi_image_device_open_complete(dev, NULL);
fpi_image_device_open_complete (dev, NULL);
}
static void dev_deinit(FpImageDevice *dev)
static void
dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table [ ] = {
{ .vid = 0x08ff, .pid = 0x1600,
}, /* AES1600 */
static const FpIdEntry id_table[] = {
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes1610";
dev_class->full_name = "AuthenTec AES1610";
@ -806,4 +875,3 @@ static void fpi_device_aes1610_class_init(FpiDeviceAes1610Class *klass) {
img_class->img_width = IMAGE_WIDTH;
img_class->img_height = -1;
}

View file

@ -27,12 +27,13 @@
#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,
G_DECLARE_FINAL_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI,
DEVICE_AES1660, FpiDeviceAesX660);
G_DEFINE_TYPE(FpiDeviceAes1660, fpi_device_aes1660, FPI_TYPE_DEVICE_AES_X660);
G_DEFINE_TYPE (FpiDeviceAes1660, fpi_device_aes1660, FPI_TYPE_DEVICE_AES_X660);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
@ -41,7 +42,7 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
.get_pixel = aes_get_pixel,
};
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x1660, },
{ .vid = 0x08ff, .pid = 0x1680, },
{ .vid = 0x08ff, .pid = 0x1681, },
@ -62,11 +63,15 @@ 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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes1660";
@ -81,10 +86,10 @@ static void fpi_device_aes1660_class_init(FpiDeviceAes1660Class *klass) {
img_class->img_height = -1;
aes_class->init_seqs[0] = aes1660_init_1;
aes_class->init_seqs_len[0] = G_N_ELEMENTS(aes1660_init_1);
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes1660_init_1);
aes_class->init_seqs[1] = aes1660_init_2;
aes_class->init_seqs_len[1] = G_N_ELEMENTS(aes1660_init_2);
aes_class->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd);
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes1660_init_2);
aes_class->start_imaging_cmd = (unsigned char *) aes1660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof (aes1660_start_imaging_cmd);
aes_class->assembling_ctx = &assembling_ctx;
}

File diff suppressed because it is too large Load diff

View file

@ -27,8 +27,8 @@
#include "aeslib.h"
#include "aes2501.h"
static void start_capture(FpImageDevice *dev);
static void complete_deactivation(FpImageDevice *dev);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
/* FIXME these need checking */
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
@ -63,7 +63,8 @@ static void complete_deactivation(FpImageDevice *dev);
/****** GENERAL FUNCTIONS ******/
struct _FpiDeviceAes2501 {
struct _FpiDeviceAes2501
{
FpImageDevice parent;
guint8 read_regs_retry_count;
@ -72,9 +73,9 @@ struct _FpiDeviceAes2501 {
gboolean deactivating;
int no_finger_cnt;
};
G_DECLARE_FINAL_TYPE(FpiDeviceAes2501, fpi_device_aes2501, FPI, DEVICE_AES2501,
G_DECLARE_FINAL_TYPE (FpiDeviceAes2501, fpi_device_aes2501, FPI, DEVICE_AES2501,
FpImageDevice);
G_DEFINE_TYPE(FpiDeviceAes2501, fpi_device_aes2501, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpiDeviceAes2501, fpi_device_aes2501, FP_TYPE_IMAGE_DEVICE);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
@ -83,54 +84,61 @@ 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;
rdata->callback(rdata->dev, error, transfer->buffer, rdata->user_data);
g_free(rdata);
rdata->callback (rdata->dev, error, transfer->buffer, rdata->user_data);
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) {
rdata->callback(dev, error, NULL, rdata->user_data);
g_free (rdata->regwrite);
if (error)
{
rdata->callback (dev, error, NULL, rdata->user_data);
g_free (rdata);
return;
}
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk(transfer, EP_IN, READ_REGS_LEN);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, READ_REGS_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
read_regs_data_cb, rdata);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
static void read_regs(FpImageDevice *dev, aes2501_read_regs_cb callback,
static void
read_regs (FpImageDevice *dev, aes2501_read_regs_cb callback,
void *user_data)
{
/* FIXME: regwrite is dynamic because of asynchronity. is this really
* required? */
struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite));
struct aes2501_read_regs *rdata = g_malloc(sizeof(*rdata));
struct aes_regwrite *regwrite = g_malloc (sizeof (*regwrite));
struct aes2501_read_regs *rdata = g_malloc (sizeof (*rdata));
G_DEBUG_HERE();
G_DEBUG_HERE ();
regwrite->reg = AES2501_REG_CTRL2;
regwrite->value = AES2501_CTRL2_READ_REGS;
rdata->dev = dev;
@ -138,20 +146,23 @@ static void read_regs(FpImageDevice *dev, aes2501_read_regs_cb callback,
rdata->user_data = user_data;
rdata->regwrite = regwrite;
aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1,
aes_write_regv (dev, (const struct aes_regwrite *) regwrite, 1,
read_regs_rq_cb, rdata);
}
/* Read 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) {
fp_err("not a register dump");
if (*data != FIRST_AES2501_REG)
{
fp_err ("not a register dump");
return -1;
}
if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG)) {
fp_err("out of range");
if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG))
{
fp_err ("out of range");
return -1;
}
@ -160,50 +171,56 @@ 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);
fpi_ssm_next_state (ssm);
else
fpi_ssm_mark_failed(ssm, error);
fpi_ssm_mark_failed (ssm, 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);
fpi_ssm_mark_failed (ssm, error);
else
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
}
/* 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;
transfer = fpi_usb_transfer_new(dev);
transfer = fpi_usb_transfer_new (dev);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk(transfer, EP_IN, bytes);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, bytes);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
generic_ignore_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/****** 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;
guint16 *histogram = (guint16 *)(data + 1);
guint16 *histogram = (guint16 *) (data + 1);
if (*data != 0xde)
return -1;
@ -248,63 +265,73 @@ static const struct aes_regwrite finger_det_reqs[] = {
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
};
static void start_finger_detection(FpImageDevice *dev);
static void start_finger_detection (FpImageDevice *dev);
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *_dev,
static void
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE(_dev);
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
unsigned char *data = transfer->buffer;
int i;
int sum = 0;
if (error) {
fpi_image_device_session_error(dev, error);
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
/* 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 {
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
else
{
/* no finger, poll for a new histogram */
start_finger_detection(dev);
start_finger_detection (dev);
}
}
static void finger_det_reqs_cb(FpImageDevice *dev, GError *error,
static void
finger_det_reqs_cb (FpImageDevice *dev, GError *error,
void *user_data)
{
FpiUsbTransfer *transfer;
if (error) {
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk(transfer, EP_IN, FINGER_DETECTION_LEN);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
static void start_finger_detection(FpImageDevice *dev)
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
G_DEBUG_HERE();
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
if (self->deactivating) {
complete_deactivation(dev);
G_DEBUG_HERE ();
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs),
aes_write_regv (dev, finger_det_reqs, G_N_ELEMENTS (finger_det_reqs),
finger_det_reqs_cb, NULL);
}
@ -383,165 +410,194 @@ 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;
unsigned char *stripdata;
FpImageDevice *dev = FP_IMAGE_DEVICE(_dev);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(_dev);
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (_dev);
unsigned char *data = transfer->buffer;
int sum;
int threshold;
if (error) {
fpi_ssm_mark_failed(ssm, error);
if (error)
{
fpi_ssm_mark_failed (ssm, error);
return;
}
threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
threshold = regval_from_dump (data + 1 + 192 * 8 + 1 + 16 * 2 + 1 + 8,
AES2501_REG_DATFMT);
if (threshold < 0) {
fpi_ssm_mark_failed(ssm,
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) {
fpi_ssm_mark_failed(ssm,
sum = sum_histogram_values (data + 1 + 192 * 8, threshold & 0x0f);
if (sum < 0)
{
fpi_ssm_mark_failed (ssm,
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
return;
}
fp_dbg("sum=%d", sum);
fp_dbg ("sum=%d", sum);
if (sum < AES2501_SUM_LOW_THRESH) {
if (sum < AES2501_SUM_LOW_THRESH)
{
strip_scan_reqs[4].value -= 0x8;
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;
}
fp_dbg("ADREFHI is %.2x", strip_scan_reqs[4].value);
fp_dbg ("ADREFHI is %.2x", strip_scan_reqs[4].value);
/* Sum is 0, maybe finger was removed? Wait for 3 empty frames
* 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);
fpi_do_movement_estimation(&assembling_ctx, self->strips);
img = fpi_assemble_frames(&assembling_ctx,
self->strips = g_slist_reverse (self->strips);
fpi_do_movement_estimation (&assembling_ctx, self->strips);
img = fpi_assemble_frames (&assembling_ctx,
self->strips);
g_slist_free_full(self->strips, g_free);
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev, FALSE);
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
/* marking machine complete will re-trigger finger detection loop */
fpi_ssm_mark_completed(ssm);
} else {
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
fpi_ssm_mark_completed (ssm);
}
} else {
else
{
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
}
}
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));
struct fpi_frame *stripe = g_malloc (FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame));
stripe->delta_x = 0;
stripe->delta_y = 0;
stripdata = stripe->data;
memcpy(stripdata, data + 1, 192*8);
memcpy (stripdata, data + 1, 192 * 8);
self->no_finger_cnt = 0;
self->strips = g_slist_prepend(self->strips, stripe);
self->strips = g_slist_prepend (self->strips, stripe);
self->strips_len++;
fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
fpi_ssm_jump_to_state (ssm, CAPTURE_REQUEST_STRIP);
}
}
static void capture_run_state(FpiSsm *ssm, FpDevice *device, void *user_data)
static void
capture_run_state (FpiSsm *ssm, FpDevice *device, void *user_data)
{
FpImageDevice *dev = user_data;
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(device);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (device);
switch (fpi_ssm_get_cur_state(ssm)) {
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_WRITE_REQS_1:
aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1),
aes_write_regv (dev, capture_reqs_1, G_N_ELEMENTS (capture_reqs_1),
generic_write_regv_cb, ssm);
break;
case CAPTURE_READ_DATA_1:
generic_read_ignore_data(ssm, device, READ_REGS_RESP_LEN);
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
break;
case CAPTURE_WRITE_REQS_2:
aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
aes_write_regv (dev, capture_reqs_2, G_N_ELEMENTS (capture_reqs_2),
generic_write_regv_cb, ssm);
break;
case CAPTURE_READ_DATA_2:
generic_read_ignore_data(ssm, device, READ_REGS_RESP_LEN);
generic_read_ignore_data (ssm, device, READ_REGS_RESP_LEN);
break;
case CAPTURE_REQUEST_STRIP:
if (self->deactivating)
fpi_ssm_mark_completed(ssm);
fpi_ssm_mark_completed (ssm);
else
aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
aes_write_regv (dev, strip_scan_reqs, G_N_ELEMENTS (strip_scan_reqs),
generic_write_regv_cb, ssm);
break;
case CAPTURE_READ_STRIP: {
FpiUsbTransfer *transfer;
transfer = fpi_usb_transfer_new(device);
transfer = fpi_usb_transfer_new (device);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk(transfer, EP_IN, STRIP_CAPTURE_LEN);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_strip_cb, NULL);
fpi_usb_transfer_unref(transfer);
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;
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(_dev);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (_dev);
G_DEBUG_HERE();
G_DEBUG_HERE ();
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
g_clear_pointer (&error, g_error_free);
} else if (error) {
fpi_image_device_session_error(dev, error);
} else {
start_finger_detection(dev);
}
fpi_ssm_free(ssm);
else if (error)
{
fpi_image_device_session_error (dev, error);
}
else
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
FpiSsm *ssm;
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
self->no_finger_cnt = 0;
/* Reset gain */
strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
G_DEBUG_HERE();
fpi_ssm_start(ssm, capture_sm_complete);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -649,34 +705,41 @@ 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);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
if (error) {
fpi_ssm_mark_failed(ssm, error);
} 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);
if (error)
{
fpi_ssm_mark_failed (ssm, error);
}
else
fpi_ssm_next_state(ssm);
{
fp_dbg ("reg 0xaf = %x", regs[0x5f]);
if (regs[0x5f] != 0x6b || ++self->read_regs_retry_count == 13)
fpi_ssm_jump_to_state (ssm, WRITE_INIT_4);
else
fpi_ssm_next_state (ssm);
}
}
static void activate_init3_cb(FpImageDevice *dev, GError *error,
static void
activate_init3_cb (FpImageDevice *dev, GError *error,
void *user_data)
{
FpiSsm *ssm = user_data;
if (!error)
fpi_ssm_jump_to_state(ssm, READ_REGS);
fpi_ssm_jump_to_state (ssm, READ_REGS);
else
fpi_ssm_mark_failed(ssm, error);
fpi_ssm_mark_failed (ssm, error);
}
static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
static void
activate_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{
FpImageDevice *dev = user_data;
@ -699,110 +762,129 @@ 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),
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);
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),
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);
read_regs (dev, activate_read_regs_cb, ssm);
break;
case WRITE_INIT_3:
aes_write_regv(dev, init_3, G_N_ELEMENTS(init_3),
aes_write_regv (dev, init_3, G_N_ELEMENTS (init_3),
activate_init3_cb, ssm);
break;
case WRITE_INIT_4:
aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
aes_write_regv (dev, init_4, G_N_ELEMENTS (init_4),
generic_write_regv_cb, ssm);
break;
case WRITE_INIT_5:
aes_write_regv(dev, init_5, G_N_ELEMENTS(init_5),
aes_write_regv (dev, init_5, G_N_ELEMENTS (init_5),
generic_write_regv_cb, ssm);
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);
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
if (!error)
start_finger_detection(FP_IMAGE_DEVICE (dev));
fpi_ssm_free(ssm);
start_finger_detection (FP_IMAGE_DEVICE (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,
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);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501(dev);
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
/* FIXME: audit cancellation points, probably need more, specifically
* 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();
FpiDeviceAes2501 *self = FPI_DEVICE_AES2501 (dev);
G_DEBUG_HERE ();
/* FIXME: if we're in the middle of a scan, we should cancel the scan.
* maybe we can do this with a master reset, unconditionally? */
self->deactivating = FALSE;
g_slist_free(self->strips);
g_slist_free (self->strips);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
/* 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);
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;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table [ ] = {
{ .vid = 0x08ff, .pid = 0x2500,
}, /* AES2500 */
{ .vid = 0x08ff, .pid = 0x2580,
}, /* AES2501 */
static const FpIdEntry id_table[] = {
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes2501";
dev_class->full_name = "AuthenTec AES2501";
@ -818,4 +900,3 @@ static void fpi_device_aes2501_class_init(FpiDeviceAes2501Class *klass) {
img_class->img_width = IMAGE_WIDTH;
img_class->img_height = -1;
}

View file

@ -57,10 +57,10 @@ enum aes2501_regs {
#define FIRST_AES2501_REG AES2501_REG_CTRL1
#define LAST_AES2501_REG AES2501_REG_CHWORD5
#define AES2501_CTRL1_MASTER_RESET (1<<0)
#define AES2501_CTRL1_SCAN_RESET (1<<1) /* stop + restart scan sequencer */
#define AES2501_CTRL1_MASTER_RESET (1 << 0)
#define AES2501_CTRL1_SCAN_RESET (1 << 1) /* stop + restart scan sequencer */
/* 1 = continuously updated, 0 = updated prior to starting a scan */
#define AES2501_CTRL1_REG_UPDATE (1<<2)
#define AES2501_CTRL1_REG_UPDATE (1 << 2)
/* 1 = continuous scans, 0 = single scans */
#define AES2501_CTRL2_CONTINUOUS 0x01

View file

@ -27,8 +27,8 @@
#include "aes2550.h"
#include "aeslib.h"
static void start_capture(FpImageDevice *dev);
static void complete_deactivation(FpImageDevice *dev);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
@ -51,7 +51,8 @@ static void complete_deactivation(FpImageDevice *dev);
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
struct _FpiDeviceAes2550 {
struct _FpiDeviceAes2550
{
FpImageDevice parent;
GSList *strips;
@ -59,9 +60,9 @@ struct _FpiDeviceAes2550 {
gboolean deactivating;
int heartbeat_cnt;
};
G_DECLARE_FINAL_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
G_DECLARE_FINAL_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
FpImageDevice);
G_DEFINE_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
@ -83,70 +84,80 @@ static unsigned char finger_det_reqs[] = {
AES2550_CMD_RUN_FD,
};
static void start_finger_detection(FpImageDevice *dev);
static void start_finger_detection (FpImageDevice *dev);
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
static void
finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
unsigned char *data = transfer->buffer;
if (error) {
fpi_image_device_session_error(FP_IMAGE_DEVICE(device), error);
if (error)
{
fpi_image_device_session_error (FP_IMAGE_DEVICE (device), error);
return;
}
fp_dbg("transfer completed, len: %.4x, data: %.2x %.2x",
(gint)transfer->actual_length, (int)data[0], (int)data[1]);
fp_dbg ("transfer completed, len: %.4x, data: %.2x %.2x",
(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 {
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
else
{
/* no finger, poll for a new histogram */
start_finger_detection(dev);
start_finger_detection (dev);
}
}
static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
static void
finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
gpointer user_data, GError *error)
{
FpiUsbTransfer *transfer;
FpImageDevice *dev = user_data;
if (error) {
fpi_image_device_session_error(dev, error);
if (error)
{
fpi_image_device_session_error (dev, error);
return;
}
transfer = fpi_usb_transfer_new (device);
/* 2 bytes of result */
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
static void start_finger_detection(FpImageDevice *dev)
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
FpiUsbTransfer *transfer;
G_DEBUG_HERE();
if (self->deactivating) {
complete_deactivation(dev);
G_DEBUG_HERE ();
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, finger_det_reqs,
sizeof(finger_det_reqs), NULL);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, finger_det_reqs,
sizeof (finger_det_reqs), NULL);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_reqs_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@ -177,202 +188,230 @@ 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;
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
struct fpi_frame *stripe;
int len;
if (data[0] != AES2550_EDATA_MAGIC) {
fp_dbg("Bogus magic: %.2x\n", (int)(data[0]));
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)) {
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];
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];
stripdata = stripe->data;
memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
self->strips = g_slist_prepend(self->strips, stripe);
memcpy (stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
self->strips = g_slist_prepend (self->strips, stripe);
self->strips_len++;
fp_dbg("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
fp_dbg ("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
return TRUE;
}
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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);
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);
img = fpi_assemble_frames(&assembling_ctx, self->strips);
g_slist_free_full(self->strips, g_free);
self->strips = g_slist_reverse (self->strips);
img = fpi_assemble_frames (&assembling_ctx, self->strips);
g_slist_free_full (self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev, FALSE);
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
/* marking machine complete will re-trigger finger detection loop */
fpi_ssm_mark_completed(transfer->ssm);
} else {
if (error)
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_completed (transfer->ssm);
}
else
fpi_ssm_mark_failed(transfer->ssm,
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
}
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);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
unsigned char *data = transfer->buffer;
if (error) {
fpi_ssm_mark_failed(transfer->ssm, error);
if (error)
{
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fp_dbg("request completed, len: %.4x", (gint)transfer->actual_length);
fp_dbg ("request completed, len: %.4x", (gint) transfer->actual_length);
if (transfer->actual_length >= 2)
fp_dbg("data: %.2x %.2x", (int)data[0], (int)data[1]);
fp_dbg ("data: %.2x %.2x", (int) data[0], (int) data[1]);
switch (transfer->actual_length) {
switch (transfer->actual_length)
{
case AES2550_STRIP_SIZE:
if (!process_strip_data(transfer->ssm, dev, data)) {
fp_dbg("Processing strip data failed");
fpi_ssm_mark_failed(transfer->ssm,
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));
return;
}
self->heartbeat_cnt = 0;
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
break;
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 {
fpi_ssm_jump_to_state(transfer->ssm,
fp_dbg ("Got 3 heartbeats => finger removed");
fpi_ssm_next_state (transfer->ssm);
}
else
{
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_READ_DATA);
}
}
break;
default:
fp_dbg("Short frame %d, skip",
(gint)transfer->actual_length);
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
fp_dbg ("Short frame %d, skip",
(gint) transfer->actual_length);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
break;
}
}
static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
static void
capture_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
{
switch (fpi_ssm_get_cur_state(ssm)) {
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_WRITE_REQS:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, capture_reqs,
sizeof(capture_reqs), NULL);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, capture_reqs,
sizeof (capture_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_reqs_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case CAPTURE_READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case CAPTURE_SET_IDLE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
capture_set_idle_reqs,
sizeof(capture_set_idle_reqs),
sizeof (capture_set_idle_reqs),
NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_set_idle_reqs_cb, NULL);
fpi_usb_transfer_unref(transfer);
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;
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(_dev);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (_dev);
fp_dbg("Capture completed");
fp_dbg ("Capture completed");
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
g_clear_pointer (&error, g_error_free);
} else if (error) {
fpi_image_device_session_error(dev, error);
} else {
start_finger_detection(dev);
}
fpi_ssm_free(ssm);
else if (error)
{
fpi_image_device_session_error (dev, error);
}
else
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
FpiSsm *ssm;
if (self->deactivating) {
complete_deactivation(dev);
if (self->deactivating)
{
complete_deactivation (dev);
return;
}
self->heartbeat_cnt = 0;
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
G_DEBUG_HERE();
fpi_ssm_start(ssm, capture_sm_complete);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -399,163 +438,179 @@ 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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, init_reqs,
sizeof(init_reqs), NULL);
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, init_reqs,
sizeof (init_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_reqs_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_read_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case CALIBRATE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT,
calibrate_reqs,
sizeof(calibrate_reqs), NULL);
sizeof (calibrate_reqs), NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_reqs_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case READ_CALIB_TABLE:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
calibrate_read_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
}
}
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);
fpi_image_device_activate_complete (dev, error);
if (!error)
start_finger_detection(dev);
fpi_ssm_free(ssm);
start_finger_detection (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,
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES, dev);
fpi_ssm_start(ssm, activate_sm_complete);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
self->deactivating = TRUE;
}
static void complete_deactivation(FpImageDevice *dev)
static void
complete_deactivation (FpImageDevice *dev)
{
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
G_DEBUG_HERE();
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
G_DEBUG_HERE ();
self->deactivating = FALSE;
g_slist_free(self->strips);
g_slist_free (self->strips);
self->strips = NULL;
self->strips_len = 0;
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
/* TODO check that device has endpoints we're using */
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
fpi_image_device_open_complete(dev, error);
fpi_image_device_open_complete (dev, error);
}
static void dev_deinit(FpImageDevice *dev)
static void
dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table [ ] = {
{ .vid = 0x08ff, .pid = 0x2550,
}, /* AES2550 */
{ .vid = 0x08ff, .pid = 0x2810,
}, /* AES2810 */
static const FpIdEntry id_table[] = {
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes2550";
dev_class->full_name = "AuthenTec AES2550/AES2810";

View file

@ -27,12 +27,13 @@
#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,
G_DECLARE_FINAL_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI,
DEVICE_AES2660, FpiDeviceAesX660);
G_DEFINE_TYPE(FpiDeviceAes2660, fpi_device_aes2660, FPI_TYPE_DEVICE_AES_X660);
G_DEFINE_TYPE (FpiDeviceAes2660, fpi_device_aes2660, FPI_TYPE_DEVICE_AES_X660);
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = FRAME_WIDTH,
@ -41,7 +42,7 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = {
.get_pixel = aes_get_pixel,
};
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x2660, },
{ .vid = 0x08ff, .pid = 0x2680, },
{ .vid = 0x08ff, .pid = 0x2681, },
@ -63,12 +64,16 @@ 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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes2660";
@ -83,10 +88,10 @@ static void fpi_device_aes2660_class_init(FpiDeviceAes2660Class *klass) {
img_class->img_height = -1;
aes_class->init_seqs[0] = aes2660_init_1;
aes_class->init_seqs_len[0] = G_N_ELEMENTS(aes2660_init_1);
aes_class->init_seqs_len[0] = G_N_ELEMENTS (aes2660_init_1);
aes_class->init_seqs[1] = aes2660_init_2;
aes_class->init_seqs_len[1] = G_N_ELEMENTS(aes2660_init_2);
aes_class->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd);
aes_class->init_seqs_len[1] = G_N_ELEMENTS (aes2660_init_2);
aes_class->start_imaging_cmd = (unsigned char *) aes2660_start_imaging_cmd;
aes_class->start_imaging_cmd_len = sizeof (aes2660_start_imaging_cmd);
aes_class->assembling_ctx = &assembling_ctx;
}

File diff suppressed because it is too large Load diff

View file

@ -115,25 +115,30 @@ static struct aes_regwrite init_reqs[] = {
{ 0x81, 0x00 },
};
struct _FpiDeviceAes3500 {
struct _FpiDeviceAes3500
{
FpiDeviceAes3k parent;
};
G_DECLARE_FINAL_TYPE(FpiDeviceAes3500, fpi_device_aes3500, FPI,
G_DECLARE_FINAL_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI,
DEVICE_AES3500, FpiDeviceAes3k);
G_DEFINE_TYPE(FpiDeviceAes3500, fpi_device_aes3500, FPI_TYPE_DEVICE_AES3K);
G_DEFINE_TYPE (FpiDeviceAes3500, fpi_device_aes3500, FPI_TYPE_DEVICE_AES3K);
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = 0x08ff, .pid = 0x5731 },
{ .vid = 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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes3500";
@ -149,5 +154,5 @@ static void fpi_device_aes3500_class_init(FpiDeviceAes3500Class *klass) {
aes_class->frame_number = FRAME_NUMBER;
aes_class->enlarge_factor = ENLARGE_FACTOR;
aes_class->init_reqs = init_reqs;
aes_class->init_reqs_len = G_N_ELEMENTS(init_reqs);
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
}

View file

@ -40,7 +40,8 @@
#include "aeslib.h"
#include "aes3k.h"
typedef struct {
typedef struct
{
FpiUsbTransfer *img_trf;
gboolean deactivating;
} FpiDeviceAes3kPrivate;
@ -49,17 +50,20 @@ typedef struct {
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
static void do_capture(FpImageDevice *dev);
static void do_capture (FpImageDevice *dev);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceAes3k, fpi_device_aes3k, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAes3k, fpi_device_aes3k, FP_TYPE_IMAGE_DEVICE);
static void aes3k_assemble_image(unsigned char *input, size_t width, size_t height,
static void
aes3k_assemble_image (unsigned char *input, size_t width, size_t height,
unsigned char *output)
{
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,79 +86,86 @@ 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)
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
return;
}
fpi_image_device_session_error (dev, error);
}
fpi_image_device_report_finger_status(dev, TRUE);
fpi_image_device_report_finger_status (dev, TRUE);
tmp = fp_image_new(cls->frame_width, cls->frame_width);
tmp = fp_image_new (cls->frame_width, cls->frame_width);
tmp->width = cls->frame_width;
tmp->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++) {
fp_dbg("frame header byte %02x", *ptr);
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));
aes3k_assemble_image (ptr, cls->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * cls->frame_width * AES3K_FRAME_HEIGHT));
ptr += cls->frame_size;
}
/* FIXME: this is an ugly hack to make the image big enough for NBIS
* to process reliably */
img = fpi_image_resize(tmp, cls->enlarge_factor, cls->enlarge_factor);
img = fpi_image_resize (tmp, cls->enlarge_factor, cls->enlarge_factor);
g_object_unref (tmp);
fpi_image_device_image_captured(dev, img);
fpi_image_device_image_captured (dev, img);
/* FIXME: rather than assuming finger has gone, we should poll regs until
* it really has, then restart the capture */
fpi_image_device_report_finger_status(dev, FALSE);
fpi_image_device_report_finger_status (dev, FALSE);
do_capture(dev);
do_capture (dev);
}
static void do_capture(FpImageDevice *dev)
static void
do_capture (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk(priv->img_trf, EP_IN, cls->data_buflen);
fpi_usb_transfer_fill_bulk (priv->img_trf, EP_IN, cls->data_buflen);
priv->img_trf->short_is_error = TRUE;
fpi_usb_transfer_submit(priv->img_trf, 0,
fpi_usb_transfer_submit (priv->img_trf, 0,
fpi_device_get_cancellable (FP_DEVICE (dev)),
img_cb, NULL);
fpi_usb_transfer_unref(priv->img_trf);
fpi_usb_transfer_unref (priv->img_trf);
}
static void init_reqs_cb(FpImageDevice *dev, GError *result, void *user_data)
static void
init_reqs_cb (FpImageDevice *dev, GError *result, void *user_data)
{
fpi_image_device_activate_complete (dev, result);
if (!result)
do_capture(dev);
do_capture (dev);
}
static void aes3k_dev_activate(FpImageDevice *dev)
static void
aes3k_dev_activate (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
priv->deactivating = FALSE;
aes_write_regv(dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
}
static void aes3k_dev_deactivate(FpImageDevice *dev)
static void
aes3k_dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
@ -161,37 +173,44 @@ static void aes3k_dev_deactivate(FpImageDevice *dev)
priv->deactivating = TRUE;
if (priv->img_trf)
return;
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void fpi_device_aes3k_init(FpiDeviceAes3k *self) {
static void
fpi_device_aes3k_init (FpiDeviceAes3k *self)
{
}
static void aes3k_dev_init(FpImageDevice *dev)
static void
aes3k_dev_init (FpImageDevice *dev)
{
GError *error = NULL;
if (!g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error)) {
fpi_image_device_open_complete(dev, error);
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
{
fpi_image_device_open_complete (dev, error);
return;
}
fpi_image_device_open_complete(dev, NULL);
fpi_image_device_open_complete (dev, NULL);
}
static void aes3k_dev_deinit(FpImageDevice *dev)
static void
aes3k_dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static void fpi_device_aes3k_class_init(FpiDeviceAes3kClass *klass) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->scan_type = FP_SCAN_TYPE_PRESS;

View file

@ -40,12 +40,13 @@
#define AES3K_FRAME_HEIGHT 16
G_DECLARE_DERIVABLE_TYPE(FpiDeviceAes3k, fpi_device_aes3k, FPI,
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAes3k, fpi_device_aes3k, FPI,
DEVICE_AES3K, FpImageDevice)
#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 */

View file

@ -112,25 +112,30 @@ static struct aes_regwrite init_reqs[] = {
{ 0x81, 0x00 },
};
struct _FpiDeviceAes4000 {
struct _FpiDeviceAes4000
{
FpiDeviceAes3k parent;
};
G_DECLARE_FINAL_TYPE(FpiDeviceAes4000, fpi_device_aes4000, FPI,
G_DECLARE_FINAL_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI,
DEVICE_AES4000, FpiDeviceAes3k);
G_DEFINE_TYPE(FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
G_DEFINE_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K);
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .pid = 0x08ff, .vid = 0x5501 },
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "aes4000";
@ -146,5 +151,5 @@ static void fpi_device_aes4000_class_init(FpiDeviceAes4000Class *klass) {
aes_class->frame_number = FRAME_NUMBER;
aes_class->enlarge_factor = ENLARGE_FACTOR;
aes_class->init_reqs = init_reqs;
aes_class->init_reqs_len = G_N_ELEMENTS(init_reqs);
aes_class->init_reqs_len = G_N_ELEMENTS (init_reqs);
}

View file

@ -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,50 +43,58 @@ 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) {
wdata->callback(FP_IMAGE_DEVICE (device), error, wdata->user_data);
g_free(wdata);
} else {
continue_write_regv(FP_IMAGE_DEVICE (device), wdata);
if (error)
{
wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
g_free (wdata);
}
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;
size_t alloc_size = num * 2;
unsigned int i;
size_t data_offset = 0;
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE (dev));
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk (transfer, EP_OUT, alloc_size);
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;
}
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
write_regv_trf_complete, wdata);
fpi_usb_transfer_unref (transfer);
}
/* 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,11 +103,13 @@ 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) {
fp_dbg("all registers written");
wdata->callback(dev, 0, wdata->user_data);
g_free(wdata);
while (TRUE)
{
if (offset >= wdata->num_regs)
{
fp_dbg ("all registers written");
wdata->callback (dev, 0, wdata->user_data);
g_free (wdata);
return;
}
if (wdata->regs[offset].reg)
@ -108,18 +119,19 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
wdata->offset = offset;
regs_remaining = wdata->num_regs - offset;
limit = MIN(regs_remaining, MAX_REGWRITES_PER_REQUEST);
limit = MIN (regs_remaining, MAX_REGWRITES_PER_REQUEST);
upper_bound = offset + limit - 1;
/* 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;
}
do_write_regv(dev, wdata, upper_bound);
do_write_regv (dev, wdata, upper_bound);
wdata->offset = upper_bound + 1;
}
@ -127,23 +139,25 @@ static void continue_write_regv(FpImageDevice *dev, struct write_regv_data *wdat
/* write a load of registers to the device, combining multiple writes in a
* 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)
{
struct write_regv_data *wdata;
fp_dbg("write %d regs", num_regs);
wdata = g_malloc(sizeof(*wdata));
fp_dbg ("write %d regs", num_regs);
wdata = g_malloc (sizeof (*wdata));
wdata->num_regs = num_regs;
wdata->regs = regs;
wdata->offset = 0;
wdata->callback = callback;
wdata->user_data = user_data;
continue_write_regv(dev, wdata);
continue_write_regv (dev, wdata);
}
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
unsigned char
aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame,
unsigned int x,
unsigned int y)

View file

@ -22,7 +22,8 @@
#include <fprint.h>
struct aes_regwrite {
struct aes_regwrite
{
unsigned char reg;
unsigned char value;
};
@ -30,17 +31,19 @@ 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,
unsigned char aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame,
unsigned int x,
unsigned int y);
#endif

View file

@ -27,7 +27,8 @@
#include "aeslib.h"
#include "aesx660.h"
typedef struct {
typedef struct
{
GByteArray *stripe_packet;
GSList *strips;
size_t strips_len;
@ -38,10 +39,10 @@ typedef struct {
unsigned int init_seq_idx;
} FpiDeviceAesX660Private;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceAesX660, fpi_device_aes_x660, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpiDeviceAesX660, fpi_device_aes_x660, FP_TYPE_IMAGE_DEVICE);
static void start_capture(FpImageDevice *dev);
static void complete_deactivation(FpImageDevice *dev);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev);
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
@ -54,84 +55,87 @@ static void complete_deactivation(FpImageDevice *dev);
#define FINGER_DET_DATA_LEN 4
static void
aesX660_send_cmd_timeout(FpiSsm *ssm,
aesX660_send_cmd_timeout (FpiSsm *ssm,
FpDevice *_dev,
const unsigned char *cmd,
size_t cmd_len,
FpiUsbTransferCallback callback,
int timeout)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, (unsigned char *)cmd,
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, (unsigned char *) cmd,
cmd_len, NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, timeout, NULL, callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_submit (transfer, timeout, NULL, callback, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
aesX660_send_cmd(FpiSsm *ssm,
aesX660_send_cmd (FpiSsm *ssm,
FpDevice *dev,
const unsigned char *cmd,
size_t cmd_len,
FpiUsbTransferCallback callback)
{
return aesX660_send_cmd_timeout(ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
return aesX660_send_cmd_timeout (ssm, dev, cmd, cmd_len, callback, BULK_TIMEOUT);
}
static void
aesX660_read_response(FpiSsm *ssm,
aesX660_read_response (FpiSsm *ssm,
FpDevice *_dev,
gboolean short_is_error,
gboolean cancellable,
size_t buf_len,
FpiUsbTransferCallback callback)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
unsigned char *data;
GCancellable *cancel = NULL;
if (cancellable)
cancel = fpi_device_get_cancellable (_dev);
data = g_malloc(buf_len);
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN, data, buf_len, NULL);
data = g_malloc (buf_len);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, buf_len, NULL);
transfer->ssm = ssm;
transfer->short_is_error = short_is_error;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, cancel, callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, cancel, callback, NULL);
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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) {
fpi_ssm_mark_failed(transfer->ssm, 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) {
fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
fpi_ssm_mark_failed(transfer->ssm,
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,
"Bogus calibrate response"));
return;
}
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
}
/****** FINGER PRESENCE DETECTION ******/
@ -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,104 +157,123 @@ 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)) {
fpi_ssm_next_state(transfer->ssm);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
fpi_ssm_next_state (transfer->ssm);
return;
}
if (error) {
fp_dbg("Failed to read FD data\n");
fpi_ssm_mark_failed(transfer->ssm, 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) {
fp_dbg("Bogus FD response: %.2x\n", data[0]);
fpi_ssm_mark_failed(transfer->ssm,
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,
"Bogus FD response"));
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 {
fp_dbg("Wait for finger returned %.2x as result\n",
fpi_ssm_next_state (transfer->ssm);
}
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);
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) {
fpi_ssm_mark_completed(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_mark_completed (transfer->ssm);
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);
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
fp_dbg("Finger detection completed");
fpi_image_device_report_finger_status(dev, TRUE);
fpi_ssm_free(ssm);
fp_dbg ("Finger detection completed");
fpi_image_device_report_finger_status (dev, TRUE);
fpi_ssm_free (ssm);
if (priv->deactivating) {
complete_deactivation(dev);
if (priv->deactivating)
{
complete_deactivation (dev);
if (error)
g_error_free (error);
} else if (error) {
fpi_image_device_session_error(dev, error);
} else {
fpi_image_device_report_finger_status(dev, TRUE);
start_capture(dev);
}
else if (error)
{
fpi_image_device_session_error (dev, error);
}
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 (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_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);
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),
aesX660_send_cmd (ssm, dev, set_idle_cmd, sizeof (set_idle_cmd),
finger_det_set_idle_cmd_cb);
break;
}
}
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) {
complete_deactivation(dev);
if (priv->deactivating)
{
complete_deactivation (dev);
return;
}
ssm = fpi_ssm_new(FP_DEVICE(dev), finger_det_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), finger_det_run_state,
FINGER_DET_NUM_STATES, dev);
fpi_ssm_start(ssm, finger_det_sm_complete);
fpi_ssm_start (ssm, finger_det_sm_complete);
}
/****** CAPTURE ******/
@ -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,36 +296,39 @@ 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);
return 0;
}
stripe = g_malloc(cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
stripe = g_malloc (cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof (struct fpi_frame)); /* 4 bpp */
stripdata = stripe->data;
fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
fp_dbg ("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
data[AESX660_LAST_FRAME_OFFSET]);
stripe->delta_x = (int8_t)data[AESX660_FRAME_DELTA_X_OFFSET];
stripe->delta_y = -(int8_t)data[AESX660_FRAME_DELTA_Y_OFFSET];
fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
stripe->delta_x = (int8_t) data[AESX660_FRAME_DELTA_X_OFFSET];
stripe->delta_y = -(int8_t) data[AESX660_FRAME_DELTA_Y_OFFSET];
fp_dbg ("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) {
memcpy(stripdata, data + AESX660_IMAGE_OFFSET, cls->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
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 = 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);
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,24 +336,28 @@ 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);
img = fpi_assemble_frames(cls->assembling_ctx, priv->strips);
g_slist_foreach(priv->strips, (GFunc) g_free, NULL);
g_slist_free(priv->strips);
priv->strips = g_slist_reverse (priv->strips);
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
g_slist_free (priv->strips);
priv->strips = NULL;
priv->strips_len = 0;
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev, FALSE);
fpi_ssm_mark_completed(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
fpi_ssm_mark_completed (transfer->ssm);
}
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);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fp_dbg("Got %lu bytes of data", actual_length);
while (actual_length) {
fp_dbg ("Got %lu bytes of data", actual_length);
while (actual_length)
{
gssize payload_length;
gssize still_needed_len;
gssize copy_len;
@ -359,7 +393,7 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
payload_length = priv->stripe_packet->data[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
(priv->stripe_packet->data[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8);
fp_dbg("Got frame, type %.2x payload of size %.4lx",
fp_dbg ("Got frame, type %.2x payload of size %.4lx",
priv->stripe_packet->data[AESX660_RESPONSE_TYPE_OFFSET],
payload_length);
@ -373,7 +407,7 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
if (priv->stripe_packet->len < payload_length + AESX660_HEADER_SIZE)
break;
finger_missing |= process_stripe_data(transfer->ssm,
finger_missing |= process_stripe_data (transfer->ssm,
self,
priv->stripe_packet->data,
priv->stripe_packet->len);
@ -381,79 +415,91 @@ static void capture_read_stripe_data_cb(FpiUsbTransfer *transfer,
g_byte_array_set_size (priv->stripe_packet, 0);
}
fp_dbg("finger %s\n", finger_missing ? "missing" : "present");
fp_dbg ("finger %s\n", finger_missing ? "missing" : "present");
if (finger_missing) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_STRIPE_DATA);
}
if (finger_missing)
fpi_ssm_next_state (transfer->ssm);
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 (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,
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,
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),
fp_dbg ("Got %lu frames\n", priv->strips_len);
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
capture_set_idle_cmd_cb);
break;
}
}
static void capture_sm_complete(FpiSsm *ssm, FpDevice *device, void *user_data,
static void
capture_sm_complete (FpiSsm *ssm, FpDevice *device, void *user_data,
GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
fp_dbg("Capture completed");
fpi_ssm_free(ssm);
fp_dbg ("Capture completed");
fpi_ssm_free (ssm);
if (priv->deactivating) {
complete_deactivation(FP_IMAGE_DEVICE (device));
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 {
start_finger_detection(FP_IMAGE_DEVICE (device));
}
else
{
start_finger_detection (FP_IMAGE_DEVICE (device));
}
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
FpiSsm *ssm;
if (priv->deactivating) {
complete_deactivation(dev);
if (priv->deactivating)
{
complete_deactivation (dev);
return;
}
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
G_DEBUG_HERE();
fpi_ssm_start(ssm, capture_sm_complete);
G_DEBUG_HERE ();
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -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,146 +524,169 @@ 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) {
fp_dbg("read_id cmd failed\n");
fpi_ssm_mark_failed(transfer->ssm, 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) {
fp_dbg("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n",
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 {
fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
fpi_ssm_mark_failed(transfer->ssm,
}
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,
"Bogus read ID response"));
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];
priv->init_seq_idx = 1;
priv->init_cmd_idx = 0;
/* Do calibration only after 1st init sequence */
fpi_ssm_jump_to_state(transfer->ssm, ACTIVATE_SEND_INIT_CMD);
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
break;
case 1:
priv->init_seq = cls->init_seqs[1];
priv->init_seq_len = cls->init_seqs_len[1];
priv->init_seq_idx = 2;
priv->init_cmd_idx = 0;
fpi_ssm_next_state(transfer->ssm);
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,
fp_dbg ("Failed to init device! init status: %.2x\n", data[7]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Failed to init device"));
break;
}
}
static void activate_read_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
static void
activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (device);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
unsigned char *data = transfer->buffer;
fp_dbg("read_init_cb\n");
fp_dbg ("read_init_cb\n");
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);
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) {
fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
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,
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read init response"));
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,
fpi_ssm_jump_to_state (transfer->ssm,
ACTIVATE_SEND_READ_ID_CMD);
else
fpi_ssm_mark_completed(transfer->ssm);
fpi_ssm_mark_completed (transfer->ssm);
return;
}
fpi_ssm_jump_to_state(transfer->ssm, ACTIVATE_SEND_INIT_CMD);
fpi_ssm_jump_to_state (transfer->ssm, ACTIVATE_SEND_INIT_CMD);
}
static void activate_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
static void
activate_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (_dev);
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),
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),
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);
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",
fp_dbg ("Activate: send init seq #%d cmd #%d\n",
priv->init_seq_idx,
priv->init_cmd_idx);
aesX660_send_cmd(ssm, _dev,
aesX660_send_cmd (ssm, _dev,
priv->init_seq[priv->init_cmd_idx].cmd,
priv->init_seq[priv->init_cmd_idx].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);
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 (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);
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);
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
if (!error)
start_finger_detection(FP_IMAGE_DEVICE (_dev));
start_finger_detection (FP_IMAGE_DEVICE (_dev));
}
static void aesX660_dev_activate(FpImageDevice *dev)
static void
aesX660_dev_activate (FpImageDevice *dev)
{
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), activate_run_state,
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES, dev);
fpi_ssm_start(ssm, activate_sm_complete);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void aesX660_dev_deactivate(FpImageDevice *dev)
static void
aesX660_dev_deactivate (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
@ -624,54 +694,61 @@ 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);
GError *error = NULL;
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
priv->stripe_packet = g_byte_array_new ();
fpi_image_device_open_complete(dev, error);
fpi_image_device_open_complete (dev, error);
}
static void aesX660_dev_deinit(FpImageDevice *dev)
static void
aesX660_dev_deinit (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
g_clear_pointer (&priv->stripe_packet, g_byte_array_unref);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static void complete_deactivation(FpImageDevice *dev)
static void
complete_deactivation (FpImageDevice *dev)
{
FpiDeviceAesX660 *self = FPI_DEVICE_AES_X660 (dev);
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
G_DEBUG_HERE();
G_DEBUG_HERE ();
priv->deactivating = FALSE;
g_slist_free(priv->strips);
g_slist_free (priv->strips);
priv->strips = NULL;
priv->strips_len = 0;
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void fpi_device_aes_x660_init(FpiDeviceAesX660 *self) {
static void
fpi_device_aes_x660_init (FpiDeviceAesX660 *self)
{
}
static void fpi_device_aes_x660_class_init(FpiDeviceAesX660Class *klass) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;

View file

@ -42,12 +42,13 @@
#define AESX660_FRAME_HEIGHT 8
G_DECLARE_DERIVABLE_TYPE(FpiDeviceAesX660, fpi_device_aes_x660, FPI,
G_DECLARE_DERIVABLE_TYPE (FpiDeviceAesX660, fpi_device_aes_x660, FPI,
DEVICE_AES_X660, FpImageDevice)
#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;
};
@ -66,33 +68,33 @@ struct aesX660_cmd {
* makes LED blink
*/
static const guint8 led_blink_cmd[] = {
0x77, 0x18, 0x00,
0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3,
0x01, 0x00, 0x7f
0x77, 0x18, 0x00,
0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3,
0x01, 0x00, 0x7f
};
/* This sequence makes LED light solid
*/
static const guint8 led_solid_cmd[] = {
0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f
0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f
};
static const guint8 wait_for_finger_cmd[] = {
0x20,
0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32
0x20,
0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32
};
/* 0x40 cmd response
*
static const guint8 pkt1371[] = {
0x40, 0x01, 0x00, 0x01
};
*/
static const guint8 pkt1371[] = {
0x40, 0x01, 0x00, 0x01
};
*/
static const guint8 set_idle_cmd[] = {
0x0d, /* Reset or "set idle"? */
@ -107,4 +109,3 @@ static const guint8 calibrate_cmd[] = {
0x44, 0x02, 0x00, 0x04, 0x00,
0x06,
};

File diff suppressed because it is too large Load diff

View file

@ -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;
@ -156,7 +157,7 @@ static const struct elan_cmd stop_cmd = {
.never_cancel = TRUE,
};
static const FpIdEntry elan_id_table [ ] = {
static const FpIdEntry elan_id_table[] = {
{.vid = ELAN_VEND_ID, .pid = 0x0903, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0907, .driver_data = ELAN_0907},
{.vid = ELAN_VEND_ID, .pid = 0x0c01, .driver_data = ELAN_ALL_DEV},
@ -214,12 +215,14 @@ static const FpIdEntry elan_id_table [ ] = {
{.vid = 0, .pid = 0, .driver_data = 0},
};
static void elan_cmd_done(FpiSsm *ssm);
static void elan_cmd_read(FpiSsm *ssm, FpDevice *dev);
static void elan_cmd_done (FpiSsm *ssm);
static void elan_cmd_read (FpiSsm *ssm,
FpDevice *dev);
static void elan_calibrate(FpDevice *dev);
static void elan_capture(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

View file

@ -34,9 +34,9 @@
#include "bmkt_response.h"
/*!
*******************************************************************************
** Type definition for result
*/
*******************************************************************************
** Type definition for result
*/
/** No error; Operation successfully completed. */
#define BMKT_SUCCESS 0
/** Fingerprint system not initialized */
@ -68,27 +68,27 @@
/** Fingerprint sensor cannot be accessed despite repeated attempts */
#define BMKT_SENSOR_TAMPERED 203
/**
* BMKT_SENSOR_NOT_INIT:
* Fingerprint sensor module not initialized yet not ready for use
* (different from error code 101 which indicates that the entire system
* has not been initialized)
*/
* BMKT_SENSOR_NOT_INIT:
* Fingerprint sensor module not initialized yet not ready for use
* (different from error code 101 which indicates that the entire system
* has not been initialized)
*/
#define BMKT_SENSOR_NOT_INIT 204
/** Number of re-pairing operations exceeded limit or re-pairing has been disabled */
#define BMKT_OWNERSHIP_RESET_MAX_EXCEEDED 205
/**
* BMKT_SENSOR_STIMULUS_ERROR:
* There is a finger or debris on the sensor that needs to be removed
* before issuing this command
*/
* BMKT_SENSOR_STIMULUS_ERROR:
* There is a finger or debris on the sensor that needs to be removed
* before issuing this command
*/
#define BMKT_SENSOR_STIMULUS_ERROR 213
/**
* BMKT_CORRUPT_TEMPLATE_DATA:
* One of the fingerprint templates stored on flash is corrupt.
* This error code is returned in case of failure in finding a fingerprint match
* during identify or verify operations while also detecting that one or more
* fingerprint templates stored on the flash has become corrupted
*/
* BMKT_CORRUPT_TEMPLATE_DATA:
* One of the fingerprint templates stored on flash is corrupt.
* This error code is returned in case of failure in finding a fingerprint match
* during identify or verify operations while also detecting that one or more
* fingerprint templates stored on the flash has become corrupted
*/
#define BMKT_CORRUPT_TEMPLATE_DATA 300
/** Failed to extract features from fingerprint image acquired by sensor */
#define BMKT_FEATURE_EXTRACT_FAIL 301
@ -129,11 +129,10 @@ extern "C" {
#endif
/**
* bmkt_mode:
* Fingerprint system operational mode values level 1
*/
typedef enum bmkt_mode
{
* bmkt_mode:
* Fingerprint system operational mode values level 1
*/
typedef enum bmkt_mode {
BMKT_STATE_UNINIT = 0xFF,
BMKT_STATE_IDLE = 0x00,
BMKT_STATE_ENROLL = 0x10,
@ -145,11 +144,10 @@ typedef enum bmkt_mode
} bmkt_mode_t;
/**
* bmkt_mode_level2:
* Fingerprint system operational mode values level 2
*/
typedef enum bmkt_mode_level2
{
* bmkt_mode_level2:
* Fingerprint system operational mode values level 2
*/
typedef enum bmkt_mode_level2 {
BMKT_STATE_L2_IDLE = 0x00,
BMKT_STATE_L2_STARTING = 0x11,
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
@ -167,36 +165,35 @@ typedef enum bmkt_mode_level2
} bmkt_mode_level2_t;
/**
* bmkt_transport_type:
* Fingerprint system transport types
*/
typedef enum bmkt_transport_type
{
* bmkt_transport_type:
* Fingerprint system transport types
*/
typedef enum bmkt_transport_type {
BMKT_TRANSPORT_TYPE_USB = 0,
} bmkt_transport_type_t;
/**
* bmkt_usb_config:
* Structure represcontainingenting USB configuration details
*/
* bmkt_usb_config:
* Structure represcontainingenting USB configuration details
*/
typedef struct bmkt_usb_config
{
int product_id; /**< USB device product ID */
} bmkt_usb_config_t;
/**
* bmkt_transport_config_t:
* Union containing transport configuration details
*/
* bmkt_transport_config_t:
* Union containing transport configuration details
*/
typedef union
{
bmkt_usb_config_t usb_config;
} bmkt_transport_config_t;
/**
* bmkt_sensor_desc_t:
* Structure containing fingerprint system description
*/
* bmkt_sensor_desc_t:
* Structure containing fingerprint system description
*/
typedef struct bmkt_sensor_desc
{
int product_id;
@ -204,20 +201,19 @@ typedef struct bmkt_sensor_desc
} bmkt_sensor_desc_t;
/**
* bmkt_finger_state_t:
* Finger state representation values.
*/
typedef enum
{
* bmkt_finger_state_t:
* Finger state representation values.
*/
typedef enum {
BMKT_FINGER_STATE_UNKNOWN = 0,
BMKT_FINGER_STATE_ON_SENSOR,
BMKT_FINGER_STATE_NOT_ON_SENSOR,
} bmkt_finger_state_t;
/**
* bmkt_finger_event_t:
* Structure containing finger state
*/
* bmkt_finger_event_t:
* Structure containing finger state
*/
typedef struct bmkt_finger_event
{
bmkt_finger_state_t finger_state;

View file

@ -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,155 +38,145 @@ static uint8_t extract8(const uint8_t *buf, int *offset)
}
static int parse_error_response(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
static int
parse_error_response (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
{
if (msg_resp->payload_len != 2)
{
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);
init_resp->finger_presence = extract8 (msg_resp->payload, NULL);
return BMKT_SUCCESS;
}
static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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))
{
if (msg_resp->payload_len != sizeof (bmkt_fps_mode_resp_t))
return BMKT_UNRECOGNIZED_MESSAGE;
}
fps_mode_resp->mode = extract8(msg_resp->payload, &offset);
fps_mode_resp->level2_mode = extract8(msg_resp->payload, &offset);
fps_mode_resp->cmd_id = extract8(msg_resp->payload, &offset);
fps_mode_resp->finger_presence = extract8(msg_resp->payload, &offset);
fps_mode_resp->mode = extract8 (msg_resp->payload, &offset);
fps_mode_resp->level2_mode = extract8 (msg_resp->payload, &offset);
fps_mode_resp->cmd_id = extract8 (msg_resp->payload, &offset);
fps_mode_resp->finger_presence = extract8 (msg_resp->payload, &offset);
return BMKT_SUCCESS;
}
static int parse_enroll_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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);
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);
memcpy (enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
return BMKT_SUCCESS;
}
static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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->match_result = (double) msg_resp->payload[0] + 0.01 * (double) msg_resp->payload[1];
id_resp->finger_id = msg_resp->payload[2];
memcpy(id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
memcpy (id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
return BMKT_SUCCESS;
}
static int parse_security_level_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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);
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);
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);
db_cap_resp->total = extract8 (msg_resp->payload, &offset);
db_cap_resp->empty = extract8 (msg_resp->payload, &offset);
if (msg_resp->payload_len == 4)
{
db_cap_resp->bad_slots = extract8(msg_resp->payload, &offset);
db_cap_resp->corrupt_templates = extract8(msg_resp->payload, &offset);
db_cap_resp->bad_slots = extract8 (msg_resp->payload, &offset);
db_cap_resp->corrupt_templates = extract8 (msg_resp->payload, &offset);
}
return BMKT_SUCCESS;
}
static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
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;
@ -192,118 +184,107 @@ static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_res
for (i = 0; i < num_fingers; i++)
{
get_enrolled_fingers_resp->fingers[i].finger_id = extract8(msg_resp->payload, &offset);
get_enrolled_fingers_resp->fingers[i].template_status = extract8(msg_resp->payload, &offset);
get_enrolled_fingers_resp->fingers[i].finger_id = extract8 (msg_resp->payload, &offset);
get_enrolled_fingers_resp->fingers[i].template_status = extract8 (msg_resp->payload, &offset);
}
return BMKT_SUCCESS;
}
static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
static int
parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
{
int offset = 0;
int i = 0;
/* the payload is 2 bytes + template data */
if (msg_resp->payload_len < 2)
{
return BMKT_UNRECOGNIZED_MESSAGE;
}
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
get_enroll_templates_resp->total_query_messages = extract8(msg_resp->payload, &offset);
get_enroll_templates_resp->query_sequence = extract8(msg_resp->payload, &offset);
get_enroll_templates_resp->total_query_messages = extract8 (msg_resp->payload, &offset);
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
int n = 0;
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
{
if (offset >= msg_resp->payload_len)
break;
get_enroll_templates_resp->templates[n].user_id_len = extract8(msg_resp->payload, &offset) - 2;
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);
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] = 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);
memcpy (get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
offset += BMKT_PART_NUM_LEN;
get_version_resp->year = extract8(msg_resp->payload, &offset);
get_version_resp->week = extract8(msg_resp->payload, &offset);
get_version_resp->patch = extract8(msg_resp->payload, &offset);
memcpy(get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
get_version_resp->year = extract8 (msg_resp->payload, &offset);
get_version_resp->week = extract8 (msg_resp->payload, &offset);
get_version_resp->patch = extract8 (msg_resp->payload, &offset);
memcpy (get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
return BMKT_SUCCESS;
}
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
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;
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
memcpy(&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
memcpy (&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
*cmd_len = message_len;
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;
memset(resp, 0, sizeof(bmkt_response_t));
memset (resp, 0, sizeof (bmkt_response_t));
resp->response_id = msg_resp->msg_id;
@ -329,12 +310,12 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
case BMKT_RSP_QUERY_PAIRING_FAIL:
case BMKT_RSP_SENSOR_STATUS_FAIL:
case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
ret = parse_error_response(msg_resp, resp);
ret = parse_error_response (msg_resp, resp);
resp->complete = 1;
break;
case BMKT_RSP_FPS_INIT_OK:
ret = parse_init_ok(msg_resp, resp);
ret = parse_init_ok (msg_resp, resp);
resp->complete = 1;
break;
@ -349,19 +330,19 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
case BMKT_RSP_FPS_MODE_REPORT:
// parse_fps_mode
ret = parse_fps_mode_report(msg_resp, resp);
ret = parse_fps_mode_report (msg_resp, resp);
resp->complete = 1;
break;
case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
/* parse security level result */
ret = parse_security_level_report(msg_resp, resp);
ret = parse_security_level_report (msg_resp, resp);
resp->complete = 1;
break;
case BMKT_RSP_DELETE_PROGRESS:
ret = parse_del_all_users_progress_report(msg_resp, resp);
ret = parse_del_all_users_progress_report (msg_resp, resp);
break;
case BMKT_RSP_CAPTURE_COMPLETE:
@ -373,38 +354,43 @@ int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
break;
case BMKT_RSP_ENROLL_REPORT:
ret = parse_enroll_report(msg_resp, resp);
ret = parse_enroll_report (msg_resp, resp);
break;
case BMKT_RSP_ENROLL_OK:
resp->complete = 1;
ret = parse_enroll_ok(msg_resp, resp);
ret = parse_enroll_ok (msg_resp, resp);
break;
case BMKT_RSP_ID_OK:
case BMKT_RSP_VERIFY_OK:
ret = parse_auth_ok(msg_resp, resp);
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);
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);
ret = parse_db_cap_report (msg_resp, resp);
break;
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
ret = parse_get_enrolled_users_report(msg_resp, resp);
ret = parse_get_enrolled_users_report (msg_resp, resp);
break;
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
resp->complete = 1;
break;
case BMKT_RSP_VERSION_INFO:
ret = parse_get_version_report(msg_resp, resp);
ret = parse_get_version_report (msg_resp, resp);
resp->complete = 1;
break;
case BMKT_RSP_POWER_DOWN_READY:
resp->complete = 1;
break;

View file

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

View file

@ -33,9 +33,9 @@
#define BMKT_RSP_NEXT_TEST_REPORT_CHUNK 0x0C
/*! \addtogroup init
* Response IDs returned by fingerprint initialization operation
* @{
*/
* Response IDs returned by fingerprint initialization operation
* @{
*/
/** Failed to initialize fingerprint sensor module */
#define BMKT_RSP_FPS_INIT_FAIL 0x12
/** Successfully initialized fingerprint sensor module */
@ -43,70 +43,70 @@
/*! @} */
/*! \addtogroup mode
* Response IDs returned by get fingerprint mode operation
* @{
*/
* Response IDs returned by get fingerprint mode operation
* @{
*/
/** Failed to get fingerprint sensor modules current operational mode */
#define BMKT_RSP_FPS_MODE_FAIL 0x22
/**
* BMKT_RSP_FPS_MODE_REPORT:
* Response containing the current operational mode of the fingerprint sensor module
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
*/
* BMKT_RSP_FPS_MODE_REPORT:
* Response containing the current operational mode of the fingerprint sensor module
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
*/
#define BMKT_RSP_FPS_MODE_REPORT 0x23
/*! @} */
/*! \addtogroup setseclevel
* Response IDs returned by set security level operation
* @{
*/
* Response IDs returned by set security level operation
* @{
*/
/** Failed to set fingerprint sensor module security level */
#define BMKT_RSP_SET_SECURITY_LEVEL_FAIL 0x32
/**
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
* Security level of the fingerprint sensor module was set successfully
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
*/
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
* Security level of the fingerprint sensor module was set successfully
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
*/
#define BMKT_RSP_SET_SECURITY_LEVEL_REPORT 0x33
/*! @} */
/*! \addtogroup getseclevel
* Response IDs returned by get security level operation
* @{
*/
* Response IDs returned by get security level operation
* @{
*/
/** Failed to get fingerprint sensor module security level */
#define BMKT_RSP_GET_SECURITY_LEVEL_FAIL 0x35
/**
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
* Returns the current security level of the fingerprint sensor module
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
*/
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
* Returns the current security level of the fingerprint sensor module
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
*/
#define BMKT_RSP_GET_SECURITY_LEVEL_REPORT 0x36
/*! @} */
/*! \addtogroup cancelop
* Response IDs returned by cancel_operation operation
* @{
*/
* Response IDs returned by cancel_operation operation
* @{
*/
/**
* BMKT_RSP_CANCEL_OP_OK:
* Successfully canceled the current operation and returned
* fingerprint sensor module to idle mode
*/
* BMKT_RSP_CANCEL_OP_OK:
* Successfully canceled the current operation and returned
* fingerprint sensor module to idle mode
*/
#define BMKT_RSP_CANCEL_OP_OK 0x42
/** Failed to cancel the current operation */
#define BMKT_RSP_CANCEL_OP_FAIL 0x43
/*! @} */
/*! \addtogroup enrollment
* Response IDs returned by enrollment operation
* @{
*/
* Response IDs returned by enrollment operation
* @{
*/
/**
* BMKT_RSP_ENROLL_READY:
* Fingerprint enrollment session has begun and the user can place
* their finger on the sensor
*/
* BMKT_RSP_ENROLL_READY:
* Fingerprint enrollment session has begun and the user can place
* their finger on the sensor
*/
#define BMKT_RSP_ENROLL_READY 0x54
/** Progress of the currently on-going fingerprint enrollment session */
#define BMKT_RSP_ENROLL_REPORT 0x55
@ -117,135 +117,135 @@
/** The current enrollment session has encountered an error */
#define BMKT_RSP_ENROLL_FAIL 0x58
/**
* BMKT_RSP_ENROLL_OK:
* User has been successfully enrolled into the fingerprint sensor module
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
*/
* BMKT_RSP_ENROLL_OK:
* User has been successfully enrolled into the fingerprint sensor module
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
*/
#define BMKT_RSP_ENROLL_OK 0x59
/**
* BMKT_RSP_CAPTURE_COMPLETE:
* Fingerprint image capture is complete and it is safe for the user
* to lift their finger off the sensor
*/
* BMKT_RSP_CAPTURE_COMPLETE:
* Fingerprint image capture is complete and it is safe for the user
* to lift their finger off the sensor
*/
#define BMKT_RSP_CAPTURE_COMPLETE 0x60
/*! @} */
/*! \addtogroup identify
* Response IDs returned by identify operation.
* @{
*/
* Response IDs returned by identify operation.
* @{
*/
/* Fingerprint identification session has begun */
#define BMKT_RSP_ID_READY 0x62
/* Identification has failed */
#define BMKT_RSP_ID_FAIL 0x63
/**
* BMKT_RSP_ID_OK:
* User has been successfully identified
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
*/
* BMKT_RSP_ID_OK:
* User has been successfully identified
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
*/
#define BMKT_RSP_ID_OK 0x64
/*! @} */
/*! \addtogroup verify
* Response IDs returned by identify operation.
* @{
*/
* Response IDs returned by identify operation.
* @{
*/
/** Fingerprint verification session has begun */
#define BMKT_RSP_VERIFY_READY 0x66
/** Verification has failed */
#define BMKT_RSP_VERIFY_FAIL 0x67
/**
* BMKT_RSP_VERIFY_OK:
* Users identity has been successfully verified
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
*/
* BMKT_RSP_VERIFY_OK:
* Users identity has been successfully verified
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
*/
#define BMKT_RSP_VERIFY_OK 0x68
/*! @} */
/**
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
* Response ID returned by get enrolled users templates record operation
* <br>Returns list of template records containing user IDs and corresponding finger IDs
* <br>Payload data represented in \ref bmkt_enroll_templates_resp_t struct
*/
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
* Response ID returned by get enrolled users templates record operation
* <br>Returns list of template records containing user IDs and corresponding finger IDs
* <br>Payload data represented in \ref bmkt_enroll_templates_resp_t struct
*/
#define BMKT_RSP_TEMPLATE_RECORDS_REPORT 0x75
/**
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
* Response ID returned by get next query response operation
* <br>Complete sequence of messages containing the template records query response has been sent
*/
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
* Response ID returned by get next query response operation
* <br>Complete sequence of messages containing the template records query response has been sent
*/
#define BMKT_RSP_QUERY_RESPONSE_COMPLETE 0x76
/**
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
* Response ID returned by get enrolled fingers operation
* <br> Returns list of IDs of enrolled fingers for a specific user,
* along with template record status corresponding to each enrolled finger
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
*/
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
* Response ID returned by get enrolled fingers operation
* <br> Returns list of IDs of enrolled fingers for a specific user,
* along with template record status corresponding to each enrolled finger
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
*/
#define BMKT_RSP_GET_ENROLLED_FINGERS_REPORT 0x77
/*! \addtogroup dbcapacity
* Response IDs returned by get database capacity operation
* @{
*/
* Response IDs returned by get database capacity operation
* @{
*/
/**
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
* Response specifying total capacity of fingerprint template database and
* how much free capacity is remaining along with how many templates are corrupted and
* how many bad (permanently unusable) storage slots are there.
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
*/
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
* Response specifying total capacity of fingerprint template database and
* how much free capacity is remaining along with how many templates are corrupted and
* how many bad (permanently unusable) storage slots are there.
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
*/
#define BMKT_RSP_DATABASE_CAPACITY_REPORT 0x78
/** Failed to execute database query */
#define BMKT_RSP_QUERY_FAIL 0x79
/*! @} */
/*! \addtogroup deluser
* Response IDs returned by delete fingerprint of specific user operation
* @{
*/
* Response IDs returned by delete fingerprint of specific user operation
* @{
*/
/** Failed to delete a users fingerprint template from the database */
#define BMKT_RSP_DEL_USER_FP_FAIL 0x82
/**
* BMKT_RSP_DEL_USER_FP_OK:
* Fingerprint template successfully deleted from the database.
* Returns the user ID and finger ID deleted. If value of finger ID is set equal to 0,
* then all fingerprint templates for that user have been deleted from the database
* <br>Payload data represented in \ref bmkt_del_user_resp_t struct
*/
* BMKT_RSP_DEL_USER_FP_OK:
* Fingerprint template successfully deleted from the database.
* Returns the user ID and finger ID deleted. If value of finger ID is set equal to 0,
* then all fingerprint templates for that user have been deleted from the database
* <br>Payload data represented in \ref bmkt_del_user_resp_t struct
*/
#define BMKT_RSP_DEL_USER_FP_OK 0x83
/*! @} */
/*! \addtogroup delfulldb
* Response IDs returned by delete entire fingerprint template DB operation
* @{
*/
* Response IDs returned by delete entire fingerprint template DB operation
* @{
*/
/** Failed to erase entire fingerprint template database */
#define BMKT_RSP_DEL_FULL_DB_FAIL 0x85
/** Successfully erased entire fingerprint template database */
#define BMKT_RSP_DEL_FULL_DB_OK 0x86
/**
* BMKT_RSP_DELETE_PROGRESS:
* Notify progress made during the on-going deletion of the full template database
* <br>Payload data represented in \ref bmkt_del_all_users_resp_t struct
*/
* BMKT_RSP_DELETE_PROGRESS:
* Notify progress made during the on-going deletion of the full template database
* <br>Payload data represented in \ref bmkt_del_all_users_resp_t struct
*/
#define BMKT_RSP_DELETE_PROGRESS 0x87
/*! @} */
/**
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
* Response ID returned by repeate last response operation
* <br>Failed to retrieve and re-send last response
*/
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
* Response ID returned by repeate last response operation
* <br>Failed to retrieve and re-send last response
*/
#define BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL 0x93
/*! \addtogroup pwrdwn
* Response IDs returned by power down notify operation
* @{
*/
* Response IDs returned by power down notify operation
* @{
*/
/** Fingerprint sensor module is ready to be powered down */
#define BMKT_RSP_POWER_DOWN_READY 0xA2
/** Failed to go into power down mode */
@ -253,24 +253,24 @@
/*! @} */
/*! \addtogroup versioninfo
* Response IDs returned by get version operation
* @{
*/
* Response IDs returned by get version operation
* @{
*/
/**
* BMKT_RSP_VERSION_INFO:
* System version information of the fingerprint sensor module
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
*/
* BMKT_RSP_VERSION_INFO:
* System version information of the fingerprint sensor module
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
*/
#define BMKT_RSP_VERSION_INFO 0xB2
/* Failed to retrieve and send last response */
#define BMKT_RSP_GET_VERSION_FAIL 0xB3
/*! @} */
/**
* BMKT_RSP_GENERAL_ERROR:
* Not tied to a specific command-response session.
* <br>Could be caused by corrupt or truncated command message
*/
* BMKT_RSP_GENERAL_ERROR:
* Not tied to a specific command-response session.
* <br>Could be caused by corrupt or truncated command message
*/
#define BMKT_RSP_GENERAL_ERROR 0xC1
#define BMKT_RSP_DISABLE_PAIRING_FAIL 0xC3
#define BMKT_RSP_DISABLE_PAIRING_OK 0xC4
@ -278,44 +278,44 @@
#define BMKT_RSP_SENSOR_PAIRING_REPORT 0xC7
/*! \addtogroup versioninfo
* Response IDs returned by get sensor module status operation
* @{
*/
* Response IDs returned by get sensor module status operation
* @{
*/
/**
* BMKT_RSP_SENSOR_STATUS_REPORT:
* Response returning the current status of the sensor module
* <br>Payload data represented in bmkt_XXX struct
*/
* BMKT_RSP_SENSOR_STATUS_REPORT:
* Response returning the current status of the sensor module
* <br>Payload data represented in bmkt_XXX struct
*/
#define BMKT_RSP_SENSOR_STATUS_REPORT 0xD2
/** Failed to retrieve sensor status */
#define BMKT_RSP_SENSOR_STATUS_FAIL 0xD3
/*! @} */
/**
* BMKT_RSP_SEND_NEXT_USER_ID:
* Response ID returned by identify user in order operation
* <br>Notify to send the next batch of user IDs in the priority list
*/
* BMKT_RSP_SEND_NEXT_USER_ID:
* Response ID returned by identify user in order operation
* <br>Notify to send the next batch of user IDs in the priority list
*/
#define BMKT_RSP_SEND_NEXT_USER_ID 0xE2
/**
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
* Response IDs returned by retrieve final result operation
* <br>Failed to retrieve and re-send cached final result
*/
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
* Response IDs returned by retrieve final result operation
* <br>Failed to retrieve and re-send cached final result
*/
#define BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL 0xE5
/**
* Response payload data structure returned by sensor initialization operation.
*/
* Response payload data structure returned by sensor initialization operation.
*/
typedef struct bmkt_init_resp
{
uint8_t finger_presence; /**< Indicates finger existence on the sensor during startup */
} bmkt_init_resp_t;
/**
* bmkt_enroll_resp:
* Response payload data structure returned by enrollment operation.
*/
* bmkt_enroll_resp:
* Response payload data structure returned by enrollment operation.
*/
typedef struct bmkt_enroll_resp
{
int progress; /**< Shows current progress stutus [0-100] */
@ -324,9 +324,9 @@ typedef struct bmkt_enroll_resp
} bmkt_enroll_resp_t;
/**
* bmkt_auth_resp:
* Response payload data structure returned by identify and verify operations.
*/
* bmkt_auth_resp:
* Response payload data structure returned by identify and verify operations.
*/
struct bmkt_auth_resp
{
double match_result; /**< match result returned by matcher */
@ -338,9 +338,9 @@ typedef struct bmkt_auth_resp bmkt_verify_resp_t; /**< Returned by verify */
typedef struct bmkt_auth_resp bmkt_identify_resp_t; /**< Returned by identify */
/**
* bmkt_fps_mode_resp:
* Response payload data structure returned by get fingerprint mode operation.
*/
* bmkt_fps_mode_resp:
* Response payload data structure returned by get fingerprint mode operation.
*/
typedef struct bmkt_fps_mode_resp
{
uint8_t mode; /**< One of the Level I bmkt_mode_t values */
@ -350,9 +350,9 @@ typedef struct bmkt_fps_mode_resp
} bmkt_fps_mode_resp_t;
/**
* bmkt_get_version_resp:
* Response payload data structure returned by get version operation.
*/
* bmkt_get_version_resp:
* Response payload data structure returned by get version operation.
*/
typedef struct bmkt_get_version_resp
{
uint8_t part[BMKT_PART_NUM_LEN]; /**< Software Part Number */
@ -363,9 +363,9 @@ typedef struct bmkt_get_version_resp
} bmkt_get_version_resp_t;
/**
* bmkt_get_db_capacity_resp:
* Response payload data structure returned by get DB capacity operation.
*/
* bmkt_get_db_capacity_resp:
* Response payload data structure returned by get DB capacity operation.
*/
typedef struct bmkt_get_db_capacity_resp
{
uint8_t total; /**< Total Available Capacity: Total number of template records that can be stored */
@ -375,47 +375,46 @@ typedef struct bmkt_get_db_capacity_resp
} bmkt_get_db_capacity_resp_t;
/**
* bmkt_sec_level:
* Security level values.
*/
typedef enum bmkt_sec_level
{
* bmkt_sec_level:
* Security level values.
*/
typedef enum bmkt_sec_level {
BMKT_SECURITY_LEVEL_LOW = 0x10,
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
BMKT_SECURITY_LEVEL_HIGH = 0x60,
} bmkt_sec_level_t;
/**
* bmkt_set_sec_level_resp:
* Response payload data structure returned by get/set security level operations.
*/
* bmkt_set_sec_level_resp:
* Response payload data structure returned by get/set security level operations.
*/
typedef struct bmkt_set_sec_level_resp
{
bmkt_sec_level_t sec_level; /**< One of the bmkt_sec_level_t values */
} bmkt_set_sec_level_resp_t;
/**
* bmkt_del_all_users_resp:
* Response payload data structure returned by delete all enrolled users operation.
*/
* bmkt_del_all_users_resp:
* Response payload data structure returned by delete all enrolled users operation.
*/
typedef struct bmkt_del_all_users_resp
{
int progress; /**< Progress indicator as a percentage */
} bmkt_del_all_users_resp_t;
/**
* bmkt_del_user_resp:
* Response payload data structure returned by delete enrolled user operation.
*/
* bmkt_del_user_resp:
* Response payload data structure returned by delete enrolled user operation.
*/
typedef struct bmkt_del_user_resp
{
int progress; /**< Progress indicator as a percentage */
} bmkt_del_user_resp_t;
/**
* bmkt_enroll_template:
* Structure of enrolled users template record data.
*/
* bmkt_enroll_template:
* Structure of enrolled users template record data.
*/
typedef struct bmkt_enroll_template
{
uint8_t user_id_len; /**< Length of user_id string */
@ -425,9 +424,9 @@ typedef struct bmkt_enroll_template
} bmkt_enroll_template_t;
/**
* bmkt_enroll_templates_resp:
* Response payload data structure returned by get enrolled user list operation.
*/
* bmkt_enroll_templates_resp:
* Response payload data structure returned by get enrolled user list operation.
*/
typedef struct bmkt_enroll_templates_resp
{
uint8_t total_query_messages; /**< Total query response messages */
@ -436,9 +435,9 @@ typedef struct bmkt_enroll_templates_resp
} bmkt_enroll_templates_resp_t;
/**
* bmkt_enrolled_fingers:
* Structure of template record status corresponding to each enrolled finger.
*/
* bmkt_enrolled_fingers:
* Structure of template record status corresponding to each enrolled finger.
*/
typedef struct bmkt_enrolled_fingers
{
uint8_t finger_id; /**< ID of enrolled finger */
@ -446,19 +445,20 @@ typedef struct bmkt_enrolled_fingers
} bmkt_enrolled_fingers_t;
/**
* bmkt_enrolled_fingers_resp:
* Response payload data structure returned by get enrolled fingers operation.
*/
* bmkt_enrolled_fingers_resp:
* Response payload data structure returned by get enrolled fingers operation.
*/
typedef struct bmkt_enrolled_fingers_resp
{
bmkt_enrolled_fingers_t fingers[10]; /**< List of enroled fingers, max number of supported fingers per user is 10 */
} bmkt_enrolled_fingers_resp_t;
/**
* bmkt_response_data_t:
* Union combining all response payload data types.
*/
typedef union {
* bmkt_response_data_t:
* Union combining all response payload data types.
*/
typedef union
{
bmkt_init_resp_t init_resp;
bmkt_enroll_resp_t enroll_resp;
bmkt_verify_resp_t verify_resp;
@ -474,10 +474,10 @@ typedef union {
} bmkt_response_data_t;
/**
* bmkt_response:
* Structure to abstract different response structure types in one API
* to be used in bmkt_resp_cb_t callback function.
*/
* bmkt_response:
* Structure to abstract different response structure types in one API
* to be used in bmkt_resp_cb_t callback function.
*/
typedef struct bmkt_response
{
int response_id; /**< Response message ID, one of th BMKT_RSP_XXX */

View file

@ -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,
@ -66,15 +65,23 @@ typedef struct bmkt_sensor
bmkt_op_state_t op_state;
} bmkt_sensor_t;
int bmkt_sensor_open(bmkt_sensor_t *sensor,
bmkt_general_error_cb_t err_cb, void *err_cb_ctx);
int bmkt_sensor_close(bmkt_sensor_t *sensor);
int bmkt_sensor_open (bmkt_sensor_t *sensor,
bmkt_general_error_cb_t err_cb,
void *err_cb_ctx);
int bmkt_sensor_close (bmkt_sensor_t *sensor);
int bmkt_sensor_init_fps(bmkt_sensor_t *sensor);
int bmkt_sensor_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);
int bmkt_sensor_send_async_read_command (bmkt_sensor_t *sensor);
#endif /* _SENSOR_H_ */

View file

@ -25,9 +25,9 @@
#include "synaptics.h"
#include "bmkt_message.h"
G_DEFINE_TYPE(FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
G_DEFINE_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FP_TYPE_DEVICE)
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0xBD, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
@ -46,16 +46,18 @@ 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;
}
res = bmkt_parse_message_header(&transfer->buffer[SENSOR_FW_REPLY_HEADER_LEN],
res = bmkt_parse_message_header (&transfer->buffer[SENSOR_FW_REPLY_HEADER_LEN],
transfer->actual_length - SENSOR_FW_REPLY_HEADER_LEN,
&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,22 +123,26 @@ 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. */
err = FP_READ_UINT16_BE(msg_resp.payload);
err = FP_READ_UINT16_BE (msg_resp.payload);
fp_warn("Received General Error %d from the sensor", (guint) err);
fp_warn ("Received General Error %d from the sensor", (guint) err);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"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;
@ -181,16 +201,18 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
}
static void
synaptics_cmd_run_state(FpiSsm *ssm,
synaptics_cmd_run_state (FpiSsm *ssm,
FpDevice *dev,
void *user_data)
{
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");
}
}
@ -287,7 +317,7 @@ static void
synaptics_sensor_cmd (FpiDeviceSynaptics *self,
gint seq_num,
guint8 msg_id,
const guint8* payload,
const guint8 * payload,
gssize payload_len,
SynCmdMsgCallback callback)
{
@ -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) {
self->last_seq_num = MAX(1, self->last_seq_num + 1);
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) {
g_assert(callback == NULL);
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);
@ -387,7 +426,7 @@ parse_print_data (GVariant *data,
if (!g_variant_check_format_string (data, "(y@ay)", FALSE))
return FALSE;
g_variant_get(data,
g_variant_get (data,
"(y@ay)",
finger,
&user_id_var);
@ -404,13 +443,14 @@ parse_print_data (GVariant *data,
}
static void
list_msg_cb(FpiDeviceSynaptics *self,
list_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
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,14 +461,17 @@ list_msg_cb(FpiDeviceSynaptics *self,
switch (resp->response_id)
{
case BMKT_RSP_QUERY_FAIL:
if (resp->result == BMKT_FP_DATABASE_EMPTY) {
fp_info("Database is 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 {
fp_info("Failed to query enrolled users: %d", resp->result);
}
else
{
fp_info ("Failed to query enrolled users: %d", resp->result);
g_clear_pointer (&self->list_result, g_ptr_array_free);
fpi_device_list_complete (FP_DEVICE (self),
NULL,
@ -436,14 +479,16 @@ list_msg_cb(FpiDeviceSynaptics *self,
"Failed to query enrolled users"));
}
break;
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
fp_info("Query complete!");
fp_info ("Query complete!");
fpi_device_list_complete (FP_DEVICE (self),
g_steal_pointer (&self->list_result),
NULL);
break;
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
for (int n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
@ -456,7 +501,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
if (get_enroll_templates_resp->templates[n].user_id_len == 0)
continue;
fp_info("![query %d of %d] template %d: status=0x%x, userId=%s, fingerId=%d",
fp_info ("![query %d of %d] template %d: status=0x%x, userId=%s, fingerId=%d",
get_enroll_templates_resp->query_sequence,
get_enroll_templates_resp->total_query_messages,
n,
@ -481,9 +526,10 @@ list_msg_cb(FpiDeviceSynaptics *self,
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (userid, "FP1-") && strlen(userid) >= 24 &&
userid[12] == '-' && userid[14] == '-' && userid[23] == '-') {
g_autofree gchar *copy = g_strdup(userid);
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
{
g_autofree gchar *copy = g_strdup (userid);
gint32 date_ymd;
GDate *date = NULL;
gint32 finger;
@ -510,7 +556,7 @@ list_msg_cb(FpiDeviceSynaptics *self,
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen(username) > 0 && g_strcmp0 (username, "nobody") != 0)
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
}
@ -529,30 +575,32 @@ list_msg_cb(FpiDeviceSynaptics *self,
}
static void
list(FpDevice *device)
list (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
G_DEBUG_HERE();
G_DEBUG_HERE ();
self->list_result = g_ptr_array_new_with_free_func (g_object_unref);
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
}
static void
verify_msg_cb(FpiDeviceSynaptics *self,
verify_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
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,
@ -565,38 +613,45 @@ verify_msg_cb(FpiDeviceSynaptics *self,
switch (resp->response_id)
{
case BMKT_RSP_VERIFY_READY:
fp_info("Place Finger on the Sensor!");
fp_info ("Place Finger on the Sensor!");
break;
case BMKT_RSP_CAPTURE_COMPLETE:
fp_info("Fingerprint image capture complete!");
fp_info ("Fingerprint image capture complete!");
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) {
fp_info("Print is not in database");
}
else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS)
{
fp_info ("Print is not in database");
fpi_device_verify_complete (device,
FPI_MATCH_ERROR,
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
} else {
fp_warn("Verify has failed: %d", resp->result);
}
else
{
fp_warn ("Verify has failed: %d", resp->result);
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
}
break;
case BMKT_RSP_VERIFY_OK:
fp_info("Verify was successful! for user: %s finger: %d score: %f",
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
fpi_device_verify_complete (device, FPI_MATCH_SUCCESS, NULL, NULL);
break;
@ -604,10 +659,11 @@ verify_msg_cb(FpiDeviceSynaptics *self,
}
static void
verify(FpDevice *device)
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,
@ -625,20 +682,21 @@ verify(FpDevice *device)
return;
}
G_DEBUG_HERE();
G_DEBUG_HERE ();
synaptics_sensor_cmd (self, 0, BMKT_CMD_VERIFY_USER, user_id, user_id_len, verify_msg_cb);
}
static void
enroll_msg_cb(FpiDeviceSynaptics *self,
enroll_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
FpDevice *device = FP_DEVICE (self);
bmkt_enroll_resp_t *enroll_resp;
if (error) {
if (error)
{
fpi_device_enroll_complete (device, NULL, error);
return;
}
@ -650,67 +708,80 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
case BMKT_RSP_ENROLL_READY:
{
self->enroll_stage = 0;
fp_info("Place Finger on the Sensor!");
fp_info ("Place Finger on the Sensor!");
break;
}
case BMKT_RSP_CAPTURE_COMPLETE:
{
fp_info("Fingerprint image capture complete!");
fp_info ("Fingerprint image capture complete!");
break;
}
case BMKT_RSP_ENROLL_REPORT:
{
gint done_stages;
fp_info("Enrollment is %d %% ", enroll_resp->progress);
fp_info ("Enrollment is %d %% ", enroll_resp->progress);
done_stages = (enroll_resp->progress * ENROLL_SAMPLES + 99) / 100;
if (enroll_resp->progress < 100)
done_stages = MIN(done_stages, ENROLL_SAMPLES - 1);
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
/* Emit a retry error if there has been no discernable
* 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!");
fp_info ("Enrollment has been paused!");
break;
}
case BMKT_RSP_ENROLL_RESUMED:
{
fp_info("Enrollment has been resumed!");
fp_info ("Enrollment has been resumed!");
break;
}
case BMKT_RSP_ENROLL_FAIL:
{
fp_info("Enrollment has failed!: %d", resp->result);
fp_info ("Enrollment has failed!: %d", resp->result);
if (resp->result == BMKT_FP_DATABASE_FULL)
{
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;
fp_info("Enrollment was successful!");
fp_info ("Enrollment was successful!");
fpi_device_get_enroll_data (device, &print);
@ -723,7 +794,7 @@ enroll_msg_cb(FpiDeviceSynaptics *self,
#define TEMPLATE_ID_SIZE 20
static void
enroll(FpDevice *device)
enroll (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
FpPrint *print = NULL;
@ -740,14 +811,17 @@ enroll(FpDevice *device)
fpi_device_get_enroll_data (device, &print);
G_DEBUG_HERE();
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;
@ -760,7 +834,7 @@ enroll(FpDevice *device)
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int();
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
@ -769,7 +843,7 @@ enroll(FpDevice *device)
username);
user_id_len = strlen (user_id);
user_id_len = MIN(BMKT_MAX_USER_ID_LEN, user_id_len);
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
/* We currently always use finger 1 from the devices piont of view */
finger = 1;
@ -787,9 +861,9 @@ enroll(FpDevice *device)
g_object_set (print, "fp-data", data, NULL);
g_object_set (print, "description", user_id, NULL);
g_debug("user_id: %s, finger: %d", user_id, finger);
g_debug ("user_id: %s, finger: %d", user_id, finger);
payload = g_malloc0(user_id_len + 2);
payload = g_malloc0 (user_id_len + 2);
/* Backup options are not supported for Prometheus */
payload[0] = 0;
@ -800,14 +874,15 @@ enroll(FpDevice *device)
}
static void
delete_msg_cb(FpiDeviceSynaptics *self,
delete_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
FpDevice *device = FP_DEVICE (self);
bmkt_del_user_resp_t *del_user_resp;
if (error) {
if (error)
{
fpi_device_delete_complete (device, error);
return;
}
@ -817,11 +892,12 @@ delete_msg_cb(FpiDeviceSynaptics *self,
switch (resp->response_id)
{
case BMKT_RSP_DELETE_PROGRESS:
fp_info("Deleting Enrolled Users is %d%% complete",
fp_info ("Deleting Enrolled Users is %d%% complete",
del_user_resp->progress);
break;
case BMKT_RSP_DEL_USER_FP_FAIL:
fp_info("Failed to delete enrolled user: %d", resp->result);
fp_info ("Failed to delete enrolled user: %d", resp->result);
if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
fpi_device_delete_complete (device,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
@ -829,18 +905,20 @@ delete_msg_cb(FpiDeviceSynaptics *self,
fpi_device_delete_complete (device,
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
break;
case BMKT_RSP_DEL_USER_FP_OK:
fp_info("Successfully deleted enrolled user");
fp_info ("Successfully deleted enrolled user");
fpi_device_delete_complete (device, NULL);
break;
}
}
static void
delete_print(FpDevice *device)
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,13 +929,14 @@ 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;
}
G_DEBUG_HERE();
G_DEBUG_HERE ();
payload = g_malloc0 (1 + user_id_len);
payload[0] = finger;
@ -867,7 +946,7 @@ delete_print(FpDevice *device)
}
static void
dev_probe(FpDevice *device)
dev_probe (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
GUsbDevice *usb_dev;
@ -879,21 +958,23 @@ dev_probe(FpDevice *device)
gboolean read_ok = TRUE;
g_autofree gchar *serial = NULL;
G_DEBUG_HERE();
G_DEBUG_HERE ();
/* Claim usb interface */
usb_dev = fpi_device_get_usb_device(device);
if (!g_usb_device_open (usb_dev, &error)) {
usb_dev = fpi_device_get_usb_device (device);
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;
}
if (!g_usb_device_claim_interface (fpi_device_get_usb_device(device), 0, 0, &error))
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
goto err_close;
/* TODO: Do not do this synchronous. */
@ -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;
@ -935,25 +1018,26 @@ dev_probe(FpDevice *device)
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.formal_release);
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.platform);
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.patch);
if (fpi_byte_reader_get_data (&reader, sizeof(self->mis_version.serial_number), &data))
memcpy (self->mis_version.serial_number, data, sizeof(self->mis_version.serial_number));
if (fpi_byte_reader_get_data (&reader, sizeof (self->mis_version.serial_number), &data))
memcpy (self->mis_version.serial_number, data, sizeof (self->mis_version.serial_number));
else
read_ok = FALSE;
read_ok &= fpi_byte_reader_get_uint16_le (&reader, &self->mis_version.security);
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.iface);
read_ok &= fpi_byte_reader_get_uint8 (&reader, &self->mis_version.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;
}
fp_dbg("Build Time: %d", self->mis_version.build_time);
fp_dbg("Build Num: %d", self->mis_version.build_num);
fp_dbg("Version: %d.%d", self->mis_version.version_major, self->mis_version.version_minor);
fp_dbg("Target: %d", self->mis_version.target);
fp_dbg("Product: %d", self->mis_version.product);
fp_dbg ("Build Time: %d", self->mis_version.build_time);
fp_dbg ("Build Num: %d", self->mis_version.build_num);
fp_dbg ("Version: %d.%d", self->mis_version.version_major, self->mis_version.version_minor);
fp_dbg ("Target: %d", self->mis_version.target);
fp_dbg ("Product: %d", self->mis_version.product);
fpi_usb_transfer_unref (transfer);
@ -995,48 +1079,55 @@ err_close:
}
static void
fps_init_msg_cb(FpiDeviceSynaptics *self,
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));
}
}
static void
fps_deinit_cb(FpiDeviceSynaptics *self,
fps_deinit_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
GError *error)
{
/* Release usb interface */
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE (self)), 0, 0, &error);
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (self)), 0, 0, &error);
g_clear_object (&self->interrupt_cancellable);
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");
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);
fp_info ("Failed to go to power down mode: %d", resp->result);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Power down failed");
break;
}
}
fpi_device_close_complete(FP_DEVICE (self), error);
fpi_device_close_complete (FP_DEVICE (self), error);
}
static void
@ -1045,7 +1136,7 @@ dev_init (FpDevice *device)
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
GError *error = NULL;
G_DEBUG_HERE();
G_DEBUG_HERE ();
self->interrupt_cancellable = g_cancellable_new ();
@ -1065,19 +1156,19 @@ error:
}
static void
dev_exit(FpDevice *device)
dev_exit (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
G_DEBUG_HERE();
G_DEBUG_HERE ();
synaptics_sensor_cmd (self, 0, BMKT_CMD_POWER_DOWN_NOTIFY, NULL, 0, fps_deinit_cb);
}
static void
cancel(FpDevice *dev)
cancel (FpDevice *dev)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS(dev);
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (dev);
/* We just send out a cancel command and hope for the best. */
synaptics_sensor_cmd (self, -1, BMKT_CMD_CANCEL_OP, NULL, 0, NULL);
@ -1091,12 +1182,14 @@ 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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
fpi_device_synaptics_class_init (FpiDeviceSynapticsClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
dev_class->id = FP_COMPONENT;
dev_class->full_name = SYNAPTICS_DRIVER_FULLNAME;

View file

@ -24,7 +24,7 @@
#define SYNAPTICS_VENDOR_ID 0x06cb
G_DECLARE_FINAL_TYPE(FpiDeviceSynaptics, fpi_device_synaptics, FPI, DEVICE_SYNAPTICS, FpDevice)
G_DECLARE_FINAL_TYPE (FpiDeviceSynaptics, fpi_device_synaptics, FPI, DEVICE_SYNAPTICS, FpDevice)
#define MAX_TRANSFER_LEN 263 + 1 /* SPI Header */ + 2 /* VCSFW header */
@ -77,20 +77,18 @@ 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 ,
SYNA_STATE_IDENTIFY ,
SYNA_STATE_IDENTIFY_DELAY_RESULT ,
SYNA_STATE_VERIFY ,
SYNA_STATE_VERIFY_DELAY_RESULT ,
SYNA_STATE_DELETE ,
SYNA_STATE_IDLE,
SYNA_STATE_ENROLL,
SYNA_STATE_IDENTIFY,
SYNA_STATE_IDENTIFY_DELAY_RESULT,
SYNA_STATE_VERIFY,
SYNA_STATE_VERIFY_DELAY_RESULT,
SYNA_STATE_DELETE,
} syna_state_t;
typedef 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
{

View file

@ -56,9 +56,10 @@ static const uint16_t crc_table[256] = {
};
uint16_t
udf_crc(unsigned char *buffer, size_t size)
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++]);

View file

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

View file

@ -27,7 +27,8 @@
#define IMG_WIDTH_1000 288
#define IMG_WIDTH_1001 216
struct sonly_regwrite {
struct sonly_regwrite
{
guint8 reg;
guint8 value;
};
@ -71,7 +72,7 @@ static const struct sonly_regwrite awfsm_2016_writev_3[] = {
static const struct sonly_regwrite awfsm_2016_writev_4[] = {
{ 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf },
{ 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\
{ 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 }, \
{ 0x05, 0x00 }, { 0x0b, 0x00 },
/* enter finger detection mode */

View file

@ -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;
@ -40,18 +41,19 @@ struct _FpiDeviceUpektc {
int init_idx;
int sum_threshold;
};
G_DECLARE_FINAL_TYPE(FpiDeviceUpektc, fpi_device_upektc, FPI, DEVICE_UPEKTC,
G_DECLARE_FINAL_TYPE (FpiDeviceUpektc, fpi_device_upektc, FPI, DEVICE_UPEKTC,
FpImageDevice);
G_DEFINE_TYPE(FpiDeviceUpektc, fpi_device_upektc, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpiDeviceUpektc, fpi_device_upektc, FP_TYPE_IMAGE_DEVICE);
enum upektc_driver_data {
UPEKTC_2015,
UPEKTC_3001,
};
static void start_capture(FpImageDevice *dev);
static void complete_deactivation(FpImageDevice *dev, GError *error);
static void start_finger_detection(FpImageDevice *dev);
static void start_capture (FpImageDevice *dev);
static void complete_deactivation (FpImageDevice *dev,
GError *error);
static void start_finger_detection (FpImageDevice *dev);
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -62,176 +64,194 @@ enum activate_states {
};
static void
upektc_next_init_cmd(FpiSsm *ssm,
upektc_next_init_cmd (FpiSsm *ssm,
FpImageDevice *dev)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
self->init_idx += 1;
if (self->init_idx == self->setup_commands_len)
fpi_ssm_mark_completed(ssm);
fpi_ssm_mark_completed (ssm);
else
fpi_ssm_jump_to_state(ssm, WRITE_INIT);
fpi_ssm_jump_to_state (ssm, WRITE_INIT);
}
static void write_init_cb(FpiUsbTransfer *transfer, FpDevice *device,
static void
write_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
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);
fpi_ssm_next_state (transfer->ssm);
else
upektc_next_init_cmd(transfer->ssm, dev);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
upektc_next_init_cmd (transfer->ssm, dev);
}
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);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
if (!error)
upektc_next_init_cmd(transfer->ssm, dev);
upektc_next_init_cmd (transfer->ssm, dev);
else
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
static void
activate_run_state (FpiSsm *ssm, FpDevice *dev, void *user_data)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
switch (fpi_ssm_get_cur_state(ssm)) {
switch (fpi_ssm_get_cur_state (ssm))
{
case WRITE_INIT:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer,
fpi_usb_transfer_fill_bulk_full (transfer,
self->ep_out,
(unsigned char *) self->setup_commands[self->init_idx].cmd,
UPEKTC_CMD_LEN,
NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
write_init_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk (transfer,
self->ep_in,
self->setup_commands[self->init_idx].response_len);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
read_init_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
}
}
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);
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
fpi_image_device_activate_complete(dev, error);
fpi_image_device_activate_complete (dev, error);
if (!error)
start_finger_detection(dev);
fpi_ssm_free(ssm);
start_finger_detection (dev);
fpi_ssm_free (ssm);
}
/****** 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);
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);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
if (error) {
fp_dbg("data transfer status %s\n", error->message);
fpi_image_device_session_error(dev, 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 {
fpi_image_device_report_finger_status (dev, TRUE);
start_capture (dev);
}
else
{
/* no finger, poll for a new histogram */
start_finger_detection(dev);
start_finger_detection (dev);
}
}
static void finger_det_cmd_cb(FpiUsbTransfer *t, FpDevice *device,
static void
finger_det_cmd_cb (FpiUsbTransfer *t, FpDevice *device,
gpointer user_data, GError *error)
{
FpiUsbTransfer *transfer;
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
if (error) {
fp_dbg("req transfer status %s\n", error->message);
fpi_image_device_session_error(dev, error);
if (error)
{
fp_dbg ("req transfer status %s\n", error->message);
fpi_image_device_session_error (dev, error);
return;
}
transfer = fpi_usb_transfer_new (device);
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk(transfer, self->ep_in,
fpi_usb_transfer_fill_bulk (transfer, self->ep_in,
IMAGE_SIZE);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
static void start_finger_detection(FpImageDevice *dev)
static void
start_finger_detection (FpImageDevice *dev)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
FpiUsbTransfer *transfer;
G_DEBUG_HERE();
if (self->deactivating) {
complete_deactivation(dev, NULL);
G_DEBUG_HERE ();
if (self->deactivating)
{
complete_deactivation (dev, NULL);
return;
}
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk_full(transfer, self->ep_out,
(unsigned char *)scan_cmd,
fpi_usb_transfer_fill_bulk_full (transfer, self->ep_out,
(unsigned char *) scan_cmd,
UPEKTC_CMD_LEN, NULL);
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_cmd_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@ -242,185 +262,209 @@ 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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpImage *img;
if (error) {
fp_dbg("request is not completed, %s", error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
if (error)
{
fp_dbg ("request is not completed, %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
img = fp_image_new(IMAGE_WIDTH, IMAGE_HEIGHT);
memcpy(img->data, transfer->buffer, IMAGE_SIZE);
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev, FALSE);
fpi_ssm_mark_completed(transfer->ssm);
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
memcpy (img->data, transfer->buffer, IMAGE_SIZE);
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev, FALSE);
fpi_ssm_mark_completed (transfer->ssm);
}
static void capture_run_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
static void
capture_run_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(_dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (_dev);
switch (fpi_ssm_get_cur_state(ssm)) {
switch (fpi_ssm_get_cur_state (ssm))
{
case CAPTURE_WRITE_CMD:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
fpi_usb_transfer_fill_bulk_full(transfer, self->ep_out,
(unsigned char *)scan_cmd,
fpi_usb_transfer_fill_bulk_full (transfer, self->ep_out,
(unsigned char *) scan_cmd,
UPEKTC_CMD_LEN, NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_cmd_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case CAPTURE_READ_DATA:
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(_dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (_dev);
fpi_usb_transfer_fill_bulk(transfer, self->ep_in,
fpi_usb_transfer_fill_bulk (transfer, self->ep_in,
IMAGE_SIZE);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_data_cb, NULL);
fpi_usb_transfer_unref(transfer);
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;
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(_dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (_dev);
fp_dbg("Capture completed");
fp_dbg ("Capture completed");
if (self->deactivating)
complete_deactivation(dev, error);
complete_deactivation (dev, error);
else if (error)
fpi_image_device_session_error(dev, error);
fpi_image_device_session_error (dev, error);
else
start_finger_detection(dev);
start_finger_detection (dev);
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
FpiSsm *ssm;
if (self->deactivating) {
complete_deactivation(dev, NULL);
if (self->deactivating)
{
complete_deactivation (dev, NULL);
return;
}
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
G_DEBUG_HERE();
fpi_ssm_start(ssm, capture_sm_complete);
G_DEBUG_HERE ();
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,
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);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
self->deactivating = TRUE;
}
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();
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
G_DEBUG_HERE ();
self->deactivating = FALSE;
fpi_image_device_deactivate_complete(dev, error);
fpi_image_device_deactivate_complete (dev, error);
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC(dev);
FpiDeviceUpektc *self = FPI_DEVICE_UPEKTC (dev);
guint64 driver_data = fpi_device_get_driver_data (FP_DEVICE (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)) {
fpi_image_device_open_complete(dev, 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;
self->setup_commands = upektc_setup_commands;
self->setup_commands_len = G_N_ELEMENTS(upektc_setup_commands);
self->setup_commands_len = G_N_ELEMENTS (upektc_setup_commands);
self->sum_threshold = UPEKTC_SUM_THRESHOLD;
break;
case UPEKTC_3001:
self->ep_in = UPEKET_EP_IN;
self->ep_out = UPEKET_EP_OUT;
self->setup_commands = upeket_setup_commands;
self->setup_commands_len = G_N_ELEMENTS(upeket_setup_commands);
self->setup_commands_len = G_N_ELEMENTS (upeket_setup_commands);
self->sum_threshold = UPEKET_SUM_THRESHOLD;
break;
default:
fp_err("Device variant %lu is not known\n", driver_data);
fp_err ("Device variant %lu is not known\n", driver_data);
g_assert_not_reached ();
fpi_image_device_open_complete(dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
fpi_image_device_open_complete (dev, fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
return;
}
fpi_image_device_open_complete(dev, NULL);
fpi_image_device_open_complete (dev, NULL);
}
static void dev_deinit(FpImageDevice *dev)
static void
dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = 0x0483, .pid = 0x2015, .driver_data = UPEKTC_2015 },
{ .vid = 0x147e, .pid = 0x3001, .driver_data = UPEKTC_3001 },
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "upektc";
dev_class->full_name = "UPEK TouchChip/Eikon Touch 300";

View file

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

View file

@ -23,8 +23,8 @@
#include "upek_proto.h"
#include "upektc_img.h"
static void start_capture(FpImageDevice *dev);
static void start_deactivation(FpImageDevice *dev);
static void start_capture (FpImageDevice *dev);
static void start_deactivation (FpImageDevice *dev);
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
@ -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];
@ -50,13 +51,14 @@ struct _FpiDeviceUpektcImg {
size_t response_rest;
gboolean deactivating;
};
G_DECLARE_FINAL_TYPE(FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
G_DECLARE_FINAL_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FPI,
DEVICE_UPEKTC_IMG, FpImageDevice);
G_DEFINE_TYPE(FpiDeviceUpektcImg, fpi_device_upektc_img, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FP_TYPE_IMAGE_DEVICE);
/****** HELPERS ******/
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,58 +68,59 @@ 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);
uint16_t crc = udf_crc (cmd_buf + 4, size - 6);
cmd_buf[size - 2] = (crc & 0x00ff);
cmd_buf[size - 1] = (crc & 0xff00) >> 8;
}
static void
upektc_img_submit_req(FpiSsm *ssm,
upektc_img_submit_req (FpiSsm *ssm,
FpImageDevice *dev,
const unsigned char *buf,
size_t buf_size,
unsigned char seq,
FpiUsbTransferCallback cb)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
BUG_ON(buf_size > MAX_CMD_SIZE);
BUG_ON (buf_size > MAX_CMD_SIZE);
memcpy(self->cmd, buf, buf_size);
upektc_img_cmd_fix_seq(self->cmd, seq);
upektc_img_cmd_update_crc(self->cmd, buf_size);
memcpy (self->cmd, buf, buf_size);
upektc_img_cmd_fix_seq (self->cmd, seq);
upektc_img_cmd_update_crc (self->cmd, buf_size);
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, self->cmd, buf_size,
fpi_usb_transfer_fill_bulk_full (transfer, EP_OUT, self->cmd, buf_size,
NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
upektc_img_read_data(FpiSsm *ssm,
upektc_img_read_data (FpiSsm *ssm,
FpImageDevice *dev,
size_t buf_size,
size_t buf_offset,
FpiUsbTransferCallback cb)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
BUG_ON(buf_offset + buf_size > MAX_RESPONSE_SIZE);
BUG_ON (buf_offset + buf_size > MAX_RESPONSE_SIZE);
fpi_usb_transfer_fill_bulk_full(transfer, EP_IN,
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN,
self->response + buf_offset, buf_size,
NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@ -133,246 +136,281 @@ 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) {
fpi_ssm_mark_failed(transfer->ssm, 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);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA_TERM);
break;
default:
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
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);
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);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
unsigned char *data = self->response;
FpImage *img;
size_t response_size;
if (error) {
fp_dbg("request is not completed, %s", error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
if (error)
{
fp_dbg ("request is not completed, %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
if (self->deactivating) {
fp_dbg("Deactivate requested\n");
fpi_ssm_mark_completed(transfer->ssm);
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) {
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_get_cur_state(transfer->ssm));
fp_dbg ("request completed, len: %.4x", (gint) transfer->actual_length);
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) {
fp_dbg("Terminating SSM\n");
fpi_ssm_mark_completed(transfer->ssm);
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) {
fp_dbg("response_size is %lu, actual_length is %d\n",
response_size, (gint)transfer->actual_length);
fp_dbg("Waiting for rest of transfer");
BUG_ON(self->response_rest);
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");
BUG_ON (self->response_rest);
self->response_rest = response_size - transfer->actual_length;
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
return;
}
}
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]) {
fp_dbg ("18th byte is %.2x\n", data[18]);
switch (data[18])
{
case 0x0c:
/* no finger */
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_ACK_00_28);
break;
case 0x00:
/* finger is present! */
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_ACK_00_28);
break;
case 0x1e:
/* short scan */
fp_err("short scan, aborting\n");
fpi_image_device_retry_scan(dev,
fp_err ("short scan, aborting\n");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY_TOO_SHORT);
fpi_image_device_report_finger_status(dev,
fpi_image_device_report_finger_status (dev,
FALSE);
fpi_ssm_jump_to_state(transfer->ssm,
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");
fpi_image_device_retry_scan(dev,
fp_err ("too much horisontal movement, aborting\n");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY_CENTER_FINGER);
fpi_image_device_report_finger_status(dev,
fpi_image_device_report_finger_status (dev,
FALSE);
fpi_ssm_jump_to_state(transfer->ssm,
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");
fpi_image_device_retry_scan(dev,
fp_err ("something bad happened, stop scan\n");
fpi_image_device_retry_scan (dev,
FP_DEVICE_RETRY);
fpi_image_device_report_finger_status(dev,
fpi_image_device_report_finger_status (dev,
FALSE);
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_ACK_00_28_TERM);
break;
}
break;
/* Image frame with additional info */
case 0x2c:
fpi_image_device_report_finger_status(dev,
fpi_image_device_report_finger_status (dev,
TRUE);
/* Plain image frame */
case 0x24:
self->image_size +=
upektc_img_process_image_frame(self->image_bits + self->image_size,
upektc_img_process_image_frame (self->image_bits + self->image_size,
data);
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_jump_to_state (transfer->ssm,
CAPTURE_ACK_FRAME);
break;
/* Last image frame */
case 0x20:
self->image_size +=
upektc_img_process_image_frame(self->image_bits + self->image_size,
upektc_img_process_image_frame (self->image_bits + self->image_size,
data);
BUG_ON(self->image_size != IMAGE_SIZE);
fp_dbg("Image size is %lu\n",
BUG_ON (self->image_size != IMAGE_SIZE);
fp_dbg ("Image size is %lu\n",
self->image_size);
img = fp_image_new(IMAGE_WIDTH, IMAGE_HEIGHT);
memcpy(img->data, self->image_bits,
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
memcpy (img->data, self->image_bits,
IMAGE_SIZE);
fpi_image_device_image_captured(dev, img);
fpi_image_device_report_finger_status(dev,
fpi_image_device_image_captured (dev, img);
fpi_image_device_report_finger_status (dev,
FALSE);
fpi_ssm_mark_completed(transfer->ssm);
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));
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);
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));
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);
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),
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)
upektc_img_read_data(ssm, dev, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
upektc_img_read_data (ssm, dev, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb);
else
upektc_img_read_data(ssm, dev, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
upektc_img_read_data (ssm, dev, MAX_RESPONSE_SIZE - SHORT_RESPONSE_SIZE,
SHORT_RESPONSE_SIZE, capture_read_data_cb);
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),
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),
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),
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);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
g_autoptr(GError) error = error_arg;
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
/* Note: We assume that the error is a cancellation in the deactivation case */
if (self->deactivating)
start_deactivation(dev);
start_deactivation (dev);
else if (error)
fpi_image_device_session_error (dev, g_steal_pointer (&error));
else
start_capture(dev);
start_capture (dev);
}
static void start_capture(FpImageDevice *dev)
static void
start_capture (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
FpiSsm *ssm;
self->image_size = 0;
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), capture_run_state,
CAPTURE_NUM_STATES, dev);
fpi_ssm_start(ssm, capture_sm_complete);
fpi_ssm_start (ssm, capture_sm_complete);
}
/****** INITIALIZATION/DEINITIALIZATION ******/
@ -383,68 +421,74 @@ 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) {
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_READ_DATA);
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) {
fpi_ssm_mark_completed(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_mark_completed (transfer->ssm);
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);
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),
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);
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;
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(_dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
fp_dbg("Deactivate completed");
fpi_ssm_free(ssm);
fp_dbg ("Deactivate completed");
fpi_ssm_free (ssm);
self->deactivating = FALSE;
fpi_image_device_deactivate_complete(dev, error);
fpi_image_device_deactivate_complete (dev, error);
}
static void start_deactivation(FpImageDevice *dev)
static void
start_deactivation (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
FpiSsm *ssm;
self->image_size = 0;
ssm = fpi_ssm_new(FP_DEVICE(dev), deactivate_run_state,
ssm = fpi_ssm_new (FP_DEVICE (dev), deactivate_run_state,
DEACTIVATE_NUM_STATES, dev);
fpi_ssm_start(ssm, deactivate_sm_complete);
fpi_ssm_start (ssm, deactivate_sm_complete);
}
enum activate_states {
@ -463,146 +507,161 @@ 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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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) {
fpi_ssm_next_state(transfer->ssm);
} else {
fpi_ssm_mark_failed(transfer->ssm, error);
}
if (!error)
fpi_ssm_next_state (transfer->ssm);
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);
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:
{
transfer = fpi_usb_transfer_new(dev);
transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_control(transfer,
fpi_usb_transfer_fill_control (transfer,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
G_USB_DEVICE_RECIPIENT_DEVICE,
0x0c, 0x100, 0x0400, 1);
transfer->buffer[0] = '\0';
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
init_reqs_ctrl_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
break;
case ACTIVATE_INIT_1:
upektc_img_submit_req(ssm, idev, upek2020_init_1, sizeof(upek2020_init_1),
upektc_img_submit_req (ssm, idev, upek2020_init_1, sizeof (upek2020_init_1),
0, init_reqs_cb);
break;
case ACTIVATE_INIT_2:
upektc_img_submit_req(ssm, idev, upek2020_init_2, sizeof(upek2020_init_2),
upektc_img_submit_req (ssm, idev, upek2020_init_2, sizeof (upek2020_init_2),
0, init_reqs_cb);
break;
case ACTIVATE_INIT_3:
upektc_img_submit_req(ssm, idev, upek2020_init_3, sizeof(upek2020_init_3),
upektc_img_submit_req (ssm, idev, upek2020_init_3, sizeof (upek2020_init_3),
0, init_reqs_cb);
break;
case ACTIVATE_INIT_4:
upektc_img_submit_req(ssm, idev, upek2020_init_4, sizeof(upek2020_init_4),
upektc_img_submit_req (ssm, idev, upek2020_init_4, sizeof (upek2020_init_4),
self->seq, init_reqs_cb);
/* 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:
case ACTIVATE_READ_INIT_2_RESP:
case ACTIVATE_READ_INIT_3_RESP:
case ACTIVATE_READ_INIT_4_RESP:
upektc_img_read_data(ssm, idev, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
upektc_img_read_data (ssm, idev, SHORT_RESPONSE_SIZE, 0, init_read_data_cb);
break;
}
}
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_ssm_free(ssm);
fpi_image_device_activate_complete(dev, error);
fpi_ssm_free (ssm);
fpi_image_device_activate_complete (dev, error);
if (!error)
start_capture(dev);
start_capture (dev);
}
static void dev_activate(FpImageDevice *dev)
static void
dev_activate (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), activate_run_state,
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);
fpi_ssm_start (ssm, activate_sm_complete);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
self->deactivating = TRUE;
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
GError *error = NULL;
/* 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)) {
fpi_image_device_open_complete(dev, 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;
}
self->image_bits = g_malloc0 (IMAGE_SIZE * 2);
fpi_image_device_open_complete(dev, NULL);
fpi_image_device_open_complete (dev, NULL);
}
static void dev_deinit(FpImageDevice *dev)
static void
dev_deinit (FpImageDevice *dev)
{
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG(dev);
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev);
GError *error = NULL;
g_clear_pointer (&self->image_bits, g_free);
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static int
discover(GUsbDevice *usb_device)
discover (GUsbDevice *usb_device)
{
gint16 pid = g_usb_device_get_pid (usb_device);
gint16 bcd = g_usb_device_get_release (usb_device);
@ -615,19 +674,21 @@ discover(GUsbDevice *usb_device)
return 0;
}
static const FpIdEntry id_table [ ] = {
{ .vid = 0x147e, .pid = 0x2016,
},
{ .vid = 0x147e, .pid = 0x2020,
},
static const FpIdEntry id_table[] = {
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "upektc_img";
dev_class->full_name = "Upek TouchChip Fingerprint Coprocessor";

View file

@ -21,124 +21,124 @@
#define __UPEKTC_IMG_H
static const unsigned char upek2020_init_1[] = {
'C', 'i', 'a', 'o',
0x04,
0x00, 0x0d,
0x01, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00,
0xda, 0xc1
'C', 'i', 'a', 'o',
0x04,
0x00, 0x0d,
0x01, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00,
0xda, 0xc1
};
static const unsigned char upek2020_init_2[] = {
0x43, 0x69, 0x61, 0x6f,
0x07,
0x00, 0x01,
0x01,
0x3d, 0x72
0x43, 0x69, 0x61, 0x6f,
0x07,
0x00, 0x01,
0x01,
0x3d, 0x72
};
static const unsigned char upek2020_init_3[] = {
'C', 'i', 'a', 'o',
0x04,
0x00, 0x0d,
0x01, 0x00, 0xbc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00,
0x55, 0x2f
'C', 'i', 'a', 'o',
0x04,
0x00, 0x0d,
0x01, 0x00, 0xbc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00,
0x55, 0x2f
};
static const unsigned char upek2020_init_4[] = {
'C', 'i', 'a', 'o',
0x00,
0x00, 0x07,
0x28, 0x04, 0x00, 0x00, 0x00, 0x06, 0x04,
0xc0, 0xd6
'C', 'i', 'a', 'o',
0x00,
0x00, 0x07,
0x28, 0x04, 0x00, 0x00, 0x00, 0x06, 0x04,
0xc0, 0xd6
};
static const unsigned char upek2020_deinit[] = {
'C', 'i', 'a', 'o',
0x07,
0x00, 0x01,
0x01,
0x3d,
0x72
'C', 'i', 'a', 'o',
0x07,
0x00, 0x01,
0x01,
0x3d,
0x72
};
static const unsigned char upek2020_init_capture[] = {
'C', 'i', 'a', 'o',
0x00,
0x00, 0x0e, /* Seq = 7, len = 0x00e */
0x28, /* CMD = 0x28 */
0x0b, 0x00, /* Inner len = 0x000b */
0x00, 0x00,
0x0e, /* SUBCMD = 0x0e */
0x02,
0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */
0x02,
0x00, /* Wait for acceptable finger */
0x02,
0x14, 0x9a /* CRC */
'C', 'i', 'a', 'o',
0x00,
0x00, 0x0e, /* Seq = 7, len = 0x00e */
0x28, /* CMD = 0x28 */
0x0b, 0x00, /* Inner len = 0x000b */
0x00, 0x00,
0x0e, /* SUBCMD = 0x0e */
0x02,
0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */
0x02,
0x00, /* Wait for acceptable finger */
0x02,
0x14, 0x9a /* CRC */
};
#if 0
static const unsigned char finger_status[] = {
'C', 'i', 'a', 'o',
0x00,
0x70, 0x14, /* Seq = 7, len = 0x014 */
0x28, /* CMD = 0x28 */
0x11, 0x00, /* Inner len = 0x0011 */
0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x26, 0x03, /* CRC */
0x00, 0x00, 0x00, /* Rest is garbage */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
'C', 'i', 'a', 'o',
0x00,
0x70, 0x14, /* Seq = 7, len = 0x014 */
0x28, /* CMD = 0x28 */
0x11, 0x00, /* Inner len = 0x0011 */
0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x26, 0x03, /* CRC */
0x00, 0x00, 0x00, /* Rest is garbage */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif
static const unsigned char upek2020_ack_00_28[] = {
'C', 'i', 'a', 'o',
0x00,
0x80, 0x08, /* Seq = 8, len = 0x008 */
0x28, /* CMD = 0x28 */
0x05, 0x00, /* Inner len = 0x0005 */
0x00, 0x00, 0x00, 0x30, 0x01,
0x6a, 0xc4 /* CRC */
'C', 'i', 'a', 'o',
0x00,
0x80, 0x08, /* Seq = 8, len = 0x008 */
0x28, /* CMD = 0x28 */
0x05, 0x00, /* Inner len = 0x0005 */
0x00, 0x00, 0x00, 0x30, 0x01,
0x6a, 0xc4 /* CRC */
};
#if 0
/* No seq should be tracked here */
static const unsigned char got_finger[] = {
'C', 'i', 'a', 'o',
0x08,
0x00, 0x00, /* Seq = 0, len = 0x000 */
0xa1, 0xa9, /* CRC */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest is garbage */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
'C', 'i', 'a', 'o',
0x08,
0x00, 0x00, /* Seq = 0, len = 0x000 */
0xa1, 0xa9, /* CRC */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest is garbage */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif
/* No seq should be put in there */
static const unsigned char upek2020_ack_08[] = {
'C', 'i', 'a', 'o',
0x09,
0x00, 0x00, /* Seq = 0, len = 0x0 */
0x91, 0x9e /* CRC */
'C', 'i', 'a', 'o',
0x09,
0x00, 0x00, /* Seq = 0, len = 0x0 */
0x91, 0x9e /* CRC */
};
static const unsigned char upek2020_ack_frame[] = {
'C', 'i', 'a', 'o',
0x00,
0x50, 0x01, /* Seq = 5, len = 0x001 */
0x30,
0xac, 0x5b /* CRC */
'C', 'i', 'a', 'o',
0x00,
0x50, 0x01, /* Seq = 5, len = 0x001 */
0x30,
0xac, 0x5b /* CRC */
};
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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;
@ -46,9 +47,9 @@ struct _FpDeviceVcom5s {
gboolean loop_running;
gboolean deactivating;
};
G_DECLARE_FINAL_TYPE(FpDeviceVcom5s, fpi_device_vcom5s, FPI, DEVICE_VCOM5S,
G_DECLARE_FINAL_TYPE (FpDeviceVcom5s, fpi_device_vcom5s, FPI, DEVICE_VCOM5S,
FpImageDevice);
G_DEFINE_TYPE(FpDeviceVcom5s, fpi_device_vcom5s, FP_TYPE_IMAGE_DEVICE);
G_DEFINE_TYPE (FpDeviceVcom5s, fpi_device_vcom5s, FP_TYPE_IMAGE_DEVICE);
enum v5s_regs {
/* when using gain 0x29:
@ -75,62 +76,64 @@ 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)
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
}
static void
sm_write_reg(FpiSsm *ssm,
sm_write_reg (FpiSsm *ssm,
FpDevice *dev,
unsigned char reg,
unsigned char value)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fp_dbg("set %02x=%02x", reg, value);
fpi_usb_transfer_fill_control(transfer,
fp_dbg ("set %02x=%02x", reg, value);
fpi_usb_transfer_fill_control (transfer,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
G_USB_DEVICE_RECIPIENT_DEVICE,
reg, value, 0, 0);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb,
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb,
NULL);
fpi_usb_transfer_unref(transfer);
}
static void sm_exec_cmd_cb(FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed(transfer->ssm, error);
else
fpi_ssm_next_state(transfer->ssm);
fpi_usb_transfer_unref (transfer);
}
static void
sm_exec_cmd(FpiSsm *ssm,
sm_exec_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state (transfer->ssm);
}
static void
sm_exec_cmd (FpiSsm *ssm,
FpDevice *dev,
unsigned char cmd,
unsigned char param)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
fp_dbg("cmd %02x param %02x", cmd, param);
fpi_usb_transfer_fill_control(transfer,
fp_dbg ("cmd %02x param %02x", cmd, param);
fpi_usb_transfer_fill_control (transfer,
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
G_USB_DEVICE_RECIPIENT_DEVICE,
cmd, param, 0, 0);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/***** FINGER DETECTION *****/
@ -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;
@ -161,51 +166,57 @@ static gboolean finger_is_present(unsigned char *data)
imgavg += rowavg;
}
imgavg /= DETBOX_ROWS;
fp_dbg("img avg %d", imgavg);
fp_dbg ("img avg %d", imgavg);
return (imgavg <= FINGER_PRESENCE_THRESHOLD);
return imgavg <= FINGER_PRESENCE_THRESHOLD;
}
/***** IMAGE ACQUISITION *****/
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);
FpImageDevice *imgdev = FP_IMAGE_DEVICE (device);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (device);
if (error) {
fpi_ssm_mark_failed(transfer->ssm, 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
* supposed to be handing off this image */
self->capture_img = NULL;
fpi_image_device_report_finger_status(imgdev,
finger_is_present(img->data));
fpi_image_device_image_captured(imgdev, img);
fpi_ssm_next_state(transfer->ssm);
} else {
capture_iterate(transfer->ssm, device);
fpi_image_device_report_finger_status (imgdev,
finger_is_present (img->data));
fpi_image_device_image_captured (imgdev, img);
fpi_ssm_next_state (transfer->ssm);
}
else
{
capture_iterate (transfer->ssm, device);
}
}
static void
capture_iterate(FpiSsm *ssm,
capture_iterate (FpiSsm *ssm,
FpDevice *dev)
{
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
int iteration = self->capture_iteration;
FpiUsbTransfer *transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
@ -221,16 +232,16 @@ capture_iterate(FpiSsm *ssm,
static void
sm_do_capture(FpiSsm *ssm,
sm_do_capture (FpiSsm *ssm,
FpDevice *dev)
{
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (dev);
G_DEBUG_HERE();
G_DEBUG_HERE ();
self->capture_img = fp_image_new (cls->img_width, cls->img_height);
self->capture_iteration = 0;
capture_iterate(ssm, dev);
capture_iterate (ssm, dev);
}
/***** CAPTURE LOOP *****/
@ -244,105 +255,127 @@ 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);
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);
sm_write_reg (ssm, dev, REG_CONTRAST, 0x01);
break;
case LOOP_SET_GAIN:
sm_write_reg(ssm, dev, REG_GAIN, 0x29);
sm_write_reg (ssm, dev, REG_GAIN, 0x29);
break;
case LOOP_CMD_SCAN:
if (self->deactivating) {
fp_dbg("deactivating, marking completed");
fpi_ssm_mark_completed(ssm);
} else
sm_exec_cmd(ssm, dev, CMD_SCAN, 0x00);
if (self->deactivating)
{
fp_dbg ("deactivating, marking completed");
fpi_ssm_mark_completed (ssm);
}
else
{
sm_exec_cmd (ssm, dev, CMD_SCAN, 0x00);
}
break;
case LOOP_CAPTURE:
sm_do_capture(ssm, dev);
sm_do_capture (ssm, dev);
break;
case LOOP_CAPTURE_DONE:
fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
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);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
g_object_unref (self->capture_img);
self->capture_img = NULL;
self->loop_running = FALSE;
if (error && !self->deactivating)
fpi_image_device_session_error(imgdev, error);
fpi_image_device_session_error (imgdev, error);
else if (error)
g_error_free (error);
if (self->deactivating)
fpi_image_device_deactivate_complete(imgdev, NULL);
fpi_image_device_deactivate_complete (imgdev, NULL);
}
static void dev_activate(FpImageDevice *dev)
static void
dev_activate (FpImageDevice *dev)
{
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), loop_run_state,
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);
fpi_ssm_start (ssm, loopsm_complete);
self->loop_running = TRUE;
fpi_image_device_activate_complete(dev, NULL);
fpi_image_device_activate_complete (dev, NULL);
}
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S(dev);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
if (self->loop_running)
self->deactivating = TRUE;
else
fpi_image_device_deactivate_complete(dev, NULL);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void dev_init(FpImageDevice *dev)
static void
dev_init (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_claim_interface (fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
fpi_image_device_open_complete(dev, error);
fpi_image_device_open_complete (dev, error);
}
static void dev_deinit(FpImageDevice *dev)
static void
dev_deinit (FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ .vid = 0x061a, .pid = 0x0110, },
{ .vid = 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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "vcom5s";
dev_class->full_name = "Veridicom 5thSense";
@ -358,4 +391,3 @@ static void fpi_device_vcom5s_class_init(FpDeviceVcom5sClass *klass) {
img_class->img_width = IMG_WIDTH;
img_class->img_height = IMG_HEIGHT;
}

View file

@ -27,21 +27,23 @@ 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) {
fp_err("USB write transfer: %s", error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
if (error)
{
fp_err ("USB write transfer: %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
}
/* Send data to EP1, the only out endpoint */
static void
async_write(FpiSsm *ssm,
async_write (FpiSsm *ssm,
FpDevice *dev,
void *data,
int len)
@ -49,33 +51,35 @@ async_write(FpiSsm *ssm,
FpiUsbTransfer *transfer;
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
fpi_usb_transfer_fill_bulk_full(transfer, 0x01, data, len, NULL);
fpi_usb_transfer_fill_bulk_full (transfer, 0x01, data, len, NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
async_write_callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/* 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) {
fp_err("USB read transfer on endpoint %d: %s", ep - 0x80,
if (error)
{
fp_err ("USB read transfer on endpoint %d: %s", ep - 0x80,
error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
}
/* Receive data from the given ep and either discard or fill the given buffer */
static void
async_read(FpiSsm *ssm,
async_read (FpiSsm *ssm,
FpDevice *dev,
int ep,
void *data,
@ -90,52 +94,57 @@ 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;
}
/* 0x83 is the only interrupt endpoint */
if (ep == EP3_IN)
fpi_usb_transfer_fill_interrupt_full(transfer, ep, data, len, free_func);
fpi_usb_transfer_fill_interrupt_full (transfer, ep, data, len, free_func);
else
fpi_usb_transfer_fill_bulk_full(transfer, ep, data, len, free_func);
fpi_usb_transfer_fill_bulk_full (transfer, ep, data, len, free_func);
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
async_read_callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/* 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);
fpi_ssm_next_state (transfer->ssm);
return;
}
if (error) {
fp_err("USB write transfer: %s", error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
if (error)
{
fp_err ("USB write transfer: %s", error->message);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* Don't stop process, only print warning */
fp_warn("Endpoint %d had extra %zd bytes readable", ep - 0x80,
fp_warn ("Endpoint %d had extra %zd bytes readable", ep - 0x80,
transfer->actual_length);
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_get_cur_state(transfer->ssm));
fpi_ssm_jump_to_state (transfer->ssm,
fpi_ssm_get_cur_state (transfer->ssm));
}
/* 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;
@ -149,31 +158,35 @@ static void async_abort(FpDevice *dev, FpiSsm *ssm, int ep)
else
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
fpi_usb_transfer_submit(transfer, VFS_USB_ABORT_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
async_abort_callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
/* 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];
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];
(int) line1->next_line_part[i] - (int) line2->data[shift + i];
res += x * x;
}
return res;
@ -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,15 +220,17 @@ 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) {
if (!is_noise(vdev->lines_buffer + height - 1))
while (height > 0)
{
if (!is_noise (vdev->lines_buffer + height - 1))
break;
--height;
}
@ -227,274 +244,298 @@ static FpImage *prepare_image(FpDeviceVfs0050 *vdev)
/* Building GSList */
GSList *lines = NULL;
for (int i = height - 1; i >= 0; --i)
lines = g_slist_prepend(lines, vdev->lines_buffer + i);
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
/* Perform line assembling */
FpImage *img = fpi_assemble_lines(&assembling_ctx, lines, height);
FpImage *img = fpi_assemble_lines (&assembling_ctx, lines, height);
g_slist_free(lines);
g_slist_free (lines);
return img;
}
/* Processes and submits image after fingerprint received */
static void submit_image(FpDeviceVfs0050 *self)
static void
submit_image (FpDeviceVfs0050 *self)
{
FpImageDevice *idev = FP_IMAGE_DEVICE(self);
FpImageDevice *idev = FP_IMAGE_DEVICE (self);
/* We were not asked to submit image actually */
if (!self->active)
return;
FpImage *img = prepare_image(self);
FpImage *img = prepare_image (self);
if (!img)
fpi_image_device_retry_scan(idev, FP_DEVICE_RETRY_TOO_SHORT);
fpi_image_device_retry_scan (idev, FP_DEVICE_RETRY_TOO_SHORT);
else
fpi_image_device_image_captured(idev, img);
fpi_image_device_image_captured (idev, img);
/* Finger not on the scanner */
fpi_image_device_report_finger_status(idev, FALSE);
fpi_image_device_report_finger_status (idev, FALSE);
}
/* Proto functions */
/* SSM loop for clear_ep2 */
static void
clear_ep2_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
clear_ep2_ssm (FpiSsm *ssm, FpDevice *dev, void *user_data)
{
char command04 = 0x04;
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));
async_write (ssm, dev, &command04, sizeof (command04));
break;
case SUBSM1_RETURN_CODE:
async_read(ssm, dev, 1, NULL, 2);
async_read (ssm, dev, 1, NULL, 2);
break;
case SUBSM1_ABORT_2:
async_abort(dev, ssm, 2);
async_abort (dev, ssm, 2);
break;
default:
fp_err("Unknown SUBSM1 state");
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
fp_err ("Unknown SUBSM1 state");
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
}
/* Send command to clear EP2 */
static void
clear_ep2(FpDevice *dev,
clear_ep2 (FpDevice *dev,
FpiSsm *ssm)
{
FpiSsm *subsm =
fpi_ssm_new(dev, clear_ep2_ssm, SUBSM1_STATES, NULL);
fpi_ssm_start_subsm(ssm, 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);
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,
async_write (ssm, dev, self->control_packet,
VFS_CONTROL_PACKET_SIZE);
break;
case SUBSM2_RETURN_CODE:
async_read(ssm, dev, 1, NULL, 2);
async_read (ssm, dev, 1, NULL, 2);
break;
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);
fpi_ssm_jump_to_state (ssm, SUBSM2_SEND_CONTROL);
break;
}
/* commit_out in Windows differs in each commit, but I send the same each time */
async_write(ssm, dev, commit_out, sizeof(commit_out));
async_write (ssm, dev, commit_out, sizeof (commit_out));
break;
case SUBSM2_COMMIT_RESPONSE:
async_read(ssm, dev, 1, NULL, VFS_COMMIT_RESPONSE_SIZE);
async_read (ssm, dev, 1, NULL, VFS_COMMIT_RESPONSE_SIZE);
break;
case SUBSM2_READ_EMPTY_INTERRUPT:
/* I don't know how to check result, it could be different
* NOTE: I guess this comment relates to the above read. */
async_read(ssm, dev, 3, self->interrupt, VFS_INTERRUPT_SIZE);
async_read (ssm, dev, 3, self->interrupt, VFS_INTERRUPT_SIZE);
break;
case SUBSM2_ABORT_3:
/* Check that interrupt is empty */
if (memcmp
(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));
(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;
}
async_abort(dev, ssm, 3);
async_abort (dev, ssm, 3);
break;
case SUBSM2_CLEAR_EP2:
/* After turn_on Windows doesn't clear EP2 */
if (self->control_packet != turn_on)
clear_ep2(dev, ssm);
clear_ep2 (dev, ssm);
else
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
break;
default:
fp_err("Unknown SUBSM2 state");
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
fp_err ("Unknown SUBSM2 state");
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
}
/* Send device state control packet */
static void
send_control_packet(FpiSsm *ssm,
send_control_packet (FpiSsm *ssm,
FpDevice *dev)
{
FpiSsm *subsm =
fpi_ssm_new(dev, send_control_packet_ssm,
fpi_ssm_new (dev, send_control_packet_ssm,
SUBSM2_STATES, NULL);
fpi_ssm_start_subsm(ssm, subsm);
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);
g_free (vdev->lines_buffer);
vdev->lines_buffer = NULL;
vdev->memory = vdev->bytes = 0;
}
/* 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);
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (device);
char *interrupt = transfer->buffer;
/* 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);
fpi_ssm_jump_to_state (transfer->ssm, SSM_CLEAR_EP2);
return;
}
if (error) {
fp_err("USB read interrupt transfer: %s",
if (error)
{
fp_err ("USB read interrupt transfer: %s",
error->message);
fpi_ssm_mark_failed(transfer->ssm, error);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* Standard interrupts */
if (memcmp(interrupt, interrupt1, VFS_INTERRUPT_SIZE) == 0 ||
memcmp(interrupt, interrupt2, VFS_INTERRUPT_SIZE) == 0 ||
memcmp(interrupt, interrupt3, VFS_INTERRUPT_SIZE) == 0) {
if (memcmp (interrupt, interrupt1, VFS_INTERRUPT_SIZE) == 0 ||
memcmp (interrupt, interrupt2, VFS_INTERRUPT_SIZE) == 0 ||
memcmp (interrupt, interrupt3, VFS_INTERRUPT_SIZE) == 0)
{
/* Go to the next ssm stage */
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
return;
}
/* When finger is on the scanner before turn_on */
if (interrupt[0] == 0x01) {
fp_warn("Finger is already on the scanner");
if (interrupt[0] == 0x01)
{
fp_warn ("Finger is already on the scanner");
/* Go to the next ssm stage */
fpi_ssm_next_state(transfer->ssm);
fpi_ssm_next_state (transfer->ssm);
return;
}
/* Unknown interrupt; abort the session */
fp_err("Unknown interrupt '%02x:%02x:%02x:%02x:%02x'!",
fp_err ("Unknown interrupt '%02x:%02x:%02x:%02x:%02x'!",
interrupt[0] & 0xff, interrupt[1] & 0xff, interrupt[2] & 0xff,
interrupt[3] & 0xff, interrupt[4] & 0xff);
/* Abort ssm */
fpi_ssm_mark_failed(transfer->ssm,
fpi_ssm_mark_failed (transfer->ssm,
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);
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (device);
if (error && !g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) {
fp_err("USB read transfer: %s", error->message);
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);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
if (error)
g_error_free (error);
/* Check if fingerprint data is over */
if (transfer->actual_length == 0) {
fpi_ssm_next_state(transfer->ssm);
} else {
if (transfer->actual_length == 0)
{
fpi_ssm_next_state (transfer->ssm);
}
else
{
self->bytes += transfer->actual_length;
/* We need more data */
fpi_ssm_jump_to_state(transfer->ssm,
fpi_ssm_get_cur_state(transfer->ssm));
fpi_ssm_jump_to_state (transfer->ssm,
fpi_ssm_get_cur_state (transfer->ssm));
}
}
/* SSM stub to prepare device to another scan after orange light was on */
static void
another_scan(FpDevice *dev,
another_scan (FpDevice *dev,
void *data)
{
FpiSsm *ssm = data;
fpi_ssm_jump_to_state(ssm, SSM_TURN_ON);
fpi_ssm_jump_to_state (ssm, SSM_TURN_ON);
}
/* Main SSM loop */
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);
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);
async_abort (dev, ssm, 1);
break;
case SSM_INITIAL_ABORT_2:
async_abort(dev, ssm, 2);
async_abort (dev, ssm, 2);
break;
case SSM_INITIAL_ABORT_3:
async_abort(dev, ssm, 3);
async_abort (dev, ssm, 3);
break;
case SSM_CLEAR_EP2:
clear_ep2(dev, ssm);
clear_ep2 (dev, ssm);
break;
case SSM_TURN_OFF:
/* Set control_packet argument */
self->control_packet = turn_off;
send_control_packet(ssm, dev);
send_control_packet (ssm, dev);
break;
case SSM_TURN_ON:
if (!self->active) {
if (!self->active)
{
/* The only correct exit */
fpi_ssm_mark_completed(ssm);
fpi_ssm_mark_completed (ssm);
if (self->need_report) {
fpi_image_device_deactivate_complete(idev,
if (self->need_report)
{
fpi_image_device_deactivate_complete (idev,
NULL);
self->need_report = 0;
}
@ -503,7 +544,7 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
/* Set control_packet argument */
self->control_packet = turn_on;
send_control_packet(ssm, dev);
send_control_packet (ssm, dev);
break;
case SSM_ASK_INTERRUPT: {
@ -511,8 +552,9 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
/* Activated, light must be blinking now */
/* If we first time here, report that activate completed */
if (self->need_report) {
fpi_image_device_activate_complete(idev, NULL);
if (self->need_report)
{
fpi_image_device_activate_complete (idev, NULL);
self->need_report = 0;
}
@ -528,11 +570,12 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
fpi_usb_transfer_unref (transfer);
/* I've put it here to be sure that data is cleared */
clear_data(self);
clear_data (self);
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
break;
}
case SSM_WAIT_INTERRUPT:
/* TODO: This state is unused at this point. When we
* are in this state, then a user cancellation will
@ -545,110 +588,119 @@ static void activate_ssm(FpiSsm *ssm, FpDevice *dev, void *user_data)
case SSM_RECEIVE_FINGER: {
FpiUsbTransfer *transfer;
if (self->memory == 0) {
if (self->memory == 0)
{
/* Initialize fingerprint buffer */
g_free(self->lines_buffer);
g_free (self->lines_buffer);
self->memory = VFS_USB_BUFFER_SIZE;
self->lines_buffer = g_malloc(self->memory);
self->lines_buffer = g_malloc (self->memory);
self->bytes = 0;
/* Finger is on the scanner */
fpi_image_device_report_finger_status(idev, TRUE);
fpi_image_device_report_finger_status (idev, TRUE);
}
/* Increase buffer size while it's insufficient */
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,
(struct vfs_line *) g_realloc (self->lines_buffer,
self->memory);
}
/* Receive chunk of data */
transfer = fpi_usb_transfer_new (dev);
fpi_usb_transfer_fill_bulk_full(transfer, 0x82,
(void *)self->lines_buffer + self->bytes,
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
(void *) self->lines_buffer + self->bytes,
VFS_USB_BUFFER_SIZE, NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit(transfer, VFS_USB_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
receive_callback, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
break;
}
case SSM_SUBMIT_IMAGE:
submit_image(self);
clear_data(self);
submit_image (self);
clear_data (self);
/* Wait for probable vdev->active changing */
fpi_device_add_timeout(dev, VFS_SSM_TIMEOUT,
fpi_device_add_timeout (dev, VFS_SSM_TIMEOUT,
fpi_ssm_next_state_timeout_cb, ssm);
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);
fpi_ssm_jump_to_state (ssm, SSM_CLEAR_EP2);
break;
}
/* Set control_packet argument */
self->control_packet = next_receive_1;
send_control_packet(ssm, dev);
send_control_packet (ssm, dev);
break;
case SSM_WAIT_ANOTHER_SCAN:
/* Orange light is on now */
fpi_device_add_timeout(dev, VFS_SSM_ORANGE_TIMEOUT,
fpi_device_add_timeout (dev, VFS_SSM_ORANGE_TIMEOUT,
another_scan, ssm);
break;
default:
fp_err("Unknown state");
fpi_ssm_mark_failed(ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
fp_err ("Unknown state");
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
}
/* 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);
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);
}
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
}
/* Activate device */
static void dev_activate(FpImageDevice *idev)
static void
dev_activate (FpImageDevice *idev)
{
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
/* Initialize flags */
self->active = 1;
self->need_report = 1;
self->ssm_active = 1;
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(idev), activate_ssm, SSM_STATES,
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES,
idev);
fpi_ssm_start(ssm, dev_activate_callback);
fpi_ssm_start (ssm, dev_activate_callback);
}
/* Deactivate device */
static void dev_deactivate(FpImageDevice *idev)
static void
dev_deactivate (FpImageDevice *idev)
{
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
if (!self->ssm_active) {
fpi_image_device_deactivate_complete(idev, NULL);
if (!self->ssm_active)
{
fpi_image_device_deactivate_complete (idev, NULL);
return;
}
@ -658,58 +710,65 @@ 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 */
fpi_image_device_open_complete(FP_IMAGE_DEVICE (dev), error);
fpi_ssm_free(ssm);
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), error);
fpi_ssm_free (ssm);
}
/* 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;
}
/* Clearing previous device state */
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(idev), activate_ssm, SSM_STATES, NULL);
fpi_ssm_start(ssm, dev_open_callback);
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES, NULL);
fpi_ssm_start (ssm, dev_open_callback);
}
/* Close device */
static void dev_close(FpImageDevice *idev)
static void
dev_close (FpImageDevice *idev)
{
GError *error = NULL;
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050(idev);
FpDeviceVfs0050 *self = FPI_DEVICE_VFS0050 (idev);
clear_data(self);
clear_data (self);
/* Release usb interface */
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(idev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (idev)),
0, 0, &error);
/* Notify close complete */
fpi_image_device_close_complete(idev, error);
fpi_image_device_close_complete (idev, error);
}
/* Usb id table of device */
static const FpIdEntry id_table [ ] = {
{.vid = 0x138a, .pid = 0x0050,
},
static const FpIdEntry id_table[] = {
{.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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "vfs0050";
dev_class->full_name = "Validity VFS0050";

View file

@ -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 */
@ -75,10 +76,11 @@ struct vfs_line {
/* scan_data is 0xfb except some rare cases, it's skipped */
unsigned char scan_data[8];
} __attribute__ ((__packed__));
} __attribute__((__packed__));
/* The main driver structure */
struct _FpDeviceVfs0050 {
struct _FpDeviceVfs0050
{
FpImageDevice parent;
/* One if we were asked to read fingerprint, zero otherwise */

File diff suppressed because it is too large Load diff

View file

@ -30,36 +30,37 @@ G_DEFINE_TYPE (FpDeviceVfs301, fpi_device_vfs301, FP_TYPE_IMAGE_DEVICE)
/* Submit asynchronous sleep */
static void
async_sleep(unsigned int msec,
async_sleep (unsigned int msec,
FpiSsm *ssm,
FpImageDevice *dev)
{
/* Add timeout */
fpi_device_add_timeout(FP_DEVICE(dev), msec,
fpi_device_add_timeout (FP_DEVICE (dev), msec,
fpi_ssm_next_state_timeout_cb, ssm);
}
static int
submit_image(FpiSsm *ssm,
submit_image (FpiSsm *ssm,
FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
int height;
FpImage *img;
#if 0
/* XXX: This is probably handled by libfprint automagically? */
if (vdev->scanline_count < 20) {
fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
if (vdev->scanline_count < 20)
{
fpi_ssm_jump_to_state (ssm, M_REQUEST_PRINT);
return 0;
}
#endif
img = fp_image_new(VFS301_FP_OUTPUT_WIDTH, self->scanline_count);
img = fp_image_new (VFS301_FP_OUTPUT_WIDTH, self->scanline_count);
if (img == NULL)
return 0;
vfs301_extract_image(self, img->data, &height);
vfs301_extract_image (self, img->data, &height);
/* TODO: how to detect flip? should the resulting image be
* oriented so that it is equal e.g. to a fingerprint on a paper,
@ -71,14 +72,13 @@ submit_image(FpiSsm *ssm,
img->width = VFS301_FP_OUTPUT_WIDTH;
img->height = height;
fpi_image_device_image_captured(dev, img);
fpi_image_device_image_captured (dev, img);
return 1;
}
/* Loop ssm states */
enum
{
enum {
/* Step 0 - Scan finger */
M_REQUEST_PRINT,
M_WAIT_PRINT,
@ -93,172 +93,191 @@ 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);
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);
vfs301_proto_request_fingerprint (self);
fpi_ssm_next_state (ssm);
break;
case M_WAIT_PRINT:
/* Wait fingerprint scanning */
async_sleep(200, ssm, dev);
async_sleep (200, ssm, dev);
break;
case M_CHECK_PRINT:
if (!vfs301_proto_peek_event(self))
fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT);
if (!vfs301_proto_peek_event (self))
fpi_ssm_jump_to_state (ssm, M_WAIT_PRINT);
else
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
break;
case M_READ_PRINT_START:
fpi_image_device_report_finger_status(dev, TRUE);
vfs301_proto_process_event_start(self);
fpi_ssm_next_state(ssm);
fpi_image_device_report_finger_status (dev, TRUE);
vfs301_proto_process_event_start (self);
fpi_ssm_next_state (ssm);
break;
case M_READ_PRINT_WAIT:
/* Wait fingerprint scanning */
async_sleep(200, ssm, dev);
async_sleep (200, ssm, dev);
break;
case M_READ_PRINT_POLL:
{
int rv = vfs301_proto_process_event_poll(self);
g_assert(rv != VFS301_FAILURE);
int rv = vfs301_proto_process_event_poll (self);
g_assert (rv != VFS301_FAILURE);
if (rv == VFS301_ONGOING)
fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT);
fpi_ssm_jump_to_state (ssm, M_READ_PRINT_WAIT);
else
fpi_ssm_next_state(ssm);
fpi_ssm_next_state (ssm);
}
break;
case M_SUBMIT_PRINT:
if (submit_image(ssm, dev)) {
fpi_ssm_mark_completed(ssm);
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 {
fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
fpi_image_device_report_finger_status (dev, FALSE);
}
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);
}
/* Free sequential state machine */
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
}
/* Exec init sequential state machine */
static void m_init_state(FpiSsm *ssm, FpDevice *_dev, void *user_data)
static void
m_init_state (FpiSsm *ssm, FpDevice *_dev, void *user_data)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(_dev);
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (_dev);
g_assert(fpi_ssm_get_cur_state(ssm) == 0);
g_assert (fpi_ssm_get_cur_state (ssm) == 0);
vfs301_proto_init(self);
vfs301_proto_init (self);
fpi_ssm_mark_completed(ssm);
fpi_ssm_mark_completed (ssm);
}
/* Complete init sequential state machine */
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) {
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (dev), error);
if (!error)
{
/* Notify activate complete */
/* Start loop ssm */
ssm_loop = fpi_ssm_new(dev, m_loop_state,
ssm_loop = fpi_ssm_new (dev, m_loop_state,
M_LOOP_NUM_STATES, dev);
fpi_ssm_start(ssm_loop, m_loop_complete);
fpi_ssm_start (ssm_loop, m_loop_complete);
}
/* Free sequential state machine */
fpi_ssm_free(ssm);
fpi_ssm_free (ssm);
}
/* Activate device */
static void dev_activate(FpImageDevice *dev)
static void
dev_activate (FpImageDevice *dev)
{
FpiSsm *ssm;
/* Start init ssm */
ssm = fpi_ssm_new(FP_DEVICE(dev), m_init_state, 1, dev);
fpi_ssm_start(ssm, m_init_complete);
ssm = fpi_ssm_new (FP_DEVICE (dev), m_init_state, 1, dev);
fpi_ssm_start (ssm, m_init_complete);
}
/* Deactivate device */
static void dev_deactivate(FpImageDevice *dev)
static void
dev_deactivate (FpImageDevice *dev)
{
FpDeviceVfs301 *self;
self = FPI_DEVICE_VFS301(dev);
vfs301_proto_deinit(self);
fpi_image_device_deactivate_complete(dev, NULL);
self = FPI_DEVICE_VFS301 (dev);
vfs301_proto_deinit (self);
fpi_image_device_deactivate_complete (dev, NULL);
}
static void dev_open(FpImageDevice *dev)
static void
dev_open (FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
GError *error = NULL;
/* Claim usb interface */
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
/* Initialize private structure */
self->scanline_count = 0;
/* Notify open complete */
fpi_image_device_open_complete(dev, error);
fpi_image_device_open_complete (dev, error);
}
static void dev_close(FpImageDevice *dev)
static void
dev_close (FpImageDevice *dev)
{
FpDeviceVfs301 *self = FPI_DEVICE_VFS301(dev);
FpDeviceVfs301 *self = FPI_DEVICE_VFS301 (dev);
GError *error = NULL;
/* Release private structure */
g_clear_pointer (&self->scanline_buf, g_free);
/* Release usb interface */
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
0, 0, &error);
/* Notify close complete */
fpi_image_device_close_complete(dev, error);
fpi_image_device_close_complete (dev, error);
}
/* Usb id table of device */
static const FpIdEntry id_table [ ] = {
static const FpIdEntry id_table[] = {
{ /* vfs301 */ .vid = 0x138a, .pid = 0x0005, },
{ /* vfs300 */ .vid = 0x138a, .pid = 0x0008, },
{ .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) {
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(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);
dev_class->id = "vfs301";
dev_class->full_name = "Validity VFS301";

View file

@ -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;
@ -124,14 +127,16 @@ typedef struct {
unsigned char sum3[3];
} vfs301_line_t;
void vfs301_proto_init(FpDeviceVfs301 *dev);
void vfs301_proto_deinit(FpDeviceVfs301 *dev);
void vfs301_proto_init (FpDeviceVfs301 *dev);
void vfs301_proto_deinit (FpDeviceVfs301 *dev);
void vfs301_proto_request_fingerprint(FpDeviceVfs301 *dev);
void vfs301_proto_request_fingerprint (FpDeviceVfs301 *dev);
/** returns 0 if no event is ready, or 1 if there is one... */
int vfs301_proto_peek_event(FpDeviceVfs301 *dev);
void vfs301_proto_process_event_start(FpDeviceVfs301 *dev);
int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev);
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);

View file

@ -41,29 +41,33 @@
/************************** 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);
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++) {
fprintf(stderr, "%.2X ", data[i]);
for (i = 0; i < MIN (length, 128); i++)
{
fprintf (stderr, "%.2X ", data[i]);
if (i % 8 == 7)
fprintf(stderr, " ");
fprintf (stderr, " ");
if (i % 32 == 31)
fprintf(stderr, "\n");
fprintf (stderr, "\n");
}
#endif
fprintf(stderr, "\n");
fprintf (stderr, "\n");
}
#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
@ -77,11 +81,12 @@ static void usb_recv(FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsb
#ifdef DEBUG
usb_print_packet(0, err, transfer->buffer, transfer->actual_length);
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_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
@ -99,15 +106,16 @@ static void usb_send(FpDeviceVfs301 *dev, const guint8 *data, gssize length, GEr
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk_full (transfer, VFS301_SEND_ENDPOINT, (guint8*) data, length, g_free);
fpi_usb_transfer_fill_bulk_full (transfer, VFS301_SEND_ENDPOINT, (guint8 *) data, length, g_free);
fpi_usb_transfer_submit_sync (transfer, VFS301_DEFAULT_WAIT_TIMEOUT, &err);
#ifdef DEBUG
usb_print_packet(1, err, data, length);
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,16 +137,19 @@ 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();
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,11 +168,12 @@ 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;
tmp = strlen(src);
tmp = strlen (src);
g_assert (tmp % 2 == 0);
src_len += tmp;
}
@ -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);
return vfs301_proto_generate_0B (subtype, len);
break;
case 0x02D0:
{
const char **dataLs[] = {
@ -213,55 +229,62 @@ static guint8 *vfs301_proto_generate(int type, int subtype, gssize *len)
vfs301_02D0_06,
vfs301_02D0_07,
};
g_assert((int)subtype <= G_N_ELEMENTS (dataLs));
return translate_str(dataLs[subtype - 1], len);
g_assert ((int) subtype <= G_N_ELEMENTS (dataLs));
return translate_str (dataLs[subtype - 1], len);
}
break;
case 0x0220:
switch (subtype) {
switch (subtype)
{
case 1:
return translate_str(vfs301_0220_01, len);
return translate_str (vfs301_0220_01, len);
break;
case 2:
return translate_str(vfs301_0220_02, len);
return translate_str (vfs301_0220_02, len);
break;
case 3:
return translate_str(vfs301_0220_03, len);
return translate_str (vfs301_0220_03, len);
break;
case 0xFA00:
case 0x2C01:
case 0x5E01: {
guint8 *data;
guint8 *field;
data = translate_str(vfs301_next_scan_template, len);
field = data + *len - (sizeof(S4_TAIL) - 1) / 2 - 4;
data = translate_str (vfs301_next_scan_template, len);
field = data + *len - (sizeof (S4_TAIL) - 1) / 2 - 4;
g_assert (field >= data && field < data + *len);
g_assert(field[0] == 0xDE);
g_assert(field[1] == 0xAD);
g_assert(field[2] == 0xDE);
g_assert(field[3] == 0xAD);
g_assert (field[0] == 0xDE);
g_assert (field[1] == 0xAD);
g_assert (field[2] == 0xDE);
g_assert (field[3] == 0xAD);
field[0] = (guint8)((subtype >> 8) & 0xFF);
field[1] = (guint8)(subtype & 0xFF);
field[0] = (guint8) ((subtype >> 8) & 0xFF);
field[1] = (guint8) (subtype & 0xFF);
field[2] = field[0];
field[3] = field[1];
return data;
break;
}
default:
g_assert_not_reached();
g_assert_not_reached ();
break;
}
break;
case 0x06:
default:
break;
}
g_assert_not_reached();
g_assert_not_reached ();
*len = 0;
return NULL;
}
@ -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;
@ -296,13 +321,14 @@ static int scanline_diff(const guint8 *scanlines, int prev, int cur)
#ifdef OUTPUT_RAW
/* We only need the image, not the surrounding stuff. */
line1 = ((vfs301_line_t*)line1)->scan;
line2 = ((vfs301_line_t*)line2)->scan;
line1 = ((vfs301_line_t *) line1)->scan;
line2 = ((vfs301_line_t *) line2)->scan;
#endif
/* 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,21 +338,22 @@ 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;
int last_line;
int i;
g_assert(vfs->scanline_count >= 1);
g_assert (vfs->scanline_count >= 1);
*output_height = 1;
memcpy(output, scanlines, VFS301_FP_OUTPUT_WIDTH);
memcpy (output, scanlines, VFS301_FP_OUTPUT_WIDTH);
last_line = 0;
/* The following algorithm is quite trivial - it just picks lines that
@ -335,9 +362,11 @@ void vfs301_extract_image(FpDeviceVfs301 *vfs, guint8 *output, int *output_heigh
* of bi/tri-linear resampling to get the output (so that we don't get so
* many false edges etc.).
*/
for (i = 1; i < vfs->scanline_count; i++) {
if (scanline_diff(scanlines, last_line, i)) {
memcpy(
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,
VFS301_FP_OUTPUT_WIDTH
@ -348,41 +377,47 @@ void vfs301_extract_image(FpDeviceVfs301 *vfs, guint8 *output, int *output_heigh
}
}
static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int len)
static int
img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int len)
{
vfs301_line_t *lines = (vfs301_line_t*)buf;
int no_lines = len / sizeof(vfs301_line_t);
vfs301_line_t *lines = (vfs301_line_t *) buf;
int no_lines = len / sizeof (vfs301_line_t);
int i;
/*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;
}
dev->scanline_buf = g_realloc(dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH);
dev->scanline_buf = g_realloc (dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH);
for (cur_line = dev->scanline_buf + last_img_height * VFS301_FP_OUTPUT_WIDTH, i = 0;
i < no_lines;
i++, cur_line += VFS301_FP_OUTPUT_WIDTH
) {
)
{
#ifndef OUTPUT_RAW
memcpy(cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH);
memcpy (cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH);
#else
memcpy(cur_line, &lines[i], VFS301_FP_OUTPUT_WIDTH);
memcpy (cur_line, &lines[i], VFS301_FP_OUTPUT_WIDTH);
#endif
}
#ifdef SCAN_FINISH_DETECTION
finished_scan = img_is_finished_scan(lines, no_lines);
finished_scan = img_is_finished_scan (lines, no_lines);
return !finished_scan;
#else /* SCAN_FINISH_DETECTION */
@ -393,44 +428,47 @@ static int img_process_data(int first_block, FpDeviceVfs301 *dev, const guint8 *
/************************** PROTOCOL STUFF ************************************/
#define USB_RECV(from, len) \
usb_recv(dev, from, len, NULL, NULL)
usb_recv (dev, from, len, NULL, NULL)
#define USB_SEND(type, subtype) \
{ \
const guint8 *data; \
gssize len; \
data = vfs301_proto_generate(type, subtype, &len); \
usb_send(dev, data, len, NULL); \
data = vfs301_proto_generate (type, subtype, &len); \
usb_send (dev, data, len, NULL); \
}
#define RAW_DATA(x) x, sizeof(x)
#define RAW_DATA(x) x, sizeof (x)
#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe))
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) {
g_assert(len >= VFS301_FP_FRAME_SIZE);
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--) {
if (IS_VFS301_FP_SEQ_START(buf))
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);
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 */
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;
@ -438,19 +476,18 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
const char no_event[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00};
USB_SEND(0x17, -1);
USB_SEND (0x17, -1);
usb_recv (dev, VFS301_RECEIVE_ENDPOINT_CTRL, 7, &transfer, &error);
/* 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 {
g_assert_not_reached();
}
else
g_assert_not_reached ();
}
/* XXX: We sometimes need to receive data on from two endpoints at the same
@ -459,49 +496,57 @@ int vfs301_proto_peek_event(FpDeviceVfs301 *dev)
*/
#define PARALLEL_RECEIVE(e1, l1, e2, l2) \
{ \
g_autoptr(GError) error = NULL;\
usb_recv(dev, e1, l1, NULL, &error); \
usb_recv(dev, e2, l2, NULL, NULL); \
g_autoptr(GError) error = NULL; \
usb_recv (dev, e1, l1, NULL, &error); \
usb_recv (dev, e2, l2, NULL, NULL); \
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
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,
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;
}
new = fpi_usb_transfer_new (device);
fpi_usb_transfer_fill_bulk(new, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_2);
fpi_usb_transfer_submit(new, VFS301_FP_RECV_TIMEOUT, NULL,
fpi_usb_transfer_fill_bulk (new, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_2);
fpi_usb_transfer_submit (new, VFS301_FP_RECV_TIMEOUT, NULL,
vfs301_proto_process_event_cb, NULL);
fpi_usb_transfer_unref (new);
return;
}
}
void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
void
vfs301_proto_process_event_start (FpDeviceVfs301 *dev)
{
FpiUsbTransfer *transfer;
@ -526,35 +571,36 @@ void vfs301_proto_process_event_start(FpDeviceVfs301 *dev)
* o FA00
* o 2C01
*/
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 64);
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 64);
/* now read the fingerprint data, while there are some */
transfer = fpi_usb_transfer_new(FP_DEVICE (dev));
transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
dev->recv_progress = VFS301_ONGOING;
fpi_usb_transfer_fill_bulk (transfer, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_1);
fpi_usb_transfer_submit(transfer, VFS301_FP_RECV_TIMEOUT, NULL,
fpi_usb_transfer_submit (transfer, VFS301_FP_RECV_TIMEOUT, NULL,
vfs301_proto_process_event_cb, NULL);
fpi_usb_transfer_unref(transfer);
fpi_usb_transfer_unref (transfer);
}
int vfs301_proto_process_event_poll(FpDeviceVfs301 *dev)
int
vfs301_proto_process_event_poll (FpDeviceVfs301 *dev)
{
if (dev->recv_progress != VFS301_ENDED)
return dev->recv_progress;
/* Finish the scan process... */
USB_SEND(0x04, -1);
USB_SEND (0x04, -1);
/* the following may come in random order, data may not come at all, don't
* try for too long... */
PARALLEL_RECEIVE(
PARALLEL_RECEIVE (
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 1204 */
VFS301_RECEIVE_ENDPOINT_DATA, 16384
);
USB_SEND(0x0220, 2);
PARALLEL_RECEIVE(
USB_SEND (0x0220, 2);
PARALLEL_RECEIVE (
VFS301_RECEIVE_ENDPOINT_DATA, 5760, /* seems to always come */
VFS301_RECEIVE_ENDPOINT_CTRL, 2 /* 0000 */
);
@ -562,92 +608,94 @@ 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);
USB_SEND(0x0B, 0x04);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 6); /* 000000000000 */
USB_SEND(0x0B, 0x05);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7); /* 00000000000000 */
USB_SEND(0x19, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 64);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 4); /* 6BB4D0BC */
usb_send(dev, RAW_DATA(vfs301_06_1), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x01, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND (0x0B, 0x04);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 6); /* 000000000000 */
USB_SEND (0x0B, 0x05);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 7); /* 00000000000000 */
USB_SEND (0x19, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 64);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 4); /* 6BB4D0BC */
usb_send (dev, RAW_DATA (vfs301_06_1), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x01, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND(0x1A, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_06_2), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x0220, 1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 256);
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 32);
USB_SEND (0x01, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND (0x1A, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_06_2), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x0220, 1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 256);
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 32);
USB_SEND(0x1A, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_06_3), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x1A, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_06_3), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x01, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND(0x02D0, 1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 11648); /* 56 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 2);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 53248); /* 2 * 128 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 3);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 19968); /* 96 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 4);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5824); /* 28 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 5);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 6);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
USB_SEND(0x02D0, 7);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 832);
usb_send(dev, RAW_DATA(vfs301_12), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x01, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND (0x02D0, 1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 11648); /* 56 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 2);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 53248); /* 2 * 128 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 3);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 19968); /* 96 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 4);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 5824); /* 28 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 5);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 6);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */
USB_SEND (0x02D0, 7);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 832);
usb_send (dev, RAW_DATA (vfs301_12), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x1A, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_06_2), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x0220, 2);
PARALLEL_RECEIVE(
USB_SEND (0x1A, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_06_2), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x0220, 2);
PARALLEL_RECEIVE (
VFS301_RECEIVE_ENDPOINT_CTRL, 2, /* 0000 */
VFS301_RECEIVE_ENDPOINT_DATA, 5760
);
USB_SEND(0x1A, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_06_1), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x1A, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_06_1), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x1A, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_06_4), NULL);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send(dev, RAW_DATA(vfs301_24), NULL); /* turns on white */
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND (0x1A, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_06_4), NULL);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
usb_send (dev, RAW_DATA (vfs301_24), NULL); /* turns on white */
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */
USB_SEND(0x01, -1);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND(0x0220, 3);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2368);
USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 36);
USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5760);
USB_SEND (0x01, -1);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 38);
USB_SEND (0x0220, 3);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 2368);
USB_RECV (VFS301_RECEIVE_ENDPOINT_CTRL, 36);
USB_RECV (VFS301_RECEIVE_ENDPOINT_DATA, 5760);
}
void vfs301_proto_deinit(FpDeviceVfs301 *dev)
void
vfs301_proto_deinit (FpDeviceVfs301 *dev)
{
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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;
@ -89,7 +93,7 @@ recv_image_img_recv_cb (GObject *source_object,
fpi_image_device_report_finger_status (device, FALSE);
/* And, listen for more images from the same client. */
recv_image(self, G_INPUT_STREAM (source_object));
recv_image (self, G_INPUT_STREAM (source_object));
}
static void
@ -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]);
@ -143,14 +152,14 @@ recv_image_hdr_recv_cb (GObject *source_object,
}
/* And, listen for more images from the same client. */
recv_image(self, G_INPUT_STREAM (source_object));
recv_image (self, G_INPUT_STREAM (source_object));
return;
}
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
g_debug ("image data: %p", self->recv_img->data);
g_input_stream_read_async (G_INPUT_STREAM (source_object),
(guint8*)self->recv_img->data,
(guint8 *) self->recv_img->data,
self->recv_img->width * self->recv_img->height,
G_PRIORITY_DEFAULT,
self->cancellable,
@ -163,7 +172,7 @@ recv_image (FpDeviceVirtualImage *dev, GInputStream *stream)
{
g_input_stream_read_async (stream,
dev->recv_img_hdr,
sizeof(dev->recv_img_hdr),
sizeof (dev->recv_img_hdr),
G_PRIORITY_DEFAULT,
dev->cancellable,
recv_image_hdr_recv_cb,
@ -182,18 +191,20 @@ 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;
g_warning ("Error accepting a new connection: %s", error->message);
start_listen(dev);
start_listen (dev);
}
/* Always further connections (but we disconnect them immediately
* if we already have a connection). */
start_listen(dev);
if (dev->connection) {
start_listen (dev);
if (dev->connection)
{
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
return;
}
@ -203,7 +214,7 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
recv_image (dev, stream);
fp_dbg("Got a new connection!");
fp_dbg ("Got a new connection!");
}
static void
@ -216,14 +227,14 @@ start_listen (FpDeviceVirtualImage *dev)
}
static void
dev_init(FpImageDevice *dev)
dev_init (FpImageDevice *dev)
{
g_autoptr(GError) error = NULL;
g_autoptr(GSocketListener) listener = NULL;
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
const char *env;
g_autoptr(GSocketAddress) addr = NULL;
G_DEBUG_HERE();
G_DEBUG_HERE ();
self->client_fd = -1;
@ -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,18 +271,19 @@ 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);
G_DEBUG_HERE();
G_DEBUG_HERE ();
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->listener);
g_clear_object (&self->connection);
fpi_image_device_close_complete(dev, NULL);
fpi_image_device_close_complete (dev, NULL);
}
static void
@ -297,4 +310,3 @@ fpi_device_virtual_image_class_init (FpDeviceVirtualImageClass *klass)
img_class->img_open = dev_init;
img_class->img_close = dev_deinit;
}

View file

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

View file

@ -28,9 +28,10 @@
GHashTable *printed = NULL;
static GList *insert_drivers (GList *list)
static GList *
insert_drivers (GList *list)
{
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof(GType));
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof (GType));
gint i;
fpi_get_driver_types (drivers);
@ -42,7 +43,8 @@ static GList *insert_drivers (GList *list)
FpDeviceClass *cls = FP_DEVICE_CLASS (g_type_class_ref (driver));
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;

View file

@ -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,9 +93,10 @@ 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));
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof (GType));
guint i;
g_print ("%p\n", drivers);
@ -102,11 +105,13 @@ int main (int argc, char **argv)
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
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;
}

View file

@ -22,4 +22,3 @@
#include "fp-context.h"
#include "fp-device.h"
#include "fp-image.h"

View file

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