Example #1
0
int
usb_close(usb_dev_handle * udev)
{
	struct usb_device *dev;
	int err;

	err = libusb20_dev_close((void *)udev);

	if (err)
		return (-1);

	if (usb_backend != NULL) {
		/*
		 * Enqueue USB device to backend queue so that it gets freed
		 * when the backend is re-scanned:
		 */
		libusb20_be_enqueue_device(usb_backend, (void *)udev);
	} else {
		/*
		 * The backend is gone. Free device data so that we
		 * don't start leaking memory!
		 */
		dev = usb_device(udev);
		libusb20_dev_free((void *)udev);
		LIST_DEL(usb_global_bus.devices, dev);
		free(dev);
	}
	return (0);
}
Example #2
0
int
usb_find_devices(void)
{
	struct libusb20_device *pdev;
	struct usb_device *udev;
	struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
	int devnum;
	int err;

	/* cleanup after last device search */
	/* close all opened devices, if any */

	while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
		udev = pdev->privLuData;
		libusb20_be_dequeue_device(usb_backend, pdev);
		libusb20_dev_free(pdev);
		if (udev != NULL) {
			LIST_DEL(usb_global_bus.devices, udev);
			free(udev);
		}
	}

	/* free old USB backend, if any */

	libusb20_be_free(usb_backend);

	/* do a new backend device search */
	usb_backend = libusb20_be_alloc_default();
	if (usb_backend == NULL) {
		return (-1);
	}
	/* iterate all devices */

	devnum = 1;
	pdev = NULL;
	while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) {
		udev = malloc(sizeof(*udev));
		if (udev == NULL)
			break;

		memset(udev, 0, sizeof(*udev));

		udev->bus = &usb_global_bus;

		snprintf(udev->filename, sizeof(udev->filename),
		    "/dev/ugen%u.%u",
		    libusb20_dev_get_bus_number(pdev),
		    libusb20_dev_get_address(pdev));

		ddesc = libusb20_dev_get_device_desc(pdev);

		udev->descriptor.bLength = sizeof(udev->descriptor);
		udev->descriptor.bDescriptorType = ddesc->bDescriptorType;
		udev->descriptor.bcdUSB = ddesc->bcdUSB;
		udev->descriptor.bDeviceClass = ddesc->bDeviceClass;
		udev->descriptor.bDeviceSubClass = ddesc->bDeviceSubClass;
		udev->descriptor.bDeviceProtocol = ddesc->bDeviceProtocol;
		udev->descriptor.bMaxPacketSize0 = ddesc->bMaxPacketSize0;
		udev->descriptor.idVendor = ddesc->idVendor;
		udev->descriptor.idProduct = ddesc->idProduct;
		udev->descriptor.bcdDevice = ddesc->bcdDevice;
		udev->descriptor.iManufacturer = ddesc->iManufacturer;
		udev->descriptor.iProduct = ddesc->iProduct;
		udev->descriptor.iSerialNumber = ddesc->iSerialNumber;
		udev->descriptor.bNumConfigurations =
		    ddesc->bNumConfigurations;
		if (udev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
			/* truncate number of configurations */
			udev->descriptor.bNumConfigurations = USB_MAXCONFIG;
		}
		udev->devnum = devnum++;
		/* link together the two structures */
		udev->dev = pdev;
		pdev->privLuData = udev;

		err = libusb20_dev_open(pdev, 0);
		if (err == 0) {
			/* XXX get all config descriptors by default */
			usb_fetch_and_parse_descriptors((void *)pdev);
			libusb20_dev_close(pdev);
		}
		LIST_ADD(usb_global_bus.devices, udev);
	}

	return (devnum - 1);			/* success */
}
Example #3
0
static void
doit(struct libusb20_device *dev)
{
  int rv;

  if (do_request)
    printf("doit(): bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\n",
	   setup.bmRequestType,
	   setup.bRequest,
	   setup.wValue,
	   setup.wIndex,
	   setup.wLength);

  /*
   * Open the device, allocating memory for two possible (bulk or
   * interrupt) transfers.
   *
   * If only control transfers are intended (via
   * libusb20_dev_request_sync()), transfer_max can be given as 0.
   */
  if ((rv = libusb20_dev_open(dev, 1)) != 0)
    {
      fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv));
      return;
    }

  /*
   * If the device has more than one configuration, select the desired
   * one here.
   */
  if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0)
    {
      fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv));
      return;
    }

  uint8_t *data = 0;
  uint16_t actlen;

  if ((setup.bmRequestType & 0x80) != 0)
    {
      /* this is an IN request, allocate a buffer */
      data = malloc(setup.wLength);
      if (data == 0)
	{
	  fprintf(stderr,
		  "Out of memory allocating %u bytes of reply buffer\n",
		  setup.wLength);
	  return;
	}
    }
  else
    data = out_buf;

  if (do_request)
    {
      if ((rv = libusb20_dev_request_sync(dev, &setup, data,
					  &actlen,
					  TIMEOUT,
					  0 /* flags */)) != 0)
	{
	  fprintf(stderr,
		  "libusb20_dev_request_sync: %s\n", libusb20_strerror(rv));
	}
      printf("sent %d bytes\n", actlen);
      if ((setup.bmRequestType & 0x80) != 0)
	{
	  print_formatted(data, (uint32_t)setup.wLength);
	  free(data);
	}
    }

  if (intr_ep != 0)
    {
      /*
       * One transfer has been requested in libusb20_dev_open() above;
       * obtain the corresponding transfer struct pointer.
       */
      struct libusb20_transfer *xfr_intr = libusb20_tr_get_pointer(dev, 0);

      if (xfr_intr == NULL)
	{
	  fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv));
	  return;
	}

      /*
       * Open the interrupt transfer.
       */
      if ((rv = libusb20_tr_open(xfr_intr, 0, 1, intr_ep)) != 0)
	{
	  fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv));
	  return;
	}

      uint8_t in_buf[BUFLEN];
      uint32_t rlen;

      if ((rv = libusb20_tr_bulk_intr_sync(xfr_intr, in_buf, BUFLEN, &rlen, TIMEOUT))
	  != 0)
	{
	  fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv));
	}
      printf("received %d bytes\n", rlen);
      if (rlen > 0)
	print_formatted(in_buf, rlen);

      libusb20_tr_close(xfr_intr);
    }

  libusb20_dev_close(dev);
}
Example #4
0
static void
doit(struct libusb20_device *dev)
{
  int rv;

  /*
   * Open the device, allocating memory for two possible (bulk or
   * interrupt) transfers.
   *
   * If only control transfers are intended (via
   * libusb20_dev_request_sync()), transfer_max can be given as 0.
   */
  if ((rv = libusb20_dev_open(dev, 2)) != 0)
    {
      fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv));
      return;
    }

  /*
   * If the device has more than one configuration, select the desired
   * one here.
   */
  if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0)
    {
      fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv));
      return;
    }

  /*
   * Two transfers have been requested in libusb20_dev_open() above;
   * obtain the corresponding transfer struct pointers.
   */
  struct libusb20_transfer *xfr_out = libusb20_tr_get_pointer(dev, 0);
  struct libusb20_transfer *xfr_in = libusb20_tr_get_pointer(dev, 1);

  if (xfr_in == NULL || xfr_out == NULL)
    {
      fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv));
      return;
    }

  /*
   * Open both transfers, the "out" one for the write endpoint, the
   * "in" one for the read endpoint (ep | 0x80).
   */
  if ((rv = libusb20_tr_open(xfr_out, 0, 1, out_ep)) != 0)
    {
      fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv));
      return;
    }
  if ((rv = libusb20_tr_open(xfr_in, 0, 1, in_ep)) != 0)
    {
      fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv));
      return;
    }

  uint8_t in_buf[BUFLEN];
  uint32_t rlen;

  if (out_len > 0)
    {
      if ((rv = libusb20_tr_bulk_intr_sync(xfr_out, out_buf, out_len, &rlen, TIMEOUT))
	  != 0)
	{
	  fprintf(stderr, "libusb20_tr_bulk_intr_sync (OUT): %s\n", libusb20_strerror(rv));
	}
      printf("sent %d bytes\n", rlen);
    }

  if ((rv = libusb20_tr_bulk_intr_sync(xfr_in, in_buf, BUFLEN, &rlen, TIMEOUT))
      != 0)
    {
      fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv));
    }
      printf("received %d bytes\n", rlen);
      if (rlen > 0)
	print_formatted(in_buf, rlen);

  libusb20_tr_close(xfr_out);
  libusb20_tr_close(xfr_in);

  libusb20_dev_close(dev);
}
Example #5
0
void
usb_control_ep_error_test(uint16_t vid, uint16_t pid)
{
	struct LIBUSB20_CONTROL_SETUP_DECODED req;
	struct libusb20_device *pdev;
	uint8_t buffer[256];
	int error;
	int fail = 0;
	int bus;
	int dev;
	int cfg;

	pdev = find_usb_device(vid, pid);
	if (pdev == NULL) {
		printf("USB device not found\n");
		return;
	}
	error = libusb20_dev_open(pdev, 0);
	if (error) {
		printf("Could not open USB device\n");
		libusb20_dev_free(pdev);
		return;
	}

	bus = libusb20_dev_get_bus_number(pdev);
	dev = libusb20_dev_get_address(pdev);

	for (cfg = 0; cfg != 255; cfg++) {

		LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
		req.bmRequestType = 0x80; /* read */
		req.bRequest = 0x06; /* descriptor */
		req.wValue = 0x0200 | cfg; /* config descriptor */
		req.wIndex = 0;
		req.wLength = 255;

		printf("Test #%d.1/3 ...\n", cfg);

		set_ctrl_ep_fail(-1,-1,0,0);

		error = libusb20_dev_request_sync(pdev, &req, buffer,
		    NULL, 1000, 0);
		if (error != 0) {
			printf("Last configuration index is: %d\n", cfg - 1);
			break;
		}

		printf("Test #%d.2/3 ...\n", cfg);

		set_ctrl_ep_fail(bus,dev,1,1);

		error = libusb20_dev_request_sync(pdev, &req, buffer,
		    NULL, 1000, 0);

		set_ctrl_ep_fail(-1,-1,0,0);

		error = libusb20_dev_request_sync(pdev, &req, buffer,
		    NULL, 1000, 0);
		if (error != 0) {
			printf("Cannot fetch descriptor (unexpected)\n");
			fail++;
		}

		printf("Test #%d.3/3 ...\n", cfg);

		set_ctrl_ep_fail(bus,dev,0,1);

		error = libusb20_dev_request_sync(pdev, &req, buffer,
		    NULL, 1000, 0);

		set_ctrl_ep_fail(-1,-1,0,0);

		error = libusb20_dev_request_sync(pdev, &req, buffer,
		    NULL, 1000, 0);
		if (error != 0) {
			printf("Cannot fetch descriptor (unexpected)\n");
			fail++;
		}
	}

	libusb20_dev_close(pdev);
	libusb20_dev_free(pdev);

	printf("Test completed detecting %d failures\nDone\n\n", fail);
}
Example #6
0
void
usb_set_alt_interface_test(uint16_t vid, uint16_t pid)
{
	struct libusb20_device *pdev;
	struct libusb20_config *config;

	int iter;
	int error;
	int errcnt;
	int n;
	int m;

	pdev = find_usb_device(vid, pid);
	if (pdev == NULL) {
		printf("USB device not found\n");
		return;
	}
	printf("Starting set alternate setting test "
	    "for VID=0x%04x PID=0x%04x\n", vid, pid);

	config = libusb20_dev_alloc_config(pdev,
	    libusb20_dev_get_config_index(pdev));
	if (config == NULL) {
		printf("Could not get configuration descriptor\n");
		libusb20_dev_free(pdev);
		return;
	}
	iter = 0;
	errcnt = 0;

	for (n = 0; n != config->num_interface; n++) {
		/* detach kernel driver */
		libusb20_dev_detach_kernel_driver(pdev, n);

		error = libusb20_dev_open(pdev, 0);
		if (error)
			printf("ERROR could not open device\n");

		/* Try the alternate settings */
		for (m = 0; m != config->interface[n].num_altsetting; m++) {

			iter++;

			if (libusb20_dev_set_alt_index(pdev, n, m + 1)) {
				printf("ERROR on interface %d alt %d\n", n, m + 1);
				errcnt++;
			}
		}

		/* Restore to default */

		iter++;

		if (libusb20_dev_set_alt_index(pdev, n, 0)) {
			printf("ERROR on interface %d alt %d\n", n, 0);
			errcnt++;
		}
		libusb20_dev_close(pdev);
	}

	libusb20_dev_free(pdev);

	printf("\n"
	    "Test summary\n"
	    "============\n"
	    "Interfaces tested: %d\n"
	    "Errors: %d\n", iter, errcnt);
}