Ejemplo n.º 1
0
	FalconCommLibUSB::~FalconCommLibUSB()
	{
		libusb_free_transfer(in_transfer);
		libusb_free_transfer(out_transfer);
		delete m_tv;
	}
Ejemplo n.º 2
0
FCDevice::Transfer::~Transfer()
{
    libusb_free_transfer(transfer);
}
Ejemplo n.º 3
0
/* read the content of SPI device to buf, make sure the buf is big enough before call  */
int32_t ch341SpiRead(uint8_t *buf, uint32_t add, uint32_t len)
{
    uint8_t out[CH341_MAX_PACKET_LEN];
    uint8_t in[CH341_PACKET_LENGTH];
    
    if (devHandle == NULL) return -1;
    /* what subtracted is: 1. first cs package, 2. leading command for every other packages,
     * 3. second package contains read flash command and 3 bytes address */
    const uint32_t max_payload = CH341_MAX_PACKET_LEN - CH341_PACKET_LENGTH - CH341_MAX_PACKETS + 1 - 4;
    uint32_t tmp, pkg_len, pkg_count;
    struct libusb_transfer *xferBulkIn, *xferBulkOut;
    uint32_t idx = 0;
    uint32_t ret = 0;
    int32_t old_counter;
    struct timeval tv = {0, 100};

    memset(out, 0xff, CH341_MAX_PACKET_LEN);
    for (int i = 1; i < CH341_MAX_PACKETS; ++i) // fill CH341A_CMD_SPI_STREAM for every packet
        out[i * CH341_PACKET_LENGTH] = CH341A_CMD_SPI_STREAM;
    memset(in, 0x00, CH341_PACKET_LENGTH);
    xferBulkIn  = libusb_alloc_transfer(0);
    xferBulkOut = libusb_alloc_transfer(0);

    while (len > 0) {
        ch341SpiCs(out, true);
        idx = CH341_PACKET_LENGTH + 1;
        out[idx++] = 0xC0; // byte swapped command for Flash Read
        tmp = add;
        for (int i = 0; i < 3; ++i) { // starting address of next read
            out[idx++] = swapByte((tmp >> 16) & 0xFF);
            tmp <<= 8;
        }
        if (len > max_payload) {
            pkg_len = CH341_MAX_PACKET_LEN;
            pkg_count = CH341_MAX_PACKETS - 1;
            len -= max_payload;
            add += max_payload;
        } else {
            pkg_count = (len + 4) / (CH341_PACKET_LENGTH - 1);
            if ((len + 4) % (CH341_PACKET_LENGTH - 1)) pkg_count ++;
            pkg_len = (pkg_count) * CH341_PACKET_LENGTH + ((len + 4) % (CH341_PACKET_LENGTH - 1)) + 1;
            len = 0;
        }
        bulkin_count = 0;
        libusb_fill_bulk_transfer(xferBulkIn, devHandle, BULK_READ_ENDPOINT, in,
                CH341_PACKET_LENGTH, cbBulkIn, buf, DEFAULT_TIMEOUT);
        buf += max_payload; // advance user's pointer
        libusb_submit_transfer(xferBulkIn);
        libusb_fill_bulk_transfer(xferBulkOut, devHandle, BULK_WRITE_ENDPOINT, out,
                pkg_len, cbBulkOut, NULL, DEFAULT_TIMEOUT);
        libusb_submit_transfer(xferBulkOut);
        old_counter = bulkin_count;
        while (bulkin_count < pkg_count) {
            libusb_handle_events_timeout(NULL, &tv);
            if (bulkin_count == -1) { // encountered error
                len = 0;
                ret = -1;
                break;
            }
            if (old_counter != bulkin_count) { // new package came
                if (bulkin_count != pkg_count)
                    libusb_submit_transfer(xferBulkIn);  // resubmit bulk in request
                old_counter = bulkin_count;
            }
        }
        ch341SpiCs(out, false);
        ret = usbTransfer(__func__, BULK_WRITE_ENDPOINT, out, 3);
        if (ret < 0) break;
        if (force_stop == 1) { // user hit ctrl+C
            force_stop = 0;
            if (len > 0)
                fprintf(stderr, "User hit Ctrl+C, reading unfinished.\n");
            break;
        }
    }
    libusb_free_transfer(xferBulkIn);
    libusb_free_transfer(xferBulkOut);
    return ret;
}
Ejemplo n.º 4
0
///////////////////////////////////////////////////////////////////////////////
///@author      Nicolae Bodislav
///@brief       Writes data from the USB device on bulk.
///@param       [in]p_pData - the buffer that contains the data to write
///@param       [in]p_nLength - size of the data contained in the buffer
///@retval      how many bytes were actually written; or < 0 for error
///////////////////////////////////////////////////////////////////////////////
int CUSBLink::WriteBulk(const unsigned char* p_pData, uint32_t p_nLength)
{
    m_nCb = 0;
    m_nTrasferedLength = 0;
    if(p_nLength > MAX_LENGTH)
    {
         NLOG_ERR("[CUSBLink][WriteBulk] To much data to write. Maz is %d", MAX_LENGTH);
         return -1;
    }

    if(m_pDevh == NULL)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Device not open.");
        return -1;
    }

    int rez = libusb_claim_interface(m_pDevh, 0);
    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] USB_claim_interface error %d\n", rez);
        return -2;
    }

    m_enumDealoc = CUSBLink::INTERFACE;

    m_pData_transfer = NULL;
    m_pData_transfer = libusb_alloc_transfer(0);
    if (!m_pData_transfer)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Transfer couldn't be allocated.");
        return -ENOMEM;
    }

    libusb_fill_bulk_transfer(m_pData_transfer, m_pDevh, m_cWriteEndpoint, (unsigned char*)p_pData, p_nLength, Cb_TransferRead, this, 1000);

    m_enumDealoc = CUSBLink::TRANSFER;


    rez = libusb_submit_transfer(m_pData_transfer);

    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Transfer couldn't be submitted.");

        libusb_cancel_transfer(m_pData_transfer);
        m_enumDealoc = CUSBLink::INTERFACE;

        while (!m_nCb)
        {   rez = libusb_handle_events(m_pContex);
            if (rez < 0)
            {   break;
            }
        }

        libusb_free_transfer(m_pData_transfer);

        return -1;
    }

    while (!m_nCb)
    {
        rez = libusb_handle_events(m_pContex);
        if (rez < 0)
        {
            libusb_free_transfer(m_pData_transfer);
            return -1;
        }
    }

    if (m_bRawLog)
    {   NLOG_DBG_HEX("[CUSBLink][WriteBulk] Wrote packet:", p_pData, m_nTrasferedLength);
    }

    return m_nTrasferedLength;
}
Ejemplo n.º 5
0
static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
	unsigned char endpoint, unsigned char *buffer, int length,
	int *transferred, unsigned int timeout, unsigned char type)
{
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	int completed = 0;
	int r;

	if (!transfer)
		return LIBUSB_ERROR_NO_MEM;

	libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
		bulk_transfer_cb, &completed, timeout);
	transfer->type = type;

	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		return r;
	}

	while (!completed) {
		r = libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed);
		if (r < 0) {
			if (r == LIBUSB_ERROR_INTERRUPTED)
				continue;
			libusb_cancel_transfer(transfer);
			while (!completed)
				if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
					break;
			libusb_free_transfer(transfer);
			return r;
		}
	}

	*transferred = transfer->actual_length;
	switch (transfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		r = 0;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		r = LIBUSB_ERROR_TIMEOUT;
		break;
	case LIBUSB_TRANSFER_STALL:
		r = LIBUSB_ERROR_PIPE;
		break;
	case LIBUSB_TRANSFER_OVERFLOW:
		r = LIBUSB_ERROR_OVERFLOW;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		r = LIBUSB_ERROR_NO_DEVICE;
		break;
	default:
		usbi_warn(HANDLE_CTX(dev_handle),
			"unrecognised status code %d", transfer->status);
		r = LIBUSB_ERROR_OTHER;
	}

	libusb_free_transfer(transfer);
	return r;
}
Ejemplo n.º 6
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
	struct sr_dev_driver *di = sdi->driver;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	struct sr_usb_dev_inst *usb;
	GVariant *gvar, *rational[2];
	const uint64_t *si;
	int req_len, buf_len, len, ret;
	unsigned char buf[9];

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	drvc = di->context;
	devc = sdi->priv;
	usb = sdi->conn;

	devc->num_samples = 0;

	std_session_send_df_header(sdi);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		/* Force configuration. */
		kecheng_kc_330b_configure(sdi);

		if (kecheng_kc_330b_status_get(sdi, &ret) != SR_OK)
			return SR_ERR;
		if (ret != DEVICE_ACTIVE) {
			sr_err("Device is inactive");
			/* Still continue though, since the device will
			 * just return 30.0 until the user hits the button
			 * on the device -- and then start feeding good
			 * samples back. */
		}
	} else {
		if (kecheng_kc_330b_log_info_get(sdi, buf) != SR_OK)
			return SR_ERR;
		devc->mqflags = buf[4] ? SR_MQFLAG_SPL_TIME_WEIGHT_S : SR_MQFLAG_SPL_TIME_WEIGHT_F;
		devc->mqflags |= buf[5] ? SR_MQFLAG_SPL_FREQ_WEIGHT_C : SR_MQFLAG_SPL_FREQ_WEIGHT_A;
		devc->stored_samples = (buf[7] << 8) | buf[8];
		if (devc->stored_samples == 0) {
			/* Notify frontend of empty log by sending start/end packets. */
			std_session_send_df_end(sdi);
			return SR_OK;
		}

		if (devc->limit_samples && devc->limit_samples < devc->stored_samples)
			devc->stored_samples = devc->limit_samples;

		si = kecheng_kc_330b_sample_intervals[buf[1]];
		rational[0] = g_variant_new_uint64(si[0]);
		rational[1] = g_variant_new_uint64(si[1]);
		gvar = g_variant_new_tuple(rational, 2);
		src = sr_config_new(SR_CONF_SAMPLE_INTERVAL, gvar);
		packet.type = SR_DF_META;
		packet.payload = &meta;
		meta.config = g_slist_append(NULL, src);
		sr_session_send(sdi, &packet);
		g_free(src);
	}

	if (!(devc->xfer = libusb_alloc_transfer(0)))
		return SR_ERR;

	usb_source_add(sdi->session, drvc->sr_ctx, 10,
		kecheng_kc_330b_handle_events, (void *)sdi);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		buf[0] = CMD_GET_LIVE_SPL;
		buf_len = 1;
		devc->state = LIVE_SPL_WAIT;
		devc->last_live_request = g_get_monotonic_time() / 1000;
		req_len = 3;
	} else {
		buf[0] = CMD_GET_LOG_DATA;
		buf[1] = 0;
		buf[2] = 0;
		buf_len = 4;
		devc->state = LOG_DATA_WAIT;
		if (devc->stored_samples < 63)
			buf[3] = devc->stored_samples;
		else
			buf[3] = 63;
		/* Command ack byte + 2 bytes per sample. */
		req_len = 1 + buf[3] * 2;
	}

	ret = libusb_bulk_transfer(usb->devhdl, EP_OUT, buf, buf_len, &len, 5);
	if (ret != 0 || len != 1) {
		sr_dbg("Failed to start acquisition: %s", libusb_error_name(ret));
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	libusb_fill_bulk_transfer(devc->xfer, usb->devhdl, EP_IN, devc->buf,
			req_len, kecheng_kc_330b_receive_transfer, (void *)sdi, 15);
	if (libusb_submit_transfer(devc->xfer) != 0) {
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	return SR_OK;
}
Ejemplo n.º 7
0
int main(void)
{
	struct sigaction sigact;
	int r = 1;

	exit_sem = sem_open (SEM_NAME, O_CREAT, 0);
	if (!exit_sem) {
		fprintf(stderr, "failed to initialise semaphore error %d", errno);
		exit(1);
	}

	/* only using this semaphore in this process so go ahead and unlink it now */
	sem_unlink (SEM_NAME);

	r = libusb_init(NULL);
	if (r < 0) {
		fprintf(stderr, "failed to initialise libusb\n");
		exit(1);
	}

	r = find_dpfp_device();
	if (r < 0) {
		fprintf(stderr, "Could not find/open device\n");
		goto out;
	}

	r = libusb_claim_interface(devh, 0);
	if (r < 0) {
		fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r));
		goto out;
	}
	printf("claimed interface\n");

	r = print_f0_data();
	if (r < 0)
		goto out_release;

	r = do_init();
	if (r < 0)
		goto out_deinit;

	/* async from here onwards */

	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);

	r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL);
	if (r)
		goto out_deinit;

	r = alloc_transfers();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	r = init_capture();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	while (!do_exit)
		sem_wait(exit_sem);

	printf("shutting down...\n");
	pthread_join(poll_thread, NULL);

	r = libusb_cancel_transfer(irq_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	r = libusb_cancel_transfer(img_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	while (img_transfer || irq_transfer)
		if (libusb_handle_events(NULL) < 0)
			break;

	if (do_exit == 1)
		r = 0;
	else
		r = 1;

out_deinit:
	libusb_free_transfer(img_transfer);
	libusb_free_transfer(irq_transfer);
	set_mode(0);
	set_hwstat(0x80);
out_release:
	libusb_release_interface(devh, 0);
out:
	libusb_close(devh);
	libusb_exit(NULL);
	return r >= 0 ? r : -r;
}
static int usb_close(void *transport_config){
    int c;
    // @TODO: remove all run loops!

    switch (libusb_state){
        case LIB_USB_CLOSED:
            break;

        case LIB_USB_TRANSFERS_ALLOCATED:
            libusb_state = LIB_USB_INTERFACE_CLAIMED;

            if(usb_timer_active) {
                run_loop_remove_timer(&usb_timer);
                usb_timer_active = 0;
            }

            // Cancel any asynchronous transfers
            for (c = 0 ; c < ASYNC_BUFFERS ; c++) {
                libusb_cancel_transfer(event_in_transfer[c]);
                libusb_cancel_transfer(acl_in_transfer[c]);
#ifdef HAVE_SCO
                libusb_cancel_transfer(sco_in_transfer[c]);
#endif
            }

            /* TODO - find a better way to ensure that all transfers have completed */
            struct timeval tv;
            memset(&tv, 0, sizeof(struct timeval));
            libusb_handle_events_timeout(NULL, &tv);

            if (doing_pollfds){
                int r;
                for (r = 0 ; r < num_pollfds ; r++) {
                    data_source_t *ds = &pollfd_data_sources[r];
                    run_loop_remove_data_source(ds);
                }
                free(pollfd_data_sources);
                pollfd_data_sources = NULL;
                num_pollfds = 0;
                doing_pollfds = 0;
            }

        case LIB_USB_INTERFACE_CLAIMED:
            for (c = 0 ; c < ASYNC_BUFFERS ; c++) {
                if (event_in_transfer[c]) libusb_free_transfer(event_in_transfer[c]);
                if (acl_in_transfer[c])   libusb_free_transfer(acl_in_transfer[c]);
#ifdef HAVE_SCO
                if (sco_in_transfer[c])   libusb_free_transfer(sco_in_transfer[c]);
#endif
            }

            // TODO free control and acl out transfers

            libusb_release_interface(handle, 0);

        case LIB_USB_DEVICE_OPENDED:
            libusb_close(handle);

        case LIB_USB_OPENED:
            libusb_exit(NULL);
    }

    libusb_state = LIB_USB_CLOSED;
    handle = NULL;

    return 0;
}
Ejemplo n.º 9
0
	void FalconCommLibUSB::cb_in(struct libusb_transfer *transfer)
	{
		((FalconCommLibUSB*)transfer->user_data)->setSent();
		libusb_free_transfer(transfer);
	}
Ejemplo n.º 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;
    }
}
Ejemplo n.º 11
0
static void generic_async_cb(struct libusb_transfer *t)
{
    libusb_free_transfer(t);
}
Ejemplo n.º 12
0
 ~Transfer() {
     libusb_free_transfer(xfer_);
     if (pack_) {
         pack_->destroy();
     }
 }
Ejemplo n.º 13
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	GSList *usb_devices, *devices, *l;
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct device_info dev_info;
	unsigned int i;
	int ret;

	(void)options;

	devices = NULL;
	drvc = di->context;
	drvc->instances = NULL;

	usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_VID_PID);

	if (!usb_devices)
		return NULL;

	for (l = usb_devices; l; l = l->next) {
		usb = l->data;

		if ((ret = sl2_get_device_info(*usb, &dev_info)) < 0) {
			sr_warn("Failed to get device information: %d.", ret);
			sr_usb_dev_inst_free(usb);
			continue;
		}

		devc = g_malloc0(sizeof(struct dev_context));

		if (!(devc->xfer_in = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			g_free(devc);
			continue;
		}

		if (!(devc->xfer_out = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			g_free(devc);
			continue;
		}

		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INACTIVE;
		sdi->vendor = g_strdup(VENDOR_NAME);
		sdi->model = g_strdup(MODEL_NAME);
		sdi->version = g_strdup_printf("%u.%u", dev_info.fw_ver_major, dev_info.fw_ver_minor);
		sdi->serial_num = g_strdup_printf("%d", dev_info.serial);
		sdi->priv = devc;
		sdi->driver = di;
		sdi->inst_type = SR_INST_USB;
		sdi->conn = usb;

		for (i = 0; i < ARRAY_SIZE(channel_names); i++)
			devc->channels[i] = sr_channel_new(sdi, i,
				SR_CHANNEL_LOGIC, TRUE, channel_names[i]);

		devc->state = STATE_IDLE;
		devc->next_state = STATE_IDLE;

		/* Set default samplerate. */
		sl2_set_samplerate(sdi, DEFAULT_SAMPLERATE);

		/* Set default capture ratio. */
		devc->capture_ratio = 0;

		/* Set default after trigger delay. */
		devc->after_trigger_delay = 0;

		memset(devc->xfer_buf_in, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);
		memset(devc->xfer_buf_out, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);

		libusb_fill_control_setup(devc->xfer_buf_in,
			USB_REQUEST_TYPE_IN, USB_HID_GET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);
		libusb_fill_control_setup(devc->xfer_buf_out,
			USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);

		devc->xfer_data_in = devc->xfer_buf_in +
			LIBUSB_CONTROL_SETUP_SIZE;
		devc->xfer_data_out = devc->xfer_buf_out +
			LIBUSB_CONTROL_SETUP_SIZE;

		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);
	}

	g_slist_free(usb_devices);

	return devices;
}
Ejemplo n.º 14
0
static int lusb_init_stream(void *driver, struct bladerf_stream *stream,
                            size_t num_transfers)
{
    int status = 0;
    size_t i;
    struct lusb_stream_data *stream_data;

    /* Fill in backend stream information */
    stream_data = malloc(sizeof(struct lusb_stream_data));
    if (!stream_data) {
        return BLADERF_ERR_MEM;
    }

    /* Backend stream information */
    stream->backend_data = stream_data;
    stream_data->transfers = NULL;
    stream_data->transfer_status = NULL;
    stream_data->num_transfers = num_transfers;
    stream_data->num_avail = 0;
    stream_data->i = 0;

    stream_data->transfers =
        malloc(num_transfers * sizeof(struct libusb_transfer *));

    if (stream_data->transfers == NULL) {
        log_error("Failed to allocate libusb tranfers\n");
        status = BLADERF_ERR_MEM;
        goto error;
    }

    stream_data->transfer_status =
        calloc(num_transfers, sizeof(transfer_status));

    if (stream_data->transfer_status == NULL) {
        log_error("Failed to allocated libusb transfer status array\n");
        status = BLADERF_ERR_MEM;
        goto error;
    }

    /* Create the libusb transfers */
    for (i = 0; i < stream_data->num_transfers; i++) {
        stream_data->transfers[i] = libusb_alloc_transfer(0);

        /* Upon error, start tearing down anything we've started allocating
         * and report that the stream is in a bad state */
        if (stream_data->transfers[i] == NULL) {

            /* Note: <= 0 not appropriate as we're dealing
             *       with an unsigned index */
            while (i > 0) {
                if (--i) {
                    libusb_free_transfer(stream_data->transfers[i]);
                    stream_data->transfers[i] = NULL;
                    stream_data->transfer_status[i] = TRANSFER_UNINITIALIZED;
                    stream_data->num_avail--;
                }
            }

            status = BLADERF_ERR_MEM;
            break;
        } else {
            stream_data->transfer_status[i] = TRANSFER_AVAIL;
            stream_data->num_avail++;
        }
    }

error:
    if (status != 0) {
        free(stream_data->transfer_status);
        free(stream_data->transfers);
        free(stream_data);
        stream->backend_data = NULL;
    }

    return status;
}
Ejemplo n.º 15
0
void receive_transfer(struct libusb_transfer *transfer)
{
	/* TODO: these statics have to move to fx2_device struct */
	static int num_samples = 0;
	static int empty_transfer_count = 0;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	struct fx2_device *fx2;
	int cur_buflen, trigger_offset, i;
	unsigned char *cur_buf, *new_buf;

	/* hw_stop_acquisition() is telling us to stop. */
	if (transfer == NULL)
		num_samples = -1;

	/*
	 * If acquisition has already ended, just free any queued up
	 * transfer that come in.
	 */
	if (num_samples == -1) {
		if (transfer)
			libusb_free_transfer(transfer);
		return;
	}

	sr_info("saleae: receive_transfer(): status %d received %d bytes",
		transfer->status, transfer->actual_length);

	/* Save incoming transfer before reusing the transfer struct. */
	cur_buf = transfer->buffer;
	cur_buflen = transfer->actual_length;
	fx2 = transfer->user_data;

	/* Fire off a new request. */
	if (!(new_buf = g_try_malloc(4096))) {
		sr_err("saleae: %s: new_buf malloc failed", __func__);
		// return SR_ERR_MALLOC;
		return; /* FIXME */
	}

	transfer->buffer = new_buf;
	transfer->length = 4096;
	if (libusb_submit_transfer(transfer) != 0) {
		/* TODO: Stop session? */
		sr_warn("eek");
	}

	if (cur_buflen == 0) {
		empty_transfer_count++;
		if (empty_transfer_count > MAX_EMPTY_TRANSFERS) {
			/*
			 * The FX2 gave up. End the acquisition, the frontend
			 * will work out that the samplecount is short.
			 */
			hw_stop_acquisition(-1, fx2->session_data);
		}
		return;
	} else {
		empty_transfer_count = 0;
	}

	trigger_offset = 0;
	if (fx2->trigger_stage >= 0) {
		for (i = 0; i < cur_buflen; i++) {

			if ((cur_buf[i] & fx2->trigger_mask[fx2->trigger_stage]) == fx2->trigger_value[fx2->trigger_stage]) {
				/* Match on this trigger stage. */
				fx2->trigger_buffer[fx2->trigger_stage] = cur_buf[i];
				fx2->trigger_stage++;

				if (fx2->trigger_stage == NUM_TRIGGER_STAGES || fx2->trigger_mask[fx2->trigger_stage] == 0) {
					/* Match on all trigger stages, we're done. */
					trigger_offset = i + 1;

					/*
					 * TODO: Send pre-trigger buffer to session bus.
					 * Tell the frontend we hit the trigger here.
					 */
					packet.type = SR_DF_TRIGGER;
					packet.timeoffset = (num_samples + i) * fx2->period_ps;
					packet.duration = 0;
					packet.payload = NULL;
					sr_session_bus(fx2->session_data, &packet);

					/*
					 * Send the samples that triggered it, since we're
					 * skipping past them.
					 */
					packet.type = SR_DF_LOGIC;
					packet.timeoffset = (num_samples + i) * fx2->period_ps;
					packet.duration = fx2->trigger_stage * fx2->period_ps;
					packet.payload = &logic;
					logic.length = fx2->trigger_stage;
					logic.unitsize = 1;
					logic.data = fx2->trigger_buffer;
					sr_session_bus(fx2->session_data, &packet);

					fx2->trigger_stage = TRIGGER_FIRED;
					break;
				}
				return;
			}

			/*
			 * We had a match before, but not in the next sample. However, we may
			 * have a match on this stage in the next bit -- trigger on 0001 will
			 * fail on seeing 00001, so we need to go back to stage 0 -- but at
			 * the next sample from the one that matched originally, which the
			 * counter increment at the end of the loop takes care of.
			 */
			if (fx2->trigger_stage > 0) {
				i -= fx2->trigger_stage;
				if (i < -1)
					i = -1; /* Oops, went back past this buffer. */
				/* Reset trigger stage. */
				fx2->trigger_stage = 0;
			}
		}
	}

	if (fx2->trigger_stage == TRIGGER_FIRED) {
		/* Send the incoming transfer to the session bus. */
		packet.type = SR_DF_LOGIC;
		packet.timeoffset = num_samples * fx2->period_ps;
		packet.duration = cur_buflen * fx2->period_ps;
		packet.payload = &logic;
		logic.length = cur_buflen - trigger_offset;
		logic.unitsize = 1;
		logic.data = cur_buf + trigger_offset;
		sr_session_bus(fx2->session_data, &packet);
		g_free(cur_buf);

		num_samples += cur_buflen;
		if (fx2->limit_samples && (unsigned int) num_samples > fx2->limit_samples) {
			hw_stop_acquisition(-1, fx2->session_data);
		}
	} else {
		/*
		 * TODO: Buffer pre-trigger data in capture
		 * ratio-sized buffer.
		 */
	}
}
Ejemplo n.º 16
0
/*
 * Called by libusb (as triggered by handle_event()) when a transfer comes in.
 * Only channel data comes in asynchronously, and all transfers for this are
 * queued up beforehand, so this just needs to chuck the incoming data onto
 * the libsigrok session bus.
 */
static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;

	sdi = transfer->user_data;
	devc = sdi->priv;

	if (devc->dev_state == FLUSH) {
		g_free(transfer->buffer);
		libusb_free_transfer(transfer);
		devc->dev_state = CAPTURE;
		devc->aq_started = g_get_monotonic_time();
		read_channel(sdi, data_amount(sdi));
		return;
	}

	if (devc->dev_state != CAPTURE)
		return;

	if (!devc->sample_buf) {
		devc->sample_buf_size = 10;
		devc->sample_buf = g_try_malloc(devc->sample_buf_size * sizeof(transfer));
		devc->sample_buf_write = 0;
	}

	if (devc->sample_buf_write >= devc->sample_buf_size) {
		devc->sample_buf_size += 10;
		devc->sample_buf = g_try_realloc(devc->sample_buf,
				devc->sample_buf_size * sizeof(transfer));
		if (!devc->sample_buf) {
			sr_err("Sample buffer malloc failed.");
			devc->dev_state = STOPPING;
			return;
		}
	}

	devc->sample_buf[devc->sample_buf_write++] = transfer;
	devc->samp_received += transfer->actual_length / NUM_CHANNELS;

	sr_spew("receive_transfer(): calculated samplerate == %" PRIu64 "ks/s",
		(uint64_t)(transfer->actual_length * 1000 /
		(g_get_monotonic_time() - devc->read_start_ts + 1) /
		NUM_CHANNELS));

	sr_spew("receive_transfer(): status %s received %d bytes.",
		libusb_error_name(transfer->status), transfer->actual_length);

	if (transfer->actual_length == 0)
		/* Nothing to send to the bus. */
		return;

	if (devc->limit_samples && devc->samp_received >= devc->limit_samples) {
		sr_info("Requested number of samples reached, stopping. %"
			PRIu64 " <= %" PRIu64, devc->limit_samples,
			devc->samp_received);
		send_data(sdi, devc->sample_buf, devc->limit_samples);
		sdi->driver->dev_acquisition_stop(sdi);
	} else if (devc->limit_msec && (g_get_monotonic_time() -
			devc->aq_started) / 1000 >= devc->limit_msec) {
		sr_info("Requested time limit reached, stopping. %d <= %d",
			(uint32_t)devc->limit_msec,
			(uint32_t)(g_get_monotonic_time() - devc->aq_started) / 1000);
		send_data(sdi, devc->sample_buf, devc->samp_received);
		g_free(devc->sample_buf);
		devc->sample_buf = NULL;
		sdi->driver->dev_acquisition_stop(sdi);
	} else {
		read_channel(sdi, data_amount(sdi));
	}
}
Ejemplo n.º 17
0
static int hw_start_acquisition(int device_index, gpointer session_data)
{
	struct sr_device_instance *sdi;
	struct sr_datafeed_packet *packet;
	struct sr_datafeed_header *header;
	struct fx2_device *fx2;
	struct libusb_transfer *transfer;
	const struct libusb_pollfd **lupfd;
	int size, i;
	unsigned char *buf;

	if (!(sdi = sr_get_device_instance(device_instances, device_index)))
		return SR_ERR;
	fx2 = sdi->priv;
	fx2->session_data = session_data;

	if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
		sr_err("saleae: %s: packet malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
		sr_err("saleae: %s: header malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	/* Start with 2K transfer, subsequently increased to 4K. */
	size = 2048;
	for (i = 0; i < NUM_SIMUL_TRANSFERS; i++) {
		if (!(buf = g_try_malloc(size))) {
			sr_err("saleae: %s: buf malloc failed", __func__);
			return SR_ERR_MALLOC;
		}
		transfer = libusb_alloc_transfer(0);
		libusb_fill_bulk_transfer(transfer, sdi->usb->devhdl,
				2 | LIBUSB_ENDPOINT_IN, buf, size,
				receive_transfer, fx2, 40);
		if (libusb_submit_transfer(transfer) != 0) {
			/* TODO: Free them all. */
			libusb_free_transfer(transfer);
			g_free(buf);
			return SR_ERR;
		}
		size = 4096;
	}

	lupfd = libusb_get_pollfds(usb_context);
	for (i = 0; lupfd[i]; i++)
		sr_source_add(lupfd[i]->fd, lupfd[i]->events, 40, receive_data,
			      NULL);
	free(lupfd);

	packet->type = SR_DF_HEADER;
	packet->payload = header;
	header->feed_version = 1;
	gettimeofday(&header->starttime, NULL);
	header->samplerate = fx2->cur_samplerate;
	header->num_logic_probes = fx2->profile->num_probes;
	header->num_analog_probes = 0;
	sr_session_bus(session_data, packet);
	g_free(header);
	g_free(packet);

	return SR_OK;
}
Ejemplo n.º 18
0
void usb_transfer_destroy(USBTransfer *usb_transfer) {
	struct timeval tv;
	time_t start;
	time_t now;
	int rc;

	log_debug("Destroying %s transfer %p (%p) for %s",
	          usb_transfer_get_type_name(usb_transfer->type, false), usb_transfer,
	          usb_transfer->handle, usb_transfer->usb_stack->base.name);

	if (usb_transfer->submitted) {
		usb_transfer->completed = false;
		usb_transfer->cancelled = true;

		rc = libusb_cancel_transfer(usb_transfer->handle);

		// if libusb_cancel_transfer fails with LIBUSB_ERROR_NO_DEVICE if the
		// device was disconnected before the transfer could be cancelled. but
		// the transfer might be cancelled anyway and we need to wait for the
		// transfer to complete. this can result in waiting for a transfer that
		// might not complete anymore. but if we don't wait for the transfer to
		// complete if it actually will complete then the libusb_device_handle
		// might be closed before the transfer completes. this results in a
		// crash by NULL pointer dereference because libusb assumes that the
		// libusb_device_handle is not closed as long as there are submitted
		// transfers.
		if (rc < 0 && rc != LIBUSB_ERROR_NO_DEVICE) {
			log_warn("Could not cancel pending %s transfer %p (%p) for %s: %s (%d)",
			         usb_transfer_get_type_name(usb_transfer->type, false), usb_transfer,
			         usb_transfer->handle, usb_transfer->usb_stack->base.name,
			         usb_get_error_name(rc), rc);
		} else {
			tv.tv_sec = 0;
			tv.tv_usec = 0;

			start = time(NULL);
			now = start;

			// FIXME: don't wait 1 second per transfer
			while (!usb_transfer->completed && now >= start && now < start + 1) {
				rc = libusb_handle_events_timeout(usb_transfer->usb_stack->context, &tv);

				if (rc < 0) {
					log_error("Could not handle USB events during %s transfer %p (%p) cancellation for %s: %s (%d)",
					          usb_transfer_get_type_name(usb_transfer->type, false),
					          usb_transfer, usb_transfer->handle,
					          usb_transfer->usb_stack->base.name,
					          usb_get_error_name(rc), rc);
				}

				now = time(NULL);
			}

			if (!usb_transfer->completed) {
				log_warn("Attempt to cancel pending %s transfer %p (%p) for %s timed out",
				         usb_transfer_get_type_name(usb_transfer->type, false), usb_transfer,
				         usb_transfer->handle, usb_transfer->usb_stack->base.name);
			}
		}
	}

	if (!usb_transfer->submitted) {
		libusb_free_transfer(usb_transfer->handle);
	} else {
		log_warn("Leaking pending %s transfer %p (%p) for %s",
		         usb_transfer_get_type_name(usb_transfer->type, false), usb_transfer,
		         usb_transfer->handle, usb_transfer->usb_stack->base.name);
	}
}
EnttecDMXDevice::Transfer::~Transfer()
{
    libusb_free_transfer(transfer);
}
Ejemplo n.º 20
0
static int start_transfers(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct sr_trigger *trigger;
	struct libusb_transfer *transfer;
	unsigned int i, num_transfers;
	int timeout, ret;
	unsigned char *buf;
	size_t size;

	devc = sdi->priv;
	usb = sdi->conn;

	devc->sent_samples = 0;
	devc->acq_aborted = FALSE;
	devc->empty_transfer_count = 0;

	if ((trigger = sr_session_trigger_get(sdi->session))) {
		int pre_trigger_samples = 0;
		if (devc->limit_samples > 0)
			pre_trigger_samples = (devc->capture_ratio * devc->limit_samples) / 100;
		devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
		if (!devc->stl)
			return SR_ERR_MALLOC;
		devc->trigger_fired = FALSE;
	} else
		devc->trigger_fired = TRUE;

	num_transfers = get_number_of_transfers(devc);

	size = get_buffer_size(devc);
	devc->submitted_transfers = 0;

	devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
	if (!devc->transfers) {
		sr_err("USB transfers malloc failed.");
		return SR_ERR_MALLOC;
	}

	timeout = get_timeout(devc);
	devc->num_transfers = num_transfers;
	for (i = 0; i < num_transfers; i++) {
		if (!(buf = g_try_malloc(size))) {
			sr_err("USB transfer buffer malloc failed.");
			return SR_ERR_MALLOC;
		}
		transfer = libusb_alloc_transfer(0);
		libusb_fill_bulk_transfer(transfer, usb->devhdl,
				2 | LIBUSB_ENDPOINT_IN, buf, size,
				receive_transfer, (void *)sdi, timeout);
		sr_info("submitting transfer: %d", i);
		if ((ret = libusb_submit_transfer(transfer)) != 0) {
			sr_err("Failed to submit transfer: %s.",
			       libusb_error_name(ret));
			libusb_free_transfer(transfer);
			g_free(buf);
			fx2lafw_abort_acquisition(devc);
			return SR_ERR;
		}
		devc->transfers[i] = transfer;
		devc->submitted_transfers++;
	}

	/*
	 * If this device has analog channels and at least one of them is
	 * enabled, use mso_send_data_proc() to properly handle the analog
	 * data. Otherwise use la_send_data_proc().
	 */
	if (g_slist_length(devc->enabled_analog_channels) > 0)
		devc->send_data_proc = mso_send_data_proc;
	else
		devc->send_data_proc = la_send_data_proc;

	std_session_send_df_header(sdi);

	return SR_OK;
}
Ejemplo n.º 21
0
///////////////////////////////////////////////////////////////////////////////
///@author      Nicolae Bodislav
///@brief       Reads data from the USB device on bulk.
///@param       [out]p_pData - Buffer to store output data
///@param       [in]p_nLegth - Size of the output buffer
///@param       [in]p_nMiliSec - How much to wait for data before abandoning the read operation
///@retval      size of the data written in the output buffer or < 0 for error
///////////////////////////////////////////////////////////////////////////////
int CUSBLink::ReadBulk(unsigned char* p_pData, uint32_t p_nLegth, unsigned int p_nMiliSec /*= 10*/ )
{
    m_nCb = 0;
    m_nTrasferedLength = 0;

    if(m_pDevh == NULL)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Device not open.");
        return -1;
    }

    int rez = libusb_claim_interface(m_pDevh, 0);
    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Couldn't claim interface.");
        return -1;
    }

    m_enumDealoc = CUSBLink::INTERFACE;

    m_pData_transfer = NULL;
    m_pData_transfer = libusb_alloc_transfer(0);
    if (!m_pData_transfer)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Transfer couldn't be allocated.");
        return -ENOMEM;
    }

    m_pDev = libusb_get_device(m_pDevh);
    int max_packet_size = libusb_get_max_packet_size(m_pDev, m_cReadEndpoint);

    libusb_fill_bulk_transfer(m_pData_transfer, m_pDevh, m_cReadEndpoint, m_pData, max_packet_size, Cb_TransferRead, this, p_nMiliSec);

    m_enumDealoc = CUSBLink::TRANSFER;

    rez = libusb_submit_transfer(m_pData_transfer);

    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Transfer couldn't be submitted.");

        libusb_cancel_transfer(m_pData_transfer);
        m_enumDealoc = CUSBLink::INTERFACE;

        while (!m_nCb)
        {   rez = libusb_handle_events(m_pContex);
            if (rez < 0)
            {   break;
            }
        }

        libusb_free_transfer(m_pData_transfer);

        return -1;
    }

    while (!m_nCb)
    {   rez = libusb_handle_events(m_pContex);
        if (rez < 0)
        {   libusb_free_transfer(m_pData_transfer);
            return -1;
        }
    }


    if(m_bHaveData)
    {
        if(m_nTrasferedLength > 0)
        {   memcpy(p_pData, m_pData, m_nTrasferedLength);
            if (m_bRawLog)
            {   NLOG_DBG_HEX("[CUSBLink][ReadBulk] Received packet:", m_pData, m_nTrasferedLength);
            }
        }
        else
            p_pData = NULL;
    }

    return m_nTrasferedLength;
}
Ejemplo n.º 22
0
UsbEndPoint::~UsbEndPoint()
{
	libusb_free_transfer(_transfer);
}
Ejemplo n.º 23
0
int main(void)
{
	struct sigaction sigact;
	int r = 1;

	r = libusb_init(NULL);
	if (r < 0) {
		fprintf(stderr, "failed to initialise libusb\n");
		exit(1);
	}

	r = find_dpfp_device();
	if (r < 0) {
		fprintf(stderr, "Could not find/open device\n");
		goto out;
	}

	r = libusb_claim_interface(devh, 0);
	if (r < 0) {
		fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r));
		goto out;
	}
	printf("claimed interface\n");

	r = print_f0_data();
	if (r < 0)
		goto out_release;

	r = do_init();
	if (r < 0)
		goto out_deinit;

	

	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);

	r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL);
	if (r)
		goto out_deinit;

	r = alloc_transfers();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	r = init_capture();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	while (!do_exit) {
		pthread_mutex_lock(&exit_cond_lock);
		pthread_cond_wait(&exit_cond, &exit_cond_lock);
		pthread_mutex_unlock(&exit_cond_lock);
	}

	printf("shutting down...\n");
	pthread_join(poll_thread, NULL);

	r = libusb_cancel_transfer(irq_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	r = libusb_cancel_transfer(img_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	while (img_transfer || irq_transfer)
		if (libusb_handle_events(NULL) < 0)
			break;

	if (do_exit == 1)
		r = 0;
	else
		r = 1;

out_deinit:
	libusb_free_transfer(img_transfer);
	libusb_free_transfer(irq_transfer);
	set_mode(0);
	set_hwstat(0x80);
out_release:
	libusb_release_interface(devh, 0);
out:
	libusb_close(devh);
	libusb_exit(NULL);
	return r >= 0 ? r : -r;
}
Ejemplo n.º 24
0
int slogic_execute_recording(struct slogic_handle *handle, struct slogic_recording *recording)
{
	/* TODO: validate recording */
	int retval =0;

	struct libusb_transfer *transfer;
	unsigned char *buffer;
	int counter;
	int ret;

	struct slogic_internal_recording *internal_recording = allocate_internal_recording(handle, recording);

	/*
	 * TODO: We probably want to tune the transfer buffer size to a sane
	 * default based on the sampling rate. If transfer_buffer_size is
	 * samples per second / 10 we can expect 10 transfers per second which
	 * should be sufficient for a user application to be responsive while
	 * not having too many transfers per second.
	 *  - Trygve
	 */

	log_printf(&logger, DEBUG, "Starting recording...\n");
	log_printf(&logger, DEBUG, "Transfer buffers:     %d\n", internal_recording->n_transfer_buffers);
	log_printf(&logger, DEBUG, "Transfer buffer size: %zu\n", handle->transfer_buffer_size);
	log_printf(&logger, DEBUG, "Transfer timeout:     %u\n", handle->transfer_timeout);

	/* Pre-allocate transfers */
	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		buffer = malloc(handle->transfer_buffer_size);
		assert(buffer);

		transfer = libusb_alloc_transfer(0);
		if (transfer == NULL) {
			log_printf(&logger, ERR, "libusb_alloc_transfer failed\n");
			recording->recording_state = UNKNOWN;
			retval = 1;
			return retval;
		}
		libusb_fill_bulk_transfer(transfer, handle->device_handle,
					  STREAMING_DATA_IN_ENDPOINT, buffer,
					  handle->transfer_buffer_size,
					  slogic_read_samples_callback,
					  &internal_recording->transfers[counter], handle->transfer_timeout);
		internal_recording->transfers[counter].internal_recording = internal_recording;
		internal_recording->transfers[counter].transfer = transfer;
	}

	recording->recording_state = WARMING_UP;
	internal_recording->done = false;

	/* Submit all transfers */
	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		internal_recording->transfers[counter].seq = tcounter++;
		ret = libusb_submit_transfer(internal_recording->transfers[counter].transfer);
		if (ret) {
			log_printf(&logger, ERR, "libusb_submit_transfer: %s\n", usbutil_error_to_string(ret));
			recording->recording_state = UNKNOWN;
			retval =1;
			return retval;
		}
	}

	log_printf(&logger, DEBUG, "sample_delay=%d\n", recording->sample_rate->sample_delay);

	struct timeval start;
	assert(gettimeofday(&start, NULL) == 0);

	struct timeval timeout = { 1, 0 };
	while (!internal_recording->done) {
		ret = libusb_handle_events_timeout(handle->context, &timeout);
		if (ret) {
			log_printf(&logger, ERR, "libusb_handle_events: %s\n", usbutil_error_to_string(ret));
			break;
		}
	}

	struct timeval end;
	assert(gettimeofday(&end, NULL) == 0);

	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		libusb_cancel_transfer(internal_recording->transfers[counter].transfer);
		libusb_free_transfer(internal_recording->transfers[counter].transfer);
		internal_recording->transfers[counter].transfer = NULL;
	}

	if (internal_recording->recording->recording_state != COMPLETED_SUCCESSFULLY) {
		log_printf(&logger, ERR, "FAIL! recording_state=%d\n", internal_recording->recording->recording_state);
		retval =1;
	} else {
		log_printf(&logger, DEBUG, "SUCCESS!\n");
	}

	log_printf(&logger, DEBUG, "Total number of samples read: %i\n", internal_recording->sample_count);
	log_printf(&logger, DEBUG, "Total number of transfers: %i\n", internal_recording->transfer_counter);

	int sec = end.tv_sec - start.tv_sec;
	int usec = (end.tv_usec - start.tv_usec) / 1000;
	if (usec < 0) {
		sec--;
		usec = 1 - usec;
	}
	log_printf(&logger, DEBUG, "Time elapsed: %d.%03ds\n", sec, usec);

	free_internal_recording(internal_recording);
	return retval;
}
Ejemplo n.º 25
0
/** \ingroup syncio
 * Perform a USB control transfer.
 *
 * The direction of the transfer is inferred from the bmRequestType field of
 * the setup packet.
 *
 * The wValue, wIndex and wLength fields values should be given in host-endian
 * byte order.
 *
 * \param dev_handle a handle for the device to communicate with
 * \param bmRequestType the request type field for the setup packet
 * \param bRequest the request field for the setup packet
 * \param wValue the value field for the setup packet
 * \param wIndex the index field for the setup packet
 * \param data a suitably-sized data buffer for either input or output
 * (depending on direction bits within bmRequestType)
 * \param wLength the length field for the setup packet. The data buffer should
 * be at least this size.
 * \param timeout timeout (in millseconds) that this function should wait
 * before giving up due to no response being received. For an unlimited
 * timeout, use value 0.
 * \returns on success, the number of bytes actually transferred
 * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
 * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
 * device
 * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
 * \returns another LIBUSB_ERROR code on other failures
 */
int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
	unsigned char *data, uint16_t wLength, unsigned int timeout)
{
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *buffer;
	int completed = 0;
	int r;

	if (!transfer)
		return LIBUSB_ERROR_NO_MEM;

	buffer = malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength);
	if (!buffer) {
		libusb_free_transfer(transfer);
		return LIBUSB_ERROR_NO_MEM;
	}

	libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex,
		wLength);
	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
		memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);

	libusb_fill_control_transfer(transfer, dev_handle, buffer,
		ctrl_transfer_cb, &completed, timeout);
	transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		return r;
	}

	while (!completed) {
		r = libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed);
		if (r < 0) {
			if (r == LIBUSB_ERROR_INTERRUPTED)
				continue;
			libusb_cancel_transfer(transfer);
			while (!completed)
				if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
					break;
			libusb_free_transfer(transfer);
			return r;
		}
	}

	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
		memcpy(data, libusb_control_transfer_get_data(transfer),
			transfer->actual_length);

	switch (transfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		r = transfer->actual_length;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		r = LIBUSB_ERROR_TIMEOUT;
		break;
	case LIBUSB_TRANSFER_STALL:
		r = LIBUSB_ERROR_PIPE;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		r = LIBUSB_ERROR_NO_DEVICE;
		break;
	case LIBUSB_TRANSFER_OVERFLOW:
		r = LIBUSB_ERROR_OVERFLOW;
		break;
	default:
		usbi_warn(HANDLE_CTX(dev_handle),
			"unrecognised status code %d", transfer->status);
		r = LIBUSB_ERROR_OTHER;
	}

	libusb_free_transfer(transfer);
	return r;
}
Ejemplo n.º 26
0
/*
 * Called by libusb (as triggered by handle_event()) when a transfer comes in.
 * Only channel data comes in asynchronously, and all transfers for this are
 * queued up beforehand, so this just needs to chuck the incoming data onto
 * the libsigrok session bus.
 */
static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_datafeed_packet packet;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	int num_samples, pre;

	sdi = transfer->user_data;
	devc = sdi->priv;
	sr_spew("receive_transfer(): status %d received %d bytes.",
		   transfer->status, transfer->actual_length);

	if (transfer->actual_length == 0)
		/* Nothing to send to the bus. */
		return;

	num_samples = transfer->actual_length / 2;

	sr_spew("Got %d-%d/%d samples in frame.", devc->samp_received + 1,
		   devc->samp_received + num_samples, devc->framesize);

	/*
	 * The device always sends a full frame, but the beginning of the frame
	 * doesn't represent the trigger point. The offset at which the trigger
	 * happened came in with the capture state, so we need to start sending
	 * from there up the session bus. The samples in the frame buffer
	 * before that trigger point came after the end of the device's frame
	 * buffer was reached, and it wrapped around to overwrite up until the
	 * trigger point.
	 */
	if (devc->samp_received < devc->trigger_offset) {
		/* Trigger point not yet reached. */
		if (devc->samp_received + num_samples < devc->trigger_offset) {
			/* The entire chunk is before the trigger point. */
			memcpy(devc->framebuf + devc->samp_buffered * 2,
					transfer->buffer, num_samples * 2);
			devc->samp_buffered += num_samples;
		} else {
			/*
			 * This chunk hits or overruns the trigger point.
			 * Store the part before the trigger fired, and
			 * send the rest up to the session bus.
			 */
			pre = devc->trigger_offset - devc->samp_received;
			memcpy(devc->framebuf + devc->samp_buffered * 2,
					transfer->buffer, pre * 2);
			devc->samp_buffered += pre;

			/* The rest of this chunk starts with the trigger point. */
			sr_dbg("Reached trigger point, %d samples buffered.",
				   devc->samp_buffered);

			/* Avoid the corner case where the chunk ended at
			 * exactly the trigger point. */
			if (num_samples > pre)
				send_chunk(sdi, transfer->buffer + pre * 2,
						num_samples - pre);
		}
	} else {
		/* Already past the trigger point, just send it all out. */
		send_chunk(sdi, transfer->buffer, num_samples);
	}

	devc->samp_received += num_samples;

	/* Everything in this transfer was either copied to the buffer or
	 * sent to the session bus. */
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);

	if (devc->samp_received >= devc->framesize) {
		/* That was the last chunk in this frame. Send the buffered
		 * pre-trigger samples out now, in one big chunk. */
		sr_dbg("End of frame, sending %d pre-trigger buffered samples.",
			   devc->samp_buffered);
		send_chunk(sdi, devc->framebuf, devc->samp_buffered);

		/* Mark the end of this frame. */
		packet.type = SR_DF_FRAME_END;
		sr_session_send(devc->cb_data, &packet);

		if (devc->limit_frames && ++devc->num_frames == devc->limit_frames) {
			/* Terminate session */
			devc->dev_state = STOPPING;
		} else {
			devc->dev_state = NEW_CAPTURE;
		}
	}
}
Ejemplo n.º 27
0
USBBuffer::~USBBuffer() {
	libusb_free_transfer(mTransfer);
	delete[] mBuffer;
}
Ejemplo n.º 28
0
static void
WriteAsyncCallback(struct libusb_transfer *transfer)
{
   free(transfer->buffer);
   libusb_free_transfer(transfer);
}
Ejemplo n.º 29
0
/* write buffer(*buf) to SPI flash */
int32_t ch341SpiWrite(uint8_t *buf, uint32_t add, uint32_t len)
{
    uint8_t out[WRITE_PAYLOAD_LENGTH];
    uint8_t in[CH341_PACKET_LENGTH];
    uint32_t tmp, pkg_count;
    struct libusb_transfer *xferBulkIn, *xferBulkOut;
    uint32_t idx = 0;
    uint32_t ret;
    int32_t old_counter;
    struct timeval tv = {0, 100};

    if (devHandle == NULL) return -1;
    memset(out, 0xff, WRITE_PAYLOAD_LENGTH);
    xferBulkIn  = libusb_alloc_transfer(0);
    xferBulkOut = libusb_alloc_transfer(0);

    while (len > 0) {
        out[0] = 0x06; // Write enable
        ret = ch341SpiStream(out, in, 1);
        ch341SpiCs(out, true);
        idx = CH341_PACKET_LENGTH;
        out[idx++] = CH341A_CMD_SPI_STREAM;
        out[idx++] = 0x40; // byte swapped command for Flash Page Write
        tmp = add;
        for (int i = 0; i < 3; ++i) { // starting address of next write
            out[idx++] = swapByte((tmp >> 16) & 0xFF);
            tmp <<= 8;
        }
        tmp = 0;
        pkg_count = 1;
        while ((idx < WRITE_PAYLOAD_LENGTH) && (len > tmp)) {
            if (idx % CH341_PACKET_LENGTH == 0) {
                out[idx++] = CH341A_CMD_SPI_STREAM;
                pkg_count ++;
            } else {
                out[idx++] = swapByte(*buf++);
                tmp++;
                if (((add + tmp) & 0xFF) == 0) // cross page boundary
                    break;
            }
        }
        len -= tmp;
        add += tmp;
        bulkin_count = 0;
        libusb_fill_bulk_transfer(xferBulkIn, devHandle, BULK_READ_ENDPOINT, in,
                CH341_PACKET_LENGTH, cbBulkIn, NULL, DEFAULT_TIMEOUT);
        libusb_submit_transfer(xferBulkIn);
        libusb_fill_bulk_transfer(xferBulkOut, devHandle, BULK_WRITE_ENDPOINT, out,
                idx, cbBulkOut, NULL, DEFAULT_TIMEOUT);
        libusb_submit_transfer(xferBulkOut);
        old_counter = bulkin_count;
        ret = 0;
        while (bulkin_count < pkg_count) {
            libusb_handle_events_timeout(NULL, &tv);
            if (bulkin_count == -1) { // encountered error
                ret = -1;
                break;
            }
            if (old_counter != bulkin_count) { // new package came
                if (bulkin_count != pkg_count)
                    libusb_submit_transfer(xferBulkIn);  // resubmit bulk in request
                old_counter = bulkin_count;
            }
        }
        if (ret < 0) break;
        ch341SpiCs(out, false);
        ret = usbTransfer(__func__, BULK_WRITE_ENDPOINT, out, 3);
        if (ret < 0) break;
        out[0] = 0x04; // Write disable
        ret = ch341SpiStream(out, in, 1);
        do {
            ret = ch341ReadStatus();
            if (ret != 0)
                libusb_handle_events_timeout(NULL, &tv);
        } while(ret != 0);
        if (force_stop == 1) { // user hit ctrl+C
            force_stop = 0;
            if (len > 0)
                fprintf(stderr, "User hit Ctrl+C, writing unfinished.\n");
            break;
        }
    }
    libusb_free_transfer(xferBulkIn);
    libusb_free_transfer(xferBulkOut);
    return ret;
}
Ejemplo n.º 30
0
int main (int argc, char **argv)
{
  bool daemonize = false;

  while (true) {
      int c;
      static struct option long_options[] =
          {
              {"help",    no_argument, NULL, 'h'},
              {"version", no_argument, NULL, 'v'},
              {"daemon",  no_argument, NULL, 'd'},
              {"fork",    no_argument, NULL, 'f'},
              {0, 0, 0, 0}
          };

      c = getopt_long(argc, argv, "hvd", long_options, NULL);
      if (c == -1)
        break;
      switch (c) {
      case 'h':
        print_usage(argv[0]);
        exit(EXIT_SUCCESS);
      case 'v':
        msg("HAMA MCE remote event client v%s for XBMC\n", VERSION);
        exit(EXIT_SUCCESS);
      case 'd':
        daemonize = true;
        break;
      default:
        print_usage(argv[0]);
        exit(EXIT_FAILURE);
      }
  }

  if (optind < (argc - 1)) {
      err("%s: too many arguments\n", argv[0]);
      exit(EXIT_FAILURE);
  }

  struct sigaction sa;
  sigemptyset(&sa.sa_mask);
  sa.sa_handler = handle_exit;
  PCHK(sigaction(SIGINT,  &sa, NULL));
  PCHK(sigaction(SIGTERM, &sa, NULL));

  libusb_context *ctx;
  libusb_device_handle *dev;
  struct libusb_transfer *transfer0x81 = libusb_alloc_transfer(0);
  struct libusb_transfer *transfer0x82 = libusb_alloc_transfer(0);
  unsigned char buf0x81 [8];
  unsigned char buf0x82 [5];

  UCHK(libusb_init(&ctx));

  if (!(dev = libusb_open_device_with_vid_pid(ctx, 0x05a4, 0x9881))) {
      err("%s: No HAMA MCE remote control found.\n", argv[0]);
      exit(EXIT_FAILURE);
  }

  int exit_code = EXIT_SUCCESS;

  if (libusb_kernel_driver_active(dev, 0))
    UCHK(libusb_detach_kernel_driver(dev, 0));
  if (libusb_kernel_driver_active(dev, 1))
    UCHK(libusb_detach_kernel_driver(dev, 1));
  UCHK(libusb_claim_interface(dev, 0));
  UCHK(libusb_claim_interface(dev, 1));

  libusb_fill_interrupt_transfer(transfer0x81, dev, 0x81, buf0x81, sizeof(buf0x81), transfer0x81_cb, NULL, 215);
  UCHK(libusb_submit_transfer(transfer0x81));

  libusb_fill_interrupt_transfer(transfer0x82, dev, 0x82, buf0x82, sizeof(buf0x82), transfer0x82_cb, NULL, 200);
  UCHK(libusb_submit_transfer(transfer0x82));

  msg("Connected HAMA MCE Remote\n");
  xbmc.SendHELO("HAMA MCE Remote", ICON_NONE);

  if (daemonize) {
      if (daemon(0,0) == -1) {
          err("Failed to fork\n");
          perror(argv[0]);
          exit_code = EXIT_FAILURE;
          goto exit;
      }
  }

  while (!(disconnected || quit)) {
      UCHK(libusb_handle_events(ctx));
  }
  exit:
  if (disconnected) {
      msg("Disconnected HAMA MCE Remote\n");
      xbmc.SendNOTIFICATION("Disconnected", "HAMA MCE Remote", ICON_NONE);
  }
  else {
      msg("Closing HAMA MCE Remote\n");
      xbmc.SendNOTIFICATION("Closing", "HAMA MCE Remote", ICON_NONE);
  }

  libusb_free_transfer(transfer0x81);
  libusb_free_transfer(transfer0x82);

  if (!disconnected) {
      // Release the remote back to the system
      UCHK(libusb_release_interface(dev, 0));
      UCHK(libusb_release_interface(dev, 1));
      UCHK(libusb_attach_kernel_driver(dev, 0));
      UCHK(libusb_attach_kernel_driver(dev, 1));
  }

  libusb_close(dev);
  libusb_exit(ctx);

  exit(exit_code);
}