+ struct dev_context *devc;
+ int packet_size;
+
+ devc = sdi->priv;
+
+ if (devc->reply_size + len > MAX_REPLY_SIZE) {
+ /* Something went very wrong. */
+ sr_dbg("Receive buffer overrun.");
+ devc->reply_size = 0;
+ return;
+ }
+
+ memcpy(devc->reply + devc->reply_size, data, len);
+ devc->reply_size += len;
+ /* Sixth byte contains the length of the packet. */
+ if (devc->reply_size >= 7) {
+ packet_size = 7 + devc->reply[6] * 7 + 2;
+ if (devc->reply_size >= packet_size) {
+ testo_receive_packet(sdi);
+ devc->num_samples++;
+ devc->reply_size = 0;
+ if (devc->limit_samples && devc->num_samples >= devc->limit_samples)
+ dev_acquisition_stop(sdi, devc->cb_data);
+ else
+ testo_request_packet(sdi);
+ }
+ }
+
+}
+
+SR_PRIV void receive_transfer(struct libusb_transfer *transfer)
+{
+ struct dev_context *devc;
+ struct sr_dev_inst *sdi;
+ int ret;
+
+ sdi = transfer->user_data;
+ devc = sdi->priv;
+ if (transfer == devc->out_transfer)
+ /* Just the command acknowledgement. */
+ return;
+
+ if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
+ /* USB device was unplugged. */
+ dev_acquisition_stop(sdi, devc->cb_data);
+ } else if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
+ /* First two bytes in any transfer are FTDI status bytes. */
+ if (transfer->actual_length > 2)
+ receive_data(sdi, transfer->buffer + 2, transfer->actual_length - 2);
+ }
+ /* Anything else is either an error or a timeout, which is fine:
+ * we were just going to send another transfer request anyway. */
+
+ if (sdi->status == SR_ST_ACTIVE) {
+ if ((ret = libusb_submit_transfer(transfer) != 0)) {
+ sr_err("Unable to resubmit transfer: %s.",
+ libusb_error_name(ret));
+ g_free(transfer->buffer);
+ libusb_free_transfer(transfer);
+ dev_acquisition_stop(sdi, devc->cb_data);
+ }
+ } else {
+ /* This was the last transfer we're going to receive, so
+ * clean up now. */
+ g_free(transfer->buffer);
+ libusb_free_transfer(transfer);
+ }
+}
+
+static int handle_events(int fd, int revents, void *cb_data)
+{
+ struct dev_context *devc;
+ struct drv_context *drvc = di->priv;
+ struct sr_datafeed_packet packet;
+ struct sr_dev_inst *sdi;
+ struct timeval tv;
+ gint64 now;
+
+ (void)fd;
+ (void)revents;
+
+ sdi = cb_data;
+ devc = sdi->priv;
+
+ if (devc->limit_msec) {
+ now = g_get_monotonic_time() / 1000;
+ if (now > devc->end_time)
+ dev_acquisition_stop(sdi, devc->cb_data);
+ }
+
+ if (sdi->status == SR_ST_STOPPING) {
+ usb_source_remove(drvc->sr_ctx);
+
+ dev_close(sdi);
+
+ packet.type = SR_DF_END;
+ sr_session_send(sdi, &packet);
+ }
+
+ memset(&tv, 0, sizeof(struct timeval));
+ libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv,
+ NULL);
+
+ return TRUE;
+}
+
+static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
+{
+ struct drv_context *drvc;
+ struct dev_context *devc;
+ struct sr_usb_dev_inst *usb;
+ struct libusb_transfer *transfer;
+ int ret;
+ unsigned char *buf;