Xbox360Controller::Xbox360Controller(struct usb_device* dev_, bool is_guitar_, bool try_detach) : dev(dev_), is_guitar(is_guitar_), dev_type(), handle(), endpoint_in(1), endpoint_out(2), read_thread() { find_endpoints(); if (0) { std::cout << "EP(IN): " << endpoint_in << std::endl; std::cout << "EP(OUT): " << endpoint_out << std::endl; } handle = usb_open(dev); if (0) { int err; if ((err = usb_set_configuration(handle, 0)) < 0) { std::ostringstream out; out << "Error set USB configuration: " << usb_strerror() << std::endl << "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver."; throw std::runtime_error(out.str()); } } if (!handle) { throw std::runtime_error("Error opening Xbox360 controller"); } else { // FIXME: bInterfaceNumber shouldn't be hardcoded int err = usb_claim_n_detach_interface(handle, 0, try_detach); if (err != 0) { std::ostringstream out; out << " Error couldn't claim the USB interface: " << usb_strerror() << std::endl << "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver."; throw std::runtime_error(out.str()); } } if (0) { unsigned char arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 255 }; for (int len = 3; len <= 8; ++len) { // Sending random data: for (int front = 0; front < 256; ++front) { for (size_t i = 0; i < sizeof(arr); ++i) { char ledcmd[] = { front, len, arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i] }; printf("%d %d %d\n", len, front, arr[i]); usb_interrupt_write(handle, endpoint_out, ledcmd, len, 0); uint8_t data[32]; int ret = usb_interrupt_read(handle, endpoint_in, reinterpret_cast<char*>(data), sizeof(data), 20); print_raw_data(std::cout, data, ret); } } } } read_thread = std::auto_ptr<USBReadThread>(new USBReadThread(handle, endpoint_in, 32)); read_thread->start_thread(); }
int do_wdioctl(int fd, unsigned int request, unsigned char *wdioctl) { struct header_struct* wdheader = (struct header_struct*)wdioctl; struct version_struct *version; int ret = 0; if (wdheader->magic != MAGIC) { fprintf(stderr,"!!!ERROR: magic header does not match!!!\n"); return (*ioctl_func) (fd, request, wdioctl); } switch(request & ~(0xc0000000)) { case VERSION: version = (struct version_struct*)(wdheader->data); strcpy(version->version, "libusb-driver.so version: " USB_DRIVER_VERSION); version->versionul = 802; DPRINTF("VERSION\n"); break; case LICENSE: DPRINTF("LICENSE\n"); break; case CARD_REGISTER_OLD: case CARD_REGISTER: DPRINTF("CARD_REGISTER\n"); { struct card_register* cr = (struct card_register*)(wdheader->data); DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", cr->Card.dwItems, (unsigned long)cr->Card.Item[0].I.IO.dwAddr, cr->Card.Item[0].I.IO.dwBytes, cr->Card.Item[0].I.IO.dwBar); DPRINTF("Items: %lu, Addr: 0x%lx, bytes: %lu, bar: %lu\n", cr->Card.dwItems, (unsigned long)cr->Card.Item[1].I.IO.dwAddr, cr->Card.Item[1].I.IO.dwBytes, cr->Card.Item[1].I.IO.dwBar); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else pport = config_get((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); if (!pport) break; ret = pport->open((unsigned long)cr->Card.Item[0].I.IO.dwAddr / 0x10); ppbase = (unsigned long)cr->Card.Item[0].I.IO.dwAddr; if (cr->Card.dwItems > 1 && cr->Card.Item[1].I.IO.dwAddr) ecpbase = (unsigned long)cr->Card.Item[1].I.IO.dwAddr; if (ret >= 0) { cr->hCard = ret; } else { cr->hCard = 0; } #endif DPRINTF("hCard: %lu\n", cr->hCard); } break; case USB_TRANSFER: DPRINTF("in USB_TRANSFER"); { struct usb_transfer *ut = (struct usb_transfer*)(wdheader->data); #ifdef DEBUG DPRINTF(" unique: %lu, pipe: %lu, read: %lu, options: %lx, size: %lu, timeout: %lx\n", ut->dwUniqueID, ut->dwPipeNum, ut->fRead, ut->dwOptions, ut->dwBufferSize, ut->dwTimeout); DPRINTF("setup packet: "); hexdump(ut->SetupPacket, 8); if (!ut->fRead && ut->dwBufferSize) { hexdump(ut->pBuffer, ut->dwBufferSize); } #endif #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else /* http://www.jungo.com/support/documentation/windriver/802/wdusb_man_mhtml/node55.html#SECTION001213000000000000000 */ if (ut->dwPipeNum == 0) { /* control pipe */ int requesttype, request, value, index, size; requesttype = ut->SetupPacket[0]; request = ut->SetupPacket[1]; value = ut->SetupPacket[2] | (ut->SetupPacket[3] << 8); index = ut->SetupPacket[4] | (ut->SetupPacket[5] << 8); size = ut->SetupPacket[6] | (ut->SetupPacket[7] << 8); DPRINTF("requesttype: %x, request: %x, value: %u, index: %u, size: %u\n", requesttype, request, value, index, size); ret = usb_control_msg(usb_devhandle, requesttype, request, value, index, ut->pBuffer, size, ut->dwTimeout); } else { if (ut->fRead) { ret = usb_bulk_read(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout); } else { ret = usb_bulk_write(usb_devhandle, ut->dwPipeNum, ut->pBuffer, ut->dwBufferSize, ut->dwTimeout); } } if (ret < 0) { fprintf(stderr, "usb_transfer: %d (%s)\n", ret, usb_strerror()); } else { ut->dwBytesTransferred = ret; ret = 0; } #endif #ifdef DEBUG DPRINTF("Transferred: %lu (%s)\n",ut->dwBytesTransferred, (ut->fRead?"read":"write")); if (ut->fRead && ut->dwBytesTransferred) { DPRINTF("Read: "); hexdump(ut->pBuffer, ut->dwBytesTransferred); } #endif } break; case INT_ENABLE_OLD: case INT_ENABLE: DPRINTF("INT_ENABLE\n"); { struct interrupt *it = (struct interrupt*)(wdheader->data); DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); it->fEnableOk = 1; it->fStopped = 0; ints_enabled = 1; pthread_mutex_trylock(&int_wait); } break; case INT_DISABLE: DPRINTF("INT_DISABLE\n"); { struct interrupt *it = (struct interrupt*)(wdheader->data); DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else it->dwCounter = 0; it->fStopped = 1; ints_enabled = 0; if (pthread_mutex_trylock(&int_wait) == EBUSY) pthread_mutex_unlock(&int_wait); #endif DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); } break; case USB_SET_INTERFACE: DPRINTF("USB_SET_INTERFACE\n"); { struct usb_set_interface *usi = (struct usb_set_interface*)(wdheader->data); DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else if (usbdevice) { if (!usb_devhandle) usb_devhandle = usb_open(usbdevice); /* FIXME: Select right interface! */ ret = usb_claim_interface(usb_devhandle, usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber); if (!ret) { if(!ret) { usbinterface = usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber; ret = usb_set_altinterface(usb_devhandle, usi->dwAlternateSetting); if (ret) fprintf(stderr, "usb_set_altinterface: %d\n", ret); } else { fprintf(stderr, "usb_set_configuration: %d (%s)\n", ret, usb_strerror()); } } else { fprintf(stderr, "usb_claim_interface: %d -> %d (%s)\n", usbdevice->config[0].interface[usi->dwInterfaceNum].altsetting[usi->dwAlternateSetting].bInterfaceNumber, ret, usb_strerror()); } } #endif DPRINTF("unique: %lu, interfacenum: %lu, alternatesetting: %lu, options: %lx\n", usi->dwUniqueID, usi->dwInterfaceNum, usi->dwAlternateSetting, usi->dwOptions); } break; case USB_GET_DEVICE_DATA_OLD: case USB_GET_DEVICE_DATA: DPRINTF("USB_GET_DEVICE_DATA\n"); { struct usb_get_device_data *ugdd = (struct usb_get_device_data*)(wdheader->data); int pSize; DPRINTF("unique: %lu, bytes: %lu, options: %lx\n", ugdd->dwUniqueID, ugdd->dwBytes, ugdd->dwOptions); pSize = ugdd->dwBytes; if (!ugdd->dwBytes) { if (usbdevice) { ugdd->dwBytes = usb_deviceinfo(NULL); } } else { usb_deviceinfo((unsigned char*)ugdd->pBuf); } } break; case EVENT_REGISTER_OLD: case EVENT_REGISTER: DPRINTF("EVENT_REGISTER\n"); { struct event *e = (struct event*)(wdheader->data); struct usb_bus *bus; int i; DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables); for (i = 0; i < e->dwNumMatchTables; i++) { DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol); for (bus = busses; bus; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev; dev = dev->next) { struct usb_device_descriptor *desc = &(dev->descriptor); if((desc->idVendor == e->matchTables[i].VendorId) && (desc->idProduct == e->matchTables[i].ProductId) && (desc->bDeviceClass == e->matchTables[i].bDeviceClass) && (desc->bDeviceSubClass == e->matchTables[i].bDeviceSubClass)) { int ac; for (ac = 0; ac < desc->bNumConfigurations; ac++) { struct usb_interface *interface = dev->config[ac].interface; int ai; for (ai = 0; ai < interface->num_altsetting; ai++) { DPRINTF("intclass: %x, intsubclass: %x, intproto: %x\n", interface->altsetting[i].bInterfaceClass, interface->altsetting[i].bInterfaceSubClass, interface->altsetting[i].bInterfaceProtocol); if ((interface->altsetting[ai].bInterfaceSubClass == e->matchTables[i].bInterfaceSubClass) && (interface->altsetting[ai].bInterfaceProtocol == e->matchTables[i].bInterfaceProtocol)){ /* TODO: check interfaceClass! */ DPRINTF("found device with libusb\n"); usbdevice = dev; card_type = e->dwCardType; } } } } } } } #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else e->handle++; #endif #ifdef DEBUG DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lu, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables); for (i = 0; i < e->dwNumMatchTables; i++) DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol); #endif } break; case TRANSFER_OLD: case TRANSFER: DPRINTF("TRANSFER\n"); { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else ret = pport->transfer(tr, fd, request, ppbase, ecpbase, 1); #endif } break; case MULTI_TRANSFER_OLD: case MULTI_TRANSFER: DPRINTF("MULTI_TRANSFER\n"); { WD_TRANSFER *tr = (WD_TRANSFER*)(wdheader->data); unsigned long num = wdheader->size/sizeof(WD_TRANSFER); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else ret = pport->transfer(tr, fd, request, ppbase, ecpbase, num); #endif } break; case EVENT_UNREGISTER: DPRINTF("EVENT_UNREGISTER\n"); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #endif break; case INT_WAIT: DPRINTF("INT_WAIT\n"); { struct interrupt *it = (struct interrupt*)(wdheader->data); DPRINTF("Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else if (usbdevice) { if (it->dwCounter == 0) { it->dwCounter = 1; } else { pthread_mutex_lock(&int_wait); pthread_mutex_unlock(&int_wait); } } else { pthread_mutex_lock(&int_wait); pthread_mutex_unlock(&int_wait); } #endif DPRINTF("INT_WAIT_RETURN: Handle: %lu, Options: %lx, ncmds: %lu, enableok: %lu, count: %lu, lost: %lu, stopped: %lu\n", it->hInterrupt, it->dwOptions, it->dwCmds, it->fEnableOk, it->dwCounter, it->dwLost, it->fStopped); } break; case CARD_UNREGISTER: DPRINTF("CARD_UNREGISTER\n"); { struct card_register* cr = (struct card_register*)(wdheader->data); DPRINTF("Addr: 0x%lx, bytes: %lu, bar: %lu\n", (unsigned long)cr->Card.Item[0].I.IO.dwAddr, cr->Card.Item[0].I.IO.dwBytes, cr->Card.Item[0].I.IO.dwBar); DPRINTF("hCard: %lu\n", cr->hCard); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else if (pport) pport->close(cr->hCard); pport = NULL; #endif } break; case EVENT_PULL: DPRINTF("EVENT_PULL\n"); { struct event *e = (struct event*)(wdheader->data); #ifdef DEBUG int i; DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables); for (i = 0; i < e->dwNumMatchTables; i++) DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol); #endif #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #else if (usbdevice) { struct usb_interface *interface = usbdevice->config->interface; e->dwCardType = card_type; e->dwAction = 1; e->dwEventId = 109; e->u.Usb.dwUniqueID = 110; e->matchTables[0].VendorId = usbdevice->descriptor.idVendor; e->matchTables[0].ProductId = usbdevice->descriptor.idProduct; e->matchTables[0].bDeviceClass = usbdevice->descriptor.bDeviceClass; e->matchTables[0].bDeviceSubClass = usbdevice->descriptor.bDeviceSubClass; e->matchTables[0].bInterfaceClass = interface->altsetting[0].bInterfaceClass; e->matchTables[0].bInterfaceSubClass = interface->altsetting[0].bInterfaceSubClass; e->matchTables[0].bInterfaceProtocol = interface->altsetting[0].bInterfaceProtocol; } #endif #ifdef DEBUG DPRINTF("handle: %lu, action: %lu, status: %lu, eventid: %lu, cardtype: %lx, kplug: %lu, options: %lu, dev: %lx:%lx, unique: %lu, ver: %lu, nummatch: %lu\n", e->handle, e->dwAction, e->dwStatus, e->dwEventId, e->dwCardType, e->hKernelPlugIn, e->dwOptions, e->u.Usb.deviceId.dwVendorId, e->u.Usb.deviceId.dwProductId, e->u.Usb.dwUniqueID, e->dwEventVer, e->dwNumMatchTables); for (i = 0; i < e->dwNumMatchTables; i++) DPRINTF("match: dev: %04x:%04x, class: %x, subclass: %x, intclass: %x, intsubclass: %x, intproto: %x\n", e->matchTables[i].VendorId, e->matchTables[i].ProductId, e->matchTables[i].bDeviceClass, e->matchTables[i].bDeviceSubClass, e->matchTables[i].bInterfaceClass, e->matchTables[i].bInterfaceSubClass, e->matchTables[i].bInterfaceProtocol); #endif } break; default: fprintf(stderr,"!!!Unsupported IOCTL: %x!!!\n", request); #ifndef NO_WINDRVR ret = (*ioctl_func) (fd, request, wdioctl); #endif break; } return ret; }
const T_HID_HDL* HidOpen( const char* const my_manufacturer, const char* const my_product ) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; T_HID_HDL_LOCAL* libhid_handle = NULL; const int my_product_id = MY_PID; usb_find_busses(); usb_find_devices(); for( bus = usb_get_busses(); bus; bus = bus->next ) { for( dev = bus->devices; dev; dev = dev->next ) { gdev = dev; /* @@@ add by tanioka */ #if DEBUG printf("dev=%04x:%04x\n",dev->descriptor.idVendor,dev->descriptor.idProduct); #endif if( (dev->descriptor.idVendor == MY_VID) && (dev->descriptor.idProduct == my_product_id) ) { char string[256]; int len; handle = usb_open( dev ); /* we need to open the device in order to query strings */ if(!handle){ fprintf( stderr, "Warning: cannot open USB device: %s\n", usb_strerror() ); continue; } if( usb_set_configuration( handle, dev->config->bConfigurationValue ) < 0 ) { fprintf( stderr, "!!usb_set_configuration Error.\n" ); } #if DEBUG printf( "!!usb_set_configuration.\n" ); #endif if( usb_claim_interface( handle, dev->config->interface->altsetting->bInterfaceNumber ) < 0 ) { fprintf( stderr, "!!usb_claim_interface Error.\n" ); } #if DEBUG printf( "usb_claim_interface.\n" ); #endif /* now check whether the names match: */ len = usbhidGetStringAscii( handle, dev->descriptor.iManufacturer, string, sizeof(string) ); if( len < 0 ) { fprintf( stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror() ); } else { #if DEBUG printf( "seen device from vendor [%s]\n", string ); #endif if( strcmp( string, my_manufacturer ) == 0 ) { len = usbhidGetStringAscii( handle, dev->descriptor.iProduct, string, sizeof(string) ); if( len < 0 ) { fprintf( stderr, "Warning: cannot query product for device: %s\n", usb_strerror() ); } else { #if DEBUG fprintf( stderr, "seen product [%s]\n", string ); #endif if( strcmp( string, my_product ) == 0 ) { break; } } } } usb_close( handle ); handle = NULL; } } } if(handle != NULL){ libhid_handle = malloc( sizeof(T_HID_HDL_LOCAL) ); if( libhid_handle ) { libhid_handle->handle = handle; } else { // usb_reset( (void*)handle ); usb_close( (void*)handle ); } } #if LINUX setuid(getuid()); // @@@ by iruka #endif return (T_HID_HDL*)libhid_handle; }
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; int errorCode = USB_ERROR_NOTFOUND; static int didUsbInit = 0; if(!didUsbInit){ didUsbInit = 1; usb_init(); } usb_find_busses(); usb_find_devices(); 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){ char string[256]; int len; /* we need to open the device in order to query strings */ handle = usb_open(dev); if(!handle){ errorCode = USB_ERROR_ACCESS; fprintf(stderr, "%s: Warning: cannot open USB device: %s\n", progname, usb_strerror()); continue; } errorCode = 0; /* now check whether the names match: */ /* if vendorName not given ignore it (any vendor matches) */ len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, string, sizeof(string)); if(len < 0){ if ((vendorName != NULL) && (vendorName[0] != 0)) { errorCode = USB_ERROR_IO; fprintf(stderr, "%s: Warning: cannot query manufacturer for device: %s\n", progname, usb_strerror()); } } else { if (verbose > 1) fprintf(stderr, "%s: seen device from vendor ->%s<-\n", progname, string); if((vendorName != NULL) && (vendorName[0] != 0) && (strcmp(string, vendorName) != 0)) errorCode = USB_ERROR_NOTFOUND; } /* if productName not given ignore it (any product matches) */ len = usb_get_string_simple(handle, dev->descriptor.iProduct, string, sizeof(string)); if(len < 0){ if ((productName != NULL) && (productName[0] != 0)) { errorCode = USB_ERROR_IO; fprintf(stderr, "%s: Warning: cannot query product for device: %s\n", progname, usb_strerror()); } } else { if (verbose > 1) fprintf(stderr, "%s: seen product ->%s<-\n", progname, string); if((productName != NULL) && (productName[0] != 0) && (strcmp(string, productName) != 0)) errorCode = USB_ERROR_NOTFOUND; } if (errorCode == 0) break; usb_close(handle); handle = NULL; } } if(handle) break; } if(handle != NULL){ errorCode = 0; *device = handle; } return errorCode; }
static int phoenix_command(const char *cmd, char *buf, size_t buflen) { char tmp[SMALLBUF]; int ret; size_t i; for (i = 0; i < 8; i++) { /* Read data in 8-byte chunks */ /* ret = usb->get_interrupt(udev, (unsigned char *)tmp, 8, 1000); */ ret = usb_interrupt_read(udev, 0x81, tmp, 8, 1000); /* * This USB to serial implementation is crappy. In order to read correct * replies we need to flush the output buffers of the converter until we * get no more data (ie, it times out). */ switch (ret) { case -EPIPE: /* Broken pipe */ usb_clear_halt(udev, 0x81); case -ETIMEDOUT: /* Connection timed out */ break; } if (ret < 0) { upsdebugx(3, "flush: %s", usb_strerror()); break; } upsdebug_hex(4, "dump", tmp, ret); } memset(tmp, 0, sizeof(tmp)); snprintf(tmp, sizeof(tmp), "%s", cmd); for (i = 0; i < strlen(tmp); i += ret) { /* Write data in 8-byte chunks */ /* ret = usb->set_report(udev, 0, (unsigned char *)&tmp[i], 8); */ ret = usb_control_msg(udev, USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE, 0x09, 0x200, 0, &tmp[i], 8, 1000); if (ret <= 0) { upsdebugx(3, "send: %s", ret ? usb_strerror() : "timeout"); return ret; } } upsdebugx(3, "send: %.*s", (int)strcspn(tmp, "\r"), tmp); memset(buf, 0, buflen); for (i = 0; (i <= buflen-8) && (strchr(buf, '\r') == NULL); i += ret) { /* Read data in 8-byte chunks */ /* ret = usb->get_interrupt(udev, (unsigned char *)&buf[i], 8, 1000); */ ret = usb_interrupt_read(udev, 0x81, &buf[i], 8, 1000); /* * Any errors here mean that we are unable to read a reply (which * will happen after successfully writing a command to the UPS) */ if (ret <= 0) { upsdebugx(3, "read: %s", ret ? usb_strerror() : "timeout"); return ret; } } upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); return i; }
unsigned char usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName, char *usbSerialID) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; unsigned char errorCode = USB_ERROR_NOTFOUND; static int didUsbInit = 0; if(!didUsbInit){ didUsbInit = 1; usb_init(); } usb_find_busses(); usb_find_devices(); 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){ char string[256]; int len; handle = usb_open(dev); /* we need to open the device in order to query strings */ if(!handle){ errorCode = USB_ERROR_ACCESS; fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); continue; } if(vendorName == NULL && productName == NULL){ /* name does not matter */ break; } /* now check whether the names match: */ len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string)); if(len < 0){ errorCode = USB_ERROR_IO; fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); }else{ errorCode = USB_ERROR_NOTFOUND; //fprintf(stderr, "seen device from vendor ->%s<-\n", string); if(strcmp(string, vendorName) == 0){ len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string)); if(len < 0){ errorCode = USB_ERROR_IO; fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); }else{ errorCode = USB_ERROR_NOTFOUND; //fprintf(stderr, "seen product ->%s<-\n", string); if(strcmp(string, productName) == 0) { len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, 0x0409, serialNumberString, sizeof(serialNumberString)); if (len < 0) { errorCode = USB_ERROR_IO; fprintf(stderr, "Warning: cannot query serial number for device: %s\n", usb_strerror()); }else{ errorCode = USB_ERROR_NOTFOUND; if ((usbSerialID == NULL) || (strcmp(serialNumberString, usbSerialID) == 0)) { break; } } } } } } usb_close(handle); handle = NULL; } } if(handle) break; } if(handle != NULL){ errorCode = USB_SUCCESS; *device = handle; } return errorCode; }
void garmin_usb_start(struct usb_device *dev, libusb_unit_data *lud) { int i; if (udev) return; udev = usb_open(dev); atexit(gusb_atexit_teardown); if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } /* * Hrmph. No iManufacturer or iProduct headers.... */ #if __APPLE__ // On Leopard, if we don't do an explicit set_configuration, some // devices will work only the first time after a reset. if (usb_set_configuration(udev, 1) < 0) { fatal("usb_set_configuration failed: %s\n", usb_strerror()); }; #endif #if 0 if (usb_set_configuration(udev, 1) < 0) { #if __linux__ char drvnm[128]; drvnm[0] = 0; /* * Most Linux distributions ship a slightly broken * kernel driver that bonds with the hardware. */ usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); #else fatal("usb_set_configuration failed: %s\n", usb_strerror()); #endif } #endif if (usb_claim_interface(udev, 0) < 0) { fatal("Claim interfaced failed: %s\n", usb_strerror()); } libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; /* * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac * with Venture HC) we get a dev with a valid vendor ID, but no * associated configuration. I was unable to see a single instance * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading * me to think this is some kind of bug in the Venture HC. * * Rather than crash, we at least print * a nastygram. Experiments with retrying various USB ops brought * no joy, so just call fatal and move on. */ if (!dev->config) { fatal("Found USB device with no configuration.\n"); } for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { struct usb_endpoint_descriptor * ep; ep = &dev->config->interface->altsetting->endpoint[i]; switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK case USB_ENDPOINT_TYPE_BULK: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; else gusb_bulk_out_ep = EA(ep->bEndpointAddress); break; case USB_ENDPOINT_TYPE_INTERRUPT: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; break; } } /* * Zero is the configuration endpoint, so if we made it through * that loop without non-zero values for all three, we're hosed. */ if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { lud->product_id = gusb_reset_toggles(); switch (lud->product_id) { // Search for "Venture HC" for more on this siliness.. // It's a case instead of an 'if' becuase I have a // feeling there are more affected models either // on the market or on the way. case 695: break; // Venture HC case 941: break; // Venture HC, Japanese version. case 957: break; // Legend H case 285: break; // GPSMap 276C/4.80 case 402: break; // GPSMap 396C/4.50 case 1095: break; // GPS72H/2.30 default: gusb_syncup(); } return; } fatal("Could not identify endpoints on USB device.\n" "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); }
void raise_usb_error() { rb_raise(cException, usb_strerror()); }
struct usb_dev_handle* LibUsb::OpenAntStick() { struct usb_bus* bus; struct usb_device* dev; struct usb_dev_handle* udev; // for Mac and Linux we do a bus reset on it first... #ifndef WIN32 for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == GARMIN_USB2_VID && dev->descriptor.idProduct == GARMIN_USB2_PID) { if ((udev = usb_open(dev))) { usb_reset(udev); usb_close(udev); } } } } #endif for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == GARMIN_USB2_VID && dev->descriptor.idProduct == GARMIN_USB2_PID) { //Avoid noisy output //qDebug() << "Found a Garmin USB2 ANT+ stick"; if ((udev = usb_open(dev))) { if (dev->descriptor.bNumConfigurations) { if ((intf = usb_find_interface(&dev->config[0])) != NULL) { int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); if (OperatingSystem == LINUX) { // looks like the udev rule has not been implemented qDebug()<<"check permissions on:"<<QString("/dev/bus/usb/%1/%2").arg(bus->dirname).arg(dev->filename); qDebug()<<"did you remember to setup a udev rule for this device?"; } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); if (OperatingSystem != OSX) { // fails on Mac OS X, we don't actually need it anyway rc = usb_set_altinterface(udev, alternate); if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); } return udev; } } usb_close(udev); } } } } return NULL; }
int main(int argc, char **argv) { usb_dev_handle *handle = NULL; const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; char buffer[4]; int cnt, vid, pid, isOn; usb_init(); if(argc < 2){ /* we need at least one argument */ usage(argv[0]); exit(1); } /* compute VID/PID from usbconfig.h so that there is a central source of information */ vid = rawVid[1] * 256 + rawVid[0]; pid = rawPid[1] * 256 + rawPid[0]; /* The following function is in opendevice.c: */ if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){ fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); exit(1); } /* Since we use only control endpoint 0, we don't need to choose a * configuration and interface. Reading device descriptor and setting a * configuration and interface is done through endpoint 0 after all. * However, newer versions of Linux require that we claim an interface * even for endpoint 0. Enable the following code if your operating system * needs it: */ #if 0 int retries = 1, usbConfiguration = 1, usbInterface = 0; if(usb_set_configuration(handle, usbConfiguration) && showWarnings){ fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); } /* now try to claim the interface and detach the kernel HID driver on * Linux and other operating systems which support the call. */ while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){ #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){ fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror()); } #endif } #endif if(strcasecmp(argv[1], "status") == 0){ cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000); if(cnt < 1){ if(cnt < 0){ fprintf(stderr, "USB error: %s\n", usb_strerror()); }else{ fprintf(stderr, "only %d bytes received.\n", cnt); } }else{ printf("LED is %s\n", buffer[0] ? "on" : "off"); } }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){ cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000); if(cnt < 0){ fprintf(stderr, "USB error: %s\n", usb_strerror()); } #if ENABLE_TEST }else if(strcasecmp(argv[1], "test") == 0){ int i; srandomdev(); for(i = 0; i < 50000; i++){ int value = random() & 0xffff, index = random() & 0xffff; int rxValue, rxIndex; if((i+1) % 100 == 0){ fprintf(stderr, "\r%05d", i+1); fflush(stderr); } cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000); if(cnt < 0){ fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror()); break; }else if(cnt != 4){ fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt); break; } rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8); rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8); if(rxValue != value || rxIndex != index){ fprintf(stderr, "\ndata error in iteration %d:\n", i); fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value); fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index); } } fprintf(stderr, "\nTest completed.\n"); #endif /* ENABLE_TEST */ }else{ usage(argv[0]); exit(1); } usb_close(handle); return 0; }
// Open connection to a Tacx Fortius // // The Fortius handlebar controller is an EZ-USB device. This is an // embedded system using an 8051 microcontroller. Firmware must be // downloaded to it once it is connected. This firmware is obviously // copyrighted by Tacx and is not distributed with Golden Cheetah. // Instead we ask the user to tell us where it can be found when they // configure the device. (On Windows platforms the firmware is installed // by the standard Tacx software as c:\windows\system32\FortiusSWPID1942Renum.hex). // // So when we open a Fortius device we need to search for an unitialised // handlebar controller 3651:e6be and upload the firmware using the EzUsb // functions. Once that has completed the controller will represent itself // as 3651:1942. // // Firmware will need to be reloaded if the device is disconnected or the // USB controller is reset after sleep/resume. // // The EZUSB code is found in EzUsb.c, which is essentially the code used // in the 'fxload' command on Linux, some minor changes have been made to the // standard code wrt to logging errors. // // The only function we use is: // int ezusb_load_ram (usb_dev_handle *device, const char *path, int fx2, int stage) // device is a usb device handle // path is the filename of the firmware file // fx2 is non-zero to indicate an fx2 device (we pass 0, since the Fortius is fx) // stage is to control two stage loading, we load in a single stage struct usb_dev_handle* LibUsb::OpenFortius() { struct usb_bus* bus; struct usb_device* dev; struct usb_dev_handle* udev; bool programmed = false; // // Search for an UN-INITIALISED Fortius device // for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == FORTIUS_VID && dev->descriptor.idProduct == FORTIUS_INIT_PID) { if ((udev = usb_open(dev))) { // LOAD THE FIRMWARE ezusb_load_ram (udev, appsettings->value(NULL, FORTIUS_FIRMWARE, "").toString().toLatin1(), 0, 0); } // Now close the connection, our work here is done usb_close(udev); programmed = true; } } } // We need to rescan devices, since once the Fortius has // been programmed it will present itself again with a // different PID. But it takes its time, so we sleep for // 3 seconds. This may be too short on some operating // systems [XXX validate this]. On my Linux host running // a v3 kernel on an AthlonXP 2 seconds is not long enough. // // Given this is only required /the first time/ the Fortius // is connected, it can't be that bad? if (programmed == true) { #ifdef WIN32 Sleep(3000); // windows sleep is in milliseconds #else sleep(3); // do not be tempted to reduce this, it really does take that long! #endif usb_find_busses(); usb_find_devices(); } // // Now search for an INITIALISED Fortius device // for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == FORTIUS_VID && (dev->descriptor.idProduct == FORTIUS_PID || dev->descriptor.idProduct == FORTIUSVR_PID)) { //Avoid noisy output //qDebug() << "Found a Garmin USB2 ANT+ stick"; if ((udev = usb_open(dev))) { if (dev->descriptor.bNumConfigurations) { if ((intf = usb_find_interface(&dev->config[0])) != NULL) { int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); if (OperatingSystem == LINUX) { // looks like the udev rule has not been implemented qDebug()<<"check permissions on:"<<QString("/dev/bus/usb/%1/%2").arg(bus->dirname).arg(dev->filename); qDebug()<<"did you remember to setup a udev rule for this device?"; } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); if (OperatingSystem != OSX) { // fails on Mac OS X, we don't actually need it anyway rc = usb_set_altinterface(udev, alternate); if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); } return udev; } } usb_close(udev); } } } } return NULL; }
int main(int argc, char **argv) { struct usb_vendprod vendprod; struct dfu_if _rt_dif, _dif, *dif = &_dif; int num_devs; int num_ifs; unsigned int transfer_size = 0; enum mode mode = MODE_NONE; struct dfu_status status; int quirks_auto_detect = 1; dfu_quirks manual_quirks; dfu_handle handle; char *filename = NULL; char *alt_name = NULL; /* query alt name if non-NULL */ char *end; int final_reset = 0; int page_size = getpagesize(); int ret; printf("dfu-util - (C) 2007-2008 by OpenMoko Inc.\n" "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); dfu_quirks_clear(&manual_quirks); memset(dif, 0, sizeof(*dif)); usb_init(); //usb_set_debug(255); usb_find_busses(); usb_find_devices(); while (1) { int c, option_index = 0; c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:C:S:RQNq:", opts, &option_index); if (c == -1) break; switch (c) { case 'h': help(); exit(0); break; case 'V': print_version(); exit(0); break; case 'v': verbose = 1; break; case 'l': list_dfu_interfaces(); exit(0); break; case 'd': /* Parse device */ if (parse_vendprod(&vendprod, optarg) < 0) { fprintf(stderr, "unable to parse `%s'\n", optarg); exit(2); } dif->vendor = vendprod.vendor; dif->product = vendprod.product; dif->flags |= (DFU_IFF_VENDOR | DFU_IFF_PRODUCT); break; case 'p': /* Parse device path */ dif->path = optarg; dif->flags |= DFU_IFF_PATH; ret = resolve_device_path(dif); if (ret < 0) { fprintf(stderr, "unable to parse `%s'\n", optarg); exit(2); } if (!ret) { fprintf(stderr, "cannot find `%s'\n", optarg); exit(1); } break; case 'c': /* Configuration */ dif->configuration = atoi(optarg); dif->flags |= DFU_IFF_CONFIG; break; case 'i': /* Interface */ dif->interface = atoi(optarg); dif->flags |= DFU_IFF_IFACE; break; case 'a': /* Interface Alternate Setting */ dif->altsetting = strtoul(optarg, &end, 0); if (*end) alt_name = optarg; dif->flags |= DFU_IFF_ALT; break; case 't': transfer_size = atoi(optarg); break; case 'U': mode = MODE_UPLOAD; filename = optarg; break; case 'D': mode = MODE_DOWNLOAD; filename = optarg; break; case 'C': mode = MODE_COMPARE; /* TODO: verify firmware */ filename = optarg; break; case 'S': filename = optarg; add_file_suffix(filename); exit(0); break; case 'R': final_reset = 1; break; case 'Q': dfu_quirks_print(); exit(0); break; case 'N': quirks_auto_detect = 0; break; case 'q': quirks_auto_detect = 0; dfu_quirk_set(&manual_quirks, atoi(optarg)); break; default: help(); exit(2); } } if (mode == MODE_NONE) { fprintf(stderr, "You need to specify one of -D or -U\n"); help(); exit(2); } if (!filename) { fprintf(stderr, "You need to specify a filename to -D -r -U\n"); help(); exit(2); } dfu_init(&handle, 5000); num_devs = count_dfu_devices(dif); if (num_devs == 0) { fprintf(stderr, "No DFU capable USB device found\n"); exit(1); } else if (num_devs > 1) { /* We cannot safely support more than one DFU capable device * with same vendor/product ID, since during DFU we need to do * a USB bus reset, after which the target device will get a * new address */ fprintf(stderr, "More than one DFU capable USB device found, " "you might try `--list' and then disconnect all but one " "device\n"); exit(3); } if (!get_first_dfu_device(dif)) exit(3); /* We have exactly one device. It's usb_device is now in dif->dev */ printf("Opening USB Device 0x%04x:0x%04x...\n", dif->vendor, dif->product); dif->dev_handle = usb_open(dif->dev); if (!dif->dev_handle) { fprintf(stderr, "Cannot open device: %s\n", usb_strerror()); exit(1); } /* try to find first DFU interface of device */ memcpy(&_rt_dif, dif, sizeof(_rt_dif)); if (!get_first_dfu_if(&_rt_dif)) exit(1); handle.device = _rt_dif.dev_handle; handle.interface = _rt_dif.interface; /* automatic quirk detection */ if(quirks_auto_detect) { /* TODO: let the detection be influenced by bcdDFU, bcdDevice */ handle.quirk_flags = dfu_quirks_detect(0, dif->vendor, dif->product, 0); } /* merge with manual quirks */ dfu_quirks_insert(&handle.quirk_flags, &manual_quirks); if(!dfu_quirks_is_empty(&handle.quirk_flags)) { printf("Selected quirks: "); dfu_quirks_print_set(&handle.quirk_flags); printf("\n"); } if (!_rt_dif.flags & DFU_IFF_DFU) { /* In the 'first round' during runtime mode, there can only be one * DFU Interface descriptor according to the DFU Spec. */ /* FIXME: check if the selected device really has only one */ printf("Claiming USB DFU Runtime Interface %d...\n", _rt_dif.interface); if (usb_claim_interface(_rt_dif.dev_handle, _rt_dif.interface) < 0) { fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); exit(1); } /* DFU 1.0, Table 4.1: in runtime-mode, alternate interface setting must be zero. therefore we can assume, '0' is correct. the reason we use usb_set_altinterface() here: switch devices to the interface set using usb_claim_interface() above - for some reason this isn't done there. is the only libusb API which issues the SET_INTERFACE USB standard request is usb_set_altinterface() */ if (usb_set_altinterface(_rt_dif.dev_handle, 0) < 0) { fprintf(stderr, "Cannot set alternate interface %d: %s\n", 0, usb_strerror()); exit(1); } printf("Determining device state: "); int state = -1; if ( (state = dfu_get_state(&handle)) < 0) { exit(1); } printf("state = %s\n", dfu_state_to_string(state)); dfu_sm_set_state_unchecked(&handle, state); printf("Determining device status: "); if (dfu_get_status(&handle, &status ) < 0) { exit(1); } printf("state = %s, status = %d = \"%s\"\n", dfu_state_to_string(status.bState), status.bStatus, dfu_status_to_string(status.bStatus) ); switch (status.bState) { case DFU_STATE_appIDLE: case DFU_STATE_appDETACH: printf("Device really in Runtime Mode, send DFU " "detach request...\n"); if(status.bState == DFU_STATE_appDETACH) { printf("Device is already in state %s, skipping DFU_DETACH request\n", dfu_state_to_string(status.bState)); } else { if (dfu_detach(&handle, 1000) < 0) { exit(1); break; } } /* handle bitWillDetach (DFU 1.1) */ if(handle.dfu_ver == DFU_VERSION_1_1 && handle.func_dfu.bmAttributes & USB_DFU_WILL_DETACH) { /* TODO: test this with a real DFU 1.1 device */ printf("Waiting for USB device's own detach (bitWillDetach=1)...\n"); dfu_sm_set_state_checked(&handle, DFU_STATE_dfuIDLE); } else { printf("Resetting USB...\n"); ret = dfu_usb_reset(&handle); if (ret < 0 && ret != -ENODEV) { /* do nothing; error msg is output in dfu_usb_reset. */ } } sleep(2); break; case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); if (dfu_clear_status(&handle) < 0) { exit(1); break; } break; default: fprintf(stderr, "WARNING: Runtime device already " "in DFU state ?!?\n"); goto dfustate; break; } /* now we need to re-scan the bus and locate our device */ if (usb_find_devices() < 2) printf("not at least 2 device changes found ?!?\n"); if (dif->flags & DFU_IFF_PATH) { ret = resolve_device_path(dif); if (ret < 0) { fprintf(stderr, "internal error: cannot re-parse `%s'\n", dif->path); abort(); } if (!ret) { fprintf(stderr, "Can't resolve path after RESET?\n"); exit(1); } } num_devs = count_dfu_devices(dif); if (num_devs == 0) { fprintf(stderr, "Lost device after RESET?\n"); exit(1); } else if (num_devs > 1) { fprintf(stderr, "More than one DFU capable USB " "device found, you might try `--list' and " "then disconnect all but one device\n"); exit(1); } if (!get_first_dfu_device(dif)) exit(3); printf("Opening USB Device...\n"); dif->dev_handle = usb_open(dif->dev); if (!dif->dev_handle) { fprintf(stderr, "Cannot open device: %s\n", usb_strerror()); exit(1); } } else { /* we're already in DFU mode, so we can skip the detach/reset * procedure */ } dfustate: if (alt_name) { int n; n = find_dfu_if(dif->dev, &alt_by_name, alt_name); if (!n) { fprintf(stderr, "No such Alternate Setting: \"%s\"\n", alt_name); exit(1); } if (n < 0) { fprintf(stderr, "Error %d in name lookup\n", n); exit(1); } dif->altsetting = n-1; } print_dfu_if(dif, NULL); num_ifs = count_dfu_interfaces(dif->dev); if (num_ifs < 0) { fprintf(stderr, "No DFU Interface after RESET?!?\n"); exit(1); } else if (num_ifs == 1) { if (!get_first_dfu_if(dif)) { fprintf(stderr, "Can't find the single available " "DFU IF\n"); exit(1); } } else if (num_ifs > 1 && (!dif->flags) & (DFU_IFF_IFACE|DFU_IFF_ALT)) { fprintf(stderr, "We have %u DFU Interfaces/Altsettings, " "you have to specify one via --intf / --alt options\n", num_ifs); exit(1); } #if 0 printf("Setting Configuration %u...\n", dif->configuration); if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) { fprintf(stderr, "Cannot set configuration: %s\n", usb_strerror()); exit(1); } #endif printf("Claiming USB DFU Interface...\n"); if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) { fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); exit(1); } printf("Setting Alternate Setting ...\n"); if (usb_set_altinterface(dif->dev_handle, dif->altsetting) < 0) { fprintf(stderr, "Cannot set alternate interface: %s\n", usb_strerror()); exit(1); } /* update the handle to point to the dfu-mode descriptor */ handle.device = dif->dev_handle; handle.interface = dif->interface; status_again: printf("Determining device status: "); if (dfu_get_status(&handle, &status ) < 0) { fprintf(stderr, "error get_status: %s\n", usb_strerror()); exit(1); } printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus); /* force the statemachine into current status */ dfu_sm_set_state_unchecked(&handle, status.bState); switch (status.bState) { case DFU_STATE_appIDLE: case DFU_STATE_appDETACH: fprintf(stderr, "Device still in Runtime Mode!\n"); exit(1); break; case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); if (dfu_clear_status(&handle) < 0) { fprintf(stderr, "error clear_status: %s\n", usb_strerror()); exit(1); } goto status_again; break; case DFU_STATE_dfuDNLOAD_IDLE: case DFU_STATE_dfuUPLOAD_IDLE: printf("aborting previous incomplete transfer\n"); if (dfu_abort(&handle) < 0) { fprintf(stderr, "can't send DFU_ABORT: %s\n", usb_strerror()); exit(1); } goto status_again; break; case DFU_STATE_dfuIDLE: printf("dfuIDLE, continuing\n"); break; } /* Obtain DFU functional descriptor */ ret = usb_get_descriptor(dif->dev_handle, 0x21, dif->interface, &(handle.func_dfu), sizeof(handle.func_dfu)); if (ret < 0) { fprintf(stderr, "Error obtaining DFU functional " "descriptor: %s\n", usb_strerror()); if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_IGNORE_INVALID_FUNCTIONAL_DESCRIPTOR)) { handle.func_dfu.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_MANIFEST_TOL; handle.func_dfu.wTransferSize = cpu_to_le16(transfer_size); if(!transfer_size) transfer_size = page_size; handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0; fprintf(stderr, " Still, try to continue with default flags/manual settings.\n"); } else { exit(1); } } else { transfer_size = le16_to_cpu(handle.func_dfu.wTransferSize); } /* why is this limited to page_size, a host-dependent value? (sgiessl) */ if (transfer_size > page_size) transfer_size = page_size; /* quirk overwriting DFU version */ if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_0)) { handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0; } else if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_1)) { handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_1; } /* read DFU version */ switch(handle.func_dfu.bcdDFUVersion) { case USB_DFU_VER_1_1: handle.dfu_ver = DFU_VERSION_1_1; break; default: printf("WARNING: device specifies unknown DFU version 0x%.2x, defaulting to DFU 1.0\n", handle.func_dfu.bcdDFUVersion); /* fall through intended */ case USB_DFU_VER_1_0: handle.dfu_ver = DFU_VERSION_1_0; break; } printf("Transfer Size = 0x%04x\n", transfer_size); printf("Device functional descriptor: %s\n", dfu_func_descriptor_to_string(&handle.func_dfu)); if (DFU_STATUS_OK != status.bStatus ) { printf("WARNING: DFU Status: '%s'\n", dfu_status_to_string(status.bStatus)); /* Clear our status & try again. */ dfu_clear_status(&handle); dfu_get_status(&handle, &status); if (DFU_STATUS_OK != status.bStatus) { fprintf(stderr, "Error: %d\n", status.bStatus); exit(1); } } switch (mode) { case MODE_UPLOAD: if (sam7dfu_do_upload(&handle, transfer_size, filename) < 0) exit(1); break; case MODE_DOWNLOAD: if (sam7dfu_do_dnload(&handle, transfer_size, filename) < 0) exit(1); break; default: fprintf(stderr, "Unsupported mode: %u\n", mode); exit(1); } if (final_reset) { if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET)) { /* DFU_DETACH is only allowed in appIDLE, so this is non-standard (as of DFU 1.0, and 1.1). */ printf("Initiating reset by sending DFU_DETACH (QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET)\n"); if (dfu_detach(&handle, 1000) < 0) { fprintf(stderr, "can't detach: %s\n", usb_strerror()); } } printf("Resetting USB to switch back to runtime mode\n"); ret = usb_reset(dif->dev_handle); if (ret < 0 && ret != -ENODEV) { fprintf(stderr, "error resetting after download: %s\n", usb_strerror()); } } exit(0); }
int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) { struct usb_device *found = NULL; struct usb_device *dev; struct usb_bus *bus; /* At last, we reach out through the USB bus to the part. There are three * ways to specify the part: by USB address, by USB vendor and product id, * and by part name. To specify the part by USB address, the user specifies * a port parameter in the form "usb:BUS:DEV" (see dfu_open()). To specify * the part by vendor and product, the user must specify a usbvid and usbpid * in the configuration file. Finally, if the user specifies the part only, * we use the default vendor and product id. */ if (pid == 0 && dfu->dev_name == NULL) { fprintf(stderr, "%s: Error: No DFU support for part; " "specify PID in config or USB address (via -P) to override.\n", progname); return -1; } /* Scan through all the devices for the part. The matching rules are: * * 1. If the user specified a USB bus name, it must match. * 2. If the user specified a USB device name, it must match. * 3. If the user didn't specify a USB device name and specified a vendor * id, the vendor id must match. * 4. If the user didn't specify a USB device name and specified a product * id, the product id must match. */ for (bus = usb_busses; !found && bus != NULL; bus = bus->next) { for (dev = bus->devices; !found && dev != NULL; dev = dev->next) { if (dfu->bus_name != NULL && strcmp(bus->dirname, dfu->bus_name)) continue; if (dfu->dev_name != NULL) { if (strcmp(dev->filename, dfu->dev_name)) continue; } else if (vid != dev->descriptor.idVendor) continue; else if (pid != 0 && pid != dev->descriptor.idProduct) continue; found = dev; } } if (found == NULL) { /* We could try to be more informative here. For example, we could report * why the match failed, and if we came across another DFU-capable part. */ fprintf(stderr, "%s: Error: No matching USB device found\n", progname); return -1; } if(verbose) fprintf(stderr, "%s: Found VID=0x%04x PID=0x%04x at %s:%s\n", progname, found->descriptor.idVendor, found->descriptor.idProduct, found->bus->dirname, found->filename); dfu->dev_handle = usb_open(found); if (dfu->dev_handle == NULL) { fprintf(stderr, "%s: Error: USB device at %s:%s: %s\n", progname, found->bus->dirname, found->filename, usb_strerror()); return -1; } /* Save device, configuration, interface and endpoint descriptors. */ memcpy(&dfu->dev_desc, &found->descriptor, sizeof(dfu->dev_desc)); memcpy(&dfu->conf_desc, found->config, sizeof(dfu->conf_desc)); dfu->conf_desc.interface = NULL; memcpy(&dfu->intf_desc, found->config->interface->altsetting, sizeof(dfu->intf_desc)); dfu->intf_desc.endpoint = &dfu->endp_desc; if (found->config->interface->altsetting->endpoint != 0) memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint, sizeof(dfu->endp_desc)); /* Get strings. */ dfu->manf_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iManufacturer); dfu->prod_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iProduct); dfu->serno_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iSerialNumber); return 0; }
int main(int argc, char **argv) { int ec = 0; struct usb_dev_handle *dev = initPanel(0); if(dev == NULL) { fprintf(stderr, "ERROR: Couldn't initialize USB button!\n"); return 2; } if(argc == 2){ unsigned char cmd = 64; if (!strcmp("close", argv[1])) { cmd = 96; //alternatively: 224 } else if(!strcmp("open", argv[1])) { cmd = 80; //alternatively: 208 } else { printf("Please specify a command (open/close)\n"); return 1; } if((ec = usb_interrupt_write(dev, 0x02, &cmd, 1, 10)) < 0){ printf("Error writing to USB device (%d): %s\n", ec, usb_strerror()); return 2; } }else if(argc == 1){ unsigned char data; unsigned char last = 0; unsigned int state = 0; fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NONBLOCK); while(1){ if(!usb_interrupt_read(dev, 0x01, &data, 1, 1)){ //printf("%x\n", data); unsigned char c = 64; if(last != data){ if((data & 0xF) == 5) printf("button pressed\n"); if(data & 0x2) printf("open button pressed\n"); if(data == 0x68) printf("opening\n"); if(data == 0x74) printf("closing\n"); if(data == 0x44 && last == 0x60) printf("open\n"); if(data == 0x58) printf("closed\n"); last = data; } if((ec = usb_interrupt_write(dev, 0x02, &c, 1, 1)) < 0){ printf("Error writing to USB device (%d): %s\n", ec, usb_strerror()); return 2; } } int len = read(0, &data, 1); if(len > 0){ char cmd; if(state == 0){ state = 1; if(data == 'c'){ cmd = 96; }else if(data == 'o'){ cmd = 80; } if((ec = usb_interrupt_write(dev, 0x02, &cmd, 1, 1)) < 0){ printf("Error writing to USB device (%d): %s\n", ec, usb_strerror()); return 2; } }else{ if(data == '\n'){ state = 0; } } } usleep(100000); } }else{ printf("Invalid argument. Specify open/close to open/close or nothing to listen.\n"); return 1; } usb_close(dev); return 0; }
struct usb_dev_handle* LibUsb::OpenAntStick() { struct usb_bus* bus; struct usb_device* dev; struct usb_dev_handle* udev; for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == USB_ST_VID && dev->descriptor.idProduct == USB_STLINK_PID) { qCritical() << "Found ST an Link V1, this one is not supported!"; return NULL; } else if (dev->descriptor.idVendor == USB_ST_VID && dev->descriptor.idProduct == USB_STLINKv2_PID) { //Avoid noisy output qInformal() << "Found an ST Link V2."; if ((udev = usb_open(dev))) { qInformal() << "Opening device..."; if (dev->descriptor.bNumConfigurations) { if ((intf = usb_find_interface(&dev->config[0])) != NULL) { // Loading first config. qint32 rc = usb_set_configuration(udev, 1); if (rc < 0) { qCritical()<<"usb_set_configuration Error: "<< usb_strerror(); #ifdef __linux__ // looks like the udev rule has not been implemented qCritical()<<"Check permissions on:"<<QString("/dev/bus/usb/%1/%2").arg(bus->dirname).arg(dev->filename); qCritical()<<"Did you remember to setup a udev rule for this device?"; qCritical()<<"Copy file 49-stlinkv2.rules to /etc/udev/rules.d/ to enable access."; return NULL; #endif } rc = usb_claim_interface(udev, this->interface); if (rc < 0) qCritical()<<"usb_claim_interface Error: "<< usb_strerror(); //#ifndef Q_OS_MAC // // fails on Mac OS X, we don't actually need it anyway // rc = usb_set_altinterface(udev, alternate); // if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); //#endif qInformal() << "Device Open."; return udev; } else qCritical() << "Could not load interface configuration."; } usb_close(udev); } } } } qCritical() << "Found nothing..."; return NULL; }
int main (int argc, char *argv[]) { int16_t calibration_index = 0x0; int16_t integral = 0xffff; int32_t xyz[3]; int8_t led = 0x03; int8_t multiplier = 0x03; int rc; int retval = 0; struct usb_device *dev = NULL; usb_dev_handle *handle = NULL; /* setup usb */ usb_init(); usb_find_busses(); usb_find_devices(); /* find the first colorhug */ dev = find_colorhug_device (); if (dev == NULL) { printf ("Cannot find device!\n"); retval = 1; goto out; } /* open device */ handle = usb_open (dev); if (handle == NULL) { printf ("Cannot open device!\n"); retval = 1; goto out; } rc = usb_set_configuration (handle, 1); if (rc < 0) printf ("Failed to set configuration, got %s\n", usb_strerror ()); /* this is not fatal, as we might have already detached the * hid driver */ rc = usb_detach_kernel_driver_np(handle, 0); if (rc < 0) printf ("Failed to detach kernel driver, got %s\n", usb_strerror ()); /* claim interface */ usb_claim_interface (handle, 0); printf ("device ready!\n"); /* turn on LEDs */ rc = write_command (handle, 0x0e, /* cmd */ (char *) &led, /* in buffer */ 1, /* in buffer size */ NULL, /* out buffer */ 0); /* out buffer size */ if (rc < 0) { printf ("Failed to turn on LEDs\n"); retval = 1; goto out; } /* set the multiplier to 100% */ rc = write_command (handle, 0x04, /* cmd */ &multiplier, /* in buffer */ 1, /* in buffer size */ NULL, /* out buffer */ 0); /* out buffer size */ if (rc < 0) { printf ("Failed to set multiplier\n"); retval = 1; goto out; } /* set the integral time to maximum */ rc = write_command (handle, 0x04, /* cmd */ (char *) &integral, /* in buffer */ 2, /* in buffer size */ NULL, /* out buffer */ 0); /* out buffer size */ if (rc < 0) { printf ("Failed to set integral\n"); retval = 1; goto out; } /* take reading with default matrix for LCD */ memset (xyz, 0x00, 3*4); rc = write_command (handle, 0x23, /* cmd */ (char *) &calibration_index, /* in buffer */ 2, /* in buffer size */ (char *) xyz, /* out buffer */ 3*4); /* out buffer size */ if (rc < 0) { printf ("Failed to take reading\n"); retval = 1; goto out; } printf ("X: %lf\n", (double) xyz[0] / (double) 0xffff); printf ("Y: %lf\n", (double) xyz[1] / (double) 0xffff); printf ("Z: %lf\n", (double) xyz[2] / (double) 0xffff); out: if (handle != NULL) { usb_release_interface (handle, 1); usb_close (handle); } return retval; }
int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; int errorCode = USBOPEN_ERR_NOTFOUND; usb_find_busses(); usb_find_devices(); for(bus = usb_get_busses(); bus; bus = bus->next){ for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ if((vendorID == 0 || dev->descriptor.idVendor == vendorID) && (productID == 0 || dev->descriptor.idProduct == productID)){ char vendor[256], product[256], serial[256]; int len; handle = usb_open(dev); /* we need to open the device in order to query strings */ if(!handle){ errorCode = USBOPEN_ERR_ACCESS; if(warningsFp != NULL) fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); continue; } /* now check whether the names match: */ len = vendor[0] = 0; if(dev->descriptor.iManufacturer > 0){ len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); } if(len < 0){ errorCode = USBOPEN_ERR_ACCESS; if(warningsFp != NULL) fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* printf("seen device from vendor ->%s<-\n", vendor); */ if(shellStyleMatch(vendor, vendorNamePattern)){ len = product[0] = 0; if(dev->descriptor.iProduct > 0){ len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); } if(len < 0){ errorCode = USBOPEN_ERR_ACCESS; if(warningsFp != NULL) fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* printf("seen product ->%s<-\n", product); */ if(shellStyleMatch(product, productNamePattern)){ len = serial[0] = 0; if(dev->descriptor.iSerialNumber > 0){ len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); } if(len < 0){ errorCode = USBOPEN_ERR_ACCESS; if(warningsFp != NULL) fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); } if(shellStyleMatch(serial, serialNamePattern)){ if(printMatchingDevicesFp != NULL){ if(serial[0] == 0){ fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); }else{ fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); } }else{ break; } } } } } } usb_close(handle); handle = NULL; } } if(handle) /* we have found a deice */ break; } if(handle != NULL){ errorCode = 0; *device = handle; } if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ errorCode = 0; return errorCode; }
/** * * Programs the bootloader. This is done starting at 16bit page 0x0000 * each page is 128bytes. After each page if flashed, the address is incremented * page PAZE_SIZE, and the next page begins. * After each page is flashed, it is read and verified. If a page fails verification, it is reflashed * */ int OSIF_bootloader_init(int adapter, int servo, char * filename) { int i; int n=2; int page_count=0; int reg_addr=0; int memory[65536]; unsigned char page[MAX_BOOTLDR_SIZE][PAGE_SIZE+10]; usb_dev_handle *handle; handle = get_adapter_handle(adapter); int page_fail_cnt=0; unsigned char verbuf[PAGE_SIZE]; char buf[255]; int max_addr=0; // load file into memory array if (load_file(filename, memory, &max_addr) <0) { printf("Failed to load file %s. Check path.\n", filename); return -1; } max_addr+=20; // break into 128 byte pages for (i=0; i< max_addr+1; i++) { //copy the temporary page into the page array page[page_count][n]=memory[i]; n++; if (n>PAGE_SIZE+1) { //start at offset 2 n=2; page_count++; } } printf( "page count %d\n", page_count); //for each page, write to the servo, and verify for (i=0; i<=page_count; i++) { //convert to uint16 page[i][0]=(reg_addr>>8)&0x00FF; page[i][1]=(reg_addr)&0x00FF; //print the data to the log. fprintf(stderr, "page %x %x\n", page[i][0], page[i][1] ); if(usb_control_msg(handle, USB_CTRL_OUT, CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, 0, servo, page[i], PAGE_SIZE+2, 1000) < 1) { fprintf(stderr, "USB error: %s\n", usb_strerror()); return -1; } //assign some memory for the verify memcpy( &verbuf, &page[i][2], PAGE_SIZE ); //only verify from page 2. lower portion is the bootloader if ( i>2) { if ( OSIF_verify_page(adapter, servo, page[i], verbuf )>0) { printf("verify OK\n"); page_fail_cnt=0; } else { //page bad if (page_fail_cnt==2) { printf("Verify FAIL. Page sent twice. ABORTING\n"); return -1; } printf("Verify FAIL. Resending page\n"); i--; page_fail_cnt++; continue; } } reg_addr+=(PAGE_SIZE); } OSIF_bootloader_reboot(adapter); return 1; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,const mxArray *prhs[]) { //lhs: left-hand-side, means outputs. rhs: right-hand-side, means inputs. const mwSize *dims1, *dims2; mwSize ndim1, ndim2; usb_dev_handle *hdl; int configuration, result; //check the number of input and output if (nrhs != 2) { mexErrMsgTxt("result = libusb_usb_set_configuration(usb_dev_hdl, configuration): need 2 inputs, no more no less."); } if (nlhs > 1) { mexErrMsgTxt("result = libusb_usb_set_configuration(usb_dev_hdl, configuration): only 1 output, no more no less."); } //check if the inputs are scalar ndim1 = mxGetNumberOfDimensions(prhs[0]); dims1 = mxGetDimensions(prhs[0]); ndim2 = mxGetNumberOfDimensions(prhs[1]); dims2 = mxGetDimensions(prhs[1]); if (ndim1 != 2 || ndim2 != 2 || dims1[0]*dims1[1] > 1 || dims2[0]*dims2[1] > 1) { mexErrMsgTxt("result = libusb_usb_set_configuration(usb_dev_hdl, configuration) input should be scalar"); } if(mxGetClassID(prhs[0]) != mxUINT64_CLASS) { mexErrMsgTxt("Function first input should be unsigned 64 bit int: result = libusb_usb_set_configuration(usb_dev_hdl, configuration)"); } if(mxGetClassID(prhs[1]) != mxINT32_CLASS) { mexErrMsgTxt("Function second input should be 32 bit int: result = libusb_usb_set_configuration(usb_dev_hdl, configuration)"); } //usb_init(); /* initialize the library */ //usb_find_busses(); /* find all busses */ //usb_find_devices(); /* find all connected devices */ hdl = (usb_dev_handle*)(*(U64*)(mxGetData(prhs[0]))); configuration = *(int*)(mxGetData(prhs[1])); plhs[0] = mxCreateNumericArray(2, dims1, mxINT32_CLASS, mxREAL); if(hdl == NULL) { mexPrintf("Device handler is null and cannot set configuration.\r\n"); *(int*)mxGetData(plhs[0]) = -1; } else { result = usb_set_configuration(hdl,configuration); if(result < 0) mexPrintf("Error when setting device 0x%x, configuration: %d, return value: %d.\r\n Error string: %s\r\n",hdl, configuration, result, usb_strerror()); else mexPrintf("Device 0x%x configuration %d set successfully. return value: %d.\r\n",hdl,configuration,result); *(int*)mxGetData(plhs[0]) = result; } }
static int krauler_command(const char *cmd, char *buf, size_t buflen) { /* * Still not implemented: * 0x6 T<n> (don't know how to pass the parameter) * 0x68 and 0x69 both cause shutdown after an undefined interval */ const struct { const char *str; /* Megatec command */ const int index; /* Krauler string index for this command */ const char prefix; /* character to replace the first byte in reply */ } command[] = { { "Q1\r", 0x03, '(' }, { "F\r", 0x0d, '#' }, { "I\r", 0x0c, '#' }, { "T\r", 0x04, '\r' }, { "TL\r", 0x05, '\r' }, { "Q\r", 0x07, '\r' }, { "C\r", 0x0b, '\r' }, { "CT\r", 0x0b, '\r' }, { NULL } }; int i; upsdebugx(3, "send: %.*s", (int)strcspn(cmd, "\r"), cmd); for (i = 0; command[i].str; i++) { int retry; if (strcmp(cmd, command[i].str)) { continue; } for (retry = 0; retry < 10; retry++) { int ret; if (langid_fix != -1) { /* Apply langid_fix value */ ret = usb_get_string(udev, command[i].index, langid_fix, buf, buflen); } else { ret = usb_get_string_simple(udev, command[i].index, buf, buflen); } if (ret <= 0) { upsdebugx(3, "read: %s", ret ? usb_strerror() : "timeout"); return ret; } /* this may serve in the future */ upsdebugx(1, "received %d (%d)", ret, buf[0]); if (langid_fix != -1) { /* Limit this check, at least for now */ /* Invalid receive size - message corrupted */ if (ret != buf[0]) { upsdebugx(1, "size mismatch: %d / %d", ret, buf[0]); continue; } /* Simple unicode -> ASCII inplace conversion * FIXME: this code is at least shared with mge-shut/libshut * Create a common function? */ unsigned int di, si, size = buf[0]; for (di = 0, si = 2; si < size; si += 2) { if (di >= (buflen - 1)) break; if (buf[si + 1]) /* high byte */ buf[di++] = '?'; else buf[di++] = buf[si]; } buf[di] = 0; ret = di; } /* "UPS No Ack" has a special meaning */ if (!strcasecmp(buf, "UPS No Ack")) { upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); continue; } /* Replace the first byte of what we received with the correct one */ buf[0] = command[i].prefix; upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); return ret; } return 0; } /* echo the unknown command back */ upsdebugx(3, "read: %.*s", (int)strcspn(cmd, "\r"), cmd); return snprintf(buf, buflen, "%s", cmd); }
int main(int argc, char **argv) { usb_dev_handle *handle; unsigned char buffer[8], prev= 0; int vid, pid; const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; int i, nBytes; int error_count = 0, packet_count = 0; int temp; usb_init(); for(i=1;i<argc;i++){ if(strcmp(argv[i], "-f") == 0){ filename = getOptionArg(&i, argc, argv); }else{ fprintf(stderr, "option \"%s\" not recognized.\n", argv[i]); usage(argv[0]); exit(1); } } /* compute VID/PID from usbconfig.h so that there is a central source of information */ vid = rawVid[1]*256 + rawVid[0]; pid = rawPid[1]*256 + rawPid[0]; restart: /* we jump back here if an error occurred */ printf("\nWaiting for device..."); /* The following function is in opendevice.c: */ if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){ fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); exit(1); } printf("Device detected\n"); if(usb_set_configuration(handle, 1) < 0){ printf("error setting USB configuration: %s\n", usb_strerror()); } if(usb_claim_interface(handle, 0) < 0){ printf("error setting USB interface: %s\n", usb_strerror()); } signalReopenFile(1); /* open file */ for(;;){ /* wait for interrupt, set timeout to more than a week */ nBytes = usb_interrupt_read(handle, USB_ENDPOINT_IN | 1 , (char *)buffer, sizeof(buffer), 700000 * 1000); if(nBytes < 0){ printf("error in USB interrupt read: %s\n", usb_strerror()); goto usbErrorOccurred; } if(nBytes < sizeof(buffer)) { printf("data format error, only %d bytes received (%d expected)\n", nBytes, sizeof(buffer)); } else { packet_count++; temp = (int16_t)((buffer[1] << 8)|buffer[2]); printf("temp = %.3f\n", (float)temp/340.0 + 36.53); if((packet_count > 1) && (buffer[0] != (unsigned char)(prev + 1)) ) { error_count++; } prev = buffer[0]; } } usbErrorOccurred: usb_close(handle); sleep(5); goto restart; return 0; }
const char *_ykusb_strerror() { return usb_strerror(); }
Xbox360Controller::Xbox360Controller(libusb_device* dev, bool chatpad, bool chatpad_no_init, bool chatpad_debug, bool headset, bool headset_debug, const std::string& headset_dump, const std::string& headset_play, bool try_detach) : USBController(dev), dev_type(), endpoint_in(1), endpoint_out(2), m_chatpad(), m_headset(), m_rumble_left(0), m_rumble_right(0) { // find endpoints endpoint_in = usb_find_ep(LIBUSB_ENDPOINT_IN, LIBUSB_CLASS_VENDOR_SPEC, 93, 1); endpoint_out = usb_find_ep(LIBUSB_ENDPOINT_OUT, LIBUSB_CLASS_VENDOR_SPEC, 93, 1); log_debug("EP(IN): " << endpoint_in); log_debug("EP(OUT): " << endpoint_out); usb_claim_interface(0, try_detach); usb_submit_read(endpoint_in, 32); // create chatpad if (chatpad) { libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(dev, &desc); if (ret != LIBUSB_SUCCESS) { raise_exception(std::runtime_error, "libusb_get_config_descriptor() failed: " << usb_strerror(ret)); } else { m_chatpad.reset(new Chatpad(m_handle, desc.bcdDevice, chatpad_no_init, chatpad_debug)); } } // create headset if (headset) { m_headset.reset(new Headset(m_handle, headset_debug)); if (!headset_play.empty()) { m_headset->play_file(headset_play); } if (!headset_dump.empty()) { m_headset->record_file(headset_dump); } } }
void Xboxdrv::run_list_controller() { int ret = libusb_init(NULL); if (ret != LIBUSB_SUCCESS) { raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret)); } libusb_device** list; ssize_t num_devices = libusb_get_device_list(NULL, &list); int id = 0; std::cout << " id | wid | idVendor | idProduct | Name" << std::endl; std::cout << "----+-----+----------+-----------+--------------------------------------" << std::endl; for(ssize_t dev_it = 0; dev_it < num_devices; ++dev_it) { libusb_device* dev = list[dev_it]; libusb_device_descriptor desc; // FIXME: we silently ignore failures if (libusb_get_device_descriptor(dev, &desc) == LIBUSB_SUCCESS) { for(int i = 0; i < xpad_devices_count; ++i) { if (desc.idVendor == xpad_devices[i].idVendor && desc.idProduct == xpad_devices[i].idProduct) { if (xpad_devices[i].type == GAMEPAD_XBOX360_WIRELESS) { for(int wid = 0; wid < 4; ++wid) { std::cout << boost::format(" %2d | %2d | 0x%04x | 0x%04x | %s (Port: %s)") % id % wid % int(xpad_devices[i].idVendor) % int(xpad_devices[i].idProduct) % xpad_devices[i].name % wid << std::endl; } } else { std::cout << boost::format(" %2d | %2d | 0x%04x | 0x%04x | %s") % id % 0 % int(xpad_devices[i].idVendor) % int(xpad_devices[i].idProduct) % xpad_devices[i].name << std::endl; } id += 1; break; } } } } if (id == 0) std::cout << "\nno controller detected" << std::endl; libusb_free_device_list(list, 1 /* unref_devices */); }
int main(void) { struct usb_device *dev = NULL; usb_dev_handle *devh = NULL; bool is_detached = false; bool is_claimed = false; usb_init(); signal(SIGINT, dummy_sigint_handler); signal(SIGTERM, dummy_sigint_handler); signal(SIGHUP, dummy_sigint_handler); signal(SIGUSR1, dummy_sigint_handler); signal(SIGUSR2, dummy_sigint_handler); while (dummy_is_running) { const int read_buf_size = 32; char read_buf[read_buf_size]; int read_size; usleep(DUMMY_LOOP_INTERVAL); usb_find_busses(); usb_find_devices(); if (!dev) { dev = dummy_find_smartboard(); continue; } if (!devh) { devh = usb_open(dev); continue; } if (!is_detached) { const int driver_name_size = 256; char driver_name[driver_name_size]; /* Assume the driver is detached if the driver's * name cannot be found. */ is_detached = usb_get_driver_np(devh, DUMMY_SB_IFACE, driver_name, driver_name_size); is_detached = is_detached || !usb_detach_kernel_driver_np(devh, DUMMY_SB_IFACE); if (!is_detached) fprintf(stderr, "error: libusb: %s\n", usb_strerror()); continue; } if (!is_claimed) { is_claimed = !usb_claim_interface(devh, DUMMY_SB_IFACE); if (!is_claimed) fprintf(stderr, "error: libusb: %s\n", usb_strerror()); continue; } do { read_size = usb_interrupt_read(devh, DUMMY_SB_EP_READ, read_buf, read_buf_size, DUMMY_SB_TIMEOUT_READ); if (read_size == -ETIMEDOUT) { break; } else if (read_size < 0) { fprintf(stderr, "error: libusb: %d %s\n", read_size, usb_strerror()); break; } else { char *hexstr; hexstr = dummy_aget_hexstr(read_buf, read_size); printf("IN: %s\n", hexstr); free(hexstr); } } while (read_size >= 0); } if (devh && is_claimed && usb_release_interface(devh, DUMMY_SB_IFACE)) fprintf(stderr, "error: libusb: %s\n", usb_strerror()); if (devh && usb_close(devh)) fprintf(stderr, "error: libusb: %s\n", usb_strerror()); printf("GracefulShutdown™!\n"); return 0; }
int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; int errorCode = USBOPEN_ERR_NOTFOUND; static int didUsbInit = 0; if(!didUsbInit){ usb_init(); didUsbInit = 1; } usb_find_busses(); usb_find_devices(); 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){ char string[256]; int len; handle = usb_open(dev); /* we need to open the device in order to query strings */ if(!handle){ errorCode = USBOPEN_ERR_ACCESS; fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); continue; } if(vendorName == NULL && productName == NULL){ /* name does not matter */ break; } /* now check whether the names match: */ len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string)); if(len < 0){ errorCode = USBOPEN_ERR_IO; fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ if(strcmp(string, vendorName) == 0){ len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string)); if(len < 0){ errorCode = USBOPEN_ERR_IO; fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); }else{ errorCode = USBOPEN_ERR_NOTFOUND; /* fprintf(stderr, "seen product ->%s<-\n", string); */ if(strcmp(string, productName) == 0) break; } } } usb_close(handle); handle = NULL; } } if(handle) break; } if(handle != NULL){ errorCode = 0; *device = (void *)handle; usesReportIDs = _usesReportIDs; } return errorCode; }
bool Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout) { uint8_t data[32]; int ret = 0; if (read_thread.get()) { ret = read_thread->read(data, sizeof(data), timeout); } else { ret = usb_interrupt_read(handle, endpoint_in, reinterpret_cast<char*>(data), sizeof(data), timeout); } if (ret == -ETIMEDOUT) { return false; } else if (ret < 0) { // Error std::ostringstream str; str << "Xbox360Controller: USBError: " << ret << "\n" << usb_strerror(); throw std::runtime_error(str.str()); } else if (ret == 0) { if (verbose) { std::cout << "zero length read" << std::endl; // happens with the Xbox360 controller every now and then, just // ignore, seems harmless, so just ignore } } else if (ret == 3 && data[0] == 0x01 && data[1] == 0x03) { if (verbose) { std::cout << "Xbox360Controller: LED Status: " << int(data[2]) << std::endl; } } else if (ret == 3 && data[0] == 0x03 && data[1] == 0x03) { if (verbose) { // data[2] == 0x00 means that rumble is disabled // data[2] == 0x01 unknown, but rumble works // data[2] == 0x02 unknown, but rumble works // data[2] == 0x03 is default with rumble enabled std::cout << "Xbox360Controller: Rumble Status: " << int(data[2]) << std::endl; } } else if (ret == 3 && data[0] == 0x08 && data[1] == 0x03) { if (!g_options->quiet) { if (data[2] == 0x00) std::cout << "Headset: none"; else if (data[2] == 0x02) std::cout << "Headset: none"; } } else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14) { if (is_guitar) { msg.type = XBOX_MSG_XBOX360_GUITAR; memcpy(&msg.guitar, data, sizeof(Xbox360GuitarMsg)); } else { msg.type = XBOX_MSG_XBOX360; memcpy(&msg.xbox360, data, sizeof(Xbox360Msg)); } return true; } else { std::cout << "Unknown: "; print_raw_data(std::cout, data, ret); } return false; }