aes2550: Port aes2550 driver to new API
This commit is contained in:
parent
441b1238a5
commit
61e49c2659
2 changed files with 241 additions and 287 deletions
|
@ -27,11 +27,11 @@
|
||||||
#include "aes2550.h"
|
#include "aes2550.h"
|
||||||
#include "aeslib.h"
|
#include "aeslib.h"
|
||||||
|
|
||||||
static void start_capture(struct fp_img_dev *dev);
|
static void start_capture(FpImageDevice *dev);
|
||||||
static void complete_deactivation(struct fp_img_dev *dev);
|
static void complete_deactivation(FpImageDevice *dev);
|
||||||
|
|
||||||
#define EP_IN (1 | LIBUSB_ENDPOINT_IN)
|
#define EP_IN (1 | FPI_USB_ENDPOINT_IN)
|
||||||
#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
|
#define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -51,12 +51,17 @@ static void complete_deactivation(struct fp_img_dev *dev);
|
||||||
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
|
||||||
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
|
||||||
|
|
||||||
struct aes2550_dev {
|
struct _FpiDeviceAes2550 {
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
GSList *strips;
|
GSList *strips;
|
||||||
size_t strips_len;
|
size_t strips_len;
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
int heartbeat_cnt;
|
int heartbeat_cnt;
|
||||||
};
|
};
|
||||||
|
G_DECLARE_FINAL_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FPI, DEVICE_AES2550,
|
||||||
|
FpImageDevice);
|
||||||
|
G_DEFINE_TYPE(FpiDeviceAes2550, fpi_device_aes2550, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
.frame_width = FRAME_WIDTH,
|
.frame_width = FRAME_WIDTH,
|
||||||
|
@ -78,89 +83,70 @@ static unsigned char finger_det_reqs[] = {
|
||||||
AES2550_CMD_RUN_FD,
|
AES2550_CMD_RUN_FD,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev);
|
static void start_finger_detection(FpImageDevice *dev);
|
||||||
|
|
||||||
static void finger_det_data_cb(struct libusb_transfer *transfer)
|
static void finger_det_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = transfer->user_data;
|
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (error) {
|
||||||
fp_dbg("data transfer status %d\n", transfer->status);
|
fpi_image_device_session_error(FP_IMAGE_DEVICE(device), error);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
return;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("transfer completed, len: %.4x, data: %.2x %.2x",
|
fp_dbg("transfer completed, len: %.4x, data: %.2x %.2x",
|
||||||
transfer->actual_length, (int)data[0], (int)data[1]);
|
(gint)transfer->actual_length, (int)data[0], (int)data[1]);
|
||||||
|
|
||||||
/* Check if we got 2 bytes, reg address 0x83 and its value */
|
/* Check if we got 2 bytes, reg address 0x83 and its value */
|
||||||
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT)) {
|
if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT)) {
|
||||||
/* finger present, start capturing */
|
/* finger present, start capturing */
|
||||||
fpi_imgdev_report_finger_status(dev, TRUE);
|
fpi_image_device_report_finger_status(dev, TRUE);
|
||||||
start_capture(dev);
|
start_capture(dev);
|
||||||
} else {
|
} else {
|
||||||
/* no finger, poll for a new histogram */
|
/* no finger, poll for a new histogram */
|
||||||
start_finger_detection(dev);
|
start_finger_detection(dev);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
g_free(data);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finger_det_reqs_cb(struct libusb_transfer *t)
|
static void finger_det_reqs_cb(FpiUsbTransfer *t, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer;
|
FpiUsbTransfer *transfer;
|
||||||
unsigned char *data;
|
FpImageDevice *dev = user_data;
|
||||||
int r;
|
|
||||||
struct fp_img_dev *dev = t->user_data;
|
|
||||||
|
|
||||||
if (t->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (error) {
|
||||||
fp_dbg("req transfer status %d\n", t->status);
|
fpi_image_device_session_error(dev, error);
|
||||||
fpi_imgdev_session_error(dev, -EIO);
|
return;
|
||||||
goto exit_free_transfer;
|
|
||||||
} else if (t->length != t->actual_length) {
|
|
||||||
fp_dbg("expected %d, got %d bytes", t->length, t->actual_length);
|
|
||||||
fpi_imgdev_session_error(dev, -EPROTO);
|
|
||||||
goto exit_free_transfer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = fpi_usb_transfer_new (device);
|
||||||
/* 2 bytes of result */
|
/* 2 bytes of result */
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
finger_det_data_cb, dev, BULK_TIMEOUT);
|
finger_det_data_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref(transfer);
|
||||||
r = libusb_submit_transfer(transfer);
|
|
||||||
if (r < 0) {
|
|
||||||
g_free(data);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
fpi_imgdev_session_error(dev, r);
|
|
||||||
}
|
|
||||||
exit_free_transfer:
|
|
||||||
libusb_free_transfer(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_finger_detection(struct fp_img_dev *dev)
|
static void start_finger_detection(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
int r;
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
FpiUsbTransfer *transfer;
|
||||||
struct libusb_transfer *transfer;
|
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (self->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer = fpi_usb_alloc();
|
transfer = fpi_usb_transfer_new(FP_DEVICE(dev));
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, finger_det_reqs,
|
transfer->short_is_error = TRUE;
|
||||||
sizeof(finger_det_reqs), finger_det_reqs_cb, dev, BULK_TIMEOUT);
|
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, finger_det_reqs,
|
||||||
r = libusb_submit_transfer(transfer);
|
sizeof(finger_det_reqs), NULL);
|
||||||
if (r < 0) {
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
libusb_free_transfer(transfer);
|
finger_det_reqs_cb, NULL);
|
||||||
fpi_imgdev_session_error(dev, r);
|
fpi_usb_transfer_unref(transfer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** CAPTURE ******/
|
/****** CAPTURE ******/
|
||||||
|
@ -191,207 +177,201 @@ enum capture_states {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns number of processed bytes */
|
/* Returns number of processed bytes */
|
||||||
static int process_strip_data(fpi_ssm *ssm, struct fp_img_dev *dev, unsigned char *data)
|
static gboolean process_strip_data(FpiSsm *ssm, FpImageDevice *dev,
|
||||||
|
unsigned char *data)
|
||||||
{
|
{
|
||||||
unsigned char *stripdata;
|
unsigned char *stripdata;
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
struct fpi_frame *stripe;
|
struct fpi_frame *stripe;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (data[0] != AES2550_EDATA_MAGIC) {
|
if (data[0] != AES2550_EDATA_MAGIC) {
|
||||||
fp_dbg("Bogus magic: %.2x\n", (int)(data[0]));
|
fp_dbg("Bogus magic: %.2x\n", (int)(data[0]));
|
||||||
return -EPROTO;
|
return FALSE;
|
||||||
}
|
}
|
||||||
len = data[1] * 256 + data[2];
|
len = data[1] * 256 + data[2];
|
||||||
if (len != (AES2550_STRIP_SIZE - 3)) {
|
if (len != (AES2550_STRIP_SIZE - 3)) {
|
||||||
fp_dbg("Bogus frame len: %.4x\n", len);
|
fp_dbg("Bogus frame len: %.4x\n", len);
|
||||||
}
|
}
|
||||||
stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bits per pixel */
|
stripe = g_malloc0(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bits per pixel */
|
||||||
stripe->delta_x = (int8_t)data[6];
|
stripe->delta_x = (int8_t)data[6];
|
||||||
stripe->delta_y = -(int8_t)data[7];
|
stripe->delta_y = -(int8_t)data[7];
|
||||||
stripdata = stripe->data;
|
stripdata = stripe->data;
|
||||||
memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
|
memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
|
||||||
aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
|
self->strips = g_slist_prepend(self->strips, stripe);
|
||||||
aesdev->strips_len++;
|
self->strips_len++;
|
||||||
|
|
||||||
fp_dbg("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
|
fp_dbg("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
|
||||||
|
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_reqs_cb(struct libusb_transfer *transfer)
|
static void capture_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
if (!error) {
|
||||||
|
fpi_ssm_next_state(transfer->ssm);
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
|
||||||
(transfer->length == transfer->actual_length)) {
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer)
|
static void capture_set_idle_reqs_cb(FpiUsbTransfer *transfer,
|
||||||
|
FpDevice *device, gpointer user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
|
||||||
|
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
if (!error && self->strips_len) {
|
||||||
(transfer->length == transfer->actual_length) &&
|
FpImage *img;
|
||||||
aesdev->strips_len) {
|
|
||||||
struct fp_img *img;
|
|
||||||
|
|
||||||
aesdev->strips = g_slist_reverse(aesdev->strips);
|
self->strips = g_slist_reverse(self->strips);
|
||||||
img = fpi_assemble_frames(&assembling_ctx,
|
img = fpi_assemble_frames(&assembling_ctx,
|
||||||
aesdev->strips, aesdev->strips_len);
|
self->strips, self->strips_len);
|
||||||
img->flags |= FP_IMG_PARTIAL;
|
g_slist_free_full(self->strips, g_free);
|
||||||
g_slist_free_full(aesdev->strips, g_free);
|
self->strips = NULL;
|
||||||
aesdev->strips = NULL;
|
self->strips_len = 0;
|
||||||
aesdev->strips_len = 0;
|
fpi_image_device_image_captured(dev, img);
|
||||||
fpi_imgdev_image_captured(dev, img);
|
fpi_image_device_report_finger_status(dev, FALSE);
|
||||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
|
||||||
/* marking machine complete will re-trigger finger detection loop */
|
/* marking machine complete will re-trigger finger detection loop */
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(transfer->ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
if (error)
|
||||||
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
|
else
|
||||||
|
fpi_ssm_mark_failed(transfer->ssm,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_read_data_cb(struct libusb_transfer *transfer)
|
static void capture_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
FpImageDevice *dev = FP_IMAGE_DEVICE(device);
|
||||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
|
||||||
unsigned char *data = transfer->buffer;
|
unsigned char *data = transfer->buffer;
|
||||||
int r;
|
|
||||||
|
|
||||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
if (error) {
|
||||||
fp_dbg("request is not completed, %d", transfer->status);
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
return;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_dbg("request completed, len: %.4x", transfer->actual_length);
|
fp_dbg("request completed, len: %.4x", (gint)transfer->actual_length);
|
||||||
if (transfer->actual_length >= 2)
|
if (transfer->actual_length >= 2)
|
||||||
fp_dbg("data: %.2x %.2x", (int)data[0], (int)data[1]);
|
fp_dbg("data: %.2x %.2x", (int)data[0], (int)data[1]);
|
||||||
|
|
||||||
switch (transfer->actual_length) {
|
switch (transfer->actual_length) {
|
||||||
case AES2550_STRIP_SIZE:
|
case AES2550_STRIP_SIZE:
|
||||||
r = process_strip_data(ssm, dev, data);
|
if (!process_strip_data(transfer->ssm, dev, data)) {
|
||||||
if (r < 0) {
|
fp_dbg("Processing strip data failed");
|
||||||
fp_dbg("Processing strip data failed: %d", r);
|
fpi_ssm_mark_failed(transfer->ssm,
|
||||||
fpi_ssm_mark_failed(ssm, -EPROTO);
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
aesdev->heartbeat_cnt = 0;
|
self->heartbeat_cnt = 0;
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
||||||
break;
|
break;
|
||||||
case AES2550_HEARTBEAT_SIZE:
|
case AES2550_HEARTBEAT_SIZE:
|
||||||
if (data[0] == AES2550_HEARTBEAT_MAGIC) {
|
if (data[0] == AES2550_HEARTBEAT_MAGIC) {
|
||||||
/* No data for a long time => finger was removed or there's no movement */
|
/* No data for a long time => finger was removed or there's no movement */
|
||||||
aesdev->heartbeat_cnt++;
|
self->heartbeat_cnt++;
|
||||||
if (aesdev->heartbeat_cnt == 3) {
|
if (self->heartbeat_cnt == 3) {
|
||||||
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
/* Got 3 heartbeat message, that's enough to consider that finger was removed,
|
||||||
* assemble image and submit it to the library */
|
* assemble image and submit it to the library */
|
||||||
fp_dbg("Got 3 heartbeats => finger removed");
|
fp_dbg("Got 3 heartbeats => finger removed");
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(transfer->ssm);
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA);
|
fpi_ssm_jump_to_state(transfer->ssm,
|
||||||
|
CAPTURE_READ_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fp_dbg("Short frame %d, skip", transfer->actual_length);
|
fp_dbg("Short frame %d, skip",
|
||||||
fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA);
|
(gint)transfer->actual_length);
|
||||||
|
fpi_ssm_jump_to_state(transfer->ssm, CAPTURE_READ_DATA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
g_free(transfer->buffer);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case CAPTURE_WRITE_REQS:
|
case CAPTURE_WRITE_REQS:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, capture_reqs,
|
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, capture_reqs,
|
||||||
sizeof(capture_reqs), capture_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(capture_reqs), NULL);
|
||||||
r = libusb_submit_transfer(transfer);
|
transfer->ssm = ssm;
|
||||||
if (r < 0) {
|
transfer->short_is_error = TRUE;
|
||||||
libusb_free_transfer(transfer);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
capture_reqs_cb, NULL);
|
||||||
}
|
fpi_usb_transfer_unref(transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_READ_DATA:
|
case CAPTURE_READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
unsigned char *data;
|
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
transfer->ssm = ssm;
|
||||||
capture_read_data_cb, ssm, BULK_TIMEOUT);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
|
capture_read_data_cb, NULL);
|
||||||
r = libusb_submit_transfer(transfer);
|
fpi_usb_transfer_unref(transfer);
|
||||||
if (r < 0) {
|
|
||||||
g_free(data);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_SET_IDLE:
|
case CAPTURE_SET_IDLE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, capture_set_idle_reqs,
|
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
||||||
sizeof(capture_set_idle_reqs), capture_set_idle_reqs_cb, ssm, BULK_TIMEOUT);
|
capture_set_idle_reqs,
|
||||||
r = libusb_submit_transfer(transfer);
|
sizeof(capture_set_idle_reqs),
|
||||||
if (r < 0) {
|
NULL);
|
||||||
libusb_free_transfer(transfer);
|
transfer->ssm = ssm;
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
transfer->short_is_error = TRUE;
|
||||||
}
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
|
capture_set_idle_reqs_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref(transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capture_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void capture_sm_complete(FpiSsm *ssm, FpDevice *_dev, void *user_data,
|
||||||
|
GError *error)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(_dev);
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(_dev);
|
||||||
|
|
||||||
fp_dbg("Capture completed");
|
fp_dbg("Capture completed");
|
||||||
if (aesdev->deactivating)
|
|
||||||
|
if (self->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
else if (fpi_ssm_get_error(ssm))
|
g_clear_pointer (&error, g_error_free);
|
||||||
fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm));
|
} else if (error) {
|
||||||
else
|
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(struct fp_img_dev *dev)
|
static void start_capture(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
fpi_ssm *ssm;
|
FpiSsm *ssm;
|
||||||
|
|
||||||
if (aesdev->deactivating) {
|
if (self->deactivating) {
|
||||||
complete_deactivation(dev);
|
complete_deactivation(dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aesdev->heartbeat_cnt = 0;
|
self->heartbeat_cnt = 0;
|
||||||
ssm = fpi_ssm_new(FP_DEV(dev), capture_run_state, CAPTURE_NUM_STATES, dev);
|
ssm = fpi_ssm_new(FP_DEVICE(dev), capture_run_state,
|
||||||
|
CAPTURE_NUM_STATES, dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
fpi_ssm_start(ssm, capture_sm_complete);
|
fpi_ssm_start(ssm, capture_sm_complete);
|
||||||
}
|
}
|
||||||
|
@ -420,201 +400,175 @@ enum activate_states {
|
||||||
ACTIVATE_NUM_STATES,
|
ACTIVATE_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init_reqs_cb(struct libusb_transfer *transfer)
|
static void init_reqs_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
if (!error) {
|
||||||
|
fpi_ssm_next_state(transfer->ssm);
|
||||||
if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
|
|
||||||
(transfer->length == transfer->actual_length)) {
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
}
|
}
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_read_data_cb(struct libusb_transfer *transfer)
|
static void init_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
if (!error) {
|
||||||
|
fpi_ssm_next_state(transfer->ssm);
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
}
|
}
|
||||||
g_free(transfer->buffer);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: use calibration table, datasheet is rather terse on that
|
/* TODO: use calibration table, datasheet is rather terse on that
|
||||||
* need more info for implementation */
|
* need more info for implementation */
|
||||||
static void calibrate_read_data_cb(struct libusb_transfer *transfer)
|
static void calibrate_read_data_cb(FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = transfer->user_data;
|
if (!error) {
|
||||||
|
fpi_ssm_next_state(transfer->ssm);
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
} else {
|
} else {
|
||||||
fpi_ssm_mark_failed(ssm, -EIO);
|
fpi_ssm_mark_failed(transfer->ssm, error);
|
||||||
}
|
}
|
||||||
g_free(transfer->buffer);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_run_state(FpiSsm *ssm, FpDevice *dev, void *user_data)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||||
case WRITE_INIT:
|
case WRITE_INIT:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, init_reqs,
|
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT, init_reqs,
|
||||||
sizeof(init_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
sizeof(init_reqs), NULL);
|
||||||
r = libusb_submit_transfer(transfer);
|
transfer->ssm = ssm;
|
||||||
if (r < 0) {
|
transfer->short_is_error = TRUE;
|
||||||
libusb_free_transfer(transfer);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
init_reqs_cb, NULL);
|
||||||
}
|
fpi_usb_transfer_unref(transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_DATA:
|
case READ_DATA:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
unsigned char *data;
|
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
transfer->ssm = ssm;
|
||||||
init_read_data_cb, ssm, BULK_TIMEOUT);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
|
init_read_data_cb, NULL);
|
||||||
r = libusb_submit_transfer(transfer);
|
fpi_usb_transfer_unref(transfer);
|
||||||
if (r < 0) {
|
|
||||||
g_free(data);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CALIBRATE:
|
case CALIBRATE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
|
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_OUT, calibrate_reqs,
|
fpi_usb_transfer_fill_bulk_full(transfer, EP_OUT,
|
||||||
sizeof(calibrate_reqs), init_reqs_cb, ssm, BULK_TIMEOUT);
|
calibrate_reqs,
|
||||||
r = libusb_submit_transfer(transfer);
|
sizeof(calibrate_reqs), NULL);
|
||||||
if (r < 0) {
|
transfer->ssm = ssm;
|
||||||
libusb_free_transfer(transfer);
|
transfer->short_is_error = TRUE;
|
||||||
fpi_ssm_mark_failed(ssm, -ENOMEM);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
}
|
init_reqs_cb, NULL);
|
||||||
|
fpi_usb_transfer_unref(transfer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_CALIB_TABLE:
|
case READ_CALIB_TABLE:
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = fpi_usb_alloc();
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
|
||||||
unsigned char *data;
|
|
||||||
|
|
||||||
data = g_malloc(AES2550_EP_IN_BUF_SIZE);
|
fpi_usb_transfer_fill_bulk(transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
|
||||||
libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(FP_DEV(dev)), EP_IN, data, AES2550_EP_IN_BUF_SIZE,
|
transfer->ssm = ssm;
|
||||||
calibrate_read_data_cb, ssm, BULK_TIMEOUT);
|
fpi_usb_transfer_submit(transfer, BULK_TIMEOUT, NULL,
|
||||||
|
calibrate_read_data_cb, NULL);
|
||||||
r = libusb_submit_transfer(transfer);
|
fpi_usb_transfer_unref(transfer);
|
||||||
if (r < 0) {
|
|
||||||
g_free(data);
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
fpi_ssm_mark_failed(ssm, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
static void activate_sm_complete(FpiSsm *ssm, FpDevice *_dev,
|
||||||
|
void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = user_data;
|
FpImageDevice *dev = user_data;
|
||||||
fp_dbg("status %d", fpi_ssm_get_error(ssm));
|
|
||||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
|
||||||
|
|
||||||
if (!fpi_ssm_get_error(ssm))
|
fpi_image_device_activate_complete(dev, error);
|
||||||
|
|
||||||
|
if (!error)
|
||||||
start_finger_detection(dev);
|
start_finger_detection(dev);
|
||||||
fpi_ssm_free(ssm);
|
fpi_ssm_free(ssm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_activate(struct fp_img_dev *dev)
|
static void dev_activate(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), activate_run_state,
|
||||||
ACTIVATE_NUM_STATES, dev);
|
ACTIVATE_NUM_STATES, dev);
|
||||||
fpi_ssm_start(ssm, activate_sm_complete);
|
fpi_ssm_start(ssm, activate_sm_complete);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_deactivate(struct fp_img_dev *dev)
|
static void dev_deactivate(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
|
|
||||||
aesdev->deactivating = TRUE;
|
self->deactivating = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_deactivation(struct fp_img_dev *dev)
|
static void complete_deactivation(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550(dev);
|
||||||
G_DEBUG_HERE();
|
G_DEBUG_HERE();
|
||||||
|
|
||||||
aesdev->deactivating = FALSE;
|
self->deactivating = FALSE;
|
||||||
g_slist_free(aesdev->strips);
|
g_slist_free(self->strips);
|
||||||
aesdev->strips = NULL;
|
self->strips = NULL;
|
||||||
aesdev->strips_len = 0;
|
self->strips_len = 0;
|
||||||
fpi_imgdev_deactivate_complete(dev);
|
fpi_image_device_deactivate_complete(dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
static void dev_init(FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
|
GError *error = NULL;
|
||||||
/* TODO check that device has endpoints we're using */
|
/* TODO check that device has endpoints we're using */
|
||||||
int r;
|
|
||||||
struct aes2550_dev *aes2550_dev;
|
|
||||||
|
|
||||||
r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
|
||||||
if (r < 0) {
|
|
||||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
fpi_image_device_open_complete(dev, error);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aes2550_dev = g_malloc0(sizeof(struct aes2550_dev));
|
static void dev_deinit(FpImageDevice *dev)
|
||||||
fp_dev_set_instance_data(FP_DEV(dev), aes2550_dev);
|
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dev_deinit(struct fp_img_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct aes2550_dev *aesdev;
|
GError *error = NULL;
|
||||||
aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
|
||||||
g_free(aesdev);
|
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)),
|
||||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
0, 0, &error);
|
||||||
fpi_imgdev_close_complete(dev);
|
fpi_image_device_close_complete(dev, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct usb_id id_table[] = {
|
static const FpIdEntry id_table [ ] = {
|
||||||
{ .vendor = 0x08ff, .product = 0x2550 }, /* AES2550 */
|
{ .vid = 0x08ff, .pid = 0x2550,
|
||||||
{ .vendor = 0x08ff, .product = 0x2810 }, /* AES2810 */
|
}, /* AES2550 */
|
||||||
{ 0, 0, 0, },
|
{ .vid = 0x08ff, .pid = 0x2810,
|
||||||
|
}, /* AES2810 */
|
||||||
|
{ .vid = 0, .pid = 0, .driver_data = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fp_img_driver aes2550_driver = {
|
static void fpi_device_aes2550_init(FpiDeviceAes2550 *self) {
|
||||||
.driver = {
|
}
|
||||||
.id = AES2550_ID,
|
static void fpi_device_aes2550_class_init(FpiDeviceAes2550Class *klass) {
|
||||||
.name = FP_COMPONENT,
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
|
||||||
.full_name = "AuthenTec AES2550/AES2810",
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
|
||||||
.id_table = id_table,
|
|
||||||
.scan_type = FP_SCAN_TYPE_SWIPE,
|
|
||||||
},
|
|
||||||
.flags = 0,
|
|
||||||
.img_height = -1,
|
|
||||||
.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
|
|
||||||
|
|
||||||
.open = dev_init,
|
dev_class->id = "aes2550";
|
||||||
.close = dev_deinit,
|
dev_class->full_name = "AuthenTec AES2550/AES2810";
|
||||||
.activate = dev_activate,
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
.deactivate = dev_deactivate,
|
dev_class->id_table = id_table;
|
||||||
};
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
|
img_class->img_open = dev_init;
|
||||||
|
img_class->img_close = dev_deinit;
|
||||||
|
img_class->activate = dev_activate;
|
||||||
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
|
img_class->img_width = FRAME_WIDTH + FRAME_WIDTH / 2;
|
||||||
|
img_class->img_height = -1;
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ mathlib_dep = cc.find_library('m', required: false)
|
||||||
drivers = get_option('drivers').split(',')
|
drivers = get_option('drivers').split(',')
|
||||||
virtual_drivers = [ 'virtual_image' ]
|
virtual_drivers = [ 'virtual_image' ]
|
||||||
#default_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan' ]
|
#default_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan' ]
|
||||||
default_drivers = [ 'upektc_img', 'vfs5011', 'aes3500', 'aes4000', 'aes1610', 'aes1660', 'aes2660', 'aes2501' ]
|
default_drivers = [ 'upektc_img', 'vfs5011', 'aes3500', 'aes4000', 'aes1610', 'aes1660', 'aes2660', 'aes2501', 'aes2550' ]
|
||||||
|
|
||||||
all_drivers = default_drivers + virtual_drivers
|
all_drivers = default_drivers + virtual_drivers
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue