Example #1
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;
	}
}
Example #2
0
static void state_init_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;
    //TODO: check for transfer errors in tranfer->status
    switch (ssm->cur_state) {
    case M_INIT_1_ONGOING:
        vfs_dev->init1_offset += transfer->actual_length;
        libusb_free_transfer(transfer);
        if (vfs_dev->init1_offset == sizeof(vfs0050_init1)) { //done transferring this initialization section
            fpi_ssm_next_state(ssm);
            break;
        }
        fpi_ssm_jump_to_state(ssm, M_INIT_1_ONGOING);
        break;
    case M_INIT_2_ONGOING:
        vfs_dev->init2_offset += transfer->actual_length;
        libusb_free_transfer(transfer);
        if (vfs_dev->init2_offset == sizeof(vfs0050_init2)) { //done transferring this initialization section
            fpi_ssm_next_state(ssm);
            break;
        }
        fpi_ssm_jump_to_state(ssm, M_INIT_2_ONGOING);
        break;
    case M_INIT_2_RECV_EP1_ONGOING:
        //we wait for a timeout here indicating no more data to receive.
        if (transfer->actual_length < 64) {
            fpi_ssm_next_state(ssm);
            break;
        }
        fpi_ssm_jump_to_state(ssm, M_INIT_2_RECV_EP1_ONGOING);
        break;
    case M_INIT_2_RECV_EP2_ONGOING:
        vfs_dev->calbuf_idx += transfer->actual_length;
        if (transfer->actual_length < 64) {
            fpi_ssm_next_state(ssm);
            break;
        }
        fpi_ssm_jump_to_state(ssm, M_INIT_2_RECV_EP2_ONGOING);
        break;
    default:
        libusb_free_transfer(transfer);
        fpi_ssm_next_state(ssm);
        break;
    }

}
Example #3
0
static int submit_image(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	vfs301_dev_t *vdev = dev->priv;
	int height;
	struct fp_img *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);
		return 0;
	}
#endif

	img = fpi_img_new(VFS301_FP_OUTPUT_WIDTH * vdev->scanline_count);
	if (img == NULL)
		return 0;

	vfs301_extract_image(vdev, 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,
	 * or to the finger when I look at it?) */
	img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED;

	img->width = VFS301_FP_OUTPUT_WIDTH;
	img->height = height;

	img = fpi_img_resize(img, img->height * img->width);
	fpi_imgdev_image_captured(dev, img);

	return 1;
}
Example #4
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;
	}
}
Example #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);
}
Example #6
0
static void async_sleep_cb(void *data)
{
    struct fpi_ssm *ssm = data;
    struct fp_img_dev *dev = ssm->priv;
    struct vfs0050_dev *vfs_dev = dev->priv;
    if (vfs_dev->is_active) {
        fpi_ssm_jump_to_state(ssm, M_ACTIVATE_START);
    } else {
        fpi_ssm_next_state(ssm);
    }
}
Example #7
0
static void capture_read_stripe_data_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;
	int finger_missing = 0;
	size_t copied, actual_len = transfer->actual_length;

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

	fp_dbg("Got %d bytes of data", actual_len);
	do {
		copied = min(aesdev->buffer_max - aesdev->buffer_size, actual_len);
		memcpy(aesdev->buffer + aesdev->buffer_size,
			data,
			copied);
		actual_len -= copied;
		data += copied;
		aesdev->buffer_size += copied;
		fp_dbg("Copied %.4x bytes into internal buffer",
			copied);
		if (aesdev->buffer_size == aesdev->buffer_max) {
			if (aesdev->buffer_max == AESX660_HEADER_SIZE) {
				aesdev->buffer_max = aesdev->buffer[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
					(aesdev->buffer[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8) + AESX660_HEADER_SIZE;
				fp_dbg("Got frame, type %.2x size %.4x",
					aesdev->buffer[AESX660_RESPONSE_TYPE_OFFSET],
					aesdev->buffer_max);
				continue;
			} else {
				finger_missing |= process_stripe_data(ssm, aesdev->buffer);
				aesdev->buffer_max = AESX660_HEADER_SIZE;
				aesdev->buffer_size = 0;
			}
		}
	} while (actual_len);

	fp_dbg("finger %s\n", finger_missing ? "missing" : "present");

	if (finger_missing) {
		fpi_ssm_next_state(ssm);
	} else {
		fpi_ssm_jump_to_state(ssm, CAPTURE_READ_STRIPE_DATA);
	}
out:
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
static void et_write_init_cb(struct libusb_transfer* transfer)
{
 struct init_data* adata=transfer->user_data;
 if(transfer->status!=LIBUSB_TRANSFER_COMPLETED)
 {
  fpi_ssm_mark_aborted(adata->ssm,-EIO);
 }
 else if(transfer->length!=transfer->actual_length)
 {
  fpi_ssm_mark_aborted(adata->ssm,-EPROTO);
 }
 else
 {
  switch(adata->init->stage)
  {
   case 3:
   case 5:
   case 7:
   case 11:
   case 13:
   case 15:
   case 17:
   case 36:
   case 40:
   case 42:
   case 44:
   case 46:
   case 48:
   case 50:
   if(!adata->init->rstage)
   {
    //fp_dbg("(%02d) ->: %s",adata->init->stage,print_cmd_buf());
    adata->init->rstage++;
    fpi_ssm_jump_to_state(adata->ssm,adata->init->ssm_state);
    goto _wicb;
   }
   else
   {
    adata->init->rstage=0;
    //fp_dbg("(%02d) ->: RETURN BUF %d",adata->init->stage,transfer->actual_length);
    goto _wicbn;
   }
   break;
  }
  //fp_dbg("(%02d) ->: %s",adata->init->stage,print_cmd_buf());
_wicbn:  
  fpi_ssm_next_state(adata->ssm);
 }
_wicb: 
 libusb_free_transfer(transfer);
}
Example #9
0
static void activate_read_id_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;

	if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
		(transfer->length != transfer->actual_length)) {
		fp_dbg("read_id cmd failed\n");
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	}
	/* ID was read correctly */
	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_aborted(ssm, -EPROTO);
		goto out;
	}

	switch (aesdev->init_seq_idx) {
	case 0:
		aesdev->init_seq = aesdev->init_seqs[0];
		aesdev->init_seq_len = aesdev->init_seqs_len[0];
		aesdev->init_seq_idx = 1;
		aesdev->init_cmd_idx = 0;
		/* Do calibration only after 1st init sequence */
		fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD);
		break;
	case 1:
		aesdev->init_seq = aesdev->init_seqs[1];
		aesdev->init_seq_len = aesdev->init_seqs_len[1];
		aesdev->init_seq_idx = 2;
		aesdev->init_cmd_idx = 0;
		fpi_ssm_next_state(ssm);
		break;
	default:
		fp_dbg("Failed to init device! init status: %.2x\n", data[7]);
		fpi_ssm_mark_aborted(ssm, -EPROTO);
		break;

	}

out:
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
Example #10
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);
}
Example #11
0
static void finger_det_read_fd_data_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;

	aesdev->fd_data_transfer = NULL;

	if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
		fp_dbg("Cancelling transfer...\n");
		fpi_ssm_next_state(ssm);
		goto out;
	}

	if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
	   (transfer->length != transfer->actual_length)) {
		fp_dbg("Failed to read FD data\n");
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	}

	if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
		fp_dbg("Bogus FD response: %.2x\n", data[0]);
		fpi_ssm_mark_aborted(ssm, -EPROTO);
		goto out;
	}

	if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || aesdev->deactivating) {
		/* Finger present or we're deactivating... */
		fpi_ssm_next_state(ssm);
	} else {
		fp_dbg("Wait for finger returned %.2x as result\n",
			data[AESX660_FINGER_PRESENT_OFFSET]);
		fpi_ssm_jump_to_state(ssm, FINGER_DET_SEND_FD_CMD);
	}
out:
	g_free(data);
	libusb_free_transfer(transfer);
}
static void et_write_enroll_cb(struct libusb_transfer* transfer)
{
 struct init_data* adata=transfer->user_data;
 
 if(transfer->status!=LIBUSB_TRANSFER_COMPLETED)
 {
  fpi_ssm_mark_aborted(adata->ssm,-EIO);
 }
 else if(transfer->length!=transfer->actual_length)
 {
  fpi_ssm_mark_aborted(adata->ssm,-EPROTO);
 }
 else
 {
  switch(adata->init->stage)
  {
   case 26:
   case 29:
   case 31:
   if(!adata->init->rstage)
   {
    adata->init->rstage++;
    fpi_ssm_jump_to_state(adata->ssm,adata->init->ssm_state);
    goto _out;
   }
   else
   {
    adata->init->rstage=0;
    goto _wedcbn;
   }
   break;
  }
  //fp_dbg("(%02d) ->: %s",adata->init->stage,print_cmd_buf());
_wedcbn:  
  fpi_ssm_next_state(adata->ssm);
 }
_out: 
 libusb_free_transfer(transfer);
}
Example #13
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;
    }
}
static void et_read_answer_cb(struct libusb_transfer* transfer)
{
 int r;
 int len;
 int comb=0; //Combined buffer (answer+data) flag
 char* result;
 
 
 struct init_data* adata=transfer->user_data;
 if(transfer->status!=LIBUSB_TRANSFER_COMPLETED)
 {
  fpi_ssm_mark_aborted(adata->ssm,-EIO);
 }
 else
 {
  if((transfer->actual_length%2) && transfer->actual_length!=13) comb=1;
  if(comb) 
  {
   len=transfer->actual_length-13;
   //fp_dbg("<-: Read %d (combined)",transfer->actual_length-13);
  }
  else 
  {
   len=transfer->actual_length;
   //fp_dbg("<-: Read %d",transfer->actual_length);
  }
  if(!adata->init->rstage)
  {
   //Data buffer received
   if(len!=13) r=et_verify_answer(adata->init,len);
   else 
   {
    //fp_dbg("Result: %s",print_buf(ret_buf));
    r=et_verify_result(ret_buf);
    if(r) goto _erv;
    goto _ern;
   }
   //fp_dbg("verified");
   if(r)
   {
_erv:
    fpi_ssm_mark_aborted(adata->ssm,r);
    goto _eret;
   }
   adata->init->rstage++;
   if(!comb && len!=13) fpi_ssm_jump_to_state(adata->ssm,adata->init->ssm_state); //Jump back, and receive result
   else
   {
    //Result received at the end of data
    result=(char*)&ret_buf[len];
    r=et_verify_result(result);
    if(r) goto _erv;
_ern:    
    adata->init->rstage=0;
    adata->init->stage++;
    fpi_ssm_next_state(adata->ssm);
   }
  }
  else
  {
   //Result received
   if(len!=13) { r=-EPROTO; goto _erv; }
   r=et_verify_result(ret_buf);
   if(r) goto _erv;
   adata->init->stage++;
   adata->init->rstage=0;
   fpi_ssm_next_state(adata->ssm);
  }
 }
_eret: 
 libusb_free_transfer(transfer);
}