Beispiel #1
0
static void loop_run_state(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	struct v5s_dev *vdev = dev->priv;

	switch (ssm->cur_state) {
	case LOOP_SET_CONTRAST:
		sm_write_reg(ssm, REG_CONTRAST, 0x01);
		break;
	case LOOP_SET_GAIN:
		sm_write_reg(ssm, REG_GAIN, 0x29);
		break;
	case LOOP_CMD_SCAN:
		if (vdev->deactivating) {
			fp_dbg("deactivating, marking completed");
			fpi_ssm_mark_completed(ssm);
		} else
			sm_exec_cmd(ssm, CMD_SCAN, 0x00);
		break;
	case LOOP_CAPTURE:
		sm_do_capture(ssm);
		break;
	case LOOP_CAPTURE_DONE:
		fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN);
		break;
	}
}
Beispiel #2
0
static void capture_read_data_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	struct fp_img_dev *dev = ssm->priv;
	unsigned char *data = transfer->buffer;
	struct fp_img *img;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		fp_dbg("request is not completed, %d", transfer->status);
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	} else if (transfer->length != transfer->actual_length) {
		fp_dbg("expected %d, sent %d bytes", transfer->length, transfer->actual_length);
		fpi_ssm_mark_aborted(ssm, -EPROTO);
		goto out;
	}

	img = fpi_img_new(IMAGE_SIZE);
	memcpy(img->data, data, IMAGE_SIZE);
	fpi_imgdev_image_captured(dev, img);
	fpi_imgdev_report_finger_status(dev, FALSE);
	fpi_ssm_mark_completed(ssm);
out:
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
Beispiel #3
0
static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;

	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
		(transfer->length == transfer->actual_length)) {
		struct fp_img *img;

		aesdev->strips = g_slist_reverse(aesdev->strips);
		img = fpi_assemble_frames(aesdev->assembling_ctx, aesdev->strips, aesdev->strips_len);
		img->flags |= aesdev->extra_img_flags;
		g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL);
		g_slist_free(aesdev->strips);
		aesdev->strips = NULL;
		aesdev->strips_len = 0;
		fpi_imgdev_image_captured(dev, img);
		fpi_imgdev_report_finger_status(dev, FALSE);
		fpi_ssm_mark_completed(ssm);
	} else {
		fpi_ssm_mark_aborted(ssm, -EIO);
	}
	libusb_free_transfer(transfer);
}
Beispiel #4
0
/* Exec loop sequential state machine */
static void m_loop_state(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	vfs301_dev_t *vdev = dev->priv;

	switch (ssm->cur_state) {
	case M_REQUEST_PRINT:
		vfs301_proto_request_fingerprint(dev->udev, vdev);
		fpi_ssm_next_state(ssm);
		break;

	case M_WAIT_PRINT:
		/* Wait fingerprint scanning */
		async_sleep(200, ssm);
		break;

	case M_CHECK_PRINT:
		if (!vfs301_proto_peek_event(dev->udev, vdev))
			fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT);
		else
			fpi_ssm_next_state(ssm);
		break;

	case M_READ_PRINT_START:
		fpi_imgdev_report_finger_status(dev, TRUE);
		vfs301_proto_process_event_start(dev->udev, vdev);
		fpi_ssm_next_state(ssm);
		break;

	case M_READ_PRINT_WAIT:
		/* Wait fingerprint scanning */
		async_sleep(200, ssm);
		break;

	case M_READ_PRINT_POLL:
		{
		int rv = vfs301_proto_process_event_poll(dev->udev, vdev);
		assert(rv != VFS301_FAILURE);
		if (rv == VFS301_ONGOING)
			fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT);
		else
			fpi_ssm_next_state(ssm);
		}
		break;

	case M_SUBMIT_PRINT:
		if (submit_image(ssm)) {
			fpi_ssm_mark_completed(ssm);
			/* NOTE: finger off is expected only after submitting image... */
			fpi_imgdev_report_finger_status(dev, FALSE);
		} else {
			fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT);
		}
		break;
	}
}
Beispiel #5
0
static void upektc_next_init_cmd(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	struct upektc_dev *upekdev = dev->priv;

	upekdev->init_idx += 1;
	if (upekdev->init_idx == upekdev->setup_commands_len)
		fpi_ssm_mark_completed(ssm);
	else
		fpi_ssm_jump_to_state(ssm, WRITE_INIT);
}
Beispiel #6
0
/* Exec init sequential state machine */
static void m_init_state(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	vfs301_dev_t *vdev = dev->priv;

	assert(ssm->cur_state == 0);

	vfs301_proto_init(dev->udev, vdev);

	fpi_ssm_mark_completed(ssm);
}
Beispiel #7
0
static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;

	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
		(transfer->length == transfer->actual_length)) {
		fpi_ssm_mark_completed(ssm);
	} else {
		fpi_ssm_mark_aborted(ssm, -EIO);
	}
	libusb_free_transfer(transfer);
}
Beispiel #8
0
static void activate_read_init_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;
	unsigned char *data = transfer->buffer;

	fp_dbg("read_init_cb\n");

	if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
		(transfer->length != transfer->actual_length)) {
		fp_dbg("read_init transfer status: %d, actual_len: %d\n", transfer->status, transfer->actual_length);
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	}
	/* ID was read correctly */
	if (data[0] != 0x42 || data[3] != 0x01) {
		fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
			data[3]);
		fpi_ssm_mark_aborted(ssm, -EPROTO);
		goto out;
	}
	aesdev->init_cmd_idx++;
	if (aesdev->init_cmd_idx == aesdev->init_seq_len) {
		if (aesdev->init_seq_idx < 2)
			fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_READ_ID_CMD);
		else
			fpi_ssm_mark_completed(ssm);
		goto out;
	}

	fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD);
out:
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
Beispiel #9
0
static void state_init(struct fpi_ssm *ssm)
{
    int transferred;
    int to_send;
    struct libusb_transfer *transfer;
    struct fp_img_dev *dev = ssm->priv;
    struct vfs0050_dev *vfs_dev = dev->priv;
    switch (ssm->cur_state) {
    case M_INIT_START:
        //couple of synchronous transfers here in the beginning, don't think this hurts much.
        vfs_dev->tmpbuf[0] = 0x1a;
        libusb_bulk_transfer(dev->udev, EP1_OUT, vfs_dev->tmpbuf, 1, &transferred, BULK_TIMEOUT);
        libusb_bulk_transfer(dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, &transferred, BULK_TIMEOUT);
        fpi_ssm_next_state(ssm);
        break;
    case M_INIT_1_ONGOING:
        to_send = sizeof(vfs0050_init1) - vfs_dev->init1_offset;
        to_send = to_send >= 64 ? 64 : to_send;
        assert(to_send > 0);
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs0050_init1 + vfs_dev->init1_offset, to_send, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_1_STEP2:
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_1_STEP3:
        vfs_dev->tmpbuf[0] = 0x01;
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs_dev->tmpbuf, 1, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_1_STEP4:
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_2_ONGOING:
        to_send = sizeof(vfs0050_init2) - vfs_dev->init2_offset;
        to_send = to_send >= 64 ? 64 : to_send;
        assert(to_send > 0);
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs0050_init2 + vfs_dev->init2_offset, to_send, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_2_RECV_EP1_ONGOING:
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    case M_INIT_2_RECV_EP2_ONGOING:
        if (vfs_dev->calbuf_idx + 64 >= vfs_dev->calbuf_sz) {
            vfs_dev->calbuf_sz <<= 1;
            vfs_dev->calbuf = g_realloc(vfs_dev->calbuf, vfs_dev->calbuf_sz);
        }
        transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(transfer, dev->udev, EP2_IN, vfs_dev->calbuf + vfs_dev->calbuf_idx, 64, state_init_cb, ssm, BULK_TIMEOUT);
        libusb_submit_transfer(transfer);
        break;
    default:
        fpi_ssm_mark_completed(ssm);
        break;
    }
}
Beispiel #10
0
static void state_activate_cb(struct libusb_transfer *transfer)
{
    struct fpi_ssm *ssm = transfer->user_data;
    struct fp_img_dev *dev = ssm->priv;
    struct vfs0050_dev *vfs_dev = dev->priv;
    switch (ssm->cur_state) {
    case M_ACTIVATE_1_SINGLE_READ:
        //check bytes are 0x00 and 0x00
        if (vfs_dev->tmpbuf[0] != 0x00 || vfs_dev->tmpbuf[1] != 0x00) {
            fp_dbg("unexpected bytes back from endpoint in M_ACTIVATE_1_SINGLE_READ");
            libusb_free_transfer(transfer);
            fpi_ssm_jump_to_state(ssm, M_ACTIVATE_START);
            break;
        }
        libusb_free_transfer(transfer);
        fpi_ssm_next_state(ssm);
        break;
    case M_ACTIVATE_2_SEND:
        vfs_dev->activate_offset += transfer->actual_length;
        if (vfs_dev->activate_offset == sizeof(vfs0050_activate2)) { //finished sending this activation section
            fpi_ssm_next_state(ssm);
            break;
        }
        fpi_ssm_jump_to_state(ssm, M_ACTIVATE_2_SEND);
        break;
    case M_ACTIVATE_EP1_DRAIN:
        //just draining this data, not sure what it does yet.
        if (transfer->actual_length < 64) {
            libusb_free_transfer(transfer);
            fpi_ssm_next_state(ssm);
            break;
        }
        libusb_free_transfer(transfer);
        fpi_ssm_jump_to_state(ssm, M_ACTIVATE_EP1_DRAIN);
        break;
    case M_ACTIVATE_EP3_INT1:
        if (transfer->actual_length != 5) {
            fp_dbg("unexpected length for interrupt transfer in M_ACTIVATE_EP3_INT1");
            //TODO: fail here, exit ssm
        }
        fpi_ssm_next_state(ssm);
        break;
    case M_ACTIVATE_AWAIT_FINGER:
        //if we got here, it's time to read fingerprint data.
        //interrupt data should be 02 00 0e 00 f0
        if (vfs_dev->is_active) {
            if (transfer->actual_length != 5) {
                fp_dbg("unexpected length for interrupt transfer in M_ACTIVATE_AWAIT_FINGER");
                //TODO: fail here, exit ssm.
            }
            if (memcmp(vfs_dev->tmpbuf, vfs0050_valid_interrupt, 5) != 0) {
                fp_dbg("invalid interrupt data in M_ACTIVATE_AWAIT_FINGER");
                //TODO: fail here, exit ssm.
            }
            fpi_imgdev_report_finger_status(dev, TRUE); //report finger on to libfprint
            fpi_ssm_next_state(ssm);
        } else {
            fpi_ssm_mark_completed(ssm);
            //break fall through
        }
        break;
    case M_ACTIVATE_RECEIVE_FINGERPRINT:
        if (transfer->actual_length == 0) {
            libusb_free_transfer(transfer);
            fpi_ssm_next_state(ssm);
            break;
        }
        vfs_dev->scanbuf_idx += transfer->actual_length;
        libusb_free_transfer(transfer);
        fpi_ssm_jump_to_state(ssm, M_ACTIVATE_RECEIVE_FINGERPRINT);
        break;
    default:
        libusb_free_transfer(transfer);
        fpi_ssm_next_state(ssm);
        break;
    }
}