Beispiel #1
0
/* Look for a descriptor in the active configuration
 * Will also find extra descriptors which are normally
 * not returned by the standard libusb_get_descriptor() */
int usb_get_any_descriptor(struct libusb_device_handle *dev_handle,
				  uint8_t desc_type,
				  uint8_t desc_index,
				  unsigned char *resbuf, int res_len)
{
	struct libusb_device *dev;
	struct libusb_config_descriptor *config;
	int ret;
	uint16_t conflen;
	unsigned char *cbuf;

	dev = libusb_get_device(dev_handle);
	if (!dev) {
		fprintf(stderr, "Error: Broken device handle\n");
		return -1;
	}
	/* Get the total length of the configuration descriptors */
	ret = libusb_get_active_config_descriptor(dev, &config);
	if (ret == LIBUSB_ERROR_NOT_FOUND) {
		fprintf(stderr, "Error: Device is unconfigured\n");
		return -1;
	} else if (ret) {
		fprintf(stderr, "Error: failed "
			"libusb_get_active_config_descriptor()\n");
		exit(1);
	}
	conflen = config->wTotalLength;
	libusb_free_config_descriptor(config);

	/* Suck in the configuration descriptor list from device */
	cbuf = malloc(conflen);
	ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG,
				    desc_index, cbuf, conflen);
	if (ret < conflen) {
		fprintf(stderr, "Warning: failed to retrieve complete "
			"configuration descriptor, got %i/%i\n",
			ret, conflen);
		conflen = ret;
	}
	/* Search through the configuration descriptor list */
	ret = find_descriptor(cbuf, conflen, desc_type, desc_index,
			      resbuf, res_len);
	free(cbuf);

	/* A descriptor must be at least 2 bytes long */
	if (ret > 1) {
		if (verbose)
			printf("Found descriptor in complete configuration "
			       "descriptor list\n");
		return ret;
	}

	/* Finally try to retrieve it requesting the device directly
	 * This is not supported on all devices for non-standard types */
	return libusb_get_descriptor(dev_handle, desc_type, desc_index,
				     resbuf, res_len);
}
Beispiel #2
0
API_EXPORTED int usb_get_descriptor(usb_dev_handle *dev, unsigned char type,
	unsigned char desc_index, void *buf, int size)
{
	int r;
	r = libusb_get_descriptor(dev->handle, type, desc_index, buf, size);
	if (r >= 0)
		return r;
	return compat_err(r);
}
Beispiel #3
0
/* Look for a descriptor in the active configuration
 * Will also find extra descriptors which are normally
 * not returned by the standard libusb_get_descriptor() */
static int usb_get_any_descriptor(struct libusb_device_handle *dev_handle,
                                  uint8_t desc_type,
                                  uint8_t desc_index,
                                  unsigned char *resbuf, int res_len)
{
    struct libusb_device *dev;
    struct libusb_config_descriptor *config;
    int ret;
    uint16_t conflen;
    unsigned char *cbuf;

    dev = libusb_get_device(dev_handle);
    if (!dev) {
        return -1;
    }
    /* Get the total length of the configuration descriptors */
    ret = libusb_get_active_config_descriptor(dev, &config);
    if (ret)
        return -1;
    conflen = config->wTotalLength;
    libusb_free_config_descriptor(config);

    /* Suck in the configuration descriptor list from device */
    cbuf = (unsigned char *)malloc(conflen);
    ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG,
                                desc_index, cbuf, conflen);
    if (ret < conflen) {
        conflen = ret;
    }
    /* Search through the configuration descriptor list */
    ret = find_descriptor(cbuf, conflen, desc_type, desc_index,
                          resbuf, res_len);
    free(cbuf);

    /* A descriptor must be at least 2 bytes long */
    if (ret > 1) {
        return ret;
    }

    /* Finally try to retrieve it requesting the device directly
         * This is not supported on all devices for non-standard types */
    return libusb_get_descriptor(dev_handle, desc_type, desc_index,
                                 resbuf, res_len);
}
Beispiel #4
0
/** \ingroup desc
 * Get a Binary Object Store (BOS) descriptor
 * This is a BLOCKING function, which will send requests to the device.
 *
 * \param handle the handle of an open libusb device
 * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
 * Must be freed with \ref libusb_free_bos_descriptor() after use.
 * \returns 0 on success
 * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
 * \returns another LIBUSB_ERROR code on error
 */
int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
	struct libusb_bos_descriptor **bos)
{
	struct libusb_bos_descriptor _bos;
	uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
	unsigned char *bos_data = NULL;
	const int host_endian = 0;
	int r;

	/* Read the BOS. This generates 2 requests on the bus,
	 * one for the header, and one for the full BOS */
	r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header,
				  LIBUSB_DT_BOS_SIZE);
	if (r < 0) {
		if (r != LIBUSB_ERROR_PIPE)
			usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
		return r;
	}
	if (r < LIBUSB_DT_BOS_SIZE) {
		usbi_err(handle->dev->ctx, "short BOS read %d/%d",
			 r, LIBUSB_DT_BOS_SIZE);
		return LIBUSB_ERROR_IO;
	}

	usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
	usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
		 _bos.wTotalLength, _bos.bNumDeviceCaps);
	bos_data = calloc(_bos.wTotalLength, 1);
	if (bos_data == NULL)
		return LIBUSB_ERROR_NO_MEM;

	r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data,
				  _bos.wTotalLength);
	if (r >= 0)
		r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian);
	else
		usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);

	free(bos_data);
	return r;
}
Beispiel #5
0
static int mainPhase(){
	int response = 0;
	static int transferred;
	int i;
	
	struct libusb_config_descriptor* config_desc;
	const struct libusb_interface_descriptor* interface_desc;
	
	response = libusb_get_descriptor(handle, LIBUSB_DT_CONFIG, 0, buffer, LIBUSB_DT_CONFIG_SIZE);
	//response = libusb_get_descriptor(handle, LIBUSB_DT_INTERFACE, 0, buffer, LIBUSB_DT_INTERFACE_SIZE);
	if(response < 0){error(response);return -1;}

	config_desc = (struct libusb_config_descriptor*)buffer;
	printf("bLength %i\n", config_desc->bLength);
	printf("bNumInterfaces %i\n", config_desc->bNumInterfaces);
	printf("MaxPower %i\n", config_desc->MaxPower);
	
	/* Send our host name to device */
	memset(buffer, 0x0, sizeof(buffer));
	gethostname((char*)buffer, sizeof(buffer));

	response = libusb_bulk_transfer(handle, OUT, buffer, sizeof(buffer), &transferred, 5000);
	if(response < 0){
		error(response);
		return -1;
	}
	else{
		printf("Done, transferred %i bytes\n", transferred);
		status(response);
	}

	/* Receive back device response */
	memset(buffer, 0x0, sizeof(buffer));
	response = libusb_bulk_transfer(handle, IN, buffer, sizeof(buffer), &transferred, 5000);
	if(response < 0){
		error(response);
		return -1;
	}
	else{
		printf("Done, received %i bytes\n", transferred);
		status(response);
	}

	printf("Received: %s\n", buffer);
	
	for(i=0; i<sizeof(buffer); i++)
		printf("%i ", buffer[i]);
	printf("\n");
	
	return 0;
}
Beispiel #6
0
bool CH341DeviceInit(void)
{
	int ret;
	unsigned char desc[0x12];

	if (CH341DeviceHanlde)
		return true;

	if ((ret = libusb_init(NULL)))
	{
		fprintf(stderr, "Error: libusb_init failed: %d (%s)\n", ret, libusb_error_name(ret));
		return false;
	}

	if (!(CH341DeviceHanlde = libusb_open_device_with_vid_pid(NULL, CH341_USB_VID, CH341_USB_PID)))
	{
		fprintf(stderr, "Error: CH341 device (%04x/%04x) not found\n", CH341_USB_VID, CH341_USB_PID);
		return false;
	}

#if !defined(_MSC_VER) && !defined(MSYS) && !defined(CYGWIN) && !defined(WIN32) && !defined(MINGW) && !defined(MINGW32)
	if (libusb_kernel_driver_active(CH341DeviceHanlde, 0))
	{
		if ((ret = libusb_detach_kernel_driver(CH341DeviceHanlde, 0)))
		{
			fprintf(stderr, "Error: libusb_detach_kernel_driver failed: %d (%s)\n", ret, libusb_error_name(ret));
			goto cleanup;
		}
	}
#endif

	if ((ret = libusb_claim_interface(CH341DeviceHanlde, 0)))
	{
		fprintf(stderr, "Error: libusb_claim_interface failed: %d (%s)\n", ret, libusb_error_name(ret));
		goto cleanup;
	}

	if (!(ret = libusb_get_descriptor(CH341DeviceHanlde, LIBUSB_DT_DEVICE, 0x00, desc, 0x12)))
	{
		fprintf(stderr, "Warning: libusb_get_descriptor failed: %d (%s)\n", ret, libusb_error_name(ret));
	}

	printf("CH341 %d.%02d found.\n\n", desc[12], desc[13]);

	return true;

cleanup:
	libusb_close(CH341DeviceHanlde);
	CH341DeviceHanlde = NULL;
	return false;
}
Beispiel #7
0
int musb_get_device(MUSB_INTERFACE *usb_interface)
{
#ifdef HAVE_LIBUSB
   struct usb_device_descriptor d;
   usb_get_descriptor(usb_interface->dev, USB_DT_DEVICE, 0, &d, sizeof(d));
   return d.bcdDevice;
#elif HAVE_LIBUSB10
   struct libusb_device_descriptor d;
   libusb_get_descriptor(usb_interface->dev, LIBUSB_DT_DEVICE, 0, (unsigned char *)&d, sizeof(d));
   return d.bcdDevice;
#else
   return 0;
#endif
}
Beispiel #8
0
static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc)
{
	struct usb_dfu_func_descriptor func_dfu;
	libusb_device_handle *devh;
	struct dfu_if *pdfu;
	struct libusb_config_descriptor *cfg;
	const struct libusb_interface_descriptor *intf;
	const struct libusb_interface *uif;
	char alt_name[MAX_DESC_STR_LEN + 1];
	char serial_name[MAX_DESC_STR_LEN + 1];
	int cfg_idx;
	int intf_idx;
	int alt_idx;
	int ret;
	int has_dfu;

	for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) {
		memset(&func_dfu, 0, sizeof(func_dfu));
		has_dfu = 0;

		ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg);
		if (ret != 0)
			return;
		if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) {
			libusb_free_config_descriptor(cfg);
			continue;
		}

		/*
		 * In some cases, noticably FreeBSD if uid != 0,
		 * the configuration descriptors are empty
		 */
		if (!cfg)
			return;

		ret = find_descriptor(cfg->extra, cfg->extra_length,
		    USB_DT_DFU, &func_dfu, sizeof(func_dfu));
		if (ret > -1)
			goto found_dfu;

		for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
		     intf_idx++) {
			uif = &cfg->interface[intf_idx];
			if (!uif)
				break;

			for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting;
			     alt_idx++) {
				intf = &uif->altsetting[alt_idx];

				if (intf->bInterfaceClass != 0xfe ||
				    intf->bInterfaceSubClass != 1)
					continue;

				ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU,
				      &func_dfu, sizeof(func_dfu));
				if (ret > -1)
					goto found_dfu;

				has_dfu = 1;
			}
		}
		if (has_dfu) {
			/*
			 * Finally try to retrieve it requesting the
			 * device directly This is not supported on
			 * all devices for non-standard types
			 */
			if (libusb_open(dev, &devh) == 0) {
				ret = libusb_get_descriptor(devh, USB_DT_DFU, 0,
				    (void *)&func_dfu, sizeof(func_dfu));
				libusb_close(devh);
				if (ret > -1)
					goto found_dfu;
			}
			warnx("Device has DFU interface, "
			    "but has no DFU functional descriptor");

			/* fake version 1.0 */
			func_dfu.bLength = 7;
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
			goto found_dfu;
		}
		libusb_free_config_descriptor(cfg);
		continue;

found_dfu:
		if (func_dfu.bLength == 7) {
			printf("Deducing device DFU version from functional descriptor "
			    "length\n");
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
		} else if (func_dfu.bLength < 9) {
			printf("Error obtaining DFU functional descriptor\n");
			printf("Please report this as a bug!\n");
			printf("Warning: Assuming DFU version 1.0\n");
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
			printf("Warning: Transfer size can not be detected\n");
			func_dfu.wTransferSize = 0;
		}

		for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
		     intf_idx++) {
			if (match_iface_index > -1 && match_iface_index != intf_idx)
				continue;

			uif = &cfg->interface[intf_idx];
			if (!uif)
				break;

			for (alt_idx = 0;
			     alt_idx < uif->num_altsetting; alt_idx++) {
				int dfu_mode;

				intf = &uif->altsetting[alt_idx];

				if (intf->bInterfaceClass != 0xfe ||
				    intf->bInterfaceSubClass != 1)
					continue;

				dfu_mode = (intf->bInterfaceProtocol == 2);
				/* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */
				if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0)
					dfu_mode = 1;

				/* LPC DFU bootloader has bInterfaceProtocol 1 (Runtime) instead of 2 */
				if (desc->idVendor == 0x1fc9 && desc->idProduct == 0x000c && intf->bInterfaceProtocol == 1)
					dfu_mode = 1;

				if (dfu_mode &&
				    match_iface_alt_index > -1 && match_iface_alt_index != alt_idx)
					continue;

				if (dfu_mode) {
					if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) ||
					    (match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) {
						continue;
					}
				} else {
					if ((match_vendor >= 0 && match_vendor != desc->idVendor) ||
					    (match_product >= 0 && match_product != desc->idProduct)) {
						continue;
					}
				}

				if (libusb_open(dev, &devh)) {
					warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct);
					break;
				}
				if (intf->iInterface != 0)
					ret = libusb_get_string_descriptor_ascii(devh,
					    intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN);
				else
					ret = -1;
				if (ret < 1)
					strcpy(alt_name, "UNKNOWN");
				if (desc->iSerialNumber != 0)
					ret = libusb_get_string_descriptor_ascii(devh,
					    desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN);
				else
					ret = -1;
				if (ret < 1)
					strcpy(serial_name, "UNKNOWN");
				libusb_close(devh);

				if (dfu_mode &&
				    match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name))
					continue;

				if (dfu_mode) {
					if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name))
						continue;
				} else {
					if (match_serial != NULL && strcmp(match_serial, serial_name))
						continue;
				}

				pdfu = dfu_malloc(sizeof(*pdfu));

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

				pdfu->func_dfu = func_dfu;
				pdfu->dev = libusb_ref_device(dev);
				pdfu->quirks = get_quirks(desc->idVendor,
				    desc->idProduct, desc->bcdDevice);
				pdfu->vendor = desc->idVendor;
				pdfu->product = desc->idProduct;
				pdfu->bcdDevice = desc->bcdDevice;
				pdfu->configuration = cfg->bConfigurationValue;
				pdfu->interface = intf->bInterfaceNumber;
				pdfu->altsetting = intf->bAlternateSetting;
				pdfu->devnum = libusb_get_device_address(dev);
				pdfu->busnum = libusb_get_bus_number(dev);
				pdfu->alt_name = strdup(alt_name);
				if (pdfu->alt_name == NULL)
					errx(EX_SOFTWARE, "Out of memory");
				pdfu->serial_name = strdup(serial_name);
				if (pdfu->serial_name == NULL)
					errx(EX_SOFTWARE, "Out of memory");
				if (dfu_mode)
					pdfu->flags |= DFU_IFF_DFU;
				if (pdfu->quirks & QUIRK_FORCE_DFU11) {
					pdfu->func_dfu.bcdDFUVersion =
					  libusb_cpu_to_le16(0x0110);
				}
				pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0;

				/* queue into list */
				pdfu->next = dfu_root;
				dfu_root = pdfu;
			}
		}
		libusb_free_config_descriptor(cfg);
	}
}
Beispiel #9
0
int cyusb_get_descriptor(cyusb_handle *h, unsigned char desc_type, unsigned char desc_index, unsigned char *data,
        int len)
{
	return ( libusb_get_descriptor(h, desc_type, desc_index, data, len) );
}
Beispiel #10
0
/* Configure CH341A, find the device and set the default interface. */
int32_t ch341Configure(uint16_t vid, uint16_t pid)
{
    struct libusb_device *dev;
    int32_t ret;
    struct sigaction sa;

    uint8_t  desc[0x12];

    if (devHandle != NULL) {
        fprintf(stderr, "Call ch341Release before re-configure\n");
        return -1;
    }
    ret = libusb_init(NULL);
    if(ret < 0) {
        fprintf(stderr, "Couldn't initialise libusb\n");
        return -1;
    }

    libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);

    if(!(devHandle = libusb_open_device_with_vid_pid(NULL, vid, pid))) {
        fprintf(stderr, "Couldn't open device [%04x:%04x].\n", vid, pid);
        return -1;
    }

    if(!(dev = libusb_get_device(devHandle))) {
        fprintf(stderr, "Couldn't get bus number and address.\n");
        goto close_handle;
    }

    if(libusb_kernel_driver_active(devHandle, 0)) {
        ret = libusb_detach_kernel_driver(devHandle, 0);
        if(ret) {
            fprintf(stderr, "Failed to detach kernel driver: '%s'\n", strerror(-ret));
            goto close_handle;
        }
    }

    ret = libusb_claim_interface(devHandle, 0);

    if(ret) {
        fprintf(stderr, "Failed to claim interface 0: '%s'\n", strerror(-ret));
        goto close_handle;
    }

    ret = libusb_get_descriptor(devHandle, LIBUSB_DT_DEVICE, 0x00, desc, 0x12);

    if(ret < 0) {
        fprintf(stderr, "Failed to get device descriptor: '%s'\n", strerror(-ret));
        goto release_interface;
    }

    printf("Device reported its revision [%d.%02d]\n", desc[12], desc[13]);
    sa.sa_handler = &sig_int;
    sa.sa_flags = SA_RESTART;
    sigfillset(&sa.sa_mask);
    if (sigaction(SIGINT, &sa, &saold) == -1) {
        perror("Error: cannot handle SIGINT"); // Should not happen
    }
    return 0;
release_interface:
    libusb_release_interface(devHandle, 0);
close_handle:
    libusb_close(devHandle);
    devHandle = NULL;
    return -1;
}
// Tests based on USB descriptors.
// This primarily tests the "Get Descriptor" request.
static void descriptor_tests(void)
{
	uint8_t buffer[1024];
	char string_buffer[1024];
	unsigned int i;
	int r;

	// Check that device descriptor is exactly 18 bytes long.
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0, buffer, sizeof(buffer));
	if (r != 18)
	{
		printf("Could not get valid device descriptor\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
	// Check that a truncated device descriptor can be obtained.
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0, buffer, 7);
	if (r != 7)
	{
		printf("Could not get truncated (length = 7) device descriptor\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
	// index != 0 is invalid for device descriptors.
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0xff, buffer, sizeof(buffer));
	if (r >= 0)
	{
		printf("Get device descriptor succeeds for index != 0\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
	// Get first configuration descriptor.
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_CONFIG, 0, buffer, sizeof(buffer));
	if (r < 0)
	{
		printf("Could not get first configuration descriptor\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
	// Get all string descriptors.
	for (i = 0; i <= 0xff; i++)
	{
		r = libusb_get_string_descriptor_ascii(device_handle, i, string_buffer, sizeof(string_buffer));
		if (r >= 0)
		{
			printf("String descriptor %u: \"%s\"\n", i, string_buffer);
		}
	}
	// Attempt to get interface and endpoint descriptors. This should fail
	// (those descriptors as supposed to be included only as part of the
	// configuration descriptor).
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_INTERFACE, 0, buffer, sizeof(buffer));
	if (r >= 0)
	{
		printf("Was able to get interface descriptor directly\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
	r = libusb_get_descriptor(device_handle, LIBUSB_DT_ENDPOINT, 0, buffer, sizeof(buffer));
	if (r >= 0)
	{
		printf("Was able to get endpoint descriptor directly\n");
		tests_failed++;
	}
	else
	{
		tests_succeeded++;
	}
}
void poke(libusb_device_handle *dev)
{
	unsigned char buffer[256];

	(void)libusb_get_descriptor(dev, 0, 0, buffer, sizeof buffer);
}
Beispiel #13
0
API_EXPORTED int usb_get_descriptor(usb_dev_handle *dev, unsigned char type,
	unsigned char desc_index, void *buf, int size)
{
	return libusb_get_descriptor(dev->handle, type, desc_index, buf, size);
}