uint8_t Device::getDeviceAddress() const { return libusb_get_device_address(dev); }
int ezusb_upload_firmware(struct slogic_ctx *handle, int configuration, const char *filename){ log_printf(DEBUG, "uploading firmware to device on %d.%d\n", libusb_get_bus_number(handle->dev), libusb_get_device_address(handle->dev)); if ((ezusb_reset(handle->device_handle, 1)) < 0) return 1; if (ezusb_install_firmware(handle->device_handle, filename) != 0) return 1; if ((ezusb_reset(handle->device_handle, 0)) < 0) return 1; return 0; }
/*! \brief Open a communcation channel to the given USB port name. */ XsResultValue UsbInterface::open(const XsPortInfo &portInfo, uint32_t, uint32_t) { d->m_endTime = 0; #ifdef USE_WINUSB JLDEBUG(gJournal, "Open usb port " << portInfo.portName().toStdString()); #else JLDEBUG(gJournal, "Open usb port " << portInfo.usbBus() << ":" << portInfo.usbAddress()); #endif if (isOpen()) { JLALERT(gJournal, "Port " << portInfo.portName().toStdString() << " already open"); return (d->m_lastResult = XRV_ALREADYOPEN); } #ifdef USE_WINUSB d->m_deviceHandle = CreateFileA(portInfo.portName().c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (d->m_deviceHandle == INVALID_HANDLE_VALUE) { d->m_deviceHandle = NULL; return (d->m_lastResult = XRV_PORTNOTFOUND); } BOOL result = FALSE; UCHAR speed = 0; ULONG length = 0; USB_INTERFACE_DESCRIPTOR interfaceDescriptor = {0,0,0,0,0,0,0,0,0}; WINUSB_PIPE_INFORMATION pipeInfo; result = WinUsb_Initialize(d->m_deviceHandle, &d->m_usbHandle[0]); if (result) { result = WinUsb_GetAssociatedInterface(d->m_usbHandle[0],0,&d->m_usbHandle[1]); } else { #ifdef XSENS_DEBUG DWORD err = GetLastError(); assert(result); #endif return (d->m_lastResult = XRV_ERROR); } for (int k = 0; k<2;k++) { if(result) { assert(d->m_usbHandle[k] != 0); length = sizeof(UCHAR); result = WinUsb_QueryDeviceInformation(d->m_usbHandle[k], DEVICE_SPEED, &length, &speed); } if(result) { d->m_deviceSpeed = speed; result = WinUsb_QueryInterfaceSettings(d->m_usbHandle[k], 0, &interfaceDescriptor); } if(result) { for(int i=0;i<interfaceDescriptor.bNumEndpoints;i++) { result = WinUsb_QueryPipe(d->m_usbHandle[k], 0, (UCHAR) i, &pipeInfo); if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId)) { d->m_bulkInPipe = pipeInfo.PipeId; d->m_bulkInPipePacketSize = pipeInfo.MaximumPacketSize; } else if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_OUT(pipeInfo.PipeId)) { d->m_bulkOutPipe = pipeInfo.PipeId; } else if(pipeInfo.PipeType == UsbdPipeTypeInterrupt) { d->m_interruptPipe = pipeInfo.PipeId; } else { result = FALSE; break; } } } } setTimeout(0); //lint !e534 flushData(); //lint !e534 sprintf(d->m_portname, "%s", portInfo.portName().c_str()); // d->m_offset = 0; ::ResetEvent(&d->m_quitEvent); //lint !e534 d->m_threadHandle = xsStartThread(usbReadThreadFunc, d, &d->m_threadId); if (d->m_threadHandle == XSENS_INVALID_THREAD) { #ifdef XSENS_DEBUG assert(0); #endif return (d->m_lastResult = XRV_ERROR); } #else // !USE_WINUSB static UsbInterfacePrivate::UsbContext contextManager; //m_contextManager; libusb_device **deviceList; ssize_t listLength = libusb_get_device_list(contextManager.m_usbContext /*d->m_contextManager.m_usbContext*/, &deviceList); if (listLength < 0) return d->m_lastResult = d->libusbErrorToXrv((int)listLength); // "USBxxx:yyy" uint8_t bus = XsPortInfo_usbBus(&portInfo); uint8_t address = XsPortInfo_usbAddress(&portInfo); XsResultValue xrv = XRV_OK; int result; libusb_device *device = NULL; for (int i = 0; i < listLength && device == NULL; ++i) { libusb_device *dev = deviceList[i]; if (libusb_get_bus_number(dev) != bus || libusb_get_device_address(dev) != address) continue; libusb_device_descriptor desc; result = libusb_get_device_descriptor(dev, &desc); if (result != LIBUSB_SUCCESS) break; libusb_config_descriptor *configDesc; result = libusb_get_active_config_descriptor(dev, &configDesc); if (result != LIBUSB_SUCCESS) break; d->m_interface = -1; d->m_interfaceCount = configDesc->bNumInterfaces; // find the bulk transfer endpoints for (uint8_t ifCount = 0; ifCount < configDesc->bNumInterfaces && d->m_interface == -1; ++ifCount) { for (uint8_t altsettingCount = 0; altsettingCount < configDesc->interface[ifCount].num_altsetting; altsettingCount++) { const libusb_endpoint_descriptor *endpoints = configDesc->interface[ifCount].altsetting[altsettingCount].endpoint; int inEndpoint = -1, outEndpoint = -1; for (uint8_t i = 0; i < configDesc->interface[ifCount].altsetting[altsettingCount].bNumEndpoints; i++) { if ((endpoints[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK) continue; switch (endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK) { case LIBUSB_ENDPOINT_IN: inEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; case LIBUSB_ENDPOINT_OUT: outEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; } } if (outEndpoint == -1 || inEndpoint == -1) continue; d->m_interface = ifCount; d->m_dataOutEndPoint = outEndpoint; d->m_dataInEndPoint = inEndpoint; } } if (d->m_interface == -1) { xrv = XRV_INPUTCANNOTBEOPENED; break; } libusb_free_config_descriptor(configDesc); libusb_ref_device(dev); device = dev; result = LIBUSB_SUCCESS; } libusb_free_device_list(deviceList, 1); if (result != LIBUSB_SUCCESS) { libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } if (xrv != XRV_OK) { libusb_unref_device(device); return d->m_lastResult = xrv; } libusb_device_handle *handle; result = libusb_open(device, &handle); if (result != LIBUSB_SUCCESS) { libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } // be rude and claim all interfaces for (int i = 0; i < d->m_interfaceCount; i++) { result = libusb_kernel_driver_active(handle, i); if (result > 0) result = libusb_detach_kernel_driver(handle, i); if (result == LIBUSB_SUCCESS) result = libusb_claim_interface(handle, i); if (result != LIBUSB_SUCCESS) { for (int j = 0; j < i; j++) { while (result != LIBUSB_SUCCESS) { result = libusb_release_interface(handle, j); libusb_attach_kernel_driver(handle, j); } } libusb_close(handle); libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } } d->m_deviceHandle = handle; sprintf(d->m_portname, "%s", portInfo.portName().c_str()); flushData(); #endif // !USE_WINUSB JLDEBUG(gJournal, "USB Port opened"); return (d->m_lastResult = XRV_OK); }
int cyusb_get_devaddr(cyusb_handle *h) { cyusb_device *tdev = libusb_get_device(h); return libusb_get_device_address( tdev ); }
XN_C_API XnStatus xnUSBEnumerateDevices(XnUInt16 nVendorID, XnUInt16 nProductID, const XnUSBConnectionString** pastrDevicePaths, XnUInt32* pnCount) { // get device list libusb_device** ppDevices; ssize_t nDeviceCount = libusb_get_device_list(g_InitData.pContext, &ppDevices); // first enumeration - count XnUInt32 nCount = 0; for (ssize_t i = 0; i < nDeviceCount; ++i) { libusb_device* pDevice = ppDevices[i]; // get device descriptor libusb_device_descriptor desc; int rc = libusb_get_device_descriptor(pDevice, &desc); if (rc != 0) { libusb_free_device_list(ppDevices, 1); return (XN_STATUS_USB_ENUMERATE_FAILED); } // check if this is the requested device if (desc.idVendor == nVendorID && desc.idProduct == nProductID) { ++nCount; } } // allocate array XnUSBConnectionString* aResult = (XnUSBConnectionString*)xnOSCalloc(nCount, sizeof(XnUSBConnectionString)); if (aResult == NULL) { libusb_free_device_list(ppDevices, 1); return XN_STATUS_ALLOC_FAILED; } // second enumeration - fill XnUInt32 nCurrent = 0; for (ssize_t i = 0; i < nDeviceCount; ++i) { libusb_device* pDevice = ppDevices[i]; // get device descriptor libusb_device_descriptor desc; int rc = libusb_get_device_descriptor(pDevice, &desc); if (rc != 0) { libusb_free_device_list(ppDevices, 1); return (XN_STATUS_USB_ENUMERATE_FAILED); } // check if this is the requested device if (desc.idVendor == nVendorID && desc.idProduct == nProductID) { sprintf(aResult[nCurrent], "%04hx/%04hx@%hhu/%hhu", nVendorID, nProductID, libusb_get_bus_number(pDevice), libusb_get_device_address(pDevice)); nCurrent++; } } *pastrDevicePaths = aResult; *pnCount = nCount; // free the list (also dereference each device) libusb_free_device_list(ppDevices, 1); return XN_STATUS_OK; }
static inline bool addr_matches(uint8_t addr, struct libusb_device *d) { return (addr == DEVINFO_BUS_ANY) || (addr == libusb_get_device_address(d)); }
void UsbConnection::print_info() { int error_config; libusb_config_descriptor *config_desc; libusb_device_descriptor desc; if (!device) { ConnectionStatus status = usb_connect (); if (status == ready){ return; } } libusb_get_device_descriptor(device, &desc); unsigned char data[255] = {}; int response = libusb_get_string_descriptor_ascii (handler, desc.iProduct, data, sizeof(data)); qDebug("Product Description: %s|\n", data); response = libusb_get_string_descriptor_ascii (handler, desc.iManufacturer, data, sizeof(data)); qDebug("Manufacturer Description: %s|\n", data); libusb_get_string_descriptor_ascii (handler, desc.iSerialNumber, data, sizeof(data)); qDebug("SerialNumber Description: %s|\n", data); qDebug("\nbegin descriptor\n"); qDebug("\tbus_num: %d\n", libusb_get_bus_number(device)); qDebug("\taddress: %d\n", libusb_get_device_address(device)); qDebug("\tspeed: %d\n", libusb_get_device_speed(device)); qDebug("\tClass: %d\n", desc.bDeviceClass); qDebug("\tSubClass: %d\n", desc.bDeviceSubClass); qDebug("\tDeviceProtocol: %d\n", desc.bDeviceProtocol); qDebug("\tidVendor: %d\n", desc.idVendor); qDebug("\tidProduct: %d\n", desc.idProduct); qDebug("\tiManufacturer: %d\n", desc.iManufacturer); qDebug("\tiProduct: %d\n", desc.iProduct); qDebug("\tiSerialNumber: %d\n", desc.iSerialNumber); qDebug("\tbMaxPacketSize0: %d\n", desc.bMaxPacketSize0); qDebug("\tbNumConfigurations: %d\n", desc.bNumConfigurations); qDebug("\tconfigDescriptor:\n"); error_config = libusb_get_active_config_descriptor(device, &config_desc); if (error_config) { if (error_config == LIBUSB_ERROR_NOT_FOUND) { qDebug("Error config not founds\n"); } else { qDebug("Error in config %s\n", libusb_error_name (error_config)); } } else { qDebug("\tiConfiguration: %d\n", config_desc->iConfiguration); qDebug("\tbNumInterface: %d\n", config_desc->bNumInterfaces); qDebug("\tbmAttributes: %d\n", config_desc->bmAttributes); for (int i_interface = 0; i_interface < config_desc->bNumInterfaces; i_interface++) { for (int i_altinterface = 0; i_altinterface < config_desc->interface[i_interface].num_altsetting; i_altinterface++) { libusb_interface_descriptor alt_settings = config_desc->interface[i_interface].altsetting[i_altinterface]; qDebug("\tbInterfaceNumber[%d][%d]: %d\n", i_interface, i_altinterface, alt_settings.bInterfaceNumber); qDebug("\tbInterfaceClass[%d][%d]: %d\n", i_interface, i_altinterface, alt_settings.bInterfaceClass); qDebug("\bInterfaceSubClass[%d][%d]: %d\n", i_interface, i_altinterface, alt_settings.bInterfaceSubClass); qDebug("\tbInterfaceProtocol[%d][%d]: %d\n", i_interface, i_altinterface, alt_settings.bInterfaceProtocol); qDebug("\textra[%d][%d]: %s\n", i_interface, i_altinterface, alt_settings.extra); for (int i_ep = 0; i_ep < alt_settings.bNumEndpoints; i_ep++) { libusb_endpoint_descriptor ep_desc = alt_settings.endpoint[i_ep]; qDebug("\t\tbEndpointAddress[%d][%d][%d]: %d (in=%d / out=%d)\n", i_interface, i_altinterface, i_ep, ep_desc.bEndpointAddress, LIBUSB_ENDPOINT_IN, LIBUSB_ENDPOINT_OUT); qDebug("\t\tbDescriptorType[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep, ep_desc.bDescriptorType); qDebug("\t\tbmAttributes[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep, ep_desc.bmAttributes); qDebug("\t\textra[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep, ep_desc.extra_length); qDebug("\t\tbSynchAddress[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep, ep_desc.bSynchAddress); } } } libusb_free_config_descriptor(config_desc); } }
static int usb_enumerate(void) { int result = -1; libusb_device **devices; libusb_device *device; int rc; int i = 0; struct libusb_device_descriptor descriptor; uint8_t bus_number; uint8_t device_address; bool known; int k; USBStack *usb_stack; // get all devices rc = libusb_get_device_list(_context, &devices); if (rc < 0) { log_error("Could not get USB device list: %s (%d)", usb_get_error_name(rc), rc); return -1; } // check for stacks for (device = devices[0]; device != NULL; device = devices[++i]) { bus_number = libusb_get_bus_number(device); device_address = libusb_get_device_address(device); rc = libusb_get_device_descriptor(device, &descriptor); if (rc < 0) { log_warn("Could not get device descriptor for USB device (bus: %u, device: %u), ignoring USB device: %s (%d)", bus_number, device_address, usb_get_error_name(rc), rc); continue; } if (descriptor.idVendor == USB_BRICK_VENDOR_ID && descriptor.idProduct == USB_BRICK_PRODUCT_ID) { if (descriptor.bcdDevice < USB_BRICK_DEVICE_RELEASE) { log_warn("USB device (bus: %u, device: %u) has unsupported protocol 1.0 firmware, please update firmware, ignoring USB device", bus_number, device_address); continue; } } else if (descriptor.idVendor == USB_RED_BRICK_VENDOR_ID && descriptor.idProduct == USB_RED_BRICK_PRODUCT_ID) { if (descriptor.bcdDevice < USB_RED_BRICK_DEVICE_RELEASE) { log_warn("USB device (bus: %u, device: %u) has unexpected release version, ignoring USB device", bus_number, device_address); continue; } } else { continue; } // check all known stacks known = false; for (k = 0; k < _usb_stacks.count; ++k) { usb_stack = array_get(&_usb_stacks, k); if (usb_stack->bus_number == bus_number && usb_stack->device_address == device_address) { // mark known USBStack as connected usb_stack->connected = true; known = true; break; } } if (known) { continue; } // create new USBStack object log_debug("Found new USB device (bus: %u, device: %u)", bus_number, device_address); usb_stack = array_append(&_usb_stacks); if (usb_stack == NULL) { log_error("Could not append to USB stacks array: %s (%d)", get_errno_name(errno), errno); goto cleanup; } if (usb_stack_create(usb_stack, bus_number, device_address) < 0) { array_remove(&_usb_stacks, _usb_stacks.count - 1, NULL); log_warn("Ignoring USB device (bus: %u, device: %u) due to an error", bus_number, device_address); continue; } // mark new stack as connected usb_stack->connected = true; log_info("Added USB device (bus: %u, device: %u) at index %d: %s", usb_stack->bus_number, usb_stack->device_address, _usb_stacks.count - 1, usb_stack->base.name); } result = 0; cleanup: libusb_free_device_list(devices, 1); return result; }
static QString getDevicePath(usb_device* dev) { QString str("//bus%1/dev%2"); return str.arg(libusb_get_bus_number(dev)).arg(libusb_get_device_address(dev)); }
static int hw_init(const char *deviceinfo) { struct sr_device_instance *sdi; struct libusb_device_descriptor des; struct fx2_profile *fx2_prof; struct fx2_device *fx2; libusb_device **devlist; int err, devcnt, i, j; /* Avoid compiler warnings. */ (void)deviceinfo; if (libusb_init(&usb_context) != 0) { sr_warn("Failed to initialize USB."); return 0; } /* Find all Saleae Logic devices and upload firmware to all of them. */ devcnt = 0; libusb_get_device_list(usb_context, &devlist); for (i = 0; devlist[i]; i++) { fx2_prof = NULL; err = libusb_get_device_descriptor(devlist[i], &des); if (err != 0) { sr_warn("failed to get device descriptor: %d", err); continue; } for (j = 0; supported_fx2[j].orig_vid; j++) { if (des.idVendor == supported_fx2[j].orig_vid && des.idProduct == supported_fx2[j].orig_pid) { fx2_prof = &supported_fx2[j]; break; } } if (!fx2_prof) /* not a supported VID/PID */ continue; sdi = sr_device_instance_new(devcnt, SR_ST_INITIALIZING, fx2_prof->vendor, fx2_prof->model, fx2_prof->model_version); if (!sdi) return 0; fx2 = fx2_device_new(); fx2->profile = fx2_prof; sdi->priv = fx2; device_instances = g_slist_append(device_instances, sdi); if (check_conf_profile(devlist[i])) { /* Already has the firmware, so fix the new address. */ sdi->status = SR_ST_INACTIVE; sdi->usb = sr_usb_device_instance_new (libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, FIRMWARE) == SR_OK) /* Remember when the firmware on this device was updated */ g_get_current_time(&fx2->fw_updated); else sr_warn("firmware upload failed for device %d", devcnt); sdi->usb = sr_usb_device_instance_new (libusb_get_bus_number(devlist[i]), 0xff, NULL); } devcnt++; } libusb_free_device_list(devlist, 1); return devcnt; }
int usb_get_interface_endpoints(libusb_device_handle *device_handle, int interface_number, uint8_t *endpoint_in, uint8_t *endpoint_out) { int rc; libusb_device *device = libusb_get_device(device_handle); uint8_t bus_number = libusb_get_bus_number(device); uint8_t device_address = libusb_get_device_address(device); int i; struct libusb_config_descriptor *config_descriptor; const struct libusb_interface_descriptor *interface_descriptor; int k; const struct libusb_endpoint_descriptor *endpoint_descriptor; rc = libusb_get_config_descriptor(device, 0, &config_descriptor); if (rc < 0) { log_error("Could not get config descriptor for USB device (bus: %u, device: %u): %s (%d)", bus_number, device_address, usb_get_error_name(rc), rc); return -1; } if (config_descriptor->bNumInterfaces == 0) { log_error("Config descriptor for USB device (bus: %u, device: %u) contains no interfaces", bus_number, device_address); return -1; } for (i = 0; i < config_descriptor->bNumInterfaces; ++i) { if (config_descriptor->interface[i].num_altsetting < 1) { log_debug("Interface at index %d of USB device (bus: %u, device: %u) has no alt setting, ignoring it", i, bus_number, device_address); continue; } interface_descriptor = &config_descriptor->interface[i].altsetting[0]; if (interface_descriptor->bInterfaceNumber != interface_number) { continue; } if (interface_descriptor->bNumEndpoints != 2) { log_debug("Interface %d of USB device (bus: %u, device: %u) has %d endpoints, expecting 2, ignoring it", interface_descriptor->bInterfaceNumber, bus_number, device_address, interface_descriptor->bNumEndpoints); continue; } for (k = 0; k < interface_descriptor->bNumEndpoints; ++k) { endpoint_descriptor = &interface_descriptor->endpoint[k]; if (endpoint_descriptor->bEndpointAddress & LIBUSB_ENDPOINT_IN) { *endpoint_in = endpoint_descriptor->bEndpointAddress; } else { *endpoint_out = endpoint_descriptor->bEndpointAddress; } } libusb_free_config_descriptor(config_descriptor); return 0; } libusb_free_config_descriptor(config_descriptor); return -1; }
static int sl_open_device(int device_index) { libusb_device **devlist; struct libusb_device_descriptor des; struct sr_device_instance *sdi; struct fx2_device *fx2; int err, skip, i; if (!(sdi = sr_get_device_instance(device_instances, device_index))) return SR_ERR; fx2 = sdi->priv; if (sdi->status == SR_ST_ACTIVE) /* already in use */ return SR_ERR; skip = 0; libusb_get_device_list(usb_context, &devlist); for (i = 0; devlist[i]; i++) { if ((err = libusb_get_device_descriptor(devlist[i], &des))) { sr_warn("failed to get device descriptor: %d", err); continue; } if (des.idVendor != fx2->profile->fw_vid || des.idProduct != fx2->profile->fw_pid) continue; if (sdi->status == SR_ST_INITIALIZING) { if (skip != device_index) { /* Skip devices of this type that aren't the one we want. */ skip += 1; continue; } } else if (sdi->status == SR_ST_INACTIVE) { /* * This device is fully enumerated, so we need to find this * device by vendor, product, bus and address. */ if (libusb_get_bus_number(devlist[i]) != sdi->usb->bus || libusb_get_device_address(devlist[i]) != sdi->usb->address) /* this is not the one */ continue; } if (!(err = libusb_open(devlist[i], &sdi->usb->devhdl))) { if (sdi->usb->address == 0xff) /* * first time we touch this device after firmware upload, * so we don't know the address yet. */ sdi->usb->address = libusb_get_device_address(devlist[i]); sdi->status = SR_ST_ACTIVE; sr_info("saleae: opened device %d on %d.%d interface %d", sdi->index, sdi->usb->bus, sdi->usb->address, USB_INTERFACE); } else { sr_warn("failed to open device: %d", err); } /* if we made it here, we handled the device one way or another */ break; } libusb_free_device_list(devlist, 1); if (sdi->status != SR_ST_ACTIVE) return SR_ERR; return SR_OK; }
int main(int argc, char*argv[]) { fx_known_device known_device[] = FX_KNOWN_DEVICES; const char *path[] = { NULL, NULL }; const char *device_id = NULL; const char *device_path = getenv("DEVICE"); const char *type = NULL; const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES; const char *ext, *img_name[] = IMG_TYPE_NAMES; int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)]; int i, j, opt, status; unsigned vid = 0, pid = 0; unsigned busnum = 0, devaddr = 0, _busnum, _devaddr; libusb_device *dev, **devs; libusb_device_handle *device = NULL; struct libusb_device_descriptor desc; while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:t:")) != EOF) switch (opt) { case 'd': device_id = optarg; if (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 ) { fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr); return -1; } break; case 'p': device_path = optarg; if (sscanf(device_path, "%u,%u", &busnum, &devaddr) != 2 ) { fputs ("please specify bus number & device number as \"bus,dev\" in decimal format\n", stderr); return -1; } break; case 'i': case 'I': path[FIRMWARE] = optarg; break; case 'V': puts(FXLOAD_VERSION); return 0; case 't': type = optarg; break; case 'v': verbose++; break; case 'q': verbose--; break; case '?': case 'h': default: return print_usage(-1); } if (path[FIRMWARE] == NULL) { logerror("no firmware specified!\n"); return print_usage(-1); } if ((device_id != NULL) && (device_path != NULL)) { logerror("only one of -d or -p can be specified\n"); return print_usage(-1); } /* determine the target type */ if (type != NULL) { for (i=0; i<FX_TYPE_MAX; i++) { if (strcmp(type, fx_name[i]) == 0) { fx_type = i; break; } } if (i >= FX_TYPE_MAX) { logerror("illegal microcontroller type: %s\n", type); return print_usage(-1); } } /* open the device using libusb */ status = libusb_init(NULL); if (status < 0) { logerror("libusb_init() failed: %s\n", libusb_error_name(status)); return -1; } libusb_set_debug(NULL, verbose); /* try to pick up missing parameters from known devices */ if ((type == NULL) || (device_id == NULL) || (device_path != NULL)) { if (libusb_get_device_list(NULL, &devs) < 0) { logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status)); goto err; } for (i=0; (dev=devs[i]) != NULL; i++) { _busnum = libusb_get_bus_number(dev); _devaddr = libusb_get_device_address(dev); if ((type != NULL) && (device_path != NULL)) { printf("Check Point 1\n"); // if both a type and bus,addr were specified, we just need to find our match if ((libusb_get_bus_number(dev) == busnum) && (libusb_get_device_address(dev) == devaddr)) { printf("Check Point 2\n"); break; } } else { status = libusb_get_device_descriptor(dev, &desc); if (status >= 0) { if (verbose >= 3) { logerror("examining %04x:%04x (%d,%d)\n", desc.idVendor, desc.idProduct, _busnum, _devaddr); } for (j=0; j<ARRAYSIZE(known_device); j++) { if ((desc.idVendor == known_device[j].vid) && (desc.idProduct == known_device[j].pid)) { printf("Check Point 3\n"); if (// nothing was specified ((type == NULL) && (device_id == NULL) && (device_path == NULL)) || // vid:pid was specified and we have a match ((type == NULL) && (device_id != NULL) && (vid == desc.idVendor) && (pid == desc.idProduct)) || // bus,addr was specified and we have a match ((type == NULL) && (device_path != NULL) && (busnum == _busnum) && (devaddr == _devaddr)) || // type was specified and we have a match ((type != NULL) && (device_id == NULL) && (device_path == NULL) && (fx_type == known_device[j].type)) ) { printf("Check Point 4\n"); fx_type = known_device[j].type; vid = desc.idVendor; pid = desc.idProduct; busnum = _busnum; devaddr = _devaddr; break; } } printf("Check Point 5\n"); } if (j < ARRAYSIZE(known_device)) { printf("Check Point 6\n"); if (verbose) logerror("found device '%s' [%04x:%04x] (%d,%d)\n", known_device[j].designation, vid, pid, busnum, devaddr); break; } } } } if (dev == NULL) { printf("Check Point 7\n"); libusb_free_device_list(devs, 1); logerror("could not find a known device - please specify type and/or vid:pid and/or bus,dev\n"); return print_usage(-1); } status = libusb_open(dev, &device); if (status < 0) { logerror("libusb_open() failed: %s\n", libusb_error_name(status)); goto err; } libusb_free_device_list(devs, 1); } else if (device_id != NULL) { printf("Check Point 9\n"); printf("Check Point 9 vid %d\n", pid); printf("Check Point 9 pid %d\n", vid); device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid); if (device == NULL) { logerror("libusb_open() failed\n"); goto err; } } /* We need to claim the first interface */ printf("Check Point 10\n"); libusb_set_auto_detach_kernel_driver(device, 1); status = libusb_claim_interface(device, 0); if (status != LIBUSB_SUCCESS) { logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status)); goto err; } if (verbose) logerror("microcontroller type: %s\n", fx_name[fx_type]); for (i=0; i<ARRAYSIZE(path); i++) { if (path[i] != NULL) { ext = path[i] + strlen(path[i]) - 4; if ((_stricmp(ext, ".hex") == 0) || (strcmp(ext, ".ihx") == 0)) img_type[i] = IMG_TYPE_HEX; else if (_stricmp(ext, ".iic") == 0) img_type[i] = IMG_TYPE_IIC; else if (_stricmp(ext, ".bix") == 0) img_type[i] = IMG_TYPE_BIX; else if (_stricmp(ext, ".img") == 0) img_type[i] = IMG_TYPE_IMG; else { logerror("%s is not a recognized image type\n", path[i]); goto err; } } if (verbose && path[i] != NULL) logerror("%s: type %s\n", path[i], img_name[img_type[i]]); } printf("Check Point 11\n"); printf("Check Point 11 img_type[FIRMWARE] %d\n", img_type[FIRMWARE]); printf("Check Point 11 fx_type %d\n", fx_type); /* single stage, put into internal memory */ if (verbose > 1) logerror("single stage: load on-chip memory\n"); status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0); libusb_release_interface(device, 0); libusb_close(device); libusb_exit(NULL); return status; err: libusb_exit(NULL); return -1; }
static bool CheckDeviceAccess(libusb_device* device) { int ret; libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor(device, &desc); if (dRet) { // could not acquire the descriptor, no point in trying to use it. ERROR_LOG(SERIALINTERFACE, "libusb_get_device_descriptor failed with error: %d", dRet); return false; } if (desc.idVendor == 0x057e && desc.idProduct == 0x0337) { NOTICE_LOG(SERIALINTERFACE, "Found GC Adapter with Vendor: %X Product: %X Devnum: %d", desc.idVendor, desc.idProduct, 1); u8 bus = libusb_get_bus_number(device); u8 port = libusb_get_device_address(device); ret = libusb_open(device, &s_handle); if (ret) { if (ret == LIBUSB_ERROR_ACCESS) { if (dRet) { ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", bus, port ); } else { ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", bus, port, desc.idVendor, desc.idProduct ); } } else { ERROR_LOG(SERIALINTERFACE, "libusb_open failed to open device with error = %d", ret); if (ret == LIBUSB_ERROR_NOT_SUPPORTED) s_libusb_driver_not_supported = true; } return false; } else if ((ret = libusb_kernel_driver_active(s_handle, 0)) == 1) { if ((ret = libusb_detach_kernel_driver(s_handle, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED) { ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret); } } // this split is needed so that we don't avoid claiming the interface when // detaching the kernel driver is successful if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED) { return false; } else if ((ret = libusb_claim_interface(s_handle, 0))) { ERROR_LOG(SERIALINTERFACE, "libusb_claim_interface failed with error: %d", ret); } else { return true; } } return false; }
void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { static u16 check = 1; int OffsetBuffer = BufferOut; int OffsetStart = 0; //int OffsetDevice = 0; int d,c,ic,i,e; /* config, interface container, interface, endpoint */ libusb_device **list; //libusb_device *found = NULL; ssize_t cnt = libusb_get_device_list(NULL, &list); DEBUG_LOG(WII_IPC_HID, "Found %ld viable USB devices.", cnt); for (d = 0; d < cnt; d++) { libusb_device *device = list[d]; struct libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor (device, &desc); if (dRet) { // could not aquire the descriptor, no point in trying to use it. DEBUG_LOG(WII_IPC_HID, "libusb_get_device_descriptor failed with error: %d", dRet); continue; } OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end OffsetBuffer += 4; // skip devNum for now WiiHIDDeviceDescriptor wii_device; ConvertDeviceToWii(&wii_device, &desc); Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); OffsetBuffer += Align(wii_device.bLength, 4); bool deviceValid = true; for (c = 0; deviceValid && c < desc.bNumConfigurations; c++) { struct libusb_config_descriptor *config = NULL; int cRet = libusb_get_config_descriptor(device, c, &config); // do not try to use usb devices with more than one interface, games can crash if(cRet == 0 && config->bNumInterfaces <= MAX_HID_INTERFACES) { WiiHIDConfigDescriptor wii_config; ConvertConfigToWii(&wii_config, config); Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); OffsetBuffer += Align(wii_config.bLength, 4); for (ic = 0; ic < config->bNumInterfaces; ic++) { const struct libusb_interface *interfaceContainer = &config->interface[ic]; for (i = 0; i < interfaceContainer->num_altsetting; i++) { const struct libusb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; WiiHIDInterfaceDescriptor wii_interface; ConvertInterfaceToWii(&wii_interface, interface); Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4)); OffsetBuffer += Align(wii_interface.bLength, 4); for (e = 0; e < interface->bNumEndpoints; e++) { const struct libusb_endpoint_descriptor *endpoint = &interface->endpoint[e]; WiiHIDEndpointDescriptor wii_endpoint; ConvertEndpointToWii(&wii_endpoint, endpoint); Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4)); OffsetBuffer += Align(wii_endpoint.bLength, 4); } //endpoints } // interfaces } // interface containters libusb_free_config_descriptor(config); config = NULL; } else { if(cRet) DEBUG_LOG(WII_IPC_HID, "libusb_get_config_descriptor failed with: %d", cRet); deviceValid = false; OffsetBuffer = OffsetStart; } } // configs if (deviceValid) { Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length int devNum = GetAvaiableDevNum(desc.idVendor, desc.idProduct, libusb_get_bus_number (device), libusb_get_device_address (device), check); if (devNum < 0 ) { // too many devices to handle. ERROR_LOG(WII_IPC_HID, "Exhausted device list, you have way too many usb devices plugged in." "Or it might be our fault. Let us know at https://code.google.com/p/dolphin-emu/issues/entry?template=Defect%%20report"); OffsetBuffer = OffsetStart; continue; } DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %X Product: %X Devnum: %d", desc.idVendor, desc.idProduct, devNum); Memory::Write_U32(devNum , OffsetStart+4); //write device num } } // Find devices that no longer exists and free them for (i=0; i<MAX_DEVICE_DEVNUM; i++) { u16 check_cur = (u16)(hidDeviceAliases[i] >> 48); if(hidDeviceAliases[i] != 0 && check_cur != check) { DEBUG_LOG(WII_IPC_HID, "Removing: device %d %hX %hX", i, check, check_cur); std::lock_guard<std::mutex> lk(s_open_devices); if (open_devices.find(i) != open_devices.end()) { libusb_device_handle *handle = open_devices[i]; libusb_close(handle); open_devices.erase(i); } hidDeviceAliases[i] = 0; } } check++; libusb_free_device_list(list, 1); Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices }
int HWStubDevice::GetDevAddress() { return libusb_get_device_address(m_dev); }
libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { u32 i; libusb_device **list; libusb_device_handle *handle = NULL; ssize_t cnt; if(devNum >= MAX_DEVICE_DEVNUM) return NULL; std::lock_guard<std::mutex> lk(s_open_devices); if (open_devices.find(devNum) != open_devices.end()) { handle = open_devices[devNum]; if(libusb_kernel_driver_active(handle, 0) != LIBUSB_ERROR_NO_DEVICE) { return handle; } else { libusb_close(handle); open_devices.erase(devNum); } } cnt = libusb_get_device_list(NULL, &list); if (cnt < 0) return NULL; for (i = 0; i < cnt; i++) { libusb_device *device = list[i]; struct libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor (device, &desc); u8 bus = libusb_get_bus_number (device); u8 port = libusb_get_device_address (device); u64 unique_id = ((u64)desc.idVendor << 32) | ((u64)desc.idProduct << 16) | ((u64)bus << 8) | (u64)port; if ((hidDeviceAliases[devNum] & HID_ID_MASK) == unique_id) { int ret = libusb_open(device, &handle); if (ret) { if (ret == LIBUSB_ERROR_ACCESS) { if( dRet ) { ERROR_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", bus, port ); } else{ ERROR_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", bus, port, desc.idVendor, desc.idProduct ); } } #ifdef _WIN32 else if (ret == LIBUSB_ERROR_NOT_SUPPORTED) { WARN_LOG(WII_IPC_HID, "Please install the libusb drivers for the device %04X:%04X", desc.idVendor, desc.idProduct); } #endif else { ERROR_LOG(WII_IPC_HID, "libusb_open failed to open device with error = %d", ret); } continue; } if (!ClaimDevice(handle)) { ERROR_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", devNum); libusb_close(handle); continue; } open_devices[devNum] = handle; break; } else { handle = NULL; } } libusb_free_device_list(list, 1); return handle; }
/////////////////////////////////////////////////////////////////////////////// ///@author Nicolae Bodislav ///@brief Creates a link with an USB device. ///@param p_oDevDesc - descriptor for the USB device. ///@retval 0 - Link ok created, < 0 - Error. /////////////////////////////////////////////////////////////////////////////// int CUSBLink::OpenLink(CUSBLink::USBDeviceDescriptor p_oDevDesc) { if(m_pDevh == NULL) { int r; int cnt; libusb_device **devs; struct libusb_device *found = NULL; struct libusb_device *dev; cnt = libusb_get_device_list(m_pContex, &devs); if (cnt < 0) { NLOG_ERR("[CUSBLink][OpenLink] Failed to get USB Devices!"); return -1; } int i = 0; for(i=0; i<cnt; i++) { dev = devs[i]; struct libusb_device_descriptor desc; r = libusb_get_device_descriptor(dev, &desc); if (r < 0) return -1; if (desc.idVendor == p_oDevDesc.m_nVendorID && desc.idProduct == p_oDevDesc.m_nProductID && (libusb_get_bus_number(dev) == p_oDevDesc.m_nBusNumber) && (libusb_get_device_address(dev) == p_oDevDesc.m_nDeviceAddress)) { found = dev; break; } } if (found) { r = libusb_open(found, &m_pDevh); m_pDev = found; if (r < 0) { NLOG_ERR("[CUSBLink][OpenLink] Failed to open link"); m_pDevh = NULL; } } libusb_free_device_list(devs, 1); if(m_pDevh != NULL) { m_enumDealoc = CUSBLink::OPEN; return 0; } else return -EIO; } else { NLOG_ERR("[CUSBLink][OpenLink] Device already open."); return -1; } }
static int lusb_open_bootloader(void **driver, uint8_t bus, uint8_t addr) { int status; struct libusb_device **dev_list = NULL; ssize_t dev_list_size, i; struct bladerf_lusb *lusb; *driver = NULL; lusb = calloc(1, sizeof(lusb[0])); if (lusb == NULL) { return BLADERF_ERR_MEM; } status = libusb_init(&lusb->context); if (status != 0) { log_debug("Failed to initialize libusb context: %s\n", libusb_error_name(status)); goto error; } dev_list_size = libusb_get_device_list(lusb->context, &dev_list); if (dev_list_size < 0) { log_debug("Failed to get device list: %s\n", libusb_error_name(status)); status = (int) dev_list_size; goto error; } for (i = 0; i < dev_list_size; i++) { if (device_is_fx3_bootloader(dev_list[i]) && bus_matches(bus, dev_list[i]) && addr_matches(addr, dev_list[i])) { status = libusb_open(dev_list[i], &lusb->handle); if (status != 0) { log_debug("Failed to open device: %s\n", libusb_error_name(status)); goto error; } else { status = libusb_claim_interface(lusb->handle, 0); if (status < 0) { log_debug("Failed to claim interface: %s\n", libusb_error_name(status)); goto error; } else { log_verbose("Opened bootloader at %u:%u\n", libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i])); *driver = lusb; } break; } } } error: if (dev_list != NULL) { libusb_free_device_list(dev_list, 1); } if (status != 0) { status = error_conv(status); lusb_close_bootloader(lusb); } else if (*driver == NULL) { status = BLADERF_ERR_NODEV; lusb_close_bootloader(lusb); } return status; }
static int probe(std::unique_ptr<usb_handle> &h, ifc_match_func callback) { usb_ifc_info info; libusb_device_descriptor ddesc; libusb_config_descriptor *pcfg; int i, j; if (libusb_open(h->dev, &h->handle) < 0) return (-1); if (libusb_get_device_descriptor(h->dev, &ddesc) < 0) { libusb_close(h->handle); return (-1); } memset(&info, 0, sizeof(info)); info.dev_vendor = ddesc.idVendor; info.dev_product = ddesc.idProduct; info.dev_class = ddesc.bDeviceClass; info.dev_subclass = ddesc.bDeviceSubClass; info.dev_protocol = ddesc.bDeviceProtocol; info.writable = 1; snprintf(info.device_path, sizeof(info.device_path), "ugen%d.%d", libusb_get_bus_number(h->dev), libusb_get_device_address(h->dev)); if (ddesc.iSerialNumber != 0) { libusb_get_string_descriptor_ascii(h->handle, ddesc.iSerialNumber, (unsigned char *)info.serial_number, sizeof(info.serial_number)); } if (libusb_get_active_config_descriptor(h->dev, &pcfg)) { libusb_close(h->handle); return (-1); } for (i = 0; i < pcfg->bNumInterfaces; i++) { h->ep_in = 0; h->ep_out = 0; h->iface = i; for (j = 0; j < pcfg->interface[i].altsetting[0].bNumEndpoints; j++) { unsigned char temp = pcfg->interface[i].altsetting[0]. endpoint[j].bEndpointAddress; unsigned char type = pcfg->interface[i].altsetting[0]. endpoint[j].bmAttributes & 0x03; /* check for BULK endpoint */ if ((type & 0x03) == 0x02) { /* check for IN endpoint */ if (temp & 0x80) h->ep_in = temp; else h->ep_out = temp; } } info.ifc_class = pcfg->interface[i].altsetting[0].bInterfaceClass; info.ifc_subclass = pcfg->interface[i].altsetting[0].bInterfaceSubClass; info.ifc_protocol = pcfg->interface[i].altsetting[0].bInterfaceProtocol; info.has_bulk_in = (h->ep_in != 0); info.has_bulk_out = (h->ep_out != 0); if (libusb_claim_interface(h->handle, h->iface) < 0) continue; if (callback(&info) == 0) { libusb_free_config_descriptor(pcfg); return (0); } libusb_release_interface(h->handle, h->iface); } libusb_free_config_descriptor(pcfg); libusb_close(h->handle); return (-1); }
/* * open USB device * * ARGS * commdev pointer to commdev_t structure * idx device index to open */ void commdev_open(struct commdev_t *commdev, int idx) { int i, cnt, ndev; int errcode; libusb_device **devs; libusb_device *dev; int r; struct libusb_device_descriptor desc; cnt = libusb_get_device_list(context, &devs); if (cnt < 0) { fprintf(stderr, "can not get divice list\r\n"); errcode = ERRCODE_LIBUSB_GETDEVLIST; goto error; } dev = NULL; ndev = 0; for (i = 0; i < cnt; i++) { r = libusb_get_device_descriptor(devs[i], &desc); if (r < 0) { fprintf(stderr, "failed to get device descriptor"); errcode = ERRCODE_LIBUSB_GETDEVDESC; goto error; } if (desc.idVendor == DEVICE_VID && desc.idProduct == DEVICE_PID) { printf("%04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(devs[i]), libusb_get_device_address(devs[i])); dev = devs[i]; if (ndev == idx) break; ndev++; } } if (dev == NULL) { fprintf(stderr, "can not find device\r\n"); errcode = ERRCODE_LIBUSB_FINDDEV; goto error; } if (libusb_open(dev, &commdev->handle)) { fprintf(stderr, "can not open device handle\r\n"); errcode = ERRCODE_LIBUSB_OPEN; goto error; } if (libusb_claim_interface(commdev->handle, 0)) { fprintf(stderr, "claim error\r\n"); errcode = ERRCODE_LIBUSB_CLAIMINTERFACE; goto error; } libusb_free_device_list(devs, 1); /* XXX receive possible unhandled data */ { uint8 buf[64]; int n; libusb_bulk_transfer(commdev->handle, LIBUSB_ENDPOINT_IN | 0x01, buf, 64, &n, 100); } return; error: exit(errcode); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; const struct zp_model *prof; struct libusb_device_descriptor des; struct libusb_device_handle *hdl; libusb_device **devlist; GSList *devices; int ret, i, j; char serial_num[64], connection_id[64]; (void)options; drvc = di->context; devices = NULL; /* Find all ZEROPLUS analyzers and add them to device list. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { libusb_get_device_descriptor(devlist[i], &des); if ((ret = libusb_open(devlist[i], &hdl)) < 0) continue; if (des.iSerialNumber == 0) { serial_num[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iSerialNumber, (unsigned char *) serial_num, sizeof(serial_num))) < 0) { sr_warn("Failed to get serial number string descriptor: %s.", libusb_error_name(ret)); continue; } libusb_close(hdl); usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); prof = NULL; for (j = 0; j < zeroplus_models[j].vid; j++) { if (des.idVendor == zeroplus_models[j].vid && des.idProduct == zeroplus_models[j].pid) { prof = &zeroplus_models[j]; } } /* Skip if the device was not found. */ if (!prof) continue; sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_NAME); sdi->model = g_strdup(prof->model_name); sdi->driver = di; sdi->serial_num = g_strdup(serial_num); sdi->connection_id = g_strdup(connection_id); /* Allocate memory for our private driver context. */ devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_sample_depth = 128 * 1024; devc->max_samplerate = 200; #else devc->max_sample_depth = prof->sample_depth * 1024; devc->max_samplerate = prof->max_sampling_freq; #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); /* Fill in channellist according to this device's profile. */ for (j = 0; j < devc->num_channels; j++) sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]); devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } libusb_free_device_list(devlist, 1); return devices; }
/***************************************************************************** * * OpenUSBByName * ****************************************************************************/ status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device) { unsigned int alias; struct libusb_device_handle *dev_handle; char infofile[FILENAME_MAX]; #ifndef __APPLE__ unsigned int device_vendor, device_product; unsigned int device_bus = 0; unsigned int device_addr = 0; #else /* 100 ms delay */ struct timespec sleep_time = { 0, 100 * 1000 * 1000 }; int count_libusb = 10; #endif int interface_number = -1; int i; static int previous_reader_index = -1; libusb_device **devs, *dev; ssize_t cnt; list_t plist, *values, *ifdVendorID, *ifdProductID, *ifdFriendlyName; int rv; int claim_failed = FALSE; int return_value = STATUS_SUCCESS; DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device); #ifndef __APPLE__ /* device name specified */ if (device) { char *dirname; /* format: usb:%04x/%04x, vendor, product */ if (strncmp("usb:", device, 4) != 0) { DEBUG_CRITICAL2("device name does not start with \"usb:\": %s", device); return STATUS_UNSUCCESSFUL; } if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2) { DEBUG_CRITICAL2("device name can't be parsed: %s", device); return STATUS_UNSUCCESSFUL; } /* format usb:%04x/%04x:libudev:%d:%s * with %d set to * 01 (or whatever the interface number is) * and %s set to * /dev/bus/usb/008/004 */ if ((dirname = strstr(device, "libudev:")) != NULL) { /* convert the interface number, bus and device ids */ if (sscanf(dirname + 8, "%d:/dev/bus/usb/%d/%d", &interface_number, &device_bus, &device_addr) == 3) { DEBUG_COMM2("interface_number: %d", interface_number); DEBUG_COMM3("usb bus/device: %d/%d", device_bus, device_addr); } } } #endif /* is the reader_index already used? */ if (usbDevice[reader_index].dev_handle != NULL) { DEBUG_CRITICAL2("USB driver with index %X already in use", reader_index); return STATUS_UNSUCCESSFUL; } /* Info.plist full patch filename */ (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist", PCSCLITE_HP_DROPDIR, BUNDLE); DEBUG_INFO2("Using: %s", infofile); rv = bundleParse(infofile, &plist); if (rv) return STATUS_UNSUCCESSFUL; #define GET_KEY(key, values) \ rv = LTPBundleFindValueWithKey(&plist, key, &values); \ if (rv) \ { \ DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \ return_value = STATUS_UNSUCCESSFUL; \ goto end1; \ } \ else \ DEBUG_INFO2(key ": %s", (char *)list_get_at(values, 0)); /* general driver info */ GET_KEY("ifdManufacturerString", values) GET_KEY("ifdProductString", values) GET_KEY("Copyright", values) if (NULL == ctx) { rv = libusb_init(&ctx); if (rv != 0) { DEBUG_CRITICAL2("libusb_init failed: %s", libusb_error_name(rv)); return_value = STATUS_UNSUCCESSFUL; goto end1; } } #define GET_KEYS(key, values) \ rv = LTPBundleFindValueWithKey(&plist, key, values); \ if (rv) \ { \ DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \ return_value = STATUS_UNSUCCESSFUL; \ goto end1; \ } GET_KEYS("ifdVendorID", &ifdVendorID) GET_KEYS("ifdProductID", &ifdProductID); GET_KEYS("ifdFriendlyName", &ifdFriendlyName) /* The 3 lists do not have the same size */ if ((list_size(ifdVendorID) != list_size(ifdProductID)) || (list_size(ifdVendorID) != list_size(ifdFriendlyName))) { DEBUG_CRITICAL2("Error parsing %s", infofile); return_value = STATUS_UNSUCCESSFUL; goto end1; } #ifdef __APPLE__ again_libusb: #endif cnt = libusb_get_device_list(ctx, &devs); if (cnt < 0) { DEBUG_CRITICAL("libusb_get_device_list() failed\n"); return_value = STATUS_UNSUCCESSFUL; goto end1; } /* for any supported reader */ for (alias=0; alias<list_size(ifdVendorID); alias++) { unsigned int vendorID, productID; char *friendlyName; vendorID = strtoul(list_get_at(ifdVendorID, alias), NULL, 0); productID = strtoul(list_get_at(ifdProductID, alias), NULL, 0); friendlyName = list_get_at(ifdFriendlyName, alias); #ifndef __APPLE__ /* the device was specified but is not the one we are trying to find */ if (device && (vendorID != device_vendor || productID != device_product)) continue; #else /* Leopard puts the friendlyname in the device argument */ if (device && strcmp(device, friendlyName)) continue; #endif /* for every device */ i = 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; struct libusb_config_descriptor *config_desc; uint8_t bus_number = libusb_get_bus_number(dev); uint8_t device_address = libusb_get_device_address(dev); #ifndef __APPLE__ if ((device_bus || device_addr) && ((bus_number != device_bus) || (device_address != device_addr))) { /* not USB the device we are looking for */ continue; } #endif DEBUG_COMM3("Try device: %d/%d", bus_number, device_address); int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { DEBUG_INFO3("failed to get device descriptor for %d/%d", bus_number, device_address); continue; } DEBUG_COMM3("vid/pid : %04X/%04X", desc.idVendor, desc.idProduct); if (desc.idVendor == vendorID && desc.idProduct == productID) { int already_used; const struct libusb_interface *usb_interface = NULL; int interface; int num = 0; const unsigned char *device_descriptor; int readerID = (vendorID << 16) + productID; #ifdef USE_COMPOSITE_AS_MULTISLOT static int static_interface = 1; /* simulate a composite device as when libudev is used */ if ((GEMALTOPROXDU == readerID) || (GEMALTOPROXSU == readerID) || (FEITIANR502DUAL == readerID)) { /* * We can't talk to the two CCID interfaces * at the same time (the reader enters a * dead lock). So we simulate a multi slot * reader. By default multi slot readers * can't use the slots at the same time. See * TAG_IFD_SLOT_THREAD_SAFE * * One side effect is that the two readers * are seen by pcscd as one reader so the * interface name is the same for the two. * * So we have: * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00 * 1: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 01 * instead of * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00 * 1: Gemalto Prox-DU [Prox-DU Contactless_09A00795] (09A00795) 01 00 */ /* the CCID interfaces are 1 and 2 */ interface_number = static_interface; } #endif /* is it already opened? */ already_used = FALSE; DEBUG_COMM3("Checking device: %d/%d", bus_number, device_address); for (r=0; r<CCID_DRIVER_MAX_READERS; r++) { if (usbDevice[r].dev_handle) { /* same bus, same address */ if (usbDevice[r].bus_number == bus_number && usbDevice[r].device_address == device_address) already_used = TRUE; } } /* this reader is already managed by us */ if (already_used) { if ((previous_reader_index != -1) && usbDevice[previous_reader_index].dev_handle && (usbDevice[previous_reader_index].bus_number == bus_number) && (usbDevice[previous_reader_index].device_address == device_address) && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex) { /* we reuse the same device * and the reader is multi-slot */ usbDevice[reader_index] = usbDevice[previous_reader_index]; /* The other slots of GemCore SIM Pro firmware * 1.0 do not have the same data rates. * Firmware 2.0 do not have this limitation */ if ((GEMCOREPOSPRO == readerID) || ((GEMCORESIMPRO == readerID) && (usbDevice[reader_index].ccid.IFD_bcdDevice < 0x0200))) { usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates; usbDevice[reader_index].ccid.dwMaxDataRate = 125000; } *usbDevice[reader_index].nb_opened_slots += 1; usbDevice[reader_index].ccid.bCurrentSlotIndex++; usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT; DEBUG_INFO2("Opening slot: %d", usbDevice[reader_index].ccid.bCurrentSlotIndex); /* This is a multislot reader * Init the multislot stuff for this next slot */ usbDevice[reader_index].multislot_extension = Multi_CreateNextSlot(previous_reader_index); goto end; } else { /* if an interface number is given by HAL we * continue with this device. */ if (-1 == interface_number) { DEBUG_INFO3("USB device %d/%d already in use." " Checking next one.", bus_number, device_address); continue; } } } DEBUG_COMM3("Trying to open USB bus/device: %d/%d", bus_number, device_address); r = libusb_open(dev, &dev_handle); if (r < 0) { DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %s", bus_number, device_address, libusb_error_name(r)); continue; } again: r = libusb_get_active_config_descriptor(dev, &config_desc); if (r < 0) { #ifdef __APPLE__ /* Some early Gemalto Ezio CB+ readers have * bDeviceClass, bDeviceSubClass and bDeviceProtocol set * to 0xFF (proprietary) instead of 0x00. * * So on Mac OS X the reader configuration is not done * by the OS/kernel and we do it ourself. */ if ((0xFF == desc.bDeviceClass) && (0xFF == desc.bDeviceSubClass) && (0xFF == desc.bDeviceProtocol)) { r = libusb_set_configuration(dev_handle, 1); if (r < 0) { (void)libusb_close(dev_handle); DEBUG_CRITICAL4("Can't set configuration on %d/%d: %s", bus_number, device_address, libusb_error_name(r)); continue; } } /* recall */ r = libusb_get_active_config_descriptor(dev, &config_desc); if (r < 0) { #endif (void)libusb_close(dev_handle); DEBUG_CRITICAL4("Can't get config descriptor on %d/%d: %s", bus_number, device_address, libusb_error_name(r)); continue; } #ifdef __APPLE__ } #endif usb_interface = get_ccid_usb_interface(config_desc, &num); if (usb_interface == NULL) { (void)libusb_close(dev_handle); if (0 == num) DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d", bus_number, device_address); interface_number = -1; continue; } device_descriptor = get_ccid_device_descriptor(usb_interface); if (NULL == device_descriptor) { (void)libusb_close(dev_handle); DEBUG_CRITICAL3("Unable to find the device descriptor for %d/%d", bus_number, device_address); return_value = STATUS_UNSUCCESSFUL; goto end2; } interface = usb_interface->altsetting->bInterfaceNumber; if (interface_number >= 0 && interface != interface_number) { /* an interface was specified and it is not the * current one */ DEBUG_INFO3("Found interface %d but expecting %d", interface, interface_number); DEBUG_INFO3("Wrong interface for USB device %d/%d." " Checking next one.", bus_number, device_address); /* check for another CCID interface on the same device */ num++; goto again; } r = libusb_claim_interface(dev_handle, interface); if (r < 0) { (void)libusb_close(dev_handle); DEBUG_CRITICAL4("Can't claim interface %d/%d: %s", bus_number, device_address, libusb_error_name(r)); claim_failed = TRUE; interface_number = -1; continue; } DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)", desc.idVendor, desc.idProduct, friendlyName); DEBUG_INFO3("Using USB bus/device: %d/%d", bus_number, device_address); /* check for firmware bugs */ if (ccid_check_firmware(&desc)) { (void)libusb_close(dev_handle); return_value = STATUS_UNSUCCESSFUL; goto end2; } #ifdef USE_COMPOSITE_AS_MULTISLOT /* use the next interface for the next "slot" */ static_interface++; /* reset for a next reader */ if (static_interface > 2) static_interface = (FEITIANR502DUAL == readerID) ? 0: 1; #endif /* Get Endpoints values*/ (void)get_end_points(config_desc, &usbDevice[reader_index], num); /* store device information */ usbDevice[reader_index].dev_handle = dev_handle; usbDevice[reader_index].bus_number = bus_number; usbDevice[reader_index].device_address = device_address; usbDevice[reader_index].interface = interface; usbDevice[reader_index].real_nb_opened_slots = 1; usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots; usbDevice[reader_index].polling_transfer = NULL; /* CCID common informations */ usbDevice[reader_index].ccid.real_bSeq = 0; usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq; usbDevice[reader_index].ccid.readerID = (desc.idVendor << 16) + desc.idProduct; usbDevice[reader_index].ccid.dwFeatures = dw2i(device_descriptor, 40); usbDevice[reader_index].ccid.wLcdLayout = (device_descriptor[51] << 8) + device_descriptor[50]; usbDevice[reader_index].ccid.bPINSupport = device_descriptor[52]; usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(device_descriptor, 44); usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(device_descriptor, 28); usbDevice[reader_index].ccid.dwDefaultClock = dw2i(device_descriptor, 10); usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(device_descriptor, 23); usbDevice[reader_index].ccid.bMaxSlotIndex = device_descriptor[4]; usbDevice[reader_index].ccid.bCurrentSlotIndex = 0; usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT; if (device_descriptor[27]) usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, config_desc, num); else { usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL; DEBUG_INFO1("bNumDataRatesSupported is 0"); } usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol; usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints; usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT; usbDevice[reader_index].ccid.bVoltageSupport = device_descriptor[5]; usbDevice[reader_index].ccid.sIFD_serial_number = NULL; usbDevice[reader_index].ccid.gemalto_firmware_features = NULL; if (desc.iSerialNumber) { unsigned char serial[128]; int ret; ret = libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, serial, sizeof(serial)); if (ret > 0) usbDevice[reader_index].ccid.sIFD_serial_number = strdup((char *)serial); } usbDevice[reader_index].ccid.sIFD_iManufacturer = NULL; if (desc.iManufacturer) { unsigned char iManufacturer[128]; int ret; ret = libusb_get_string_descriptor_ascii(dev_handle, desc.iManufacturer, iManufacturer, sizeof(iManufacturer)); if (ret > 0) usbDevice[reader_index].ccid.sIFD_iManufacturer = strdup((char *)iManufacturer); } usbDevice[reader_index].ccid.IFD_bcdDevice = desc.bcdDevice; /* If this is a multislot reader, init the multislot stuff */ if (usbDevice[reader_index].ccid.bMaxSlotIndex) usbDevice[reader_index].multislot_extension = Multi_CreateFirstSlot(reader_index); else usbDevice[reader_index].multislot_extension = NULL; goto end; } } } end: if (usbDevice[reader_index].dev_handle == NULL) { /* free the libusb allocated list & devices */ libusb_free_device_list(devs, 1); #ifdef __APPLE__ /* give some time to libusb to detect the new USB devices on Mac OS X */ if (count_libusb > 0) { count_libusb--; DEBUG_INFO2("Wait after libusb: %d", count_libusb); nanosleep(&sleep_time, NULL); goto again_libusb; } #endif /* failed */ close_libusb_if_needed(); if (claim_failed) return STATUS_COMM_ERROR; DEBUG_INFO1("Device not found?"); return STATUS_NO_SUCH_DEVICE; } /* memorise the current reader_index so we can detect * a new OpenUSBByName on a multi slot reader */ previous_reader_index = reader_index; end2: /* free the libusb allocated list & devices */ libusb_free_device_list(devs, 1); end1: /* free bundle list */ bundleRelease(&plist); if (return_value != STATUS_SUCCESS) close_libusb_if_needed(); return return_value; } /* OpenUSBByName */
int main(int argc, char *argv[]) { int o, flags, server_fd = -1; char *endptr, *delim; int port = 4000; int usbbus = -1; int usbaddr = -1; int usbvendor = -1; int usbproduct = -1; int on = 1; struct sockaddr_in6 serveraddr; struct sigaction act; libusb_device_handle *handle = NULL; while ((o = getopt_long(argc, argv, "hp:v:", longopts, NULL)) != -1) { switch (o) { case 'p': port = strtol(optarg, &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "Invalid value for --port: '%s'\n", optarg); usage(1, argv[0]); } break; case 'v': verbose = strtol(optarg, &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "Invalid value for --verbose: '%s'\n", optarg); usage(1, argv[0]); } break; case '?': case 'h': usage(o == '?', argv[0]); break; } } if (optind == argc) { fprintf(stderr, "Missing usb device identifier argument\n"); usage(1, argv[0]); } delim = strchr(argv[optind], '-'); if (delim && delim[1]) { usbbus = strtol(argv[optind], &endptr, 10); if (*endptr != '-') { invalid_usb_device_id(argv[optind], argv[0]); } usbaddr = strtol(delim + 1, &endptr, 10); if (*endptr != '\0') { invalid_usb_device_id(argv[optind], argv[0]); } } else { delim = strchr(argv[optind], ':'); if (!delim || !delim[1]) { invalid_usb_device_id(argv[optind], argv[0]); } usbvendor = strtol(argv[optind], &endptr, 16); if (*endptr != ':') { invalid_usb_device_id(argv[optind], argv[0]); } usbproduct = strtol(delim + 1, &endptr, 16); if (*endptr != '\0') { invalid_usb_device_id(argv[optind], argv[0]); } } optind++; if (optind != argc) { fprintf(stderr, "Excess non option arguments\n"); usage(1, argv[0]); } memset(&act, 0, sizeof(act)); act.sa_handler = quit_handler; sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGQUIT, &act, NULL); if (libusb_init(&ctx)) { fprintf(stderr, "Could not init libusb\n"); exit(1); } libusb_set_debug(ctx, verbose); server_fd = socket(AF_INET6, SOCK_STREAM, 0); if (server_fd == -1) { perror("Error creating ipv6 socket"); exit(1); } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { perror("Error setsockopt(SO_REUSEADDR) failed"); exit(1); } memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin6_family = AF_INET6; serveraddr.sin6_port = htons(port); serveraddr.sin6_addr = in6addr_any; if (bind(server_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) { fprintf(stderr, "Error binding port %d: %s\n", port, strerror(errno)); exit(1); } if (listen(server_fd, 1)) { perror("Error listening"); exit(1); } while (running) { client_fd = accept(server_fd, NULL, 0); if (client_fd == -1) { if (errno == EINTR) { continue; } perror("accept"); break; } flags = fcntl(client_fd, F_GETFL); if (flags == -1) { perror("fcntl F_GETFL"); break; } flags = fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); if (flags == -1) { perror("fcntl F_SETFL O_NONBLOCK"); break; } /* Try to find the specified usb device */ if (usbvendor != -1) { handle = libusb_open_device_with_vid_pid(ctx, usbvendor, usbproduct); if (!handle) { fprintf(stderr, "Could not open an usb-device with vid:pid %04x:%04x\n", usbvendor, usbproduct); } } else { libusb_device **list = NULL; ssize_t i, n; n = libusb_get_device_list(ctx, &list); for (i = 0; i < n; i++) { if (libusb_get_bus_number(list[i]) == usbbus && libusb_get_device_address(list[i]) == usbaddr) break; } if (i < n) { if (libusb_open(list[i], &handle) != 0) { fprintf(stderr, "Could not open usb-device at bus-addr %d-%d\n", usbbus, usbaddr); } } else { fprintf(stderr, "Could not find an usb-device at bus-addr %d-%d\n", usbbus, usbaddr); } libusb_free_device_list(list, 1); } if (!handle) { close(client_fd); continue; } host = usbredirhost_open(ctx, handle, usbredirserver_log, usbredirserver_read, usbredirserver_write, NULL, SERVER_VERSION, verbose, 0); if (!host) exit(1); run_main_loop(); usbredirhost_close(host); handle = NULL; } close(server_fd); libusb_exit(ctx); exit(0); }
XN_C_API XnStatus xnUSBOpenDeviceByPath(const XnUSBConnectionString strDevicePath, XN_USB_DEV_HANDLE* pDevHandlePtr) { XnStatus nRetVal = XN_STATUS_OK; // parse connection string XnUInt16 nVendorID = 0; XnUInt16 nProductID = 0; XnUInt8 nBus = 0; XnUInt8 nAddress = 0; sscanf(strDevicePath, "%hx/%hx@%hhu/%hhu", &nVendorID, &nProductID, &nBus, &nAddress); if (nVendorID == 0 || nProductID == 0 || nBus == 0 || nAddress == 0) { XN_LOG_WARNING_RETURN(XN_STATUS_USB_DEVICE_OPEN_FAILED, "Invalid connection string: %s", strDevicePath); } // find device libusb_device** ppDevices; ssize_t nDeviceCount = libusb_get_device_list(g_InitData.pContext, &ppDevices); libusb_device* pRequestedDevice = NULL; for (ssize_t i = 0; i < nDeviceCount; ++i) { libusb_device* pDevice = ppDevices[i]; // get device descriptor libusb_device_descriptor desc; int rc = libusb_get_device_descriptor(pDevice, &desc); if (rc != 0) { libusb_free_device_list(ppDevices, 1); return (XN_STATUS_USB_ENUMERATE_FAILED); } // check if this is the requested device if (desc.idVendor == nVendorID && desc.idProduct == nProductID && libusb_get_bus_number(pDevice) == nBus && libusb_get_device_address(pDevice) == nAddress) { // add a reference to the device (so it won't be destroyed when list is freed) libusb_ref_device(pDevice); pRequestedDevice = pDevice; break; } } libusb_free_device_list(ppDevices, 1); nRetVal = xnUSBOpenDeviceImpl(pRequestedDevice, pDevHandlePtr); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
bool CameraUSB::connect(const CameraInfo &info) { int ret; // com settings _vendorId = info.getParam("vendorId").toString().toInt(0, 16); _productId = info.getParam("productId").toString().toInt(0, 16); _epIn = info.getParam("EPIN").toString().toInt(0, 16); _epOut = info.getParam("EPOUT").toString().toInt(0, 16); _interfaceNumber = info.getParam("interface").toString().toInt(0, 16); if(_vendorId == 0 || _productId == 0) { qDebug()<<"USB bad vendorId/productId settings"; return false; } // connect if(info.addr().isEmpty()) { qDebug()<<"addr empty"; _devHandle = libusb_open_device_with_vid_pid(_ctx, _vendorId, _productId); } else { // get list usb device libusb_device **devs; ssize_t cnt = libusb_get_device_list(_ctx, &devs); for(int i = 0; i < cnt; i++) { libusb_device_descriptor desc; if(libusb_get_device_descriptor(devs[i], &desc)==LIBUSB_SUCCESS) { if(desc.idVendor==_vendorId && desc.idProduct==_productId) { QString addr = QString("%1.%2").arg((int)libusb_get_bus_number(devs[i])) .arg((int)libusb_get_device_address(devs[i])); if(addr==info.addr()) { _device = devs[i]; libusb_open(devs[i], &_devHandle); } } } } libusb_free_device_list(devs, 1); } if(_devHandle == NULL) { qDebug()<<"Cannot open device"<<endl; return false; } // reset device if((ret = libusb_reset_device(_devHandle)) != 0) qDebug()<<"Cannot reset device"<<libusb_strerror(libusb_error(ret)); if(libusb_kernel_driver_active(_devHandle, _interfaceNumber) == 1) //find out if kernel driver is attached { printf("Kernel Driver Active\n"); if(libusb_detach_kernel_driver(_devHandle, _interfaceNumber) == 0) //detach it printf("Kernel Driver Detached!\n"); } ret = libusb_claim_interface(_devHandle, _interfaceNumber); if(ret != 0) { qDebug()<<"Cannot claim device"<<libusb_strerror(libusb_error(ret)); return false; } if((ret = libusb_clear_halt(_devHandle, _epOut)) != 0) qDebug()<<"Cannot clear EPOUT"<<libusb_strerror(libusb_error(ret)); if((ret = libusb_clear_halt(_devHandle, _epIn)) != 0) qDebug()<<"Cannot clear EPIN"<<libusb_strerror(libusb_error(ret)); //libusb_set_debug(_ctx, LIBUSB_LOG_LEVEL_DEBUG); //flush(); return true; }
int musb_open(MUSB_INTERFACE **musb_interface, int vendor, int product, int instance, int configuration, int usbinterface) { #if defined(HAVE_LIBUSB) struct usb_bus *bus; struct usb_device *dev; int count = 0; usb_init(); usb_find_busses(); usb_find_devices(); usb_set_debug(3); for (bus = usb_get_busses(); bus; bus = bus->next) for (dev = bus->devices; dev; dev = dev->next) if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { if (count == instance) { int status; usb_dev_handle *udev; udev = usb_open(dev); if (!udev) { fprintf(stderr, "musb_open: usb_open() error\n"); return MUSB_ACCESS_ERROR; } status = usb_set_configuration(udev, configuration); if (status < 0) { fprintf(stderr, "musb_open: usb_set_configuration() error %d (%s)\n", status, strerror(-status)); fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\" and \"/dev/bus/usb/%s/%s\"\n", vendor, product, instance, bus->dirname, dev->filename, bus->dirname, dev->filename); return MUSB_ACCESS_ERROR; } /* see if we have write access */ status = usb_claim_interface(udev, usbinterface); if (status < 0) { fprintf(stderr, "musb_open: usb_claim_interface() error %d (%s)\n", status, strerror(-status)); #ifdef _MSC_VER fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n", vendor, product, instance); #else fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\"\n", vendor, product, instance, bus->dirname, dev->filename); #endif return MUSB_ACCESS_ERROR; } *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE)); (*musb_interface)->dev = udev; (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; return MUSB_SUCCESS; } count++; } return MUSB_NOT_FOUND; #elif defined(HAVE_LIBUSB10) static int first_call = 1; libusb_device **dev_list; libusb_device_handle *dev; struct libusb_device_descriptor desc; int status, i, n; int count = 0; if (first_call) { first_call = 0; libusb_init(NULL); // libusb_set_debug(NULL, 3); } n = libusb_get_device_list(NULL, &dev_list); for (i=0 ; i<n ; i++) { status = libusb_get_device_descriptor(dev_list[i], &desc); if (desc.idVendor == vendor && desc.idProduct == product) { if (count == instance) { status = libusb_open(dev_list[i], &dev); if (status < 0) { fprintf(stderr, "musb_open: libusb_open() error %d\n", status); return MUSB_ACCESS_ERROR; } status = libusb_set_configuration(dev, configuration); if (status < 0) { fprintf(stderr, "musb_open: usb_set_configuration() error %d\n", status); fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\" and \"/dev/bus/usb/%d/%d\"\n", vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]), libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i])); return MUSB_ACCESS_ERROR; } /* see if we have write access */ status = libusb_claim_interface(dev, usbinterface); if (status < 0) { fprintf(stderr, "musb_open: libusb_claim_interface() error %d\n", status); #ifdef _MSC_VER fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n", vendor, product, instance); #else fprintf(stderr, "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\"\n", vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i])); #endif return MUSB_ACCESS_ERROR; } *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE)); (*musb_interface)->dev = dev; (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; return MUSB_SUCCESS; } count++; } } libusb_free_device_list(dev_list, 1); return MUSB_NOT_FOUND; #elif defined(OS_DARWIN) kern_return_t status; io_iterator_t iter; io_service_t service; IOCFPlugInInterface **plugin; SInt32 score; IOUSBDeviceInterface **device; UInt16 xvendor, xproduct; int count = 0; *musb_interface = calloc(1, sizeof(MUSB_INTERFACE)); status = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &iter); assert(status == kIOReturnSuccess); while ((service = IOIteratorNext(iter))) { status = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); assert(status == kIOReturnSuccess); status = IOObjectRelease(service); assert(status == kIOReturnSuccess); status = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void *) &device); assert(status == kIOReturnSuccess); status = (*plugin)->Release(plugin); status = (*device)->GetDeviceVendor(device, &xvendor); assert(status == kIOReturnSuccess); status = (*device)->GetDeviceProduct(device, &xproduct); assert(status == kIOReturnSuccess); //fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x\n", xvendor, xproduct); if (xvendor == vendor && xproduct == product) { if (count == instance) { fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x, instance %d\n", xvendor, xproduct, instance); status = (*device)->USBDeviceOpen(device); fprintf(stderr, "musb_open: USBDeviceOpen status 0x%x\n", status); assert(status == kIOReturnSuccess); (*musb_interface)->usb_configuration = configuration; (*musb_interface)->usb_interface = usbinterface; (*musb_interface)->device = (void*)device; (*musb_interface)->interface = NULL; status = darwin_configure_device(*musb_interface); if (status == kIOReturnSuccess) return MUSB_SUCCESS; fprintf(stderr, "musb_open: USB device exists, but configuration fails!"); return MUSB_NOT_FOUND; } count++; } (*device)->Release(device); } return MUSB_NOT_FOUND; #elif defined(_MSC_VER) GUID guid; HDEVINFO hDevInfoList; SP_DEVICE_INTERFACE_DATA deviceInfoData; PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData; ULONG predictedLength, requiredLength; int status; char device_name[256], str[256]; *musb_interface = (MUSB_INTERFACE *)calloc(1, sizeof(MUSB_INTERFACE)); guid = GUID_CLASS_MSCB_BULK; // Retrieve device list for GUID that has been specified. hDevInfoList = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); status = FALSE; if (hDevInfoList != NULL) { // Clear data structure memset(&deviceInfoData, 0, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // retrieves a context structure for a device interface of a device information set. if (SetupDiEnumDeviceInterfaces(hDevInfoList, 0, &guid, instance, &deviceInfoData)) { // Must get the detailed information in two steps // First get the length of the detailed information and allocate the buffer // retrieves detailed information about a specified device interface. functionClassDeviceData = NULL; predictedLength = requiredLength = 0; SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, NULL, // Not yet allocated 0, // Set output buffer length to zero &requiredLength, // Find out memory requirement NULL); predictedLength = requiredLength; functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(predictedLength); functionClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Second, get the detailed information if (SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { // Save the device name for subsequent pipe open calls strcpy(device_name, functionClassDeviceData->DevicePath); free(functionClassDeviceData); // Signal device found status = TRUE; } else free(functionClassDeviceData); } } // SetupDiDestroyDeviceInfoList() destroys a device information set // and frees all associated memory. SetupDiDestroyDeviceInfoList(hDevInfoList); if (status) { // Get the read handle sprintf(str, "%s\\PIPE00", device_name); (*musb_interface)->rhandle = CreateFile(str, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if ((*musb_interface)->rhandle == INVALID_HANDLE_VALUE) return MUSB_ACCESS_ERROR; // Get the write handle sprintf(str, "%s\\PIPE01", device_name); (*musb_interface)->whandle = CreateFile(str, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ((*musb_interface)->whandle == INVALID_HANDLE_VALUE) return MUSB_ACCESS_ERROR; return MUSB_SUCCESS; } return MUSB_NOT_FOUND; #endif }
GSM_Error GSM_USB_Probe(GSM_StateMachine *s, GSM_USB_Match_Function matcher) { libusb_device **devs; libusb_device *dev; GSM_Device_USBData *d = &s->Device.Data.USB; ssize_t cnt; int rc; int i = 0; struct libusb_device_descriptor desc; struct libusb_config_descriptor *config; GSM_Error error; int vendor = -1, product = -1, bus = -1, deviceid = -1; char *serial = NULL; char buffer[300]; gboolean do_match; /* Device selection */ GSM_USB_ParseDevice(s, &vendor, &product, &bus, &deviceid, &serial); do_match = (vendor != -1 || product != -1 || bus != -1 || deviceid != -1 || serial != NULL); cnt = libusb_get_device_list(d->context, &devs); if (cnt < 0) { smprintf(s, "Failed to list USB devices (%d)!\n", (int)cnt); return GSM_USB_Error(s, cnt); } /* Check all devices */ i = 0; while ((dev = devs[i++]) != NULL) { rc = libusb_get_device_descriptor(dev, &desc); if (rc < 0) { smprintf(s, "Failed to get device descriptor (%d)!\n", rc); GSM_USB_Error(s, rc); continue; } smprintf(s, "Checking %04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev)); if (do_match) { if (vendor != -1 && vendor != desc.idVendor) { smprintf(s, "Vendor does not match requested 0x%04x, ignoring\n", vendor); continue; } if (product != -1 && product != desc.idProduct) { smprintf(s, "Product does not match requested 0x%04x, ignoring\n", product); continue; } if (bus != -1 && bus != libusb_get_bus_number(dev)) { smprintf(s, "Bus does not match requested %d, ignoring\n", bus); continue; } if (deviceid != -1 && deviceid != libusb_get_device_address(dev)) { smprintf(s, "Device address does not match requested %d, ignoring\n", deviceid); continue; } if (serial != NULL && desc.iSerialNumber) { rc = libusb_open(dev, &d->handle); if (rc != 0) { smprintf(s, "Failed to read serial!\n"); } else { libusb_get_string_descriptor_ascii(d->handle, desc.iSerialNumber, buffer, sizeof(buffer) - 1); smprintf(s, "Device serial: %s\n", buffer); libusb_close(d->handle); if (strcasecmp(buffer, serial) != 0) { smprintf(s, "Device serial does not match requested %s, ignoring\n", serial); continue; } } } } if (matcher(s, dev, &desc)) { break; } } if (dev == NULL) { error = ERR_DEVICENOTEXIST; goto done; } smprintf(s, "Trying to open device, config=%d, c_iface=%d, c_alt=%d, d_iface=%d, d_alt=%d\n", d->configuration, d->control_iface, d->control_altsetting, d->data_iface, d->data_altsetting); rc = libusb_open(dev, &d->handle); if (rc != 0) { d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } /* Unhook kernel driver */ rc = libusb_get_active_config_descriptor(dev, &config); if (rc != 0) { smprintf(s, "Failed to get current device configuration!\n"); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } /* Do we have to change configuration? */ if (config->bConfigurationValue != d->configuration) { smprintf(s, "Will change configuration, unhooking all interfaces!\n"); for (i = 0; i < config->bNumInterfaces; i++) { if (libusb_kernel_driver_active(d->handle, i) == 1) { smprintf(s, "Detaching kernel driver from interface %d\n", i); rc = libusb_detach_kernel_driver(d->handle, i); if (rc != 0) { smprintf(s, "Failed to detach kernel driver!\n"); libusb_free_config_descriptor(config); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } } } smprintf(s, "Configuring USB device...\n"); rc = libusb_set_configuration(d->handle, d->configuration); if (rc != 0) { smprintf(s, "Failed to set device configuration %d (%d)!\n", d->configuration, rc); libusb_free_config_descriptor(config); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } } else { smprintf(s, "Configuration change not required, unhooking only required interfaces!\n"); if (libusb_kernel_driver_active(d->handle, d->control_iface) == 1) { smprintf(s, "Detaching kernel driver from interface %d\n", d->control_iface); rc = libusb_detach_kernel_driver(d->handle, d->control_iface); if (rc != 0) { smprintf(s, "Failed to detach kernel driver!\n"); libusb_free_config_descriptor(config); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } } if (libusb_kernel_driver_active(d->handle, d->data_iface) == 1) { smprintf(s, "Detaching kernel driver from interface %d\n", d->data_iface); rc = libusb_detach_kernel_driver(d->handle, d->data_iface); if (rc != 0) { smprintf(s, "Failed to detach kernel driver!\n"); libusb_free_config_descriptor(config); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } } } libusb_free_config_descriptor(config); smprintf(s, "Claiming USB control interface...\n"); rc = libusb_claim_interface(d->handle, d->control_iface); if (rc != 0) { smprintf(s, "Failed to set claim control interface %d (%d)!\n", d->control_iface, rc); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } smprintf(s, "Configuring USB control interface...\n"); rc = libusb_set_interface_alt_setting(d->handle, d->control_iface, d->control_altsetting); if (rc != 0) { smprintf(s, "Failed to set control alt setting %d (%d)!\n", d->control_altsetting, rc); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } smprintf(s, "Claiming USB data interface...\n"); rc = libusb_claim_interface(d->handle, d->data_iface); if (rc != 0) { smprintf(s, "Failed to set claim data interface %d (%d)!\n", d->data_iface, rc); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } smprintf(s, "Configuring USB data interface...\n"); rc = libusb_set_interface_alt_setting(d->handle, d->data_iface, d->data_altsetting); if (rc != 0) { smprintf(s, "Failed to set data alt setting %d (%d)!\n", d->data_altsetting, rc); libusb_close(d->handle); d->handle = NULL; error = GSM_USB_Error(s, rc); goto done; } smprintf(s, "Connected!\n"); error = ERR_NONE; done: return error; }
vrpn_libusb::vrpn_libusb(const char *name, vrpn_Connection *c, std::string configFile) : vrpn_Button(name,c), vrpn_Analog(name,c) { _devList = NULL; _dev = NULL; _vendorID = -1; _productID = -1; _entryNum = 0; _configNum = 0; _numConfigs = 0; _interfaceNum = 0; _numInterfaces = 0; _altSettingNum = 0; _numAltSettings = 0; _endpointNum = 0; _numEndpoints = 0; _address = 0; _packetSize = 0; _printPacket = false; _context = NULL; _error = false; num_buttons = 0; num_channel = 0; _driverPresent = false; if(!loadConfigFile(configFile)) { _error = true; return; } if(libusb_init(&_context) < 0) { std::cerr << "Error libusb init." << std::endl; _error = true; return; } int devCount; if((devCount = libusb_get_device_list(NULL, &_devList)) < 0 ) { std::cerr << "Error getting device list .." << std::endl; _error = true; return; } if(_vendorID < 0 || _productID < 0) { std::cerr << "Error: vendorID/productID must be set." << std::endl; std::cerr << "Printing list of usb devices:" << std::endl; printDevices(_devList); _error = true; return; } bool usberror = false; _dev = findDevice(_devList); if(!_dev) { printConfig(); std::cerr << "Error: device with vendorID/productID with given entry not found." << std::endl; std::cerr << "Printing list of usb devices:" << std::endl; printDevices(_devList); _error = true; return; } libusb_device_descriptor desc; if(libusb_get_device_descriptor(_dev,&desc) >= 0) { _numConfigs = (int)desc.bNumConfigurations; if(_configNum >= 0 && _configNum < _numConfigs) { libusb_config_descriptor * cdesc; if(libusb_get_config_descriptor(_dev,_configNum,&cdesc) >= 0) { _numInterfaces = (int)cdesc->bNumInterfaces; if(_interfaceNum >= 0 && _interfaceNum < _numInterfaces) { libusb_interface interface = cdesc->interface[_interfaceNum]; _numAltSettings = (int)interface.num_altsetting; if(_altSettingNum >= 0 && _altSettingNum < _numAltSettings) { libusb_interface_descriptor idesc = interface.altsetting[_altSettingNum]; _numEndpoints = (int)idesc.bNumEndpoints; if(_endpointNum >= 0 && _endpointNum < _numEndpoints) { libusb_endpoint_descriptor edesc = idesc.endpoint[_endpointNum]; _address = (int)edesc.bEndpointAddress; _packetSize = (int)edesc.wMaxPacketSize; } else { std::cerr << "Error: Invalid endpoint number." << std::endl; usberror = true; } } else { std::cerr << "Error: Invalid altSetting number." << std::endl; usberror = true; } } else { std::cerr << "Error: Invalid interface number." << std::endl; usberror == true; } } else { std::cerr << "Error: unable to get config descriptor." << std::endl; usberror = true; } } else { std::cerr << "Error: Invalid config number." << std::endl; usberror = true; } } else { std::cerr << "Error: unable to get device descriptor." << std::endl; usberror = true; } printConfig(); if(libusb_open(_dev, &_handle) < 0) { std::cerr << "Error opening device bus: " << libusb_get_bus_number(_dev) << " device: " << libusb_get_device_address(_dev) << std::endl; usberror = true; } if(usberror) { _error = true; return; } num_buttons = 0; for(int i = 0; i < _buttonGroups.size(); ++i) { num_buttons += _buttonGroups[i]->numButtons; } for(int i = 0; i < num_buttons; i++) { buttons[i] = 0; lastbuttons[i] = 0; } num_channel = _valuators.size(); _packet = new unsigned char[_packetSize]; for(int i = 0; i < _numInterfaces; i++) { if(libusb_kernel_driver_active(_handle, i) == 1) { _driverPresent = true; if(libusb_detach_kernel_driver(_handle, i) != 0) { std::cerr << "Error detaching driver from interface " << i << std::endl; } } else { _driverPresent = false; } } if(libusb_claim_interface(_handle, _interfaceNum) != 0) { std::cerr << "Error: could not claim device interface." << std::endl; _error = true; return; } vrpn_gettimeofday(&_lastUpdateTime,NULL); _transfer = libusb_alloc_transfer(5); libusb_fill_interrupt_transfer(_transfer, _handle, _address, _packet, _packetSize, transCallback, (void*)this, 10000); libusb_submit_transfer(_transfer); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); _ti = new ThreadInit; _ti->context = _context; _ti->quit = false; pthread_create(&_updateThread,&attr,libusbUpdate,(void*)_ti); pthread_attr_destroy(&attr); std::cerr << "Init good." << std::endl; }
static int print_device(libusb_device *dev, int level) { struct libusb_device_descriptor desc; libusb_device_handle *handle = NULL; char description[256]; char string[256]; int ret, i; ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { fprintf(stderr, "failed to get device descriptor"); return -1; } ret = libusb_open(dev, &handle); if (LIBUSB_SUCCESS == ret) { if (desc.iManufacturer) { ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string)); if (ret > 0) snprintf(description, sizeof(description), "%s - ", string); else snprintf(description, sizeof(description), "%04X - ", desc.idVendor); } else snprintf(description, sizeof(description), "%04X - ", desc.idVendor); if (desc.iProduct) { ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string)); if (ret > 0) snprintf(description + strlen(description), sizeof(description) - strlen(description), "%s", string); else snprintf(description + strlen(description), sizeof(description) - strlen(description), "%04X", desc.idProduct); } else snprintf(description + strlen(description), sizeof(description) - strlen(description), "%04X", desc.idProduct); } else { snprintf(description, sizeof(description), "%04X - %04X", desc.idVendor, desc.idProduct); } printf("%.*sDev (bus %d, device %d): %s\n", level * 2, " ", libusb_get_bus_number(dev), libusb_get_device_address(dev), description); if (handle && verbose) { if (desc.iSerialNumber) { ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string)); if (ret > 0) printf("%.*s - Serial Number: %s\n", level * 2, " ", string); } } if (verbose) { for (i = 0; i < desc.bNumConfigurations; i++) { struct libusb_config_descriptor *config; ret = libusb_get_config_descriptor(dev, i, &config); if (LIBUSB_SUCCESS != ret) { printf(" Couldn't retrieve descriptors\n"); continue; } print_configuration(config); libusb_free_config_descriptor(config); } if (handle && desc.bcdUSB >= 0x0201) { print_bos(handle); } } if (handle) libusb_close(handle); return 0; }