#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <ctype.h>
#include <usb.h>
#include <unistd.h>

struct usb_dev_handle *devh;

void release_usb_device(int dummy) {
    int ret;
    ret = usb_release_interface(devh, 0);
    if (!ret)
	printf("failed to release interface: %d\n", ret);
    usb_close(devh);
    if (!ret)
	printf("failed to close interface: %d\n", ret);
    exit(1);
}

void list_devices() {
    struct usb_bus *bus;
    for (bus = usb_get_busses(); bus; bus = bus->next) {
	struct usb_device *dev;
	
	for (dev = bus->devices; dev; dev = dev->next)
	    printf("0x%04x 0x%04x\n",
		   dev->descriptor.idVendor,
		   dev->descriptor.idProduct);
    }
}    

struct usb_device *find_device(int vendor, int product) {
    struct usb_bus *bus;
    
    for (bus = usb_get_busses(); bus; bus = bus->next) {
	struct usb_device *dev;
	
	for (dev = bus->devices; dev; dev = dev->next) {
	    if (dev->descriptor.idVendor == vendor
		&& dev->descriptor.idProduct == product)
		return dev;
	}
    }
    return NULL;
}

void print_bytes(char *bytes, int len) {
    int i;
    if (len > 0) {
	for (i=0; i<len; i++) {
	    fprintf(stderr, "%02x ", (int)((unsigned char)bytes[i]));
	}
	fprintf(stderr, "\"");
        for (i=0; i<len; i++) {
		fprintf(stderr, "%c", isprint(bytes[i]) ? bytes[i] : '.');
        }
        fprintf(stderr, "\"");
    }
}


void init(char *buf, int verbose) {
    int ret;
    
    ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000009);
    if (verbose) fprintf(stderr, "1 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000022);
    if (verbose) fprintf(stderr, "2 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(7*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "3 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(9*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "4 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(156*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008a, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "5 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0000000, 0x0000000, buf, 0x0000024, 1000);
    if (verbose) fprintf(stderr, "6 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(10*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "7 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "8 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "9 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
    if (verbose) fprintf(stderr, "10 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(14*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "11 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 1);
    if (verbose) fprintf(stderr, "11 set alternate setting returned %d\n", ret);
    usleep(21*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "12 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0007856, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "13 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "14 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(116*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "15 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(109*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "16 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(110*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "17 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(109*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "18 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(110*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "19 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(109*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "20 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(110*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "21 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008a, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "22 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(2*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "23 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0001000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "24 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0002000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "25 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(9*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000086, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "26 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "27 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "28 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 0);
    if (verbose) fprintf(stderr, "28 set alternate setting returned %d\n", ret);
    usleep(280*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "29 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 1);
    if (verbose) fprintf(stderr, "29 set alternate setting returned %d\n", ret);
    usleep(25*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "30 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0007856, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "31 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "32 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008a, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "33 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "34 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0001000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "35 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0002000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "36 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(9*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000086, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "37 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "38 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 0);
    if (verbose) fprintf(stderr, "38 set alternate setting returned %d\n", ret);
    usleep(1633*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "39 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 1);
    if (verbose) fprintf(stderr, "39 set alternate setting returned %d\n", ret);
    usleep(28*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "40 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0007856, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "41 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008a, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "42 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "43 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0001000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "44 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0002000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "45 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "46 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008f, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "47 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "48 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(4*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "49 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(11*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "50 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0003412, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "51 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(2*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0007856, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "52 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008f, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "53 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "54 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "55 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "56 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(6*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "57 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(2500*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008d, 0x0000000, 0x0000000, buf, 0x0000008, 1000);
    if (verbose) fprintf(stderr, "58 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(7*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0003412, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "59 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000088, 0x0007856, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "60 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "61 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 0);
    if (verbose) fprintf(stderr, "61 set alternate setting returned %d\n", ret);
    usleep(14*1000);
    ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
    if (verbose) fprintf(stderr, "62 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
    if (verbose) fprintf(stderr, "63 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(8*1000);
    ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
    if (verbose) fprintf(stderr, "64 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(9*1000);
    ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
    if (verbose) fprintf(stderr, "65 get descriptor returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(4*1000);
    ret = usb_set_configuration(devh, 0x0000001);
    if (verbose) fprintf(stderr, "66 set configuration returned %d\n", ret);
    ret = usb_set_altinterface(devh, 1);
    if (verbose) fprintf(stderr, "66 set alternate setting returned %d\n", ret);
    usleep(23*1000);
    usleep(1*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "75 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE, 0x0000009, 0x0000000, 0x0000000, buf, 0x0000000, 1000);
    if (verbose) fprintf(stderr, "76 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(67*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008c, 0x0000000, 0x0000000, buf, 0x0000001, 1000);
    if (verbose) fprintf(stderr, "77 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "78 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(5*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008a, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "79 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(3*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008b, 0x0000000, 0x0000000, buf, 0x0000024, 1000);
    if (verbose) fprintf(stderr, "80 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(10*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000093, 0x0000000, 0x0000000, buf, 0x0000002, 1000);
    if (verbose) fprintf(stderr, "81 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(1*1000);
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x0000085, 0x0000000, 0x0000000, buf, 0x0000010, 1000);
    if (verbose) fprintf(stderr, "82 control msg returned %d, bytes: ", ret);
    if (verbose) print_bytes(buf, ret);
    if (verbose) fprintf(stderr, "\n");
    usleep(15*1000);
}

void copydata(char *buf) {
    int ret, i;
    
    /*
      stv680.c: [stv_init:381] STV(i): CIF is supported
      stv680.c: [stv_init:386] STV(i): Firmware rev is 1.0
      stv680.c: [stv_init:387] STV(i): ASIC rev is 7.6
      stv680.c: [stv_init:388] STV(i): Sensor ID is 410
      stv680.c: [stv_init:399] STV(i): Camera has 0 pictures.
      stv680.c: [stv_init:426] STV(i): Video Mode set to CIF
      stv680.c: [stv_init:468] STV(i): width = 352, height = 288, rawbufsize = 103952
      stv680.c: [stv_init:488] STV(i): swapRGB is (auto) OFF
      stv680.c: [stv_set_video_mode:302] STV(i): Setting video mode.
      stv680.c: [stv_stop_video:244] STV(i): Camera reset to idle mode.
    */
    
    ret = usb_control_msg(devh, USB_TYPE_VENDOR + USB_RECIP_INTERFACE + USB_ENDPOINT_IN, 0x000008c, 0x0000000, 0x0000000, buf, 0x0000001, 1000);
    do {
        ret = usb_bulk_read(devh, 0x00000082, buf, 0x0001000, 1000);
    } while (ret != 1552);
    
    for(;;) {
        for (i = 0; i < 33; i++) {
            ret = usb_bulk_read(devh, 0x00000082, buf, 32768, 1000);
            if (ret > 0) {
                write(1, buf, ret);
            }
        }
    }
}

int main(int argc, char **argv) {
    int ret, vendor, product;
    struct usb_device *dev;
    char buf[65535];
    int verbose;
    usb_init();
    usb_find_busses();
    usb_find_devices();

    if (argc<3) {
        printf("usage: %s vendorID productID\n", argv[0]);
        printf("ID numbers of currently attached devices:\n");
        list_devices();
        exit(1);
    }
    if (argc==4 && argv[3][0] == '-' && argv[3][1] == 'v' && argv[3][2] == 0)
        verbose = 1;
    else
        verbose = 0;
    vendor = strtol(argv[1], NULL, 16);
    product = strtol(argv[2], NULL, 16);
    if (vendor <= 1 || product <= 1) {
	printf("invalid vendor or product id\n");
	exit(1);
    }
    dev = find_device(vendor, product);
    assert(dev);
    
    devh = usb_open(dev);
    assert(devh);
    
    signal(SIGTERM, release_usb_device);

    ret = usb_claim_interface(devh, 0);
    if (ret != 0) {
	    printf("claim failed with error %d\n", ret);
	    exit(1);
    }
    
    ret = usb_set_altinterface(devh, 0);
    assert(ret >= 0);

    init(buf, verbose);

    copydata(buf);
    
    return 0;
}
