示例#1
0
文件: libusb.c 项目: HalasNet/bladeRF
static inline void get_libusb_version(char *buf, size_t buf_len)
{
    const struct libusb_version *version;
    version = libusb_get_version();

    snprintf(buf, buf_len, "%d.%d.%d.%d%s", version->major, version->minor,
             version->micro, version->nano, version->rc);
}
示例#2
0
static void
get_version(void)
{
  struct libusb_version *v;

  v = libusb_get_version();
  printf("libusb %d.%d.%d.%d%s %s\n"
	 , v->major
	 , v->minor
	 , v->micro
	 , v->nano
	 , v->rc
	 , v->describe
	 );
}
示例#3
0
void commdev_init()
{
    int errcode;
    const struct libusb_version *lv;

    errcode = 0;

    lv = libusb_get_version();
    printf("libusb version %d.%d.%d\r\n", lv->major, lv->minor, lv->micro);

    if (libusb_init(&context))
    {
        fprintf(stderr, "libusb init error\r\n");
        errcode = ERRCODE_LIBUSB_INIT;
        context = NULL;
        goto error;
    }

    return;
error:
    exit(errcode);
}
int Protonect::openKinect(std::string binpath){
  if( bOpened ){
    closeKinect();
  }
  cmd_seq = 0;

  uint16_t vid = 0x045E;
  uint16_t pid[2] = {0x02d8, 0x02C4};
  uint16_t mi = 0x00;

  bool debug_mode = false;

  uint8_t bus;

  int r;

  const struct libusb_version* version;
  version = libusb_get_version();
  printf("Using libusbx v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);

  r = libusb_init(NULL);
  if (r < 0) return r;

  libusb_set_debug(NULL, debug_mode ? LIBUSB_LOG_LEVEL_DEBUG : LIBUSB_LOG_LEVEL_INFO);

  for(int i = 0; i < 2; i++){
      printf("Trying to open device %04X:%04X...\n", vid, pid[i]);

  handle = NULL;
  int tryCount = 4;
  if (handle == NULL){
    while(tryCount > 0 && handle == NULL){
                handle = libusb_open_device_with_vid_pid(NULL, vid, pid[i]);
        tryCount--;
        usleep(100);
        
        if( handle ){
          libusb_reset_device(handle);
          usleep(100);
                  handle = libusb_open_device_with_vid_pid(NULL, vid, pid[i]);
                }
            }
      }
      if(handle !=  NULL){
        break;
      }
  }
  
    if( handle == NULL ){
        perr("Protonect::openKinect  Failed. - handle is NULL\n");
        return -1;
    }

  dev = libusb_get_device(handle);
  bus = libusb_get_bus_number(dev);
  /*
   struct libusb_device_descriptor dev_desc;

   printf("\nReading device descriptor:\n");
   CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc));
   printf("            length: %d\n", dev_desc.bLength);
   printf("      device class: %d\n", dev_desc.bDeviceClass);
   printf("               S/N: %d\n", dev_desc.iSerialNumber);
   printf("           VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
   printf("         bcdDevice: %04X\n", dev_desc.bcdDevice);
   printf("   iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
   printf("          nb confs: %d\n", dev_desc.bNumConfigurations);
   */

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  int active_cfg = -5;
  r = libusb_get_configuration(handle, &active_cfg);

  printf("active configuration: %d, err: %d", active_cfg, r);
  int configId = 1;
  if (active_cfg != configId)
  {
    printf("Setting config: %d\n", configId);
    r = libusb_set_configuration(handle, configId);
    if (r != LIBUSB_SUCCESS)
    {
      perr("  Can't set configuration. Error code: %d (%s)\n", r, libusb_error_name(r));
    }
  }

  int iface = 0;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  iface = 1;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  InitKinect(handle);

  // install signal handler now
  signal(SIGINT,sigint_handler);
  shutdown = false;

  usb_loop.start();
  
  //INITIALIZE OBJECTS
  
 // frame_listener = new libfreenect2::FrameListener(libfreenect2::Frame::Color | libfreenect2::Frame::Ir | libfreenect2::Frame::Depth);
  rgb_bulk_transfers = new libfreenect2::usb::BulkTransferPool(handle, 0x83);
  
  //rgb_processor = new libfreenect2::ofRGBPacketProcessor();
 // rgb_packet_stream_parser = new libfreenect2::RgbPacketStreamParser(rgb_processor);

 // rgb_processor->setFrameListener(frame_listener);

  rgb_bulk_transfers->allocate(50, 0x4000);
  rgb_bulk_transfers->setCallback(rgb_packet_stream_parser);
  rgb_bulk_transfers->enableSubmission();
  rgb_bulk_transfersPtr = rgb_bulk_transfers;

  depth_iso_transfers = new libfreenect2::usb::IsoTransferPool(handle, 0x84);
  
  depth_processor = new libfreenect2::CpuDepthPacketProcessor();
  depth_processor->setFrameListener(frame_listener);
  depth_processor->load11To16LutFromFile((binpath + "11to16.bin").c_str());
  depth_processor->loadXTableFromFile((binpath + "xTable.bin").c_str());
  depth_processor->loadZTableFromFile((binpath + "zTable.bin").c_str());

  depth_packet_stream_parser = new libfreenect2::DepthPacketStreamParser(depth_processor); 

  size_t max_packet_size = libusb_get_max_iso_packet_size(dev, 0x84);
  std::cout << "iso max_packet_size: " << max_packet_size << std::endl;

  depth_iso_transfers = new libfreenect2::usb::IsoTransferPool(handle, 0x84);
  depth_iso_transfers->allocate(80, 8, max_packet_size);
  depth_iso_transfers->setCallback(depth_packet_stream_parser);
  depth_iso_transfers->enableSubmission();
  depth_iso_transfersPtr = depth_iso_transfers;

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  RunKinect(handle, *depth_processor);

  rgb_bulk_transfers->submit(10);
  depth_iso_transfers->submit(60);

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);
  
  bOpened = true;

    return 0;
}
示例#5
0
int main(int argc, char** argv)
{
	bool show_help = false;
	bool debug_mode = false;
	const struct libusb_version* version;
	int j, r;
	size_t i, arglen;
	unsigned tmp_vid, tmp_pid;
	uint16_t endian_test = 0xBE00;
	char *error_lang = NULL, *old_dbg_str = NULL, str[256];

	// Default to generic, expecting VID:PID
	VID = 0;
	PID = 0;
	test_mode = USE_GENERIC;

	if (((uint8_t*)&endian_test)[0] == 0xBE) {
		printf("Despite their natural superiority for end users, big endian\n"
			"CPUs are not supported with this program, sorry.\n");
		return 0;
	}

	if (argc >= 2) {
		for (j = 1; j<argc; j++) {
			arglen = strlen(argv[j]);
			if ( ((argv[j][0] == '-') || (argv[j][0] == '/'))
			  && (arglen >= 2) ) {
				switch(argv[j][1]) {
				case 'd':
					debug_mode = true;
					break;
				case 'i':
					extra_info = true;
					break;
				case 'w':
					force_device_request = true;
					break;
				case 'b':
					if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
						printf("   Option -b requires a file name\n");
						return 1;
					}
					binary_name = argv[++j];
					binary_dump = true;
					break;
				case 'l':
					if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
						printf("   Option -l requires an ISO 639-1 language parameter\n");
						return 1;
					}
					error_lang = argv[++j];
					break;
				case 'j':
					// OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
					if (!VID && !PID) {
						VID = 0x15BA;
						PID = 0x0004;
					}
					break;
				case 'k':
					// Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
					if (!VID && !PID) {
						VID = 0x0204;
						PID = 0x6025;
					}
					break;
				// The following tests will force VID:PID if already provided
				case 'p':
					// Sony PS3 Controller - 1 interface
					VID = 0x054C;
					PID = 0x0268;
					test_mode = USE_PS3;
					break;
				case 's':
					// Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
					VID = 0x045E;
					PID = 0x0008;
					test_mode = USE_HID;
					break;
				case 'x':
					// Microsoft XBox Controller Type S - 1 interface
					VID = 0x045E;
					PID = 0x0289;
					test_mode = USE_XBOX;
					break;
				default:
					show_help = true;
					break;
				}
			} else {
				for (i=0; i<arglen; i++) {
					if (argv[j][i] == ':')
						break;
				}
				if (i != arglen) {
					if (sscanf(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
						printf("   Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
						return 1;
					}
					VID = (uint16_t)tmp_vid;
					PID = (uint16_t)tmp_pid;
				} else {
					show_help = true;
				}
			}
		}
	}

	if ((show_help) || (argc == 1) || (argc > 7)) {
		printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]\n", argv[0]);
		printf("   -h      : display usage\n");
		printf("   -d      : enable debug output\n");
		printf("   -i      : print topology and speed info\n");
		printf("   -j      : test composite FTDI based JTAG device\n");
		printf("   -k      : test Mass Storage device\n");
		printf("   -b file : dump Mass Storage data to file 'file'\n");
		printf("   -p      : test Sony PS3 SixAxis controller\n");
		printf("   -s      : test Microsoft Sidewinder Precision Pro (HID)\n");
		printf("   -x      : test Microsoft XBox Controller Type S\n");
		printf("   -l lang : language to report errors in (ISO 639-1)\n");
		printf("   -w      : force the use of device requests when querying WCID descriptors\n");
		printf("If only the vid:pid is provided, xusb attempts to run the most appropriate test\n");
		return 0;
	}

	// xusb is commonly used as a debug tool, so it's convenient to have debug output during libusb_init(),
	// but since we can't call on libusb_set_debug() before libusb_init(), we use the env variable method
	old_dbg_str = getenv("LIBUSB_DEBUG");
	if (debug_mode) {
		putenv("LIBUSB_DEBUG=4");	// LIBUSB_LOG_LEVEL_DEBUG
	}

	version = libusb_get_version();
	printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);
	r = libusb_init(NULL);
	if (r < 0)
		return r;

	// If not set externally, and no debug option was given, use info log level
	if ((old_dbg_str == NULL) && (!debug_mode))
		libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO);
	if (error_lang != NULL) {
		r = libusb_setlocale(error_lang);
		if (r < 0)
			printf("Invalid or unsupported locale '%s': %s\n", error_lang, libusb_strerror((enum libusb_error)r));
	}

	test_device(VID, PID);

	libusb_exit(NULL);

	if (debug_mode) {
		snprintf(str, sizeof(str), "LIBUSB_DEBUG=%s", (old_dbg_str == NULL)?"":old_dbg_str);
		str[sizeof(str) - 1] = 0;	// Windows may not NUL terminate the string
	}

	return 0;
}
int main(int argc, char** argv)
{
	bool show_help = false;
	bool debug_mode = false;
	const struct libusb_version* version;
	int j, r;
	size_t i, arglen;
	unsigned tmp_vid, tmp_pid;
	uint16_t endian_test = 0xBE00;

	// Default to generic, expecting VID:PID
	VID = 0;
	PID = 0;
	test_mode = USE_GENERIC;

	if (((uint8_t*)&endian_test)[0] == 0xBE) {
		printf("Despite their natural superiority for end users, big endian\n"
			"CPUs are not supported with this program, sorry.\n");
		return 0;
	}

	if (argc >= 2) {
		for (j = 1; j<argc; j++) {
			arglen = strlen(argv[j]);
			if ( ((argv[j][0] == '-') || (argv[j][0] == '/'))
			  && (arglen >= 2) ) {
				switch(argv[j][1]) {
				case 'd':
					debug_mode = true;
					break;
				case 'b':
					if (j+1 < argc) {
						strncpy(binary_name, argv[j+1], 64);
						j++;
					}
					binary_dump = true;
					break;
				case 'g':
					break;
				case 'j':
					// OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
					if (!VID && !PID) {
						VID = 0x15BA;
						PID = 0x0004;
					}
					break;
				case 'k':
					// Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
					if (!VID && !PID) {
						VID = 0x0204;
						PID = 0x6025;
					}
					break;
				// The following tests will force VID:PID if already provided
				case 'p':
					// Sony PS3 Controller - 1 interface
					VID = 0x054C;
					PID = 0x0268;
					test_mode = USE_PS3;
					break;
				case 's':
					// Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
					VID = 0x045E;
					PID = 0x0008;
					test_mode = USE_HID;
					break;
				case 'x':
					// Microsoft XBox Controller Type S - 1 interface
					VID = 0x045E;
					PID = 0x0289;
					test_mode = USE_XBOX;
					break;
				default:
					show_help = true;
					break;
				}
			} else {
				for (i=0; i<arglen; i++) {
					if (argv[j][i] == ':')
						break;
				}
				if (i != arglen) {
					if (sscanf_s(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
						printf("   Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
						return 1;
					}
					VID = (uint16_t)tmp_vid;
					PID = (uint16_t)tmp_pid;
				} else {
					show_help = true;
				}
			}
		}
	}

	if ((show_help) || (argc == 1) || (argc > 7)) {
		printf("usage: %s [-d] [-b [file]] [-h] [-i] [-j] [-k] [-x] [vid:pid]\n", argv[0]);
		printf("   -h: display usage\n");
		printf("   -d: enable debug output (if library was compiled with debug enabled)\n");
		printf("   -b: dump Mass Storage first block to binary file\n");
		printf("   -g: short generic test (default)\n");
		printf("   -k: test generic Mass Storage USB device (using WinUSB)\n");
		printf("   -j: test FTDI based JTAG device (using WinUSB)\n");
		printf("   -p: test Sony PS3 SixAxis controller (using WinUSB)\n");
		printf("   -s: test Microsoft Sidewinder Precision Pro (using HID)\n");
		printf("   -x: test Microsoft XBox Controller Type S (using WinUSB)\n");
		return 0;
	}

	version = libusb_get_version();
	printf("Using libusbx v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);
	r = libusb_init(NULL);
	if (r < 0)
		return r;

	libusb_set_debug(NULL, debug_mode?LOG_LEVEL_DEBUG:LOG_LEVEL_INFO);

	test_device(VID, PID);

	libusb_exit(NULL);

	return 0;
}
示例#7
0
int main(int argc, char *argv[])
{
  std::string program_path(argv[0]);
  size_t executable_name_idx = program_path.rfind("Protonect");

  std::string binpath = "/";

  if(executable_name_idx != std::string::npos)
  {
    binpath = program_path.substr(0, executable_name_idx);
  }

  uint16_t vid = 0x045E;
  uint16_t pid = 0x02C4;
  uint16_t mi = 0x00;

  bool debug_mode = false;

  libusb_device_handle *handle;
  libusb_device *dev;
  uint8_t bus;
  const char* speed_name[5] =
  { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)" };

  int r;

  const struct libusb_version* version;
  version = libusb_get_version();
  printf("Using libusbx v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);

  r = libusb_init(NULL);
  if (r < 0)
    return r;

  libusb_set_debug(NULL, debug_mode ? LIBUSB_LOG_LEVEL_DEBUG : LIBUSB_LOG_LEVEL_INFO);

  printf("Opening device %04X:%04X...\n", vid, pid);
  handle = libusb_open_device_with_vid_pid(NULL, vid, pid);

  if (handle == NULL)
  {
    perr("  Failed.\n");
    //system("PAUSE");
    return -1;
  }

  dev = libusb_get_device(handle);
  bus = libusb_get_bus_number(dev);
  /*
   struct libusb_device_descriptor dev_desc;

   printf("\nReading device descriptor:\n");
   CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc));
   printf("            length: %d\n", dev_desc.bLength);
   printf("      device class: %d\n", dev_desc.bDeviceClass);
   printf("               S/N: %d\n", dev_desc.iSerialNumber);
   printf("           VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
   printf("         bcdDevice: %04X\n", dev_desc.bcdDevice);
   printf("   iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
   printf("          nb confs: %d\n", dev_desc.bNumConfigurations);
   */

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  int active_cfg = -5;
  r = libusb_get_configuration(handle, &active_cfg);

  printf("active configuration: %d, err: %d", active_cfg, r);
  int configId = 1;
  if (active_cfg != configId)
  {
    printf("Setting config: %d\n", configId);
    r = libusb_set_configuration(handle, configId);
    if (r != LIBUSB_SUCCESS)
    {
      perr("  Can't set configuration. Error code: %d (%s)\n", r, libusb_error_name(r));
    }
  }

  int iface = 0;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  iface = 1;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  InitKinect(handle);

  // install signal handler now
  signal(SIGINT,sigint_handler);
  shutdown = false;

  libfreenect2::usb::EventLoop usb_loop;
  usb_loop.start();

  libfreenect2::FrameMap frames;
  libfreenect2::FrameListener frame_listener(libfreenect2::Frame::Color | libfreenect2::Frame::Ir | libfreenect2::Frame::Depth);

  //libfreenect2::DumpRgbPacketProcessor rgb_processor;
  libfreenect2::TurboJpegRgbPacketProcessor rgb_processor;
  rgb_processor.setFrameListener(&frame_listener);
  libfreenect2::RgbPacketStreamParser rgb_packet_stream_parser(&rgb_processor);

  libfreenect2::usb::BulkTransferPool rgb_bulk_transfers(handle, 0x83);
  rgb_bulk_transfers.allocate(50, 0x4000);
  rgb_bulk_transfers.setCallback(&rgb_packet_stream_parser);
  rgb_bulk_transfers.enableSubmission();

  libfreenect2::CpuDepthPacketProcessor depth_processor;
  depth_processor.setFrameListener(&frame_listener);
  depth_processor.load11To16LutFromFile((binpath + "../11to16.bin").c_str());
  depth_processor.loadXTableFromFile((binpath + "../xTable.bin").c_str());
  depth_processor.loadZTableFromFile((binpath + "../zTable.bin").c_str());

  libfreenect2::DepthPacketStreamParser depth_packet_stream_parser(&depth_processor);

  size_t max_packet_size = libusb_get_max_iso_packet_size(dev, 0x84);
  std::cout << "iso max_packet_size: " << max_packet_size << std::endl;

  libfreenect2::usb::IsoTransferPool depth_iso_transfers(handle, 0x84);
  depth_iso_transfers.allocate(80, 8, max_packet_size);
  depth_iso_transfers.setCallback(&depth_packet_stream_parser);
  depth_iso_transfers.enableSubmission();

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  RunKinect(handle, depth_processor);

  rgb_bulk_transfers.submit(10);
  depth_iso_transfers.submit(60);

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  while(!shutdown)
  {
    frame_listener.waitForNewFrame(frames);

    libfreenect2::Frame *rgb = frames[libfreenect2::Frame::Color];
    libfreenect2::Frame *ir = frames[libfreenect2::Frame::Ir];
    libfreenect2::Frame *depth = frames[libfreenect2::Frame::Depth];

    cv::imshow("rgb", cv::Mat(rgb->height, rgb->width, CV_8UC3, rgb->data));
    cv::imshow("ir", cv::Mat(ir->height, ir->width, CV_32FC1, ir->data) / 20000.0f);
    cv::imshow("depth", cv::Mat(depth->height, depth->width, CV_32FC1, depth->data) / 4500.0f);
    cv::waitKey(1);

    frame_listener.release(frames);
  }

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  rgb_bulk_transfers.disableSubmission();
  depth_iso_transfers.disableSubmission();

  CloseKinect(handle);

  rgb_bulk_transfers.cancel();
  depth_iso_transfers.cancel();

  // wait for all transfers to cancel
  // TODO: better implementation
  libfreenect2::this_thread::sleep_for(libfreenect2::chrono::seconds(2));

  rgb_bulk_transfers.deallocate();
  depth_iso_transfers.deallocate();

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  iface = 0;
  printf("Releasing interface %d...\n", iface);
  libusb_release_interface(handle, iface);

  iface = 1;
  printf("Releasing interface %d...\n", iface);
  libusb_release_interface(handle, iface);

  printf("Closing device...\n");
  libusb_close(handle);

  usb_loop.stop();

  libusb_exit(NULL);

  //system("PAUSE");
  return 0;
}
示例#8
0
int main(int argc, char *argv[])
{
    const struct libusb_version *ver = libusb_get_version();
    printf("%u.%u.%u\n", ver->major, ver->minor, ver->micro);
    return 0;
}
int main(int argc, char **argv) {
  reset_wacom_inkling();
  
  const struct libusb_version *version = libusb_get_version();
  printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);

  int r=1;

  r = libusb_init(NULL);
  if (r < 0) {
    fprintf(stderr, "Failed to initialise libusb\n");
    return 1;
  }

  // discover devices
  libusb_device **list;
  libusb_device *found = NULL;
  libusb_context *ctx = NULL;
  int attached = 0;

  ssize_t cnt = libusb_get_device_list(ctx, &list);
  ssize_t i = 0;
  int err = 0;
  if (cnt < 0){
    printf( "no usb devices found\n" );
    goto out;
  }

  // find our device
  for(i = 0; i < cnt; i++){
    libusb_device *device = list[i];
    struct libusb_device_descriptor desc;
    int r = libusb_get_device_descriptor( device, &desc );

    if( desc.idVendor == VENDOR_ID && desc.idProduct == PRODUCT_ID ){
      found=device;
    }
  }

  if (found == NULL){
    printf("Unable to find usb device\n");
    goto out;
  }

  libusb_device_handle *devh; 
  err = libusb_open(found, &devh);
  if (err){
    printf("Unable to open usb device\n");
    goto out;
  }

  printf("Successfully find device\n");

//#ifdef LINUX 
  if (libusb_kernel_driver_active(devh,0)==1){
    printf("Device busy...detaching...\n"); 
    attached = 1;
    libusb_detach_kernel_driver(devh, 0);   
  }
//#endif 


  err = libusb_claim_interface( devh, 0 );
  if (err){
    printf( "Failed to claim interface. " );
    switch( err ){
    case LIBUSB_ERROR_NOT_FOUND:	
      printf( "not found\n" );	break;
    case LIBUSB_ERROR_BUSY:		
      printf( "busy\n" );		break;
    case LIBUSB_ERROR_NO_DEVICE:	
      printf( "no device\n" );	break;
    default:			
      printf( "other\n" );		break;
    }
    goto out;
  } 
  printf( "interface claimed\n" );


  {//important to enable device, buf[4]=1 will enable output while 2 will disable
   //seems only 1 and 2 are valid from reading function
    char buf[]={0x80,0x01,0x02,0x01,0x02};
    send_control_transfer(devh,buf,sizeof(buf));
  }  

  {//I guess it is setting ID. 01 is mouse and 02 are digitizer,
   //04 is undefined but looks like raw data we want. 08 has too many data that crash RPi, won't listen to 128
    int report_id_setting=4;
    char buf[]={0x80,0x01,0x03,0x01,report_id_setting};
    send_control_transfer(devh,buf,sizeof(buf));
  }

  {//read back report id settings
    char buf[]={0x80,0x01,0x0A,0x01,0x01,0x03,0x01};
    send_control_transfer(devh,buf,sizeof(buf));
  }
  receive_control_transfer(devh);

  {//not sure what this is but seems important 
    char buf[]={0x80,0x01,0x0B,0x01};
    send_control_transfer(devh,buf,sizeof(buf));
  }

  {//re-enable output
    char buf[]={0x80,0x01,0x02,0x01,0x01};
    send_control_transfer(devh,buf,sizeof(buf));
  }
  
  printf("Yeah\n");

  int bytes_transferred;

  while(1){
    r = libusb_bulk_transfer(devh,0x83,data_in,16,&bytes_transferred,TIMEOUT_MS);
    switch(r){
	case 0:	//success
	  {
	    if (data_in[0]==2){
	      int x=data_in[1]+data_in[2]*256;
	      int y=data_in[3]+data_in[4]*256;
	      int button=data_in[5];
	      int pressure=data_in[6]+data_in[7]*256;
	      int x_tilt=(signed char)data_in[8];
	      int y_tilt=(signed char)data_in[9];
		
	      printf("x:%d\ty:%d\tb:%d\tp:%d\txt:%d\tyt:%d\n",x,y,button,pressure,x_tilt,y_tilt);
	    }else if (data_in[0]==4){
	      int x=data_in[3]+data_in[2]*256;	//ignore the 3rd byte
	      if (x>32767) x=x-65536;
	      int y=data_in[6]+data_in[5]*256;
	      int button=data_in[7];
	      int pressure=data_in[8]+data_in[9]*256;
	      int x_tilt=(signed char)data_in[10];
	      int y_tilt=(signed char)data_in[11];
	      static int button_last=0;
	      if (debug_output){
		printf("x:%d\ty:%d\tb:%d\tp:%d\txt:%d\tyt:%d\n",x,y,button,pressure,x_tilt,y_tilt);
	      }else{
		if (button!=0){
		  printf("d:%d %d\n",x,y);
		}else{
		  if (button_last!=0){
		    printf("u:\n");
		    fflush(stdout);
		  }
		}
	      }
	      button_last=button;
	    }else{
	      if (debug_output){
		for(i = 0; i < bytes_transferred; i++){
		  printf("%02x ",data_in[i]);
		}
		printf("\n");
	      }
	    }
	  }
	  
	  break;
	  
    case LIBUSB_ERROR_TIMEOUT :	
      printf( "LIBUSB_ERROR_TIMEOUT (Don't worry)\n" );	break;
    case LIBUSB_ERROR_PIPE :		
      printf( "LIBUSB_ERROR_PIPE \n" );		break;
    case LIBUSB_ERROR_OVERFLOW :	
      printf( "no LIBUSB_ERROR_OVERFLOW \n" );	break;
    case LIBUSB_ERROR_NO_DEVICE :	
      printf( "no LIBUSB_ERROR_NO_DEVICE \n" );	break;
    default:			
      printf( "other\n" );		break;
    } 
  }	
out:
  //libusb_reset_device(devh);
  libusb_close(devh);
  libusb_exit(NULL);

  return 0;
}