void QUsbHid::close() { QMutexLocker lock(mutex); if (m_isOpen) { flush(); if(interface >=0){ libusb_release_interface(handle, interface); } libusb_attach_kernel_driver(handle, 0); libusb_close(handle); handle = 0; if(worker){ worker->wait(500); if(!worker->isFinished()){ worker->terminate(); } delete worker; } QIODevice::close(); // mark ourselves as closed _bytesToWrite = 0; } m_isOpen = false; lastErr = 0; }
libusb_device_handle * LedDeviceHyperionUsbasp::openDevice(libusb_device *device) { Logger * log = Logger::getInstance("LedDevice"); libusb_device_handle * handle = nullptr; int error = libusb_open(device, &handle); if (error != LIBUSB_SUCCESS) { Error(log, "unable to open device(%d): %s",error,libusb_error_name(error)); throw error; } // detach kernel driver if it is active if (libusb_kernel_driver_active(handle, 0) == 1) { error = libusb_detach_kernel_driver(handle, 0); if (error != LIBUSB_SUCCESS) { Error(log, "unable to detach kernel driver(%d): %s",error,libusb_error_name(error)); libusb_close(handle); throw error; } } error = libusb_claim_interface(handle, 0); if (error != LIBUSB_SUCCESS) { Error(log, "unable to claim interface(%d): %s", error, libusb_error_name(error)); libusb_attach_kernel_driver(handle, 0); libusb_close(handle); throw error; } return handle; }
USBHost::~USBHost() { int i = USB_MAX_DEVICE - 1; unsigned int port_number = 0; if (init_flag) { while (i >= 0) { if (devh[i] != NULL) { D(bug("USBHost: Trying to close device %d", i)); while (port_number < NUMBER_OF_PORTS) { if (roothub.port[port_number].device_index == i) { if (libusb_release_interface(devh[i], roothub.port[port_number].interface) < 0) { D(bug("USBHost: unable to release device interface")); } if (libusb_attach_kernel_driver(devh[i], roothub.port[port_number].interface) < 0) { D(bug("USBHost: unable to reattach kernel driver to interface")); } break; } port_number++; } libusb_close(devh[i]); devh[i] = NULL; D(bug("USBHost: %d device closed", i)); } i--; } usbhost_free_usb_devices(); libusb_exit(NULL); } D(bug("USBHost: destroyed")); }
static void exit_release_resources(int code) { if(tap_fd >= 0) { if_down(); while (wait(NULL) > 0) {} if_release(); while (wait(NULL) > 0) {} } if(ctx != NULL) { if(req_transfer != NULL) { libusb_cancel_transfer(req_transfer); libusb_free_transfer(req_transfer); } libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); if(fds != NULL) { free(fds); } if(devh != NULL) { libusb_release_interface(devh, 0); if (kernel_driver_active) libusb_attach_kernel_driver(devh, 0); libusb_unlock_events(ctx); libusb_close(devh); } libusb_exit(ctx); } if(logfile != NULL) { fclose(logfile); } exit(code); }
static int scpi_usbtmc_libusb_close(struct sr_scpi_dev_inst *scpi) { struct scpi_usbtmc_libusb *uscpi = scpi->priv; struct sr_usb_dev_inst *usb = uscpi->usb; int ret; if (!usb->devhdl) return SR_ERR; scpi_usbtmc_local(uscpi); if ((ret = libusb_release_interface(usb->devhdl, uscpi->interface)) < 0) sr_err("Failed to release interface: %s.", libusb_error_name(ret)); if (uscpi->detached_kernel_driver) { if ((ret = libusb_attach_kernel_driver(usb->devhdl, uscpi->interface)) < 0) sr_err("Failed to re-attach kernel driver: %s.", libusb_error_name(ret)); uscpi->detached_kernel_driver = 0; } sr_usb_close(usb); return SR_OK; }
void freespace_closeDevice(FreespaceDeviceId id) { struct FreespaceDevice* device; device = findDeviceById(id); if (device != NULL && device->handle_ != NULL) { // Stop receives. freespace_terminateReceiveTransfers(device); // Should we wait until everything terminates cleanly? // Release our lock on the interface. libusb_release_interface(device->handle_, device->api_->controlInterfaceNumber_); // Re-attach the kernel driver if we detached it before. if (device->kernelDriverDetached_) { // This currently fails, and there doesn't seem to be anything that we // can do. libusb_attach_kernel_driver(device->handle_, device->api_->controlInterfaceNumber_); } libusb_close(device->handle_); device->handle_ = NULL; if (device->state_ == FREESPACE_DISCONNECTED) { removeFreespaceDevice(device); } else { device->state_ = FREESPACE_CONNECTED; } } }
/*----------------------------------------------------------------------------- * Name : usb_close * Purpose : Close USB port * Inputs : p : port structure * Outputs : <> * Return : APS_OK or error code * -----------------------------------------------------------------------------*/ int usb_close(aps_port_t *p) { int n; /*release interface zero*/ n = libusb_release_interface(p->set.usb.hdev, 0); if (n != 0) { return APS_IO_ERROR; } /*if a kernel driver was connected, try reconnecting*/ if (p->set.usb.was_kernel_driver_attached) { n = libusb_attach_kernel_driver(p->set.usb.hdev, 0); if (n != 0) { return APS_IO_ERROR; } } /*close device*/ libusb_close(p->set.usb.hdev); p->set.usb.hdev = 0; return APS_OK; }
/* ---- * device_close() * * Close the specified card. * ---- */ static PyObject * device_close(PyObject *self, PyObject *args) { int cardNumber = 0; int interface = 0; /* ---- * Parse command arguments * ---- */ if (!PyArg_ParseTuple(args, "i", &cardNumber)) return NULL; if (cardNumber < 0 || cardNumber >= OPEN8055_MAX_CARDS) { PyErr_SetString(PyExc_ValueError, "invalid card number"); return NULL; } if (deviceCard[cardNumber].handle == NULL) { PyErr_SetString(PyExc_RuntimeError, "card not open"); return NULL; } libusb_free_transfer(deviceCard[cardNumber].readTransfer); libusb_free_transfer(deviceCard[cardNumber].writeTransfer); libusb_release_interface(deviceCard[cardNumber].handle, interface); if (deviceCard[cardNumber].hadKernelDriver) libusb_attach_kernel_driver(deviceCard[cardNumber].handle, interface); libusb_close(deviceCard[cardNumber].handle); deviceCard[cardNumber].handle = NULL; return Py_BuildValue("i", cardNumber); }
GlobalTrainer::~GlobalTrainer() { free(read_buf); if (interface_claimed) { const int ecode = libusb_release_interface(usb_handle, 1); if (ecode) { std::cerr << "Error releasing interface: " << libusb_error_name(ecode) << std::endl; } } if (detached_kernel) { const int ecode = libusb_attach_kernel_driver(usb_handle, 1); if (ecode) { std::cerr << "Error reattaching kernel driver: " << libusb_error_name(ecode) << std::endl; } } const int ecode = libusb_reset_device(usb_handle); if (ecode && ecode != LIBUSB_ERROR_NOT_FOUND) { std::cerr << "Error reseting USB device: " << libusb_error_name(ecode) << std::endl; } if (usb_handle) { libusb_close(usb_handle); } if (usb_ctxt) { libusb_exit(usb_ctxt); } }
static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface) { PRINTF_LINE("Reattach kernel driver to USB interface..."); PRINTF_END(); libusb_release_interface(udev, interface); libusb_attach_kernel_driver(udev, interface); }
void Device::attachKernelDriver(uint8_t interface) const throw(USBError) { int rc = libusb_attach_kernel_driver(dev_handle, interface); if (rc < 0) { debug(LOG_ERR, DEBUG_LOG, 0, "cannot attach kernel driver: %s", libusb_error_name(rc)); throw USBError(libusb_error_name(rc)); } }
void test_exit(struct test_state *state) { libusb_release_interface(state->handle, 0); if (state->attached == 1) libusb_attach_kernel_driver(state->handle, 0); libusb_close(state->handle); libusb_exit(state->ctx); }
void UsbCamera::release_interface () { int r = libusb_release_interface(this->dev_handle, this->interface); if (r != 0) { throw std::runtime_error("Unable to release intreface."); } libusb_attach_kernel_driver(this->dev_handle, this->interface); }
/* Deinitialize the audio path */ int mxuvc_audio_deinit() { RECORD(""); int ret, i; int int_num[2] = {aud_cfg.ctrlif, aud_cfg.interface}; if(!audio_initialized) return 1; deregister_libusb_removal_cb((libusb_pollfd_removed_cb) audio_removed); if(!audio_disconnected) { /* Stop the audio first if not stopped yet */ if(aud_started == 1) mxuvc_audio_stop(AUD_CH1); for(i=0; i<2; i++) { TRACE2("Releasing audio interface %i\n", int_num[i]); ret = libusb_release_interface(audio_hdl, int_num[i]); CHECK_ERROR(ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND && ret != LIBUSB_ERROR_NO_DEVICE, -1, "Unable to release USB interface %i. Libusb " "return code is: %i", int_num[i], ret); } /* Re-attach the previously attached kernel driver */ for(i=0; i<2; i++) libusb_attach_kernel_driver(audio_hdl, int_num[i]); } /* Exit Camera Event loop/thread */ stop_libusb_events(); /* Free USB resources */ TRACE("Freeing USB audio resources\n"); //if(mxuvc_audio_alive()) libusb_close(audio_hdl); exit_libusb(&audio_ctx); if(aud_cfg.xfers) { free(aud_cfg.xfers); aud_cfg.xfers = NULL; } if(abuf) { free(abuf); abuf = NULL; } audio_hdl = NULL; audio_ctx = NULL; audio_initialized = 0; TRACE("The audio has been successfully uninitialized\n"); //mxuvc_debug_stoprec(); return 0; }
void alienFx::cAlienfx_device::UnInit() { if (lAlienFx != NULL) { libusb_release_interface(lAlienFx, 0); libusb_attach_kernel_driver(lAlienFx, 0); libusb_close(lAlienFx); } lAlienFx = NULL; if (lUsbContext != NULL) { libusb_exit(lUsbContext); } lUsbContext = NULL; }
libusb_device_handle* close_usb (libusb_device_handle* handle) { libusb_close (handle); #if defined(__linux__) if (detached_iface >= 0) // detach requested ? { libusb_attach_kernel_driver (handle, 0); // restore status quo detached_iface = -1; } #endif return NULL; }
int send_command(libusb_device_handle *handle, cmdstruct command ) { if (command.numCmds == 0) { printf( "send_command: Empty command provided! Not sending anything...\n"); return 0; } int stat; stat = libusb_detach_kernel_driver(handle, 0); if ((stat < 0 ) || verbose_flag) perror("Detach kernel driver"); stat = libusb_claim_interface( handle, 0 ); if ( (stat < 0) || verbose_flag) perror("Claiming USB interface"); int transferred = 0; // send all command strings provided in command int cmdCount; for (cmdCount=0; cmdCount < command.numCmds; cmdCount++) { if (verbose_flag) { char raw_string[255]; print_cmd(raw_string, command.cmds[cmdCount]); printf("\tSending string: \"%s\"\n", raw_string); } stat = libusb_interrupt_transfer( handle, 1, command.cmds[cmdCount], sizeof( command.cmds[cmdCount] ), &transferred, TRANSFER_WAIT_TIMEOUT_MS ); if ( (stat < 0) || verbose_flag) perror("Sending USB command"); } /* In case the command just sent caused the device to switch from restricted mode to native mode * the following two commands will fail due to invalid device handle (because the device changed * its pid on the USB bus). * So it is not possible anymore to release the interface and re-attach kernel driver. * I am not sure if this produces a memory leak within libusb, but i do not think there is another * solution possible... */ stat = libusb_release_interface(handle, 0 ); if (stat != LIBUSB_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above. if ( (stat < 0) || verbose_flag) { perror("Releasing USB interface."); } } stat = libusb_attach_kernel_driver( handle, 0); if (stat != LIBUSB_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above. if ( (stat < 0) || verbose_flag) { perror("Reattaching kernel driver"); } } return 0; }
static int gp_libusb1_close (GPPort *port) { C_PARAMS (port); if (port->pl->dh == NULL) return GP_OK; _close_async_interrupts(port); if (libusb_release_interface (port->pl->dh, port->settings.usb.interface) < 0) { int saved_errno = errno; gp_port_set_error (port, _("Could not release interface %d (%s)."), port->settings.usb.interface, strerror(saved_errno)); return GP_ERROR_IO; } #if 0 /* This confuses the EOS 5d camera and possible other EOSs. *sigh* */ /* This is only for our very special Canon cameras which need a good * whack after close, otherwise they get timeouts on reconnect. */ if (port->pl->d->descriptor.idVendor == 0x04a9) { if (usb_reset (port->pl->dh) < 0) { int saved_errno = errno; gp_port_set_error (port, _("Could not reset " "USB port (%s)."), strerror(saved_errno)); return (GP_ERROR_IO); } } #endif if (port->pl->detached) { if (LOG_ON_LIBUSB_E (libusb_attach_kernel_driver (port->pl->dh, port->settings.usb.interface))) gp_port_set_error (port, _("Could not reattach kernel driver of camera device.")); } libusb_close (port->pl->dh); free (port->pl->irqs); port->pl->irqs = NULL; free (port->pl->irqlens); port->pl->irqlens = NULL; port->pl->nrofirqs = 0; port->pl->dh = NULL; return GP_OK; }
int fnusb_close_subdevices(freenect_device *dev) { if (dev->usb_cam.dev) { libusb_release_interface(dev->usb_cam.dev, 0); #ifndef _WIN32 libusb_attach_kernel_driver(dev->usb_cam.dev, 0); #endif libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; } if (dev->usb_motor.dev) { libusb_release_interface(dev->usb_motor.dev, 0); libusb_close(dev->usb_motor.dev); dev->usb_motor.dev = NULL; } return 0; }
LedDeviceHyperionUsbasp::~LedDeviceHyperionUsbasp() { if (_deviceHandle != nullptr) { libusb_release_interface(_deviceHandle, 0); libusb_attach_kernel_driver(_deviceHandle, 0); libusb_close(_deviceHandle); _deviceHandle = nullptr; } if (_libusbContext != nullptr) { libusb_exit(_libusbContext); _libusbContext = nullptr; } }
static void ant_usb_destroy(ant_t *ant) { antusb_t *usbant = (antusb_t*)ant; devlist_t *devlist; bool removed = false; DBG("destroy %s\n", ant->name); if (usbant->dev) { if (usbant->attached == 1) { libusb_attach_kernel_driver(usbant->dev, 0); } libusb_close(usbant->dev); } for (devlist = opendevices; devlist; devlist = devlist->next) { if (devlist->usbant != usbant) continue; removed = true; /* remove from the list of open devices */ if (devlist == opendevices) { opendevices = devlist->next; if (opendevices) opendevices->prev = NULL; } else { devlist->prev->next = devlist->next; if (devlist->next) devlist->next->prev = devlist->prev; } /* cleanup */ free(devlist); break; } free(usbant); if (removed && !opendevices) { DBG("no open devices, cleaning up libusb\n"); libusb_exit(_usb); } }
enum libusb_error uhd_iface_attach(uhd_iface *iface) { enum libusb_error err; assert(uhd_iface_valid(iface)); if (iface->detached) { err = libusb_attach_kernel_driver(iface->dev->handle, iface->number); if (err != LIBUSB_SUCCESS) return err; iface->detached = false; } return LIBUSB_SUCCESS; }
int CNIF_USB_Close() { int i = 0; int e = 0; /*----------free configuration----------- */ if(g_cptr != NULL){ libusb_free_config_descriptor(g_cptr); g_cptr = NULL; } /*----------release interface/attache kernel----------- */ for(; i < g_usblp_attached; i++) { if( (e = libusb_release_interface(g_dh, g_claimed_interface[i])) < 0) { #ifdef _DEBUG_MODE_ fprintf(stderr, "ERROR: libusb_release_interface Error.%d (%d)\n", g_claimed_interface[i], e); #endif } #ifdef _DEBUG_MODE_ fprintf(stderr, "DEBUG: End of release interface %d \n", g_claimed_interface[i]); #endif e = libusb_attach_kernel_driver(g_dh, g_claimed_interface[i]); #ifdef _DEBUG_MODE_ fprintf(stderr, "DEBUG: End of attache %d ,%d \n", g_claimed_interface[i], e); #endif g_claimed_interface[i] = 0; } g_usblp_attached = 0; /*----------close device----------- */ if(g_dh != NULL) { libusb_close(g_dh); g_dh = NULL; } /*----------free libusb context----------- */ if(g_context != NULL) { libusb_exit(g_context); g_context = NULL; } return 0; }
static int gp_port_usb_close (GPPort *port) { if (!port || !port->pl->dh) return GP_ERROR_BAD_PARAMETERS; if (libusb_release_interface (port->pl->dh, port->settings.usb.interface) < 0) { int saved_errno = errno; gp_port_set_error (port, _("Could not release " "interface %d (%s)."), port->settings.usb.interface, strerror(saved_errno)); return (GP_ERROR_IO); } #if 0 /* This confuses the EOS 5d camera and possible other EOSs. *sigh* */ /* This is only for our very special Canon cameras which need a good * whack after close, otherwise they get timeouts on reconnect. */ if (port->pl->d->descriptor.idVendor == 0x04a9) { if (usb_reset (port->pl->dh) < 0) { int saved_errno = errno; gp_port_set_error (port, _("Could not reset " "USB port (%s)."), strerror(saved_errno)); return (GP_ERROR_IO); } } #endif if (port->pl->detached) { int ret; ret = libusb_attach_kernel_driver (port->pl->dh, port->settings.usb.interface); if (ret < 0) gp_port_set_error (port, _("Could not reattach kernel driver of camera device.")); } libusb_close (port->pl->dh); port->pl->dh = NULL; return GP_OK; }
void BOOT_Deinit(struct ols_boot_t *ob) { #if IS_WIN32 CloseHandle(ob->hDevice); ob->hDevice = INVALID_HANDLE_VALUE; #else libusb_release_interface(ob->dev, 0); if (ob->attach) { if (libusb_attach_kernel_driver(ob->dev, 0)) { fprintf(stderr, "Unable to reattach kernel driver\n"); } } libusb_close(ob->dev); libusb_exit(ob->ctx); ob->dev = NULL; ob->ctx = NULL; #endif }
int usb_close(int usb_number) { struct usb_state* state = usb_states+usb_number; if(state->devh) { if(state->type == C_TYPE_XONE_PAD) { unsigned char power_off[] = { 0x05, 0x20, 0x00, 0x01, 0x04 }; usb_send_interrupt_out_sync(usb_number, power_off, sizeof(power_off)); } cancel_transfers();//TODO MLA: selective cancels libusb_release_interface(state->devh, controller[state->type].interface); #if !defined(LIBUSB_API_VERSION) && !defined(LIBUSBX_API_VERSION) #ifndef WIN32 libusb_attach_kernel_driver(state->devh, 0); #endif #endif libusb_close(state->devh); state->devh = NULL; --nb_opened; if(!nb_opened) { libusb_free_device_list(devs, 1); devs = NULL; if(ctx) { libusb_exit(ctx); ctx = NULL; } } } set_done(); return 1; }
void yyyPacketShutdown(yInterfaceSt *iface) { int res,j; iface->flags.yyySetupDone = 0; HALLOG("%s:%d cancel all transfer\n",iface->serial,iface->ifaceno); for(j=0;j< NB_LINUX_USB_TR ; j++){ int count=10; int res =libusb_cancel_transfer(iface->rdTr[j].tr); if(res==0){ while(count && iface->rdTr[j].tr->status != LIBUSB_TRANSFER_CANCELLED){ usleep(1000); count--; } } } for(j=0;j< NB_LINUX_USB_TR ; j++){ if (iface->rdTr[j].tr){ HALLOG("%s:%d libusb_TR free %d\n",iface->serial,iface->ifaceno,j); libusb_free_transfer(iface->rdTr[j].tr); iface->rdTr[j].tr=NULL; } } HALLOG("%s:%d libusb relase iface\n",iface->serial,iface->ifaceno); res = libusb_release_interface(iface->hdl,iface->ifaceno); if(res != 0 && res!=LIBUSB_ERROR_NOT_FOUND && res!=LIBUSB_ERROR_NO_DEVICE){ HALLOG("%s:%dlibusb_release_interface error\n",iface->serial,iface->ifaceno); } res = libusb_attach_kernel_driver(iface->hdl,iface->ifaceno); if(res<0 && res!=LIBUSB_ERROR_NO_DEVICE){ HALLOG("%s:%d libusb_attach_kernel_driver error\n",iface->serial,iface->ifaceno); } libusb_close(iface->hdl); yPktQueueFree(&iface->rxQueue); yPktQueueFree(&iface->txQueue); }
static int scpi_usbtmc_libusb_close(void *priv) { int ret; struct scpi_usbtmc_libusb *uscpi = priv; struct sr_usb_dev_inst *usb = uscpi->usb; if (!usb->devhdl) return SR_ERR; if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_in_ep)) < 0) sr_err("Failed to clear halt/stall condition for EP %d: %s.", uscpi->bulk_in_ep, libusb_error_name(ret)); if ((ret = libusb_clear_halt(usb->devhdl, uscpi->bulk_out_ep)) < 0) sr_err("Failed to clear halt/stall condition for EP %d: %s.", uscpi->bulk_out_ep, libusb_error_name(ret)); if ((ret = libusb_clear_halt(usb->devhdl, uscpi->interrupt_ep)) < 0) sr_err("Failed to clear halt/stall condition for EP %d: %s.", uscpi->interrupt_ep, libusb_error_name(ret)); if ((ret = libusb_release_interface(usb->devhdl, uscpi->interface)) < 0) sr_err("Failed to release interface: %s.", libusb_error_name(ret)); if (uscpi->detached_kernel_driver) { if ((ret = libusb_attach_kernel_driver(usb->devhdl, uscpi->interface)) < 0) sr_err("Failed to re-attach kernel driver: %s.", libusb_error_name(ret)); uscpi->detached_kernel_driver = 0; } libusb_close(usb->devhdl); usb->devhdl = NULL; return SR_OK; }
//------------------------------------------------------------------------------ int ttwatch_close(TTWATCH *watch) { if (!watch) return TTWATCH_InvalidParameter; if (watch->preferences_changed) RETURN_ERROR(ttwatch_write_preferences(watch)); if (watch->manifest_changed) RETURN_ERROR(ttwatch_write_manifest(watch)); libusb_release_interface(watch->device, 0); if (watch->attach_kernel_driver) libusb_attach_kernel_driver(watch->device, 0); libusb_close(watch->device); if (watch->preferences_file) free(watch->preferences_file); if (watch->manifest_file) free(watch->manifest_file); free(watch); return TTWATCH_NoError; }
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { libusb_device **devs; libusb_device *dev; libusb_device_handle *handle; ssize_t num_devs; int i = 0; struct hid_device_info *root = NULL; // return object struct hid_device_info *cur_dev = NULL; setlocale(LC_ALL,""); if (!initialized) hid_init(); num_devs = libusb_get_device_list(NULL, &devs); if (num_devs < 0) return NULL; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; struct libusb_config_descriptor *conf_desc = NULL; int j, k; int interface_num = 0; int res = libusb_get_device_descriptor(dev, &desc); unsigned short dev_vid = desc.idVendor; unsigned short dev_pid = desc.idProduct; /* HID's are defined at the interface level. */ if (desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE) continue; res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); if (conf_desc) { for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { const struct libusb_interface_descriptor *intf_desc; intf_desc = &intf->altsetting[k]; if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { interface_num = intf_desc->bInterfaceNumber; /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 && product_id == 0x0) || (vendor_id == dev_vid && product_id == dev_pid)) { struct hid_device_info *tmp; /* VID/PID match. Create the record. */ tmp = calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Fill out the record */ cur_dev->next = NULL; cur_dev->path = make_path(dev, interface_num); res = libusb_open(dev, &handle); if (res >= 0) { /* Serial Number */ if (desc.iSerialNumber > 0) cur_dev->serial_number = get_usb_string(handle, desc.iSerialNumber); /* Manufacturer and Product strings */ if (desc.iManufacturer > 0) cur_dev->manufacturer_string = get_usb_string(handle, desc.iManufacturer); if (desc.iProduct > 0) cur_dev->product_string = get_usb_string(handle, desc.iProduct); #ifdef INVASIVE_GET_USAGE /* This section is removed because it is too invasive on the system. Getting a Usage Page and Usage requires parsing the HID Report descriptor. Getting a HID Report descriptor involves claiming the interface. Claiming the interface involves detaching the kernel driver. Detaching the kernel driver is hard on the system because it will unclaim interfaces (if another app has them claimed) and the re-attachment of the driver will sometimes change /dev entry names. It is for these reasons that this section is #if 0. For composite devices, use the interface field in the hid_device_info struct to distinguish between interfaces. */ int detached = 0; unsigned char data[256]; /* Usage Page and Usage */ res = libusb_kernel_driver_active(handle, interface_num); if (res == 1) { res = libusb_detach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); else detached = 1; } res = libusb_claim_interface(handle, interface_num); if (res >= 0) { /* Get the HID Report Descriptor. */ res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); if (res >= 0) { unsigned short page=0, usage=0; /* Parse the usage and usage page out of the report descriptor. */ get_usage(data, res, &page, &usage); cur_dev->usage_page = page; cur_dev->usage = usage; } else LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); /* Release the interface */ res = libusb_release_interface(handle, interface_num); if (res < 0) LOG("Can't release the interface.\n"); } else LOG("Can't claim interface %d\n", res); /* Re-attach kernel driver if necessary. */ if (detached) { res = libusb_attach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't re-attach kernel driver.\n"); } #endif /*******************/ libusb_close(handle); } /* VID/PID */ cur_dev->vendor_id = dev_vid; cur_dev->product_id = dev_pid; /* Release Number */ cur_dev->release_number = desc.bcdDevice; /* Interface Number */ cur_dev->interface_number = interface_num; } } } /* altsettings */ } /* interfaces */ libusb_free_config_descriptor(conf_desc); } } libusb_free_device_list(devs, 1); return root; }