struct usb_device_info * usb_open_and_wait_for_device(void) { libusb_device **devs; libusb_device **dev; struct usb_device_info * ret = NULL; int i = 0; void (*prev)(int); static char progress[] = {'/','-','\\', '|'}; if ( libusb_init(NULL) < 0 ) { PRINTF_LINE("libusb_init failed"); PRINTF_END(); return NULL; } PRINTF_BACK(); printf("\n"); signal_quit = 0; prev = signal(SIGINT, signal_handler); while ( ! signal_quit ) { PRINTF_LINE("Waiting for USB device... %c", progress[++i%sizeof(progress)]); if ( libusb_get_device_list(NULL, &devs) < 0 ) { PRINTF_LINE("Listing USB devices failed"); PRINTF_END(); break; } for ( dev = devs; *dev != NULL; ++dev ) { ret = usb_device_is_valid(*dev); if ( ret ) break; } libusb_free_device_list(devs, 1); if ( ret ) break; SLEEP(0xc350); // 0.5s } if ( prev != SIG_ERR ) signal(SIGINT, prev); PRINTF_BACK(); printf("\n"); if ( ! ret ) return NULL; return ret; }
static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface) { PRINTF_LINE("Reattach kernel driver to USB interface..."); PRINTF_END(); libusb_release_interface(udev, interface); libusb_attach_kernel_driver(udev, interface); }
static void usb_descriptor_info_print(libusb_device_handle * udev, struct libusb_device * dev, char * product, size_t size) { struct libusb_device_descriptor desc; char buf[1024]; char buf2[1024]; unsigned int x; int ret; int i; if ( libusb_get_device_descriptor(dev, &desc) < 0 ) { PRINTF_LINE("libusb_get_device_descriptor() failed"); PRINTF_END(); return; } memset(buf, 0, sizeof(buf)); libusb_get_string_descriptor_ascii(udev, desc.iProduct, (unsigned char *)buf, sizeof(buf)); PRINTF_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)"); PRINTF_END(); if ( product && buf[0] ) strncpy(product, buf, size); memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); ret = libusb_get_string_descriptor_ascii(udev, desc.iSerialNumber, (unsigned char *)buf, sizeof(buf)); if ( ! isalnum(buf[0]) ) buf[0] = 0; for ( i = 0; i < ret; i+=2 ) { sscanf(buf+i, "%2x", &x); if ( x > 32 && x < 128 ) buf2[i/2] = x; else { buf2[0] = 0; break; } } if ( ! isalnum(buf2[0]) ) buf2[0] = 0; PRINTF_LINE("USB device serial number string: %s", buf2[0] ? buf2 : ( buf[0] ? buf : "(not detected)" )); PRINTF_END(); }
static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) { char buf[1024]; char buf2[1024]; unsigned int x; int ret; int i; memset(buf, 0, sizeof(buf)); usb_get_string_simple(udev, dev->descriptor.iProduct, buf, sizeof(buf)); PRINTF_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)"); PRINTF_END(); if ( product && buf[0] ) strncpy(product, buf, size); memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, buf, sizeof(buf)); if ( ! isalnum(buf[0]) ) buf[0] = 0; for ( i = 0; i < ret; i+=2 ) { sscanf(buf+i, "%2x", &x); if ( x > 32 && x < 128 ) buf2[i/2] = x; else { buf2[0] = 0; break; } } if ( ! isalnum(buf2[0]) ) buf2[0] = 0; PRINTF_LINE("USB device serial number string: %s", buf2[0] ? buf2 : ( buf[0] ? buf : "(not detected)" )); PRINTF_END(); }
void printf_progressbar(unsigned long long part, unsigned long long total) { char *columns = getenv("COLUMNS"); int pc; int tmp, cols = 80; /* percentage calculation */ pc = total == 0 ? 100 : (int)(part*100/total); ( pc < 0 ) ? pc = 0 : ( pc > 100 ) ? pc = 100 : 0; PRINTF_BACK(); PRINTF_ADD("\x1b[K %3d%% [", pc); if ( columns ) cols = atoi(columns); if ( cols > 115 ) cols = 115; cols-=15; for ( tmp = cols*pc/100; tmp; tmp-- ) PRINTF_ADD("#"); for ( tmp = cols-(cols*pc/100); tmp; tmp-- ) PRINTF_ADD("-"); PRINTF_ADD("]"); if ( part == total ) PRINTF_END(); fflush(stdout); }
static struct usb_device_info * usb_device_is_valid(struct libusb_device * dev) { int err, i; char product[1024]; libusb_device_handle * udev; struct usb_device_info * ret = NULL; struct libusb_device_descriptor desc; if ( libusb_get_device_descriptor(dev, &desc) < 0 ) { PRINTF_LINE("libusb_get_device_descriptor failed"); PRINTF_END(); return NULL; } for ( i = 0; usb_devices[i].vendor; ++i ) { if ( desc.idVendor == usb_devices[i].vendor && desc.idProduct == usb_devices[i].product ) { printf("\b\b "); PRINTF_END(); PRINTF_ADD("Found "); usb_flash_device_info_print(&usb_devices[i]); PRINTF_END(); PRINTF_LINE("Opening USB..."); err = libusb_open(dev, &udev); if ( err < 0 ) { PRINTF_ERROR("libusb_open failed"); fprintf(stderr, "\n"); return NULL; } usb_descriptor_info_print(udev, dev, product, sizeof(product)); if ( usb_devices[i].interface >= 0 ) { PRINTF_LINE("Detaching kernel from USB interface..."); libusb_detach_kernel_driver(udev, usb_devices[i].interface); PRINTF_LINE("Claiming USB interface..."); if ( libusb_claim_interface(udev, usb_devices[i].interface) < 0 ) { PRINTF_ERROR("libusb_claim_interface failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); libusb_close(udev); return NULL; } } if ( usb_devices[i].alternate >= 0 ) { PRINTF_LINE("Setting alternate USB interface..."); if ( libusb_set_interface_alt_setting(udev, usb_devices[i].interface, usb_devices[i].alternate) < 0 ) { PRINTF_ERROR("libusb_claim_interface failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); libusb_close(udev); return NULL; } } if ( usb_devices[i].configuration >= 0 ) { PRINTF_LINE("Setting USB configuration..."); if ( libusb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { PRINTF_ERROR("libusb_set_configuration failed"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); libusb_close(udev); return NULL; } } ret = calloc(1, sizeof(struct usb_device_info)); if ( ! ret ) { ALLOC_ERROR(); usb_reattach_kernel_driver(udev, usb_devices[i].interface); libusb_close(udev); return NULL; } if ( strstr(product, "N900") ) ret->device = DEVICE_RX_51; else if ( strstr(product, "N950") ) ret->device = DEVICE_RM_680; else ret->device = DEVICE_UNKNOWN; /* TODO: Autodetect more devices */ if ( device_to_string(ret->device) ) PRINTF_LINE("Detected USB device: %s", device_to_string(ret->device)); else PRINTF_LINE("Detected USB device: (not detected)"); PRINTF_END(); if ( ret->device ) { enum device * device; for ( device = usb_devices[i].devices; *device; ++device ) if ( *device == ret->device ) break; if ( ! *device ) { ERROR("Device mishmash"); fprintf(stderr, "\n"); usb_reattach_kernel_driver(udev, usb_devices[i].interface); libusb_close(udev); free(ret); return NULL; } } ret->hwrev = -1; ret->flash_device = &usb_devices[i]; ret->udev = udev; break; } } return ret; }
static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { int i; char product[1024]; struct usb_device_info * ret = NULL; for ( i = 0; usb_devices[i].vendor; ++i ) { if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) { printf("\b\b "); PRINTF_END(); PRINTF_ADD("Found "); usb_flash_device_info_print(&usb_devices[i]); PRINTF_END(); PRINTF_LINE("Opening USB..."); usb_dev_handle * udev = usb_open(dev); if ( ! udev ) { PRINTF_ERROR("usb_open failed"); fprintf(stderr, "\n"); return NULL; } usb_descriptor_info_print(udev, dev, product, sizeof(product)); #if defined(LIBUSB_HAS_GET_DRIVER_NP) && defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) PRINTF_LINE("Detaching kernel from USB interface..."); usb_detach_kernel_driver_np(udev, usb_devices[i].interface); #endif PRINTF_LINE("Claiming USB interface..."); if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); usb_close(udev); return NULL; } if ( usb_devices[i].alternate >= 0 ) { PRINTF_LINE("Setting alternate USB interface..."); if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); usb_close(udev); return NULL; } } if ( usb_devices[i].configuration >= 0 ) { PRINTF_LINE("Setting USB configuration..."); if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { PRINTF_ERROR("usb_set_configuration failed"); fprintf(stderr, "\n"); usb_close(udev); return NULL; } } ret = calloc(1, sizeof(struct usb_device_info)); if ( ! ret ) { ALLOC_ERROR(); usb_close(udev); return NULL; } if ( strstr(product, "N900") ) ret->device = DEVICE_RX_51; else ret->device = DEVICE_UNKNOWN; /* TODO: Autodetect more devices */ if ( device_to_string(ret->device) ) PRINTF_LINE("Detected USB device: %s", device_to_string(ret->device)); else PRINTF_LINE("Detected USB device: (not detected)"); PRINTF_END(); if ( ret->device ) { enum device * device; for ( device = usb_devices[i].devices; *device; ++device ) if ( *device == ret->device ) break; if ( ! *device ) { ERROR("Device mishmash"); fprintf(stderr, "\n"); usb_close(udev); return NULL; } } ret->hwrev = -1; ret->flash_device = &usb_devices[i]; ret->udev = udev; break; } } return ret; }