/* Submit asynchronous sleep */ static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; struct fpi_timeout *timeout; /* Add timeout */ timeout = fpi_timeout_add(msec, async_sleep_cb, ssm); if (timeout == NULL) { /* Failed to add timeout */ fp_err("failed to add timeout"); fpi_imgdev_session_error(dev, -ETIME); fpi_ssm_mark_aborted(ssm, -ETIME); } }
static void state_activate(struct fpi_ssm *ssm) { struct libusb_transfer *transfer; struct fp_img_dev *dev = ssm->priv; struct vfs0050_dev *vfs_dev = dev->priv; int to_send; switch (ssm->cur_state) { case M_ACTIVATE_START: vfs_dev->activate_offset = 0; transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs0050_activate1, 64, state_activate_cb, ssm, BULK_TIMEOUT); libusb_submit_transfer(transfer); break; case M_ACTIVATE_1_STEP2: transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs0050_activate1 + 64, 61, state_activate_cb, ssm, BULK_TIMEOUT); libusb_submit_transfer(transfer); break; case M_ACTIVATE_1_SINGLE_READ: transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, state_activate_cb, ssm, BULK_TIMEOUT); libusb_submit_transfer(transfer); break; case M_ACTIVATE_2_SEND: to_send = sizeof(vfs0050_activate2) - vfs_dev->activate_offset; to_send = to_send >= 64 ? 64 : to_send; transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP1_OUT, vfs0050_activate2 + vfs_dev->activate_offset, to_send, state_activate_cb, ssm, BULK_TIMEOUT); libusb_submit_transfer(transfer); break; case M_ACTIVATE_EP1_DRAIN: transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP1_IN, vfs_dev->tmpbuf, 64, state_activate_cb, ssm, BULK_TIMEOUT); libusb_submit_transfer(transfer); break; case M_ACTIVATE_EP3_INT1: //first interrupt, should be 5 x 0x00 transfer = libusb_alloc_transfer(0); libusb_fill_interrupt_transfer(transfer, dev->udev, EP3_IN, vfs_dev->tmpbuf, 8, state_activate_cb, ssm, INTERRUPT_TIMEOUT1); libusb_submit_transfer(transfer); break; case M_ACTIVATE_AWAIT_FINGER: //this sets up infinite wait for interrupt. When the interrupt occurs, we're ready to read data on EP2. if (!vfs_dev->is_active) { vfs_dev->is_active = 1; fpi_imgdev_activate_complete(dev, 0); //notify libfprint activation complete. } transfer = libusb_alloc_transfer(0); libusb_fill_interrupt_transfer(transfer, dev->udev, EP3_IN, vfs_dev->tmpbuf, 8, state_activate_cb, ssm, INTERRUPT_TIMEOUT_NONE); libusb_submit_transfer(transfer); break; case M_ACTIVATE_RECEIVE_FINGERPRINT: if (vfs_dev->scanbuf_idx + 64 >= vfs_dev->scanbuf_sz) { vfs_dev->scanbuf_sz <<= 1; vfs_dev->scanbuf = g_realloc(vfs_dev->scanbuf, vfs_dev->scanbuf_sz); } transfer = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(transfer, dev->udev, EP2_IN, vfs_dev->scanbuf + vfs_dev->scanbuf_idx, 64, state_activate_cb, ssm, 500); libusb_submit_transfer(transfer); break; case M_ACTIVATE_POST_RECEIVE: submit_image(dev); fpi_imgdev_report_finger_status(dev, FALSE); vfs_dev->activate_offset = 0; vfs_dev->scanbuf_idx = 0; fpi_timeout_add(300, async_sleep_cb, ssm); //wait a bit and see if we're swiping again. break; } }