int fnusb_process_events(fnusb_ctx *ctx) { return libusb_handle_events(ctx->ctx); }
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(NULL); if (res < 0) { /* There was an error. Break out of this loop. */ break; } } /* Cancel any transfer that may be pending. This call will fail if no transfers are pending, but that's OK. */ if (libusb_cancel_transfer(dev->transfer) == 0) { /* The transfer was cancelled, so wait for its completion. */ libusb_handle_events(NULL); } /* 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; }
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; /* 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) { 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; }
bool USBMgr::handleEvents() { return (libusb_handle_events(instance()->usb_context) == 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); }
int main(int argc, char *argv[]) { libusb_hotplug_callback_handle hp[2]; int product_id, vendor_id, class_id = LIBUSB_HOTPLUG_MATCH_ANY; g_Command_Attach = ""; g_Command_Detach = ""; int rc; char flag_initial_search = 0; /* getopt */ while ((rc = getopt(argc, argv, "c:a:d:ih")) != -1) { switch (rc) { case 'c': class_id = strtol(optarg, NULL, 0); break; case 'a': g_Command_Attach = optarg; break; case 'd': g_Command_Detach = optarg; break; case 'i': flag_initial_search = 1; break; case 'h': default: /* '?' */ print_usage(argv[0]); exit(EXIT_FAILURE); } } if (optind + 2 > argc) { print_usage(argv[0]); exit(EXIT_FAILURE); } vendor_id = strtol(argv[optind++], NULL, 0); product_id = strtol(argv[optind++], NULL, 0); /* 初期化 */ rc = libusb_init (NULL); if (rc < 0) { fprintf(stderr, "failed to initialise libusb: %s\n", libusb_error_name(rc)); return EXIT_FAILURE; } /* シグナルハンドリング */ signal(SIGINT, finish); signal(SIGTERM, finish); /* ホットプラグ対応のプラットフォームか調べる */ if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { fprintf (stderr, "Hotplug capabilites are not supported on this platform\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* (オプションi)起動した時点での状態から目的のUSBデバイスを探す。 */ if (flag_initial_search) { if (find_device(vendor_id, product_id)) { func_attached(); } else { func_detached(); } } /* デバイスが接続されたら実行される関数を登録 */ rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id, product_id, class_id, hotplug_callback, NULL, &hp[0]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 0\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* デバイスが切断されたら実行される関数を登録 */ rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id, product_id,class_id, hotplug_callback_detach, NULL, &hp[1]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 1\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* メインループ。イベントを回し続ける */ while (1) { rc = libusb_handle_events (NULL); if (rc < 0) fprintf(stderr, "libusb_handle_events() failed: %s\n", libusb_error_name(rc)); } /* 到達不能コード。終了処理はシグナルにより呼び出される。 */ /* libusb_exit (NULL); */ }
/** \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 no 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 */ API_EXPORTED int 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(HANDLE_CTX(dev_handle)); if (r < 0) { libusb_cancel_transfer(transfer); while (!completed) if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 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; default: usbi_warn(HANDLE_CTX(dev_handle), "unrecognised status code %d", transfer->status); r = LIBUSB_ERROR_OTHER; } libusb_free_transfer(transfer); return r; }
KeyCode activity(const char* cmd, const char* value) { libusb_handle_events(context); return key; }
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); } }