示例#1
0
文件: vfs301.c 项目: kunalg/libfprint
/* 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;
	}
}
示例#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);
}
示例#3
0
static void finger_det_data_cb(struct libusb_transfer *transfer)
{
	struct fp_img_dev *dev = transfer->user_data;
	struct upektc_dev *upekdev = dev->priv;
	unsigned char *data = transfer->buffer;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		fp_dbg("data transfer status %d\n", transfer->status);
		fpi_imgdev_session_error(dev, -EIO);
		goto out;
	} else if (transfer->length != transfer->actual_length) {
		fp_dbg("expected %d, got %d bytes", transfer->length,
			transfer->actual_length);
		fpi_imgdev_session_error(dev, -EPROTO);
	}

	if (finger_present(data, IMAGE_SIZE, upekdev->sum_threshold)) {
		/* finger present, start capturing */
		fpi_imgdev_report_finger_status(dev, TRUE);
		start_capture(dev);
	} else {
		/* no finger, poll for a new histogram */
		start_finger_detection(dev);
	}

out:
	g_free(data);
	libusb_free_transfer(transfer);
}
示例#4
0
static void capture_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	struct fp_img_dev *dev = ssm->priv;
	struct v5s_dev *vdev = dev->priv;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	}

	if (++vdev->capture_iteration == NR_REQS) {
		struct fp_img *img = vdev->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 */
		vdev->capture_img = NULL;

		fpi_imgdev_report_finger_status(dev, finger_is_present(img->data));
		fpi_imgdev_image_captured(dev, img);
		fpi_ssm_next_state(ssm);
	} else {
		capture_iterate(ssm);
	}

out:
	libusb_free_transfer(transfer);
}
示例#5
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);
}
static void et_read_poll_cb(struct libusb_transfer* transfer)
{
 int len;
 char* br;
 int r;
 
 struct poll_data* adata=transfer->user_data;
 struct fpi_img_dev* dev=adata->dev;
 if(transfer->status!=LIBUSB_TRANSFER_COMPLETED)
 {
  /*WORKAROUND NEEDED, SOMETIME ALL FREEZES, RESET DEVICE AND REACTIVATE???*/
  libusb_free_transfer(transfer);
  fp_dbg("ERROR");
  fpi_imgdev_session_error(dev,-EIO);
  //return;
  goto _st;
 }
 len=transfer->actual_length-13;
 if(len!=512)
 {
  fp_dbg("Invalid return buffer, length: %d",transfer->actual_length);
  libusb_free_transfer(transfer);
  fpi_imgdev_session_error(dev,-EPROTO);
  return;
 }
 libusb_free_transfer(transfer);
 //Check poll cmd result
 br=(char*)&ret_buf[len];
 r=et_verify_result(br);
 if(r)
 {
  fp_dbg("Invalid result: %s",print_buf(br));
  fpi_imgdev_session_error(dev,-EPROTO);
  return;
 }
 //fp_dbg("0x%02hhX,0x%02hhX",ret_buf[0],ret_buf[1]);
 if((unsigned char)ret_buf[0]==0x82)
 {
  if(adata->init->rstage<20) 
  {
  /*VERY UGLY workaround below, but I don't know how to deal with it.
  Sometime ret_buf[0] equals 0x82 at the first poll rounds, but
  really no finger on the scanner
  */ 
   fp_dbg("POLL WORKAROUND");
   goto _st;
  }
  //Finger detected
  //fp_dbg("FINGER DETECTED!");
  //fp_dbg("BUF: %s",print_buf(ret_buf));
  fpi_imgdev_report_finger_status(dev,TRUE);
  start_capture(dev);
  return;
 }
 //No finger detected
_st:
 adata->init->rstage++; 
 start_finger_detection(dev,adata);
}
示例#7
0
static void finger_det_sm_complete(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;
	int err = ssm->error;

	fp_dbg("Finger detection completed");
	fpi_imgdev_report_finger_status(dev, TRUE);
	fpi_ssm_free(ssm);

	if (aesdev->deactivating)
		complete_deactivation(dev);
	else if (err)
		fpi_imgdev_session_error(dev, err);
	else {
		fpi_imgdev_report_finger_status(dev, TRUE);
		start_capture(dev);
	}
}
static void capture_sm_complete(struct fpi_ssm *ssm)
{
	static struct poll_data adata;
	struct fp_img_dev *dev = ssm->priv;
	struct etss801u_dev *etdev = dev->priv;

	fp_dbg("");
	if (etdev->deactivating)
		complete_deactivation(dev);
	else if (ssm->error)
		fpi_imgdev_session_error(dev, ssm->error);
	else
		/*Done finger enrolling, assemble image and give it to library*/
		et_assemble_image(dev);
		fpi_imgdev_report_finger_status(dev, FALSE);
		memset(&einit,0,sizeof(struct et_init));
		adata.dev=(struct fpi_img_dev*)dev;
		adata.init=&einit;
		start_finger_detection(dev,&adata);
	fpi_ssm_free(ssm);
}
示例#9
0
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;

    }
}
示例#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;
    }
}