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); }
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; }
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); }
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); } }
/** 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); } }
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); } }
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" ); }
/* 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); }
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; }
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; } }
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 }
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; }
//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; }
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); } }