Пример #1
0
void FCServer::mainLoop()
{
    for (;;) {
        struct timeval timeout;
        timeout.tv_sec = 0;
        timeout.tv_usec = 100000;

        int err = libusb_handle_events_timeout_completed(mUSB, &timeout, 0);
        if (err) {
            std::clog << "Error handling USB events: " << libusb_strerror(libusb_error(err)) << "\n";
            // Sometimes this happens on Windows during normal operation if we're queueing a lot of output URBs. Meh.
        }

        // We may have been asked for a one-shot poll, to retry connecting devices that failed.
        if (mPollForDevicesOnce) {
            mPollForDevicesOnce = false;
            usbHotplugPoll();
        }

        // Flush completed transfers
        mEventMutex.lock();
        for (std::vector<USBDevice*>::iterator i = mUSBDevices.begin(), e = mUSBDevices.end(); i != e; ++i) {
            USBDevice *dev = *i;
            dev->flush();
        }
        mEventMutex.unlock();
    }
}
//For events on USB socket
void usb_monitor_usb_event_cb(void *ptr, int32_t fd, uint32_t events)
{
    struct timeval tv = {0 ,0};
    libusb_unlock_events(NULL);
    libusb_handle_events_timeout_completed(NULL, &tv, NULL);
    libusb_lock_events(NULL);
}
Пример #3
0
SR_PRIV int ikalogic_scanalogic2_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct drv_context *drvc;
	struct timeval tv;
	int64_t current_time, time_elapsed;
	int ret = 0;

	(void)fd;
	(void)revents;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	drvc = di->priv;
	current_time = g_get_monotonic_time();

	if (devc->state == STATE_WAIT_DATA_READY &&
			!devc->wait_data_ready_locked) {
		time_elapsed = current_time - devc->wait_data_ready_time;

		/*
		 * Check here for stopping in addition to the transfer
		 * callback functions to avoid waiting until the
		 * WAIT_DATA_READY_INTERVAL has expired.
		 */
		if (sdi->status == SR_ST_STOPPING) {
			if (!devc->stopping_in_progress) {
				devc->next_state = STATE_RESET_AND_IDLE;
				devc->stopping_in_progress = TRUE;
				ret = libusb_submit_transfer(devc->xfer_in);
			}
		} else if (time_elapsed >= WAIT_DATA_READY_INTERVAL) {
			devc->wait_data_ready_locked = TRUE;
			ret = libusb_submit_transfer(devc->xfer_in);
		}
	}

	if (ret != 0) {
		sr_err("Submit transfer failed: %s.", libusb_error_name(ret));
		abort_acquisition(sdi);
		return TRUE;
	}

	tv.tv_sec = 0;
	tv.tv_usec = 0;

	libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv,
		NULL);

	/* Check if an error occurred on a transfer. */
	if (devc->transfer_error)
		abort_acquisition(sdi);

	return TRUE;
}
Пример #4
0
int A2300::UsbDevice::PollAsynchronousEvents( double timeout, int& completed)
{
	timeval tv;
	tv.tv_sec = (time_t)(timeout);
	timeout -= (double)(tv.tv_sec);
	tv.tv_usec = (suseconds_t)(timeout*((double)(1.0e6)));

	return libusb_handle_events_timeout_completed(m_pCtx, &tv, &completed);
}
Пример #5
0
static void poll_thread(void *data)
{
   libusb_hid_t *hid = (libusb_hid_t*)data;

   while (!hid->quit)
   {
      struct timeval timeout = {0};
      libusb_handle_events_timeout_completed(NULL,
            &timeout, &hid->quit);
   }
}
Пример #6
0
/** Execute the job, until shut down. */
void EventLoop::execute()
{
    timeval t;
    t.tv_sec = 0;
    t.tv_usec = 100000;

    while(!shutdown_)
    {
        libusb_handle_events_timeout_completed(reinterpret_cast<libusb_context *>(usb_context_), &t, 0);
    }
}
Пример #7
0
void UsbHandler::handle_events ()
{
    struct timeval tv = {};
    tv.tv_usec = 200;
    while (run_event_thread)
    {
        libusb_handle_events_timeout_completed(this->session->get_session(),
                                               &tv,
                                               nullptr);
    }
}
Пример #8
0
void FX3Dev::event_loop( void ) {
    fprintf( stderr, "FX3Dev::read_loop() started\n" );
    while(event_loop_running) {
        struct timeval tv  = { 0, DEV_DOWNLOAD_TIMEOUT_MS * 1000 };
        int res = libusb_handle_events_timeout_completed( NULL, &tv, NULL );
        if(res != 0) {
            fprintf(stderr,"FX3Dev::read_loop() __error__ %d, read error: %s\n", res, libusb_error_name(res));
            abort();
        }
    }
    fprintf( stderr, "FX3Dev::read_loop() finished\n" );
}
Пример #9
0
/* USB I/O source callback.
 */
static int transfer_event(int fd, int revents, void *cb_data)
{
	const struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct drv_context *drvc;
	struct timeval tv;
	int ret;

	(void)fd;

	sdi  = cb_data;
	devc = sdi->priv;
	drvc = sdi->driver->context;

	if (!devc || !drvc)
		return G_SOURCE_REMOVE;

	/* Handle pending USB events without blocking. */
	tv.tv_sec  = 0;
	tv.tv_usec = 0;
	ret = libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx,
						     &tv, NULL);
	if (ret != 0) {
		sr_err("Event handling failed: %s.", libusb_error_name(ret));
		devc->transfer_error = TRUE;
	}

	if (!devc->transfer_error && devc->state == STATE_STATUS_WAIT) {
		if (devc->cancel_requested)
			submit_request(sdi, STATE_STOP_CAPTURE);
		else if (revents == 0) /* status poll timeout */
			submit_request(sdi, STATE_STATUS_REQUEST);
	}

	/* Stop processing events if an error occurred on a transfer. */
	if (devc->transfer_error)
		devc->state = STATE_IDLE;

	if (devc->state != STATE_IDLE)
		return G_SOURCE_CONTINUE;

	sr_info("Acquisition stopped.");

	/* We are done, clean up and send end packet to session bus. */
	clear_acquisition_state(sdi);
	std_session_send_df_end(sdi, LOG_PREFIX);

	return G_SOURCE_REMOVE;
}
//This function is called for every iteration + every second. Latter is needed
//in case of restart
void usb_monitor_itr_cb(void *ptr)
{
    struct usb_monitor_ctx *ctx = ptr;
    struct timeval tv = {0 ,0};

    //First, check for any of libusb's timers. We are incontrol of timer, so no
    //need for this function to block

    libusb_unlock_events(NULL);
    libusb_handle_events_timeout_completed(NULL, &tv, NULL);
    libusb_lock_events(NULL);

    //Check if we have any pending timeouts
    //TODO: Consider using the event loop timer queue for this
    usb_monitor_check_timeouts(ctx);
}
Пример #11
0
static int receive_usb_data(int fd, int revents, void *cb_data)
{
	struct drv_context *drvc;
	struct timeval tv;

	(void)fd;
	(void)revents;

	drvc = (struct drv_context *)cb_data;

	tv.tv_sec = 0;
	tv.tv_usec = 0;

	libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx,
		&tv, NULL);

	return TRUE;
}
Пример #12
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;
		}
	}
Пример #13
0
void USBHost::StartThreads()
{
  if (Core::WantsDeterminism())
    return;

  if (!m_scan_thread_running.IsSet())
  {
    m_scan_thread_running.Set();
    m_scan_thread = std::thread([this] {
      Common::SetCurrentThreadName("USB Scan Thread");
      while (m_scan_thread_running.IsSet())
      {
        UpdateDevices();
        Common::SleepCurrentThread(50);
      }
    });
  }

#ifdef __LIBUSB__
  if (!m_event_thread_running.IsSet() && m_libusb_context)
  {
    m_event_thread_running.Set();
    m_event_thread = std::thread([this] {
      Common::SetCurrentThreadName("USB Passthrough Thread");
      while (m_event_thread_running.IsSet())
      {
        if (SConfig::GetInstance().m_usb_passthrough_devices.empty())
        {
          Common::SleepCurrentThread(50);
          continue;
        }

        static timeval tv = {0, 50000};
        libusb_handle_events_timeout_completed(m_libusb_context, &tv, nullptr);
      }
    });
  }
#endif
}
Пример #14
0
int hmcfgusb_poll(struct hmcfgusb_dev *dev, int timeout)
{
	struct timeval tv;
	int usb_event = 0;
	int timed_out = 0;
	int i;
	int n;
	int fd_n;
	int err;

	errno = 0;

	memset(&tv, 0, sizeof(tv));
	err = libusb_get_next_timeout(NULL, &tv);
	if (err < 0) {
		fprintf(stderr, "libusb_get_next_timeout: %s\n", usb_strerror(err));
		errno = EIO;
		return -1;
	} else if (err == 0) {
		/* No pending timeout or a sane platform */
	} else {
		if ((tv.tv_sec == 0) && (tv.tv_usec == 0)) {
			usb_event = 1;
		} else if ((tv.tv_sec * 1000) < timeout) {
			timeout = tv.tv_sec * 1000;
		}
	}

	if (!usb_event) {
		for (i = 0; i < dev->n_pfd; i++) {
			dev->pfd[i].revents = 0;
		}

		n = poll(dev->pfd, dev->n_pfd, timeout);
		if (n < 0) {
			perror("poll");
			errno = 0;
			return -1;
		} else if (n == 0) {
			usb_event = 1;
			timed_out = 1;
		} else {
			for (fd_n = 0; fd_n < dev->n_pfd; fd_n++) {
				if (dev->pfd[fd_n].revents) {
					if (fd_n < dev->n_usb_pfd) {
						usb_event = 1;
						break;
					} else {
						errno = 0;
						return dev->pfd[fd_n].fd;
					}
				}
			}
		}
	}

	if (usb_event) {
		memset(&tv, 0, sizeof(tv));
		err = libusb_handle_events_timeout_completed(NULL, &tv, NULL);
		if (err < 0) {
			fprintf(stderr, "libusb_handle_events_timeout_completed: %s\n", usb_strerror(err));
			errno = EIO;
			return -1;
		}
	}

	errno = 0;
	if (quit) {
		fprintf(stderr, "closing device-connection due to error %d\n", quit);
		errno = quit;
	}

	if (timed_out)
		errno = ETIMEDOUT;

	return -1;
}
Пример #15
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;
}
Пример #16
0
UsbNotifier::~UsbNotifier()
{
    d->end = true;
    terminate();

    struct timeval emitTimer = (struct timeval){0};
    libusb_handle_events_timeout_completed(NULL, &emitTimer, NULL);

    // callbacks are eliminated on exit
    // http://libusb.sourceforge.net/api-1.0/hotplug.html
    libusb_exit(NULL);

    delete d;
}

UsbDevice* UsbNotifier::extractUsbDevice(libusb_device *device)
{
    struct libusb_device_descriptor descriptor;
    struct libusb_device_handle *myHandle = nullptr;
    int operationResult = 0;

    if (libusb_get_device_descriptor(device, &descriptor) < 0) {
        qDebug("COMPLETE FAIL");
        return nullptr;
    }

    // I need to open the device to get more information about the usb
    operationResult = libusb_open(device, &myHandle);

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - Can't open usb device @ " << libusb_get_device_address(device) << " ERROR NO: " << operationResult;
        return nullptr;
    }

    char manufacturer[256];
    char product[256];

    operationResult = libusb_get_string_descriptor_ascii(myHandle
    , descriptor.iManufacturer
    , (unsigned char*)manufacturer
    , sizeof(manufacturer));

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - something went wrong while extracting the manufacturer";
        return nullptr;
    }

    operationResult = libusb_get_string_descriptor_ascii(myHandle
    , descriptor.iProduct
    , (unsigned char*)product
    , sizeof(product));

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - something went wrong while extracting the product";
        return nullptr;
    }

    libusb_close(myHandle);

    return new UsbDevice(libusb_get_device_address(device)
                        , libusb_get_bus_number(device)
                        , descriptor.idVendor
                        , libusb_get_port_number(device)
                        , descriptor.idProduct
                        , manufacturer
                        , product
                        , device);
}


void UsbNotifier::run()
{
    // do a quick check for already plugged in usb devices
    int result = 0;
    d->end = false;
    libusb_device **deviceList;

    result = libusb_get_device_list(NULL, &deviceList);

    if (result < 0) {
        // TODO handle error
        qDebug() << "[UsbNotifier::run] result value: " << result;
        qDebug() << "UsbNotifier::run] ERROR: " << libusb_error_name(result);
    } else {
        libusb_device_handle *handle = nullptr;

        for (int i = 0; i < result; ++i) {
            // test if the device is usable. There might be some usb device which we don't have permission
            // to operate on. This test is done by a simple libusb_open/close test.
            if (libusb_open(deviceList[i], &handle) == LIBUSB_SUCCESS) {
                libusb_close(handle);

                UsbDevice *usbDevice = extractUsbDevice(deviceList[i]);

                if (usbDevice && (d->product == 0 || d->vendor == 0)) {
                    Q_EMIT deviceAttached(usbDevice);
                } else {
                    if (usbDevice
                        && (usbDevice->productId() == d->product && usbDevice->vendorId() == d->vendor)) {
                        Q_EMIT deviceAttached(usbDevice);
                    }
                }
            }
        }

        libusb_free_device_list(deviceList, 1);
    }

    // and now start watching for events
    setTerminationEnabled(true);
    while (!d->end) {
        libusb_handle_events(NULL);
    }
}