Пример #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;
	}
}
Пример #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;
    }

}
Пример #3
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);
}
Пример #4
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);
    }
}
Пример #5
0
static void capture_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_next_state(ssm);
	} else {
		fpi_ssm_mark_aborted(ssm, -EIO);
	}
	libusb_free_transfer(transfer);
}
Пример #6
0
static void sm_write_reg_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
		fpi_ssm_mark_aborted(ssm, -EIO);
	else
		fpi_ssm_next_state(ssm);

	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
Пример #7
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);
}
Пример #8
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);
}
Пример #9
0
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);
}
Пример #10
0
static void aesX660_send_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_next_state(ssm);
	} else {
		fp_dbg("tx transfer status: %d, actual_len: %.4x\n",
			transfer->status, transfer->actual_length);
		fpi_ssm_mark_aborted(ssm, -EIO);
	}
	libusb_free_transfer(transfer);
}
Пример #11
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);
}
Пример #12
0
static void write_init_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	struct fp_img_dev *dev = ssm->priv;
	struct upektc_dev *upekdev = dev->priv;

	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
		(transfer->length == transfer->actual_length)) {
		if (upekdev->setup_commands[upekdev->init_idx].response_len)
			fpi_ssm_next_state(ssm);
		else
			upektc_next_init_cmd(ssm);
	} else {
		fpi_ssm_mark_aborted(ssm, -EIO);
	}
	libusb_free_transfer(transfer);
}
Пример #13
0
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);
}
Пример #14
0
static void aesX660_read_calibrate_data_cb(struct libusb_transfer *transfer)
{
	struct fpi_ssm *ssm = transfer->user_data;
	unsigned char *data = transfer->buffer;

	if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
		(transfer->length != transfer->actual_length)) {
		fpi_ssm_mark_aborted(ssm, -EIO);
		goto out;
	}
	/* Calibrate response was read correctly? */
	if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
		fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
		fpi_ssm_mark_aborted(ssm, -EPROTO);
		goto out;
	}

	fpi_ssm_next_state(ssm);
out:
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);
}
Пример #15
0
/* Callback of asynchronous sleep */
static void async_sleep_cb(void *data)
{
	struct fpi_ssm *ssm = data;

	fpi_ssm_next_state(ssm);
}
Пример #16
0
static void et_read_enroll_cb(struct libusb_transfer* transfer)
{
 int r;
 int len;
 int comb=0; //Combined buffer (data+result) 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);
  }
  //Data buffer received
  if(len!=13) r=et_verify_enroll_data(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) 
  {
   fp_dbg("We should not be here!");
   fpi_ssm_mark_aborted(adata->ssm,-EPROTO);
   //fpi_ssm_jump_to_state(adata->ssm,adata->init->ssm_state); //Jump back, and receive result
  }
  else
  {
   //Result received at the end of data
   switch(adata->init->stage)
   {
    case 17:
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23:
    case 24:
    //fp_dbg("Piece %d: %s",(adata->init->stage-17)+1,print_buf(et_img_buf[adata->init->stage-17]));
    result=(char*)&et_img_buf[adata->init->stage-17][len];
    break;
    
    default:
    result=(char*)&ret_buf[len];
    break;
   }
   r=et_verify_result(result);
   if(r) goto _erv;
_ern:    
   adata->init->rstage=0;
   adata->init->stage++;
   fpi_ssm_next_state(adata->ssm);
  }
 }
_eret:
 libusb_free_transfer(transfer); 
}
Пример #17
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;
    }
}
Пример #18
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;
    }
}
Пример #19
0
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);
}