Esempio n. 1
0
static void *usb_pump_events(void *user_data)
{
	IGNORE(user_data);

	for (;;) {
		// NOTE: This is a blocking call so
		// no need for sleep()
		libusb_handle_events_completed(NULL, NULL);
	}
}
Esempio n. 2
0
int64_t FX3Stream::send(int64_t words, uint32_t *data, unsigned timeout) {
    if( error ) { cerr << "Blocked" << endl; return 0; }
    totalBytes = words*4;
    extBuf = (unsigned char*)data;
    transferredBytes = 0;
    submittedBytes = 0;
    shortPackets = 0;

    //Start transfer
    for( unsigned i = 0; i < transfers.size() && transferredBytes+submittedBytes < totalBytes; ++i ) {
        int64_t remainingBytes = totalBytes-(transferredBytes+submittedBytes);
        if( remainingBytes > FX3_TRANSFER_SIZE ) {
            libusb_fill_bulk_transfer( transfers[i], devhandle, FX3_OUT_EP, &extBuf[transferredBytes+submittedBytes],
                    FX3_TRANSFER_SIZE, FX3Stream::sendCallback, this, timeout );
            submittedBytes += FX3_TRANSFER_SIZE;
        }
        else if( remainingBytes > 0 ) {
            libusb_fill_bulk_transfer( transfers[i], devhandle, FX3_OUT_EP, &extBuf[transferredBytes+submittedBytes],
                    remainingBytes, FX3Stream::sendCallback, this, timeout );
            submittedBytes += remainingBytes;
        }
        error = libusb_submit_transfer( transfers[i] );
        if( error ) {
            cerr << "Error submitting transfer: " << libusb_error_name(error) << endl;
            break;
        }
    }
    //Wait for transfer
    while( submittedBytes ) {
        int r = libusb_handle_events_completed(0,0);
        if( r ) {
            cerr << "Error handling events: " << libusb_error_name(r) << endl;
            error = r;
            break;
        }
    }
    if( shortPackets ) {
        cerr << "Error: Short packet(s) in outgoing transfers." << endl;
        shortPackets = 0;
    }
    if( error < 0 ) {
        cerr << "Error sending data: " << libusb_error_name(error) << endl;
    }
    if( error == LIBUSB_ERROR_TIMEOUT ) {
        error = 0;
    }
    return transferredBytes/4;
}
Esempio n. 3
0
int USBRequest::request(libusb_context* ctx, USBDevice *device, unsigned char endpoint, size_t request_bytes) {
	std::cout << "Request start" << std::endl;
	bytes = request_bytes;
	mDevice = device;
	err = 0;
	done = 0;
	ep = endpoint;
	addBuffers();
	while(!done) {
		libusb_handle_events_completed(ctx, &done);
	}
	std::cout << "Remaining: " << bytes << std::endl;
	if(err != 0) {
		std::cout << "Erreur" << std::endl;
	}
	return err;
}
Esempio n. 4
0
static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)
{
	int r, *completed = transfer->user_data;
	struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle);

	while (!*completed) {
		r = libusb_handle_events_completed(ctx, completed);
		if (r < 0) {
			if (r == LIBUSB_ERROR_INTERRUPTED)
				continue;
			usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying",
				 libusb_error_name(r));
			libusb_cancel_transfer(transfer);
			continue;
		}
	}
}
Esempio n. 5
0
	int Context::handleEvents(State & state, Context_wrapper * wrapper){
		Stack * stack = state.stack;
		int result = 0;
		
		timeval tv;
		bool timeValSet = fillTimeval(state, tv, 1);
		int completed;
		if (stack->is<LUA_TBOOLEAN>(2)){
			completed = (stack->to<bool>(2)) ? 1 : 0;
		}
		else{
			completed = -1;
		}

		if (timeValSet){
			if (completed >= 0){
				result = libusb_handle_events_timeout_completed(wrapper->context, &tv, &completed);
			}
			else{
				result = libusb_handle_events_timeout(wrapper->context, &tv);
			}
		}
		else{
			if (completed >= 0){
				result = libusb_handle_events_completed(wrapper->context, &completed);
			}
			else{
				result = libusb_handle_events(wrapper->context);
			}
		}

		if (result == LIBUSB_SUCCESS){
			stack->push<bool>(true);
			return 1;
		}
		else{
			stack->push<bool>(false);
			stack->push<int>(result);
			return 2;
		}
	}
Esempio n. 6
0
static void *read_thread(void *param)
{
	hid_device *dev = param;
	unsigned char *buf;
	const size_t length = dev->input_ep_max_packet_size;

	/* Set up the transfer object. */
	buf = malloc(length);
	dev->transfer = libusb_alloc_transfer(0);
	libusb_fill_interrupt_transfer(dev->transfer,
		dev->device_handle,
		dev->input_endpoint,
		buf,
		length,
		read_callback,
		dev,
		5000/*timeout*/);

	/* Make the first submission. Further submissions are made
	   from inside read_callback() */
	libusb_submit_transfer(dev->transfer);

	/* Notify the main thread that the read thread is up and running. */
	pthread_barrier_wait(&dev->barrier);

	/* Handle all the events. */
	while (!dev->shutdown_thread) {
		int res;
		res = libusb_handle_events(usb_context);
		if (res < 0) {
			/* There was an error. */
			LOG("read_thread(): libusb reports error # %d\n", res);

			/* Break out of this loop only on fatal error.*/
			if (res != LIBUSB_ERROR_BUSY &&
			    res != LIBUSB_ERROR_TIMEOUT &&
			    res != LIBUSB_ERROR_OVERFLOW &&
			    res != LIBUSB_ERROR_INTERRUPTED) {
				break;
			}
		}
	}

	/* Cancel any transfer that may be pending. This call will fail
	   if no transfers are pending, but that's OK. */
	libusb_cancel_transfer(dev->transfer);

	while (!dev->cancelled)
		libusb_handle_events_completed(usb_context, &dev->cancelled);

	/* Now that the read thread is stopping, Wake any threads which are
	   waiting on data (in hid_read_timeout()). Do this under a mutex to
	   make sure that a thread which is about to go to sleep waiting on
	   the condition acutally will go to sleep before the condition is
	   signaled. */
	pthread_mutex_lock(&dev->mutex);
	pthread_cond_broadcast(&dev->condition);
	pthread_mutex_unlock(&dev->mutex);

	/* The dev->transfer->buffer and dev->transfer objects are cleaned up
	   in hid_close(). They are not cleaned up here because this thread
	   could end either due to a disconnect or due to a user
	   call to hid_close(). In both cases the objects can be safely
	   cleaned up after the call to pthread_join() (in hid_close()), but
	   since hid_close() calls libusb_cancel_transfer(), on these objects,
	   they can not be cleaned up here. */

	return NULL;
}
Esempio n. 7
0
//We adopted for async method here because there are 2 thread polling same fd
// i.e both read and write are polling same fd when one event triggers and other one is
//not completed then another thread will wait for more than 60sec.
CY_RETURN_STATUS CySpiRead (
        CY_HANDLE handle,
        CY_DATA_BUFFER *readBuffer,
        UINT32 ioTimeout
        )
{
    struct libusb_transfer *readTransfer;
    CY_DEVICE *device;
    libusb_device_handle *devHandle;
    int readCompleted = 0;
    struct timeval time;
    int r;
    if (handle == NULL)
        return CY_ERROR_INVALID_HANDLE;
    device = (CY_DEVICE *)handle;
    devHandle = device->devHandle;
    readBuffer->transferCount = 0;
    readTransfer = libusb_alloc_transfer(0);
    if (readTransfer == NULL){
        CY_DEBUG_PRINT_ERROR("CY:Error in allocating transfers \n");
        return CY_ERROR_ALLOCATION_FAILED;
    }
    libusb_fill_bulk_transfer(readTransfer, devHandle, device->inEndpoint, readBuffer->buffer, readBuffer->length,
            spi_read_cb, &readCompleted, ioTimeout);
    libusb_submit_transfer (readTransfer);
    time.tv_sec = (ioTimeout / 1000);
    time.tv_usec = ((ioTimeout % 1000) * 1000);//polling timeout.
    while (readCompleted == 0){
        r = libusb_handle_events_timeout_completed(glContext, &time, &readCompleted);
        if (r < 0) {
			if (r == LIBUSB_ERROR_INTERRUPTED)
				continue;
			libusb_cancel_transfer(readTransfer);
			while (!readCompleted)
				if (libusb_handle_events_completed(glContext, &readCompleted) < 0)
					break;
            readBuffer->transferCount = readTransfer->actual_length;
			libusb_free_transfer(readTransfer);
			return r;
		}
    }
    if (readTransfer->status == LIBUSB_TRANSFER_COMPLETED){
        readBuffer->transferCount = readTransfer->actual_length;
        libusb_free_transfer (readTransfer);
        return CY_SUCCESS;
    }
    else{
        if (readTransfer->status == LIBUSB_TRANSFER_TIMED_OUT){
            //We should not be hitting this case.. As the time out is infinite!!
            CY_DEBUG_PRINT_ERROR ("CY:Timeout error in doing SPI read/write .... %d Libusb errors %d\n",
                            readTransfer->actual_length,readTransfer->status);
            readBuffer->transferCount = readTransfer->actual_length;
            CySpiReset (handle);
            libusb_free_transfer (readTransfer);
            return CY_ERROR_IO_TIMEOUT;
        }
        if (readTransfer->status == LIBUSB_TRANSFER_OVERFLOW){
            //Need to handle this properly!
            CY_DEBUG_PRINT_ERROR ("CY:OverFlow error in doing SPI read/write .... Libusb errors %d %d \n",
                            readTransfer->status, readTransfer->actual_length);
            readBuffer->transferCount = readTransfer->actual_length;
            CySpiReset (handle);
            libusb_free_transfer (readTransfer);
            return CY_ERROR_BUFFER_OVERFLOW;
        }
        if (readTransfer->status != LIBUSB_TRANSFER_COMPLETED){
            CY_DEBUG_PRINT_ERROR ("CY:Error in doing SPI read/write .... Libusb errors are %d %d\n",
                            readTransfer->status, readTransfer->actual_length);
            readBuffer->transferCount = readTransfer->actual_length;
            CySpiReset (handle);
            libusb_free_transfer (readTransfer);
            //If timer is not completed then it implies we have timeout error
            return CY_ERROR_REQUEST_FAILED;
        }
    }
    return CY_ERROR_REQUEST_FAILED;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
int64_t FX3Stream::receive(int64_t maxWords, uint32_t *data, unsigned timeout, bool shortOK) {
    if( error ) { cerr << "Blocked" << endl; return 0; }
    totalBytes = maxWords*4;
    extBuf = (unsigned char*)data;
    transferredBytes = 0;
    submittedBytes = 0;
    shortPackets = 0;

    while( transferredBytes < totalBytes ) {
        //Retrieve from internal buffer
        while( consumedBytes < storedBytes && transferredBytes < totalBytes ) {
            extBuf[transferredBytes] = intBuf[consumedBytes];
            transferredBytes += 1;
            consumedBytes += 1;
        }

        if( transferredBytes && shortOK ) {
            break;
        }

        //Request remaining data
        if( transferredBytes < totalBytes ) {
            storedBytes = 0;
            consumedBytes = 0;
            for( unsigned i = 0; i < transfers.size() && transferredBytes+submittedBytes < totalBytes; ++i ) {
                int64_t remainingBytes = totalBytes-(transferredBytes+submittedBytes);
                uint32_t size = FX3_TRANSFER_SIZE;
                if( remainingBytes < FX3_TRANSFER_SIZE  ) { //request full packets
                    size = ((remainingBytes+inPktSize-1)/inPktSize)*inPktSize;
                }
                libusb_fill_bulk_transfer( transfers[i], devhandle, FX3_IN_EP, recvBufs[i],
                                           size, FX3Stream::receiveCallback, this, timeout );
                error = libusb_submit_transfer( transfers[i] );
                if( error ) {
                    cerr << "Error submitting transfer: " << libusb_error_name(error) << endl;
                    break;
                }
                submittedBytes += size;
            }
            //Wait for data
            while( submittedBytes ) {
                int r = libusb_handle_events_completed(0,0);
                if( r ) {
                    cerr << "Error handling events: " << libusb_error_name(r) << endl;
                    error = r;
                    break;
                }
            }
            if( shortPackets ) {
                if( FX3_DEBUG ) cerr << "Warning: " << shortPackets << " short packets in middle of incoming transfers." << endl;
                shortPackets = 0;
            }
            if( error < 0 && error != LIBUSB_ERROR_TIMEOUT ) {
                cerr << "Error receiving data: " << libusb_error_name(error) << endl;
                break;
            }
            else if( error == LIBUSB_ERROR_TIMEOUT ) {
                error = 0;
                break;
            }
        }
    }
    if( FX3_DEBUG ) {
        cerr << "R: " << transferredBytes << " bytes, " << shortPackets << " short packets" << endl;
        if( FX3_PRINT_DATA ) {
            for( int i = 0; i < transferredBytes-3; i += 4 ) {
                cerr << hex << setw(2) << setfill('0') << (unsigned)extBuf[i+3];
                cerr << hex << setw(2) << setfill('0') << (unsigned)extBuf[i+2];
                cerr << hex << setw(2) << setfill('0') << (unsigned)extBuf[i+1];
                cerr << hex << setw(2) << setfill('0') << (unsigned)extBuf[i+0] << dec << ' ';
            }
            cerr << endl;
        }
    }
    return transferredBytes/4;
}