コード例 #1
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
/* Returns number of processed bytes */
static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data)
{
	struct fpi_frame *stripe;
	unsigned char *stripdata;
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;

	stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
	stripdata = stripe->data;

	fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
		data[AESX660_LAST_FRAME_OFFSET]);

	stripe->delta_x = (int8_t)data[AESX660_FRAME_DELTA_X_OFFSET];
	stripe->delta_y = -(int8_t)data[AESX660_FRAME_DELTA_Y_OFFSET];
	fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);

	if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) {
		memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2);

		aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
		aesdev->strips_len++;
		return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
	} else {
		return 0;
	}

}
コード例 #2
0
ファイル: upektc.c プロジェクト: anarsoul/libfprint
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
ファイル: upektc.c プロジェクト: anarsoul/libfprint
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
ファイル: img.c プロジェクト: FabriceSalvaire/libfprint-baspi
/** \ingroup img
 * A quick convenience function to save an image to a file in
 * <a href="http://netpbm.sourceforge.net/doc/pgm.html">PGM format</a>.
 * \param img the image to save
 * \param path the path to save the image. Existing files will be overwritten.
 * \returns 0 on success, non-zero on error.
 */
API_EXPORTED int fp_img_save_to_file(struct fp_img *img, char *path)
{
	FILE *fd = fopen(path, "w");
	size_t write_size = img->width * img->height;
	int r;

	if (!fd) {
		fp_dbg("could not open '%s' for writing: %d", path, errno);
		return -errno;
	}

	r = fprintf(fd, "P5 %d %d 255\n", img->width, img->height);
	if (r < 0) {
		fp_err("pgm header write failed, error %d", r);
		return r;
	}

	r = fwrite(img->data, 1, write_size, fd);
	if (r < write_size) {
		fp_err("short write (%d)", r);
		return -EIO;
	}

	fclose(fd);
	fp_dbg("written to '%s'", path);
	return 0;
}
コード例 #5
0
ファイル: imgdev.c プロジェクト: herrsergio/libfprintPRB
void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
{
	struct fp_print_data *print;
	int r;
	fp_dbg("");

	if (imgdev->action_state != IMG_ACQUIRE_STATE_AWAIT_IMAGE) {
		fp_dbg("ignoring due to current state %d", imgdev->action_state);
		return;
	}

	if (imgdev->action_result) {
		fp_dbg("not overwriting existing action result");
		return;
	}

	r = sanitize_image(imgdev, &img);
	if (r < 0) {
		imgdev->action_result = r;
		fp_img_free(img);
		goto next_state;
	}

	fp_img_standardize(img);
	imgdev->acquire_img = img;
	r = fpi_img_to_print_data(imgdev, img, &print);
	if (r < 0) {
		fp_dbg("image to print data conversion error: %d", r);
		imgdev->action_result = FP_ENROLL_RETRY;
		goto next_state;
	} else if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) {
		fp_dbg("not enough minutiae, %d/%d", img->minutiae->num,
			MIN_ACCEPTABLE_MINUTIAE);
		fp_print_data_free(print);
		/* depends on FP_ENROLL_RETRY == FP_VERIFY_RETRY */
		imgdev->action_result = FP_ENROLL_RETRY;
		goto next_state;
	}

	imgdev->acquire_data = print;
	switch (imgdev->action) {
	case IMG_ACTION_ENROLL:
		imgdev->action_result = FP_ENROLL_COMPLETE;
		break;
	case IMG_ACTION_VERIFY:
		verify_process_img(imgdev);
		break;
	case IMG_ACTION_IDENTIFY:
		identify_process_img(imgdev);
		break;
	default:
		BUG();
		break;
	}

next_state:
	imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF;
	dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF);
}
コード例 #6
0
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
ファイル: data.c プロジェクト: anarsoul/libfprint
/** \ingroup dscv_print
 * Removes a discovered print from disk. After successful return of this
 * function, functions such as fp_dscv_print_get_finger() will continue to
 * operate as before, however calling fp_print_data_from_dscv_print() will
 * fail for obvious reasons.
 * \param print the discovered print to remove from disk
 * \returns 0 on success, negative on error
 */
API_EXPORTED int fp_dscv_print_delete(struct fp_dscv_print *print)
{
	int r;
	fp_dbg("remove at %s", print->path);
	r = g_unlink(print->path);
	if (r < 0)
		fp_dbg("unlink failed with error %d", r);

	/* FIXME: cleanup empty directory */
	return r;
}
コード例 #8
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
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);
}
コード例 #9
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
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);
}
コード例 #10
0
ファイル: imgdev.c プロジェクト: herrsergio/libfprintPRB
void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
	gboolean present)
{
	int r = imgdev->action_result;
	struct fp_print_data *data = imgdev->acquire_data;
	struct fp_img *img = imgdev->acquire_img;

	fp_dbg(present ? "finger on sensor" : "finger removed");

	if (present && imgdev->action_state == IMG_ACQUIRE_STATE_AWAIT_FINGER_ON) {
		dev_change_state(imgdev, IMGDEV_STATE_CAPTURE);
		imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_IMAGE;
		return;
	} else if (present
			|| imgdev->action_state != IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF) {
		fp_dbg("ignoring status report");
		return;
	}

	/* clear these before reporting results to avoid complications with
	 * call cascading in and out of the library */
	imgdev->acquire_img = NULL;
	imgdev->acquire_data = NULL;

	/* finger removed, report results */
	switch (imgdev->action) {
	case IMG_ACTION_ENROLL:
		fp_dbg("reporting enroll result");
		fpi_drvcb_enroll_stage_completed(imgdev->dev, r, data, img);
		if (r > 0 && r != FP_ENROLL_COMPLETE && r != FP_ENROLL_FAIL) {
			imgdev->action_result = 0;
			imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_ON;
			dev_change_state(imgdev, IMG_ACQUIRE_STATE_AWAIT_FINGER_ON);
		}
		break;
	case IMG_ACTION_VERIFY:
		fpi_drvcb_report_verify_result(imgdev->dev, r, img);
		fp_print_data_free(data);
		break;
	case IMG_ACTION_IDENTIFY:
		fpi_drvcb_report_identify_result(imgdev->dev, r,
			imgdev->identify_match_offset, img);
		fp_print_data_free(data);
		break;
	default:
		fp_err("unhandled action %d", imgdev->action);
		break;
	}
}
コード例 #11
0
ファイル: data.c プロジェクト: anarsoul/libfprint
/** \ingroup print_data
 * Removes a stored print from disk previously saved with fp_print_data_save().
 * \param dev the device that the print belongs to
 * \param finger the finger of the file you are deleting
 * \returns 0 on success, negative on error
 */
API_EXPORTED int fp_print_data_delete(struct fp_dev *dev,
	enum fp_finger finger)
{
	int r;
	gchar *path = get_path_to_print(dev, finger);

	fp_dbg("remove finger %d at %s", finger, path);
	r = g_unlink(path);
	g_free(path);
	if (r < 0)
		fp_dbg("unlink failed with error %d", r);

	/* FIXME: cleanup empty directory */
	return r;
}
コード例 #12
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len,
	libusb_transfer_cb_fn callback)
{
	struct fp_img_dev *dev = ssm->priv;
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *data;
	int r;

	if (!transfer) {
		fpi_ssm_mark_aborted(ssm, -ENOMEM);
		return;
	}

	data = g_malloc(buf_len);
	libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN,
		data, buf_len,
		callback, ssm, BULK_TIMEOUT);

	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		fp_dbg("Failed to submit rx transfer: %d\n", r);
		g_free(data);
		libusb_free_transfer(transfer);
		fpi_ssm_mark_aborted(ssm, r);
	}
}
コード例 #13
0
ファイル: vfs0050.c プロジェクト: Jack-Q/libfprint
static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
{
    struct fpi_ssm *init_ssm;
    struct vfs0050_dev *vdev = NULL;
    int r;
    fp_dbg("dev_open called");
    //TODO: this is probably frowned upon :/ but right now a reset is the only
    // way for me to know I'm working with a clean slate and the rest of this will work.
    // Will be trying to reverse engineer more of the protocol so I can avoid resetting
    // the device each time it's opened.
    libusb_reset_device(dev->udev);

    r = libusb_claim_interface(dev->udev, 0);
    if (r < 0) {
        fp_err("could not claim interface 0");
        return r;
    }
    libusb_control_transfer(dev->udev, 0x00, 0x09, 0x0001, 0, NULL, 0, 100);


    vdev = g_malloc0(sizeof(struct vfs0050_dev));
    vdev->scanbuf = g_malloc0(VFS0050_INITIAL_SCANBUF_SIZE);
    vdev->scanbuf_sz = VFS0050_INITIAL_SCANBUF_SIZE;
    vdev->calbuf = g_malloc0(VFS0050_INITIAL_SCANBUF_SIZE);
    vdev->calbuf_sz = VFS0050_INITIAL_SCANBUF_SIZE;
    dev->priv = vdev;
    init_ssm = fpi_ssm_new(dev->dev, state_init, M_INIT_NUMSTATES);
    init_ssm->priv = dev;
    fpi_ssm_start(init_ssm, state_init_complete);

    return 0;
}
コード例 #14
0
static void complete_deactivation(struct fp_img_dev *dev)
{
	struct etss801u_dev *etdev = dev->priv;
	fp_dbg("");
	etdev->deactivating = FALSE;
	fpi_imgdev_deactivate_complete(dev);
}
コード例 #15
0
ファイル: vcom5s.c プロジェクト: anarsoul/libfprint
static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg,
	unsigned char value)
{
	struct fp_img_dev *dev = ssm->priv;
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *data;
	int r;
	
	if (!transfer) {
		fpi_ssm_mark_aborted(ssm, -ENOMEM);
		return;
	}

	fp_dbg("set %02x=%02x", reg, value);
	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0);
	libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb,
		ssm, CTRL_TIMEOUT);
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		g_free(data);
		libusb_free_transfer(transfer);
		fpi_ssm_mark_aborted(ssm, r);
	}
}
コード例 #16
0
ファイル: vcom5s.c プロジェクト: anarsoul/libfprint
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;
	}
}
コード例 #17
0
ファイル: vcom5s.c プロジェクト: anarsoul/libfprint
static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd,
	unsigned char param)
{
	struct fp_img_dev *dev = ssm->priv;
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *data;
	int r;
	
	if (!transfer) {
		fpi_ssm_mark_aborted(ssm, -ENOMEM);
		return;
	}

	fp_dbg("cmd %02x param %02x", cmd, param);
	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0);
	libusb_fill_control_transfer(transfer, dev->udev, data, sm_exec_cmd_cb,
		ssm, CTRL_TIMEOUT);
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		g_free(data);
		libusb_free_transfer(transfer);
		fpi_ssm_mark_aborted(ssm, r);
	}
}
コード例 #18
0
ファイル: img.c プロジェクト: sunbiz/libfprint
struct fp_img *fpi_img_new(size_t length)
{
	struct fp_img *img = g_malloc0(sizeof(*img) + length);
	fp_dbg("length=%zd", length);
	img->length = length;
	return img;
}
コード例 #19
0
ファイル: imgdev.c プロジェクト: anarsoul/libfprint
void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status)
{
	fp_dbg("status %d", status);

	switch (imgdev->action) {
	case IMG_ACTION_ENROLL:
		fpi_drvcb_enroll_started(imgdev->dev, status);
		break;
	case IMG_ACTION_VERIFY:
		fpi_drvcb_verify_started(imgdev->dev, status);
		break;
	case IMG_ACTION_IDENTIFY:
		fpi_drvcb_identify_started(imgdev->dev, status);
		break;
	case IMG_ACTION_CAPTURE:
		fpi_drvcb_capture_started(imgdev->dev, status);
		break;
	default:
		fp_err("unhandled action %d", imgdev->action);
		return;
	}

	if (status == 0) {
		imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_ON;
		dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON);
	}
}
コード例 #20
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
static void capture_run_state(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;

	switch (ssm->cur_state) {
	case CAPTURE_SEND_LED_CMD:
		aesX660_send_cmd(ssm, led_solid_cmd, sizeof(led_solid_cmd),
			aesX660_send_cmd_cb);
	break;
	case CAPTURE_SEND_CAPTURE_CMD:
		aesdev->buffer_size = 0;
		aesdev->buffer_max = AESX660_HEADER_SIZE;
		aesX660_send_cmd(ssm, aesdev->start_imaging_cmd,
			aesdev->start_imaging_cmd_len,
			aesX660_send_cmd_cb);
	break;
	case CAPTURE_READ_STRIPE_DATA:
		aesX660_read_response(ssm, AESX660_BULK_TRANSFER_SIZE,
			capture_read_stripe_data_cb);
	break;
	case CAPTURE_SET_IDLE:
		fp_dbg("Got %d frames\n", aesdev->strips_len);
		aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
			capture_set_idle_cmd_cb);
	break;
	}
}
コード例 #21
0
ファイル: imgdev.c プロジェクト: anarsoul/libfprint
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
{
	fp_dbg("");

	switch (imgdev->action) {
	case IMG_ACTION_ENROLL:
		fpi_drvcb_enroll_stopped(imgdev->dev);
		break;
	case IMG_ACTION_VERIFY:
		fpi_drvcb_verify_stopped(imgdev->dev);
		break;
	case IMG_ACTION_IDENTIFY:
		fpi_drvcb_identify_stopped(imgdev->dev);
		break;
	case IMG_ACTION_CAPTURE:
		fpi_drvcb_capture_stopped(imgdev->dev);
		break;
	default:
		fp_err("unhandled action %d", imgdev->action);
		break;
	}

	imgdev->action = IMG_ACTION_NONE;
	imgdev->action_state = 0;
}
コード例 #22
0
ファイル: data.c プロジェクト: anarsoul/libfprint
static int load_from_file(char *path, struct fp_print_data **data)
{
	gsize length;
	gchar *contents;
	GError *err = NULL;
	struct fp_print_data *fdata;

	fp_dbg("from %s", path);
	g_file_get_contents(path, &contents, &length, &err);
	if (err) {
		int r = err->code;
		fp_err("%s load failed: %s", path, err->message);
		g_error_free(err);
		/* FIXME interpret more error codes */
		if (r == G_FILE_ERROR_NOENT)
			return -ENOENT;
		else
			return r;
	}

	fdata = fp_print_data_from_data(contents, length);
	g_free(contents);
	if (!fdata)
		return -EIO;
	*data = fdata;
	return 0;
}
コード例 #23
0
ファイル: sync.c プロジェクト: Gnate/libfprint
static void sync_open_cb(struct fp_dev *dev, int status, void *user_data)
{
	struct sync_open_data *odata = user_data;
	fp_dbg("status %d", status);
	odata->dev = dev;
	odata->status = status;
}
コード例 #24
0
ファイル: sync.c プロジェクト: Gnate/libfprint
/** \ingroup dev
 * Performs an enroll stage. See \ref enrolling for an explanation of enroll
 * stages.
 *
 * If no enrollment is in process, this kicks of the process and runs the
 * first stage. If an enrollment is already in progress, calling this
 * function runs the next stage, which may well be the last.
 *
 * A negative error code may be returned from any stage. When this occurs,
 * further calls to the enroll function will start a new enrollment process,
 * i.e. a negative error code indicates that the enrollment process has been
 * aborted. These error codes only ever indicate unexpected internal errors
 * or I/O problems.
 *
 * The RETRY codes from #fp_enroll_result may be returned from any enroll
 * stage. These codes indicate that the scan was not succesful in that the
 * user did not position their finger correctly or similar. When a RETRY code
 * is returned, the enrollment stage is <b>not</b> advanced, so the next call
 * into this function will retry the current stage again. The current stage may
 * need to be retried several times.
 *
 * The fp_enroll_result#FP_ENROLL_FAIL code may be returned from any enroll
 * stage. This code indicates that even though the scans themselves have been
 * acceptable, data processing applied to these scans produces incomprehensible
 * results. In other words, the user may have been scanning a different finger
 * for each stage or something like that. Like negative error codes, this
 * return code indicates that the enrollment process has been aborted.
 *
 * The fp_enroll_result#FP_ENROLL_PASS code will only ever be returned for
 * non-final stages. This return code indicates that the scan was acceptable
 * and the next call into this function will advance onto the next enroll
 * stage.
 *
 * The fp_enroll_result#FP_ENROLL_COMPLETE code will only ever be returned
 * from the final enroll stage. It indicates that enrollment completed
 * successfully, and that print_data has been assigned to point to the
 * resultant enrollment data. The print_data parameter will not be modified
 * during any other enrollment stages, hence it is actually legal to pass NULL
 * as this argument for all but the final stage.
 * 
 * If the device is an imaging device, it can also return the image from
 * the scan, even when the enroll fails with a RETRY or FAIL code. It is legal
 * to call this function even on non-imaging devices, just don't expect them to
 * provide images.
 *
 * \param dev the device
 * \param print_data a location to return the resultant enrollment data from
 * the final stage. Must be freed with fp_print_data_free() after use.
 * \param img location to store the scan image. accepts NULL for no image
 * storage. If an image is returned, it must be freed with fp_img_free() after
 * use.
 * \return negative code on error, otherwise a code from #fp_enroll_result
 */
API_EXPORTED int fp_enroll_finger_img(struct fp_dev *dev,
	struct fp_print_data **print_data, struct fp_img **img)
{
	struct fp_driver *drv = dev->drv;
	int stage = dev->__enroll_stage;
	gboolean final = FALSE;
	gboolean stopped = FALSE;
	struct sync_enroll_data *edata = NULL;
	int r;
	fp_dbg("");

	/* FIXME __enroll_stage is ugly, can we replace it by some function that
	 * says whether we're enrolling or not, and then put __enroll_stage into
	 * edata? */

	if (stage == -1) {
		edata = g_malloc0(sizeof(struct sync_enroll_data));
		r = fp_async_enroll_start(dev, sync_enroll_cb, edata);
		if (r < 0) {
			g_free(edata);
			return r;
		}

		dev->__enroll_stage = ++stage;
	} else if (stage >= dev->nr_enroll_stages) {
		fp_err("exceeding number of enroll stages for device claimed by "
			"driver %s (%d stages)", drv->name, dev->nr_enroll_stages);
		dev->__enroll_stage = -1;
		r = -EINVAL;
		final = TRUE;
コード例 #25
0
ファイル: upektc.c プロジェクト: anarsoul/libfprint
static void start_finger_detection(struct fp_img_dev *dev)
{
	int r;
	struct upektc_dev *upekdev = dev->priv;
	struct libusb_transfer *transfer;
	fp_dbg("");

	if (upekdev->deactivating) {
		complete_deactivation(dev);
		return;
	}

	transfer = libusb_alloc_transfer(0);
	if (!transfer) {
		fpi_imgdev_session_error(dev, -ENOMEM);
		return;
	}
	libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out,
		(unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
		finger_det_cmd_cb, dev, BULK_TIMEOUT);
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		fpi_imgdev_session_error(dev, r);
	}
}
コード例 #26
0
ファイル: img.c プロジェクト: zyh329/libfprint
int fpi_img_detect_minutiae(struct fp_img *img)
{
	struct fp_minutiae *minutiae;
	int r;
	int *direction_map, *low_contrast_map, *low_flow_map;
	int *high_curve_map, *quality_map;
	int map_w, map_h;
	unsigned char *bdata;
	int bw, bh, bd;
	GTimer *timer;

	if (img->flags & FP_IMG_STANDARDIZATION_FLAGS) {
		fp_err("cant detect minutiae for non-standardized image");
		return -EINVAL;
	}

	/* Remove convex hull points from partial image */
	if (img->flags & FP_IMG_PARTIAL)
		g_lfsparms_V2.remove_convex_hull_pts = TRUE;
	else
		g_lfsparms_V2.remove_convex_hull_pts = FALSE;

	/* 25.4 mm per inch */
	timer = g_timer_new();
	r = get_minutiae(&minutiae, &quality_map, &direction_map,
                         &low_contrast_map, &low_flow_map, &high_curve_map,
                         &map_w, &map_h, &bdata, &bw, &bh, &bd,
                         img->data, img->width, img->height, 8,
						 DEFAULT_PPI / (double)25.4, &g_lfsparms_V2);
	g_timer_stop(timer);
	fp_dbg("minutiae scan completed in %f secs", g_timer_elapsed(timer, NULL));
	g_timer_destroy(timer);
	if (r) {
		fp_err("get minutiae failed, code %d", r);
		return r;
	}
	fp_dbg("detected %d minutiae", minutiae->num);
	img->minutiae = minutiae;
	img->binarized = bdata;

	free(quality_map);
	free(direction_map);
	free(low_contrast_map);
	free(low_flow_map);
	free(high_curve_map);
	return minutiae->num;
}
コード例 #27
0
ファイル: upektc.c プロジェクト: anarsoul/libfprint
static void complete_deactivation(struct fp_img_dev *dev)
{
	struct upektc_dev *upekdev = dev->priv;
	fp_dbg("");

	upekdev->deactivating = FALSE;
	fpi_imgdev_deactivate_complete(dev);
}
コード例 #28
0
ファイル: aesx660.c プロジェクト: anarsoul/libfprint
static void activate_run_state(struct fpi_ssm *ssm)
{
	struct fp_img_dev *dev = ssm->priv;
	struct aesX660_dev *aesdev = dev->priv;

	switch (ssm->cur_state) {
	case ACTIVATE_SET_IDLE:
		aesdev->init_seq_idx = 0;
		fp_dbg("Activate: set idle\n");
		aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
			aesX660_send_cmd_cb);
	break;
	case ACTIVATE_SEND_READ_ID_CMD:
		fp_dbg("Activate: read ID\n");
		aesX660_send_cmd(ssm, read_id_cmd, sizeof(read_id_cmd),
			aesX660_send_cmd_cb);
	break;
	case ACTIVATE_READ_ID:
		/* Should return 8-byte response */
		aesX660_read_response(ssm, 8, activate_read_id_cb);
	break;
	case ACTIVATE_SEND_INIT_CMD:
		fp_dbg("Activate: send init seq #%d cmd #%d\n",
			aesdev->init_seq_idx,
			aesdev->init_cmd_idx);
		aesX660_send_cmd(ssm,
			aesdev->init_seq[aesdev->init_cmd_idx].cmd,
			aesdev->init_seq[aesdev->init_cmd_idx].len,
			aesX660_send_cmd_cb);
	break;
	case ACTIVATE_READ_INIT_RESPONSE:
		fp_dbg("Activate: read init response\n");
		/* Should return 4-byte response */
		aesX660_read_response(ssm, 4, activate_read_init_cb);
	break;
	case ACTIVATE_SEND_CALIBRATE_CMD:
		aesX660_send_cmd(ssm, calibrate_cmd, sizeof(calibrate_cmd),
			aesX660_send_cmd_cb);
	break;
	case ACTIVATE_READ_CALIBRATE_DATA:
		/* Should return 4-byte response */
		aesX660_read_response(ssm, 4, aesX660_read_calibrate_data_cb);
	break;
	}
}
コード例 #29
0
ファイル: core.c プロジェクト: vimiii/fprint-bsapi
static void register_driver(struct fp_driver *drv)
{
	if (drv->id == 0) {
		fp_err("not registering driver %s: driver ID is 0", drv->name);
		return;
	}
	registered_drivers = g_slist_prepend(registered_drivers, (gpointer) drv);
	fp_dbg("registered driver %s", drv->name);
}
コード例 #30
0
ファイル: vfs0050.c プロジェクト: Jack-Q/libfprint
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
{
    fp_dbg("dev_activate called");
    struct fpi_ssm *activate_ssm;
    activate_ssm = fpi_ssm_new(dev->dev, state_activate, M_ACTIVATE_NUMSTATES);
    activate_ssm->priv = dev;
    fpi_ssm_start(activate_ssm, state_activate_complete);
    return 0;
}