/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
/*
 * USB descriptor handling functions for libusb
 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "libusbi.h"

#include <string.h>

#define DESC_HEADER_LENGTH	2

/** @defgroup libusb_desc USB descriptors
 * This page details how to examine the various standard USB descriptors
 * for detected devices
 */

#define READ_LE16(p) ((uint16_t)	\
	(((uint16_t)((p)[1]) << 8) |	\
	 ((uint16_t)((p)[0]))))

#define READ_LE32(p) ((uint32_t)	\
	(((uint32_t)((p)[3]) << 24) |	\
	 ((uint32_t)((p)[2]) << 16) |	\
	 ((uint32_t)((p)[1]) <<  8) |	\
	 ((uint32_t)((p)[0]))))

union config_desc_buf {
	struct usbi_configuration_descriptor desc;
	uint8_t buf[LIBUSB_DT_CONFIG_SIZE];
	uint16_t dummy;		/* Force 2-byte alignment */
};

union string_desc_buf {
	struct usbi_string_descriptor desc;
	uint8_t buf[255];	/* Some devices choke on size > 255 */
	uint16_t dummy;		/* Force 2-byte alignment */
};

union bos_desc_buf {
	struct usbi_bos_descriptor desc;
	uint8_t buf[LIBUSB_DT_BOS_SIZE];
	uint16_t dummy;		/* Force 2-byte alignment */
};

static void parse_descriptor(const void *source, const char *descriptor, void *dest)
{
	const uint8_t *sp = source;
	uint8_t *dp = dest;
	char field_type;

	while (*descriptor) {
		field_type = *descriptor++;
		switch (field_type) {
		case 'b':	/* 8-bit byte */
			*dp++ = *sp++;
			break;
		case 'w':	/* 16-bit word, convert from little endian to CPU */
			dp += ((uintptr_t)dp & 1);	/* Align to 16-bit word boundary */

			*((uint16_t *)dp) = READ_LE16(sp);
			sp += 2;
			dp += 2;
			break;
		case 'd':	/* 32-bit word, convert from little endian to CPU */
			dp += 4 - ((uintptr_t)dp & 3);	/* Align to 32-bit word boundary */

			*((uint32_t *)dp) = READ_LE32(sp);
			sp += 4;
			dp += 4;
			break;
		case 'u':	/* 16 byte UUID */
			memcpy(dp, sp, 16);
			sp += 16;
			dp += 16;
			break;
		}
	}
}

static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
{
	free((void *)endpoint->extra);
}

static int parse_endpoint(struct libusb_context *ctx,
	struct libusb_endpoint_descriptor *endpoint, const uint8_t *buffer, int size)
{
	const struct usbi_descriptor_header *header;
	const uint8_t *begin;
	void *extra;
	int parsed = 0;
	int len;

	if (size < DESC_HEADER_LENGTH) {
		usbi_err(ctx, "short endpoint descriptor read %d/%d",
			 size, DESC_HEADER_LENGTH);
		return LIBUSB_ERROR_IO;
	}

	header = (const struct usbi_descriptor_header *)buffer;
	if (header->bDescriptorType != LIBUSB_DT_ENDPOINT) {
		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
			header->bDescriptorType, LIBUSB_DT_ENDPOINT);
		return parsed;
	} else if (header->bLength < LIBUSB_DT_ENDPOINT_SIZE) {
		usbi_err(ctx, "invalid endpoint bLength (%u)", header->bLength);
		return LIBUSB_ERROR_IO;
	} else if (header->bLength > size) {
		usbi_warn(ctx, "short endpoint descriptor read %d/%u",
			  size, header->bLength);
		return parsed;
	}

	if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE)
		parse_descriptor(buffer, "bbbbwbbb", endpoint);
	else
		parse_descriptor(buffer, "bbbbwb", endpoint);

	buffer += header->bLength;
	size -= header->bLength;
	parsed += header->bLength;

	/* Skip over the rest of the Class Specific or Vendor Specific */
	/*  descriptors */
	begin = buffer;
	while (size >= DESC_HEADER_LENGTH) {
		header = (const struct usbi_descriptor_header *)buffer;
		if (header->bLength < DESC_HEADER_LENGTH) {
			usbi_err(ctx, "invalid extra ep desc len (%u)",
				 header->bLength);
			return LIBUSB_ERROR_IO;
		} else if (header->bLength > size) {
			usbi_warn(ctx, "short extra ep desc read %d/%u",
				  size, header->bLength);
			return parsed;
		}

		/* If we find another "proper" descriptor then we're done  */
		if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
		    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
		    header->bDescriptorType == LIBUSB_DT_CONFIG ||
		    header->bDescriptorType == LIBUSB_DT_DEVICE)
			break;

		usbi_dbg("skipping descriptor 0x%x", header->bDescriptorType);
		buffer += header->bLength;
		size -= header->bLength;
		parsed += header->bLength;
	}

	/* Copy any unknown descriptors into a storage area for drivers */
	/*  to later parse */
	len = (int)(buffer - begin);
	if (len <= 0)
		return parsed;

	extra = malloc((size_t)len);
	if (!extra)
		return LIBUSB_ERROR_NO_MEM;

	memcpy(extra, begin, len);
	endpoint->extra = extra;
	endpoint->extra_length = len;

	return parsed;
}

static void clear_interface(struct libusb_interface *usb_interface)
{
	int i;

	if (usb_interface->altsetting) {
		for (i = 0; i < usb_interface->num_altsetting; i++) {
			struct libusb_interface_descriptor *ifp =
				(struct libusb_interface_descriptor *)
				usb_interface->altsetting + i;

			free((void *)ifp->extra);
			if (ifp->endpoint) {
				uint8_t j;

				for (j = 0; j < ifp->bNumEndpoints; j++)
					clear_endpoint((struct libusb_endpoint_descriptor *)
						       ifp->endpoint + j);
			}
			free((void *)ifp->endpoint);
		}
	}
	free((void *)usb_interface->altsetting);
	usb_interface->altsetting = NULL;
}

static int parse_interface(libusb_context *ctx,
	struct libusb_interface *usb_interface, const uint8_t *buffer, int size)
{
	int len;
	int r;
	int parsed = 0;
	int interface_number = -1;
	const struct usbi_descriptor_header *header;
	const struct usbi_interface_descriptor *if_desc;
	struct libusb_interface_descriptor *ifp;
	const uint8_t *begin;

	while (size >= LIBUSB_DT_INTERFACE_SIZE) {
		struct libusb_interface_descriptor *altsetting;

		altsetting = realloc((void *)usb_interface->altsetting,
			sizeof(*altsetting) * (size_t)(usb_interface->num_altsetting + 1));
		if (!altsetting) {
			r = LIBUSB_ERROR_NO_MEM;
			goto err;
		}
		usb_interface->altsetting = altsetting;

		ifp = altsetting + usb_interface->num_altsetting;
		parse_descriptor(buffer, "bbbbbbbbb", ifp);
		if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
			usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
				 ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
			return parsed;
		} else if (ifp->bLength < LIBUSB_DT_INTERFACE_SIZE) {
			usbi_err(ctx, "invalid interface bLength (%u)",
				 ifp->bLength);
			r = LIBUSB_ERROR_IO;
			goto err;
		} else if (ifp->bLength > size) {
			usbi_warn(ctx, "short intf descriptor read %d/%u",
				 size, ifp->bLength);
			return parsed;
		} else if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
			usbi_err(ctx, "too many endpoints (%u)", ifp->bNumEndpoints);
			r = LIBUSB_ERROR_IO;
			goto err;
		}

		usb_interface->num_altsetting++;
		ifp->extra = NULL;
		ifp->extra_length = 0;
		ifp->endpoint = NULL;

		if (interface_number == -1)
			interface_number = ifp->bInterfaceNumber;

		/* Skip over the interface */
		buffer += ifp->bLength;
		parsed += ifp->bLength;
		size -= ifp->bLength;

		begin = buffer;

		/* Skip over any interface, class or vendor descriptors */
		while (size >= DESC_HEADER_LENGTH) {
			header = (const struct usbi_descriptor_header *)buffer;
			if (header->bLength < DESC_HEADER_LENGTH) {
				usbi_err(ctx,
					 "invalid extra intf desc len (%u)",
					 header->bLength);
				r = LIBUSB_ERROR_IO;
				goto err;
			} else if (header->bLength > size) {
				usbi_warn(ctx,
					  "short extra intf desc read %d/%u",
					  size, header->bLength);
				return parsed;
			}

			/* If we find another "proper" descriptor then we're done */
			if (header->bDescriptorType == LIBUSB_DT_INTERFACE ||
			    header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
			    header->bDescriptorType == LIBUSB_DT_DEVICE)
				break;

			buffer += header->bLength;
			parsed += header->bLength;
			size -= header->bLength;
		}

		/* Copy any unknown descriptors into a storage area for */
		/*  drivers to later parse */
		len = (int)(buffer - begin);
		if (len > 0) {
			void *extra = malloc((size_t)len);

			if (!extra) {
				r = LIBUSB_ERROR_NO_MEM;
				goto err;
			}

			memcpy(extra, begin, len);
			ifp->extra = extra;
			ifp->extra_length = len;
		}

		if (ifp->bNumEndpoints > 0) {
			struct libusb_endpoint_descriptor *endpoint;
			uint8_t i;

			endpoint = calloc(ifp->bNumEndpoints, sizeof(*endpoint));
			if (!endpoint) {
				r = LIBUSB_ERROR_NO_MEM;
				goto err;
			}

			ifp->endpoint = endpoint;
			for (i = 0; i < ifp->bNumEndpoints; i++) {
				r = parse_endpoint(ctx, endpoint + i, buffer, size);
				if (r < 0)
					goto err;
				if (r == 0) {
					ifp->bNumEndpoints = i;
					break;
				}

				buffer += r;
				parsed += r;
				size -= r;
			}
		}

		/* We check to see if it's an alternate to this one */
		if_desc = (const struct usbi_interface_descriptor *)buffer;
		if (size < LIBUSB_DT_INTERFACE_SIZE ||
		    if_desc->bDescriptorType != LIBUSB_DT_INTERFACE ||
		    if_desc->bInterfaceNumber != interface_number)
			return parsed;
	}

	return parsed;
err:
	clear_interface(usb_interface);
	return r;
}

static void clear_configuration(struct libusb_config_descriptor *config)
{
	uint8_t i;

	if (config->interface) {
		for (i = 0; i < config->bNumInterfaces; i++)
			clear_interface((struct libusb_interface *)
					config->interface + i);
	}
	free((void *)config->interface);
	free((void *)config->extra);
}

static int parse_configuration(struct libusb_context *ctx,
	struct libusb_config_descriptor *config, const uint8_t *buffer, int size)
{
	uint8_t i;
	int r;
	const struct usbi_descriptor_header *header;
	struct libusb_interface *usb_interface;

	if (size < LIBUSB_DT_CONFIG_SIZE) {
		usbi_err(ctx, "short config descriptor read %d/%d",
			 size, LIBUSB_DT_CONFIG_SIZE);
		return LIBUSB_ERROR_IO;
	}

	parse_descriptor(buffer, "bbwbbbbb", config);
	if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
			 config->bDescriptorType, LIBUSB_DT_CONFIG);
		return LIBUSB_ERROR_IO;
	} else if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
		usbi_err(ctx, "invalid config bLength (%u)", config->bLength);
		return LIBUSB_ERROR_IO;
	} else if (config->bLength > size) {
		usbi_err(ctx, "short config descriptor read %d/%u",
			 size, config->bLength);
		return LIBUSB_ERROR_IO;
	} else if (config->bNumInterfaces > USB_MAXINTERFACES) {
		usbi_err(ctx, "too many interfaces (%u)", config->bNumInterfaces);
		return LIBUSB_ERROR_IO;
	}

	usb_interface = calloc(config->bNumInterfaces, sizeof(*usb_interface));
	if (!usb_interface)
		return LIBUSB_ERROR_NO_MEM;

	config->interface = usb_interface;

	buffer += config->bLength;
	size -= config->bLength;

	for (i = 0; i < config->bNumInterfaces; i++) {
		int len;
		const uint8_t *begin;

		/* Skip over the rest of the Class Specific or Vendor */
		/*  Specific descriptors */
		begin = buffer;
		while (size >= DESC_HEADER_LENGTH) {
			header = (const struct usbi_descriptor_header *)buffer;
			if (header->bLength < DESC_HEADER_LENGTH) {
				usbi_err(ctx,
					 "invalid extra config desc len (%u)",
					 header->bLength);
				r = LIBUSB_ERROR_IO;
				goto err;
			} else if (header->bLength > size) {
				usbi_warn(ctx,
					  "short extra config desc read %d/%u",
					  size, header->bLength);
				config->bNumInterfaces = i;
				return size;
			}

			/* If we find another "proper" descriptor then we're done */
			if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
			    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
			    header->bDescriptorType == LIBUSB_DT_DEVICE)
				break;

			usbi_dbg("skipping descriptor 0x%x", header->bDescriptorType);
			buffer += header->bLength;
			size -= header->bLength;
		}

		/* Copy any unknown descriptors into a storage area for */
		/*  drivers to later parse */
		len = (int)(buffer - begin);
		if (len > 0) {
			uint8_t *extra = realloc((void *)config->extra,
						 (size_t)(config->extra_length + len));

			if (!extra) {
				r = LIBUSB_ERROR_NO_MEM;
				goto err;
			}

			memcpy(extra + config->extra_length, begin, len);
			config->extra = extra;
			config->extra_length += len;
		}

		r = parse_interface(ctx, usb_interface + i, buffer, size);
		if (r < 0)
			goto err;
		if (r == 0) {
			config->bNumInterfaces = i;
			break;
		}

		buffer += r;
		size -= r;
	}

	return size;

err:
	clear_configuration(config);
	return r;
}

static int raw_desc_to_config(struct libusb_context *ctx,
	const uint8_t *buf, int size, struct libusb_config_descriptor **config)
{
	struct libusb_config_descriptor *_config = calloc(1, sizeof(*_config));
	int r;

	if (!_config)
		return LIBUSB_ERROR_NO_MEM;

	r = parse_configuration(ctx, _config, buf, size);
	if (r < 0) {
		usbi_err(ctx, "parse_configuration failed with error %d", r);
		free(_config);
		return r;
	} else if (r > 0) {
		usbi_warn(ctx, "still %d bytes of descriptor data left", r);
	}

	*config = _config;
	return LIBUSB_SUCCESS;
}

static int get_active_config_descriptor(struct libusb_device *dev,
	uint8_t *buffer, size_t size)
{
	int r = usbi_backend.get_active_config_descriptor(dev, buffer, size);

	if (r < 0)
		return r;

	if (r < LIBUSB_DT_CONFIG_SIZE) {
		usbi_err(DEVICE_CTX(dev), "short config descriptor read %d/%d",
			 r, LIBUSB_DT_CONFIG_SIZE);
		return LIBUSB_ERROR_IO;
	} else if (r != (int)size) {
		usbi_warn(DEVICE_CTX(dev), "short config descriptor read %d/%d",
			 r, (int)size);
	}

	return r;
}

static int get_config_descriptor(struct libusb_device *dev, uint8_t config_idx,
	uint8_t *buffer, size_t size)
{
	int r = usbi_backend.get_config_descriptor(dev, config_idx, buffer, size);

	if (r < 0)
		return r;
	if (r < LIBUSB_DT_CONFIG_SIZE) {
		usbi_err(DEVICE_CTX(dev), "short config descriptor read %d/%d",
			 r, LIBUSB_DT_CONFIG_SIZE);
		return LIBUSB_ERROR_IO;
	} else if (r != (int)size) {
		usbi_warn(DEVICE_CTX(dev), "short config descriptor read %d/%d",
			 r, (int)size);
	}

	return r;
}

/** \ingroup libusb_desc
 * Get the USB device descriptor for a given device.
 *
 * This is a non-blocking function; the device descriptor is cached in memory.
 *
 * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this
 * function always succeeds.
 *
 * \param dev the device
 * \param desc output location for the descriptor data
 * \returns 0 on success or a LIBUSB_ERROR code on failure
 */
int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
	struct libusb_device_descriptor *desc)
{
	usbi_dbg(" ");
	static_assert(sizeof(dev->device_descriptor) == LIBUSB_DT_DEVICE_SIZE,
		      "struct libusb_device_descriptor is not expected size");
	*desc = dev->device_descriptor;
	return 0;
}

/** \ingroup libusb_desc
 * Get the USB configuration descriptor for the currently active configuration.
 * This is a non-blocking function which does not involve any requests being
 * sent to the device.
 *
 * \param dev a device
 * \param config output location for the USB configuration descriptor. Only
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
 * after use.
 * \returns 0 on success
 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
 * \returns another LIBUSB_ERROR code on error
 * \see libusb_get_config_descriptor
 */
int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
	struct libusb_config_descriptor **config)
{
	union config_desc_buf _config;
	uint16_t config_len;
	uint8_t *buf;
	int r;

	r = get_active_config_descriptor(dev, _config.buf, sizeof(_config.buf));
	if (r < 0)
		return r;

	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
	buf = malloc(config_len);
	if (!buf)
		return LIBUSB_ERROR_NO_MEM;

	r = get_active_config_descriptor(dev, buf, config_len);
	if (r >= 0)
		r = raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);

	free(buf);
	return r;
}

/** \ingroup libusb_desc
 * Get a USB configuration descriptor based on its index.
 * This is a non-blocking function which does not involve any requests being
 * sent to the device.
 *
 * \param dev a device
 * \param config_index the index of the configuration you wish to retrieve
 * \param config output location for the USB configuration descriptor. Only
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
 * after use.
 * \returns 0 on success
 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
 * \returns another LIBUSB_ERROR code on error
 * \see libusb_get_active_config_descriptor()
 * \see libusb_get_config_descriptor_by_value()
 */
int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
	uint8_t config_index, struct libusb_config_descriptor **config)
{
	union config_desc_buf _config;
	uint16_t config_len;
	uint8_t *buf;
	int r;

	usbi_dbg("index %u", config_index);
	if (config_index >= dev->device_descriptor.bNumConfigurations)
		return LIBUSB_ERROR_NOT_FOUND;

	r = get_config_descriptor(dev, config_index, _config.buf, sizeof(_config.buf));
	if (r < 0)
		return r;

	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
	buf = malloc(config_len);
	if (!buf)
		return LIBUSB_ERROR_NO_MEM;

	r = get_config_descriptor(dev, config_index, buf, config_len);
	if (r >= 0)
		r = raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);

	free(buf);
	return r;
}

/** \ingroup libusb_desc
 * Get a USB configuration descriptor with a specific bConfigurationValue.
 * This is a non-blocking function which does not involve any requests being
 * sent to the device.
 *
 * \param dev a device
 * \param bConfigurationValue the bConfigurationValue of the configuration you
 * wish to retrieve
 * \param config output location for the USB configuration descriptor. Only
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
 * after use.
 * \returns 0 on success
 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
 * \returns another LIBUSB_ERROR code on error
 * \see libusb_get_active_config_descriptor()
 * \see libusb_get_config_descriptor()
 */
int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
	uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
{
	uint8_t idx;
	int r;

	if (usbi_backend.get_config_descriptor_by_value) {
		void *buf;

		r = usbi_backend.get_config_descriptor_by_value(dev,
			bConfigurationValue, &buf);
		if (r < 0)
			return r;

		return raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);
	}

	usbi_dbg("value %u", bConfigurationValue);
	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
		union config_desc_buf _config;

		r = get_config_descriptor(dev, idx, _config.buf, sizeof(_config.buf));
		if (r < 0)
			return r;

		if (_config.desc.bConfigurationValue == bConfigurationValue)
			return libusb_get_config_descriptor(dev, idx, config);
	}

	return LIBUSB_ERROR_NOT_FOUND;
}

/** \ingroup libusb_desc
 * Free a configuration descriptor obtained from
 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
 * It is safe to call this function with a NULL config parameter, in which
 * case the function simply returns.
 *
 * \param config the configuration descriptor to free
 */
void API_EXPORTED libusb_free_config_descriptor(
	struct libusb_config_descriptor *config)
{
	if (!config)
		return;

	clear_configuration(config);
	free(config);
}

/** \ingroup libusb_desc
 * Get an endpoints superspeed endpoint companion descriptor (if any)
 *
 * \param ctx the context to operate on, or NULL for the default context
 * \param endpoint endpoint descriptor from which to get the superspeed
 * endpoint companion descriptor
 * \param ep_comp output location for the superspeed endpoint companion
 * descriptor. Only valid if 0 was returned. Must be freed with
 * libusb_free_ss_endpoint_companion_descriptor() after use.
 * \returns 0 on success
 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
 * \returns another LIBUSB_ERROR code on error
 */
int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
	libusb_context *ctx,
	const struct libusb_endpoint_descriptor *endpoint,
	struct libusb_ss_endpoint_companion_descriptor **ep_comp)
{
	struct usbi_descriptor_header *header;
	const uint8_t *buffer = endpoint->extra;
	int size = endpoint->extra_length;

	*ep_comp = NULL;

	while (size >= DESC_HEADER_LENGTH) {
		header = (struct usbi_descriptor_header *)buffer;
		if (header->bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
			if (header->bLength < DESC_HEADER_LENGTH) {
				usbi_err(ctx, "invalid descriptor length %u",
					 header->bLength);
				return LIBUSB_ERROR_IO;
			}
			buffer += header->bLength;
			size -= header->bLength;
			continue;
		} else if (header->bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
			usbi_err(ctx, "invalid ss-ep-comp-desc length %u",
				 header->bLength);
			return LIBUSB_ERROR_IO;
		} else if (header->bLength > size) {
			usbi_err(ctx, "short ss-ep-comp-desc read %d/%u",
				 size, header->bLength);
			return LIBUSB_ERROR_IO;
		}

		*ep_comp = malloc(sizeof(**ep_comp));
		if (!*ep_comp)
			return LIBUSB_ERROR_NO_MEM;
		parse_descriptor(buffer, "bbbbw", *ep_comp);
		return LIBUSB_SUCCESS;
	}
	return LIBUSB_ERROR_NOT_FOUND;
}

/** \ingroup libusb_desc
 * Free a superspeed endpoint companion descriptor obtained from
 * libusb_get_ss_endpoint_companion_descriptor().
 * It is safe to call this function with a NULL ep_comp parameter, in which
 * case the function simply returns.
 *
 * \param ep_comp the superspeed endpoint companion descriptor to free
 */
void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
	struct libusb_ss_endpoint_companion_descriptor *ep_comp)
{
	free(ep_comp);
}

static int parse_bos(struct libusb_context *ctx,
	struct libusb_bos_descriptor **bos,
	const uint8_t *buffer, int size)
{
	struct libusb_bos_descriptor *_bos;
	const struct usbi_bos_descriptor *bos_desc;
	const struct usbi_descriptor_header *header;
	uint8_t i;

	if (size < LIBUSB_DT_BOS_SIZE) {
		usbi_err(ctx, "short bos descriptor read %d/%d",
			 size, LIBUSB_DT_BOS_SIZE);
		return LIBUSB_ERROR_IO;
	}

	bos_desc = (const struct usbi_bos_descriptor *)buffer;
	if (bos_desc->bDescriptorType != LIBUSB_DT_BOS) {
		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
			 bos_desc->bDescriptorType, LIBUSB_DT_BOS);
		return LIBUSB_ERROR_IO;
	} else if (bos_desc->bLength < LIBUSB_DT_BOS_SIZE) {
		usbi_err(ctx, "invalid bos bLength (%u)", bos_desc->bLength);
		return LIBUSB_ERROR_IO;
	} else if (bos_desc->bLength > size) {
		usbi_err(ctx, "short bos descriptor read %d/%u",
			 size, bos_desc->bLength);
		return LIBUSB_ERROR_IO;
	}

	_bos = calloc(1, sizeof(*_bos) + bos_desc->bNumDeviceCaps * sizeof(void *));
	if (!_bos)
		return LIBUSB_ERROR_NO_MEM;

	parse_descriptor(buffer, "bbwb", _bos);
	buffer += _bos->bLength;
	size -= _bos->bLength;

	/* Get the device capability descriptors */
	for (i = 0; i < _bos->bNumDeviceCaps; i++) {
		if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
			usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
				  size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
			break;
		}
		header = (const struct usbi_descriptor_header *)buffer;
		if (header->bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
			usbi_warn(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
				  header->bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
			break;
		} else if (header->bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
			usbi_err(ctx, "invalid dev-cap bLength (%u)",
				 header->bLength);
			libusb_free_bos_descriptor(_bos);
			return LIBUSB_ERROR_IO;
		} else if (header->bLength > size) {
			usbi_warn(ctx, "short dev-cap descriptor read %d/%u",
				  size, header->bLength);
			break;
		}

		_bos->dev_capability[i] = malloc(header->bLength);
		if (!_bos->dev_capability[i]) {
			libusb_free_bos_descriptor(_bos);
			return LIBUSB_ERROR_NO_MEM;
		}
		memcpy(_bos->dev_capability[i], buffer, header->bLength);
		buffer += header->bLength;
		size -= header->bLength;
	}
	_bos->bNumDeviceCaps = i;
	*bos = _bos;

	return LIBUSB_SUCCESS;
}

/** \ingroup libusb_desc
 * Get a Binary Object Store (BOS) descriptor
 * This is a BLOCKING function, which will send requests to the device.
 *
 * \param dev_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 *dev_handle,
	struct libusb_bos_descriptor **bos)
{
	union bos_desc_buf _bos;
	uint16_t bos_len;
	uint8_t *bos_data;
	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(dev_handle, LIBUSB_DT_BOS, 0, _bos.buf, sizeof(_bos.buf));
	if (r < 0) {
		if (r != LIBUSB_ERROR_PIPE)
			usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
		return r;
	}
	if (r < LIBUSB_DT_BOS_SIZE) {
		usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d",
			 r, LIBUSB_DT_BOS_SIZE);
		return LIBUSB_ERROR_IO;
	}

	bos_len = libusb_le16_to_cpu(_bos.desc.wTotalLength);
	usbi_dbg("found BOS descriptor: size %u bytes, %u capabilities",
		 bos_len, _bos.desc.bNumDeviceCaps);
	bos_data = calloc(1, bos_len);
	if (!bos_data)
		return LIBUSB_ERROR_NO_MEM;

	r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, bos_len);
	if (r >= 0) {
		if (r != (int)bos_len)
			usbi_warn(HANDLE_CTX(dev_handle), "short BOS read %d/%u",
				  r, bos_len);
		r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r);
	} else {
		usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
	}

	free(bos_data);
	return r;
}

/** \ingroup libusb_desc
 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
 * It is safe to call this function with a NULL bos parameter, in which
 * case the function simply returns.
 *
 * \param bos the BOS descriptor to free
 */
void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
{
	uint8_t i;

	if (!bos)
		return;

	for (i = 0; i < bos->bNumDeviceCaps; i++)
		free(bos->dev_capability[i]);
	free(bos);
}

/** \ingroup libusb_desc
 * Get an USB 2.0 Extension descriptor
 *
 * \param ctx the context to operate on, or NULL for the default context
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
 * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
 * LIBUSB_BT_USB_2_0_EXTENSION
 * \param usb_2_0_extension output location for the USB 2.0 Extension
 * descriptor. Only valid if 0 was returned. Must be freed with
 * libusb_free_usb_2_0_extension_descriptor() after use.
 * \returns 0 on success
 * \returns a LIBUSB_ERROR code on error
 */
int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
	libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
{
	struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;

	if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
			 dev_cap->bDevCapabilityType,
			 LIBUSB_BT_USB_2_0_EXTENSION);
		return LIBUSB_ERROR_INVALID_PARAM;
	} else if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
			 dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
		return LIBUSB_ERROR_IO;
	}

	_usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
	if (!_usb_2_0_extension)
		return LIBUSB_ERROR_NO_MEM;

	parse_descriptor(dev_cap, "bbbd", _usb_2_0_extension);

	*usb_2_0_extension = _usb_2_0_extension;
	return LIBUSB_SUCCESS;
}

/** \ingroup libusb_desc
 * Free a USB 2.0 Extension descriptor obtained from
 * libusb_get_usb_2_0_extension_descriptor().
 * It is safe to call this function with a NULL usb_2_0_extension parameter,
 * in which case the function simply returns.
 *
 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
 */
void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
	struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
{
	free(usb_2_0_extension);
}

/** \ingroup libusb_desc
 * Get a SuperSpeed USB Device Capability descriptor
 *
 * \param ctx the context to operate on, or NULL for the default context
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
 * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
 * Capability descriptor. Only valid if 0 was returned. Must be freed with
 * libusb_free_ss_usb_device_capability_descriptor() after use.
 * \returns 0 on success
 * \returns a LIBUSB_ERROR code on error
 */
int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
	libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
{
	struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;

	if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
			 dev_cap->bDevCapabilityType,
			 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
		return LIBUSB_ERROR_INVALID_PARAM;
	} else if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
			 dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
		return LIBUSB_ERROR_IO;
	}

	_ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
	if (!_ss_usb_device_cap)
		return LIBUSB_ERROR_NO_MEM;

	parse_descriptor(dev_cap, "bbbbwbbw", _ss_usb_device_cap);

	*ss_usb_device_cap = _ss_usb_device_cap;
	return LIBUSB_SUCCESS;
}

/** \ingroup libusb_desc
 * Free a SuperSpeed USB Device Capability descriptor obtained from
 * libusb_get_ss_usb_device_capability_descriptor().
 * It is safe to call this function with a NULL ss_usb_device_cap
 * parameter, in which case the function simply returns.
 *
 * \param ss_usb_device_cap the SuperSpeed USB Device Capability descriptor
 * to free
 */
void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
	struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
{
	free(ss_usb_device_cap);
}

/** \ingroup libusb_desc
 * Get a Container ID descriptor
 *
 * \param ctx the context to operate on, or NULL for the default context
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
 * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
 * LIBUSB_BT_CONTAINER_ID
 * \param container_id output location for the Container ID descriptor.
 * Only valid if 0 was returned. Must be freed with
 * libusb_free_container_id_descriptor() after use.
 * \returns 0 on success
 * \returns a LIBUSB_ERROR code on error
 */
int API_EXPORTED libusb_get_container_id_descriptor(libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_container_id_descriptor **container_id)
{
	struct libusb_container_id_descriptor *_container_id;

	if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
			 dev_cap->bDevCapabilityType,
			 LIBUSB_BT_CONTAINER_ID);
		return LIBUSB_ERROR_INVALID_PARAM;
	} else if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
			 dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
		return LIBUSB_ERROR_IO;
	}

	_container_id = malloc(sizeof(*_container_id));
	if (!_container_id)
		return LIBUSB_ERROR_NO_MEM;

	parse_descriptor(dev_cap, "bbbbu", _container_id);

	*container_id = _container_id;
	return LIBUSB_SUCCESS;
}

/** \ingroup libusb_desc
 * Free a Container ID descriptor obtained from
 * libusb_get_container_id_descriptor().
 * It is safe to call this function with a NULL container_id parameter,
 * in which case the function simply returns.
 *
 * \param container_id the Container ID descriptor to free
 */
void API_EXPORTED libusb_free_container_id_descriptor(
	struct libusb_container_id_descriptor *container_id)
{
	free(container_id);
}

/** \ingroup libusb_desc
 * Retrieve a string descriptor in C style ASCII.
 *
 * Wrapper around libusb_get_string_descriptor(). Uses the first language
 * supported by the device.
 *
 * \param dev_handle a device handle
 * \param desc_index the index of the descriptor to retrieve
 * \param data output buffer for ASCII string descriptor
 * \param length size of data buffer
 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
 */
int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
	uint8_t desc_index, unsigned char *data, int length)
{
	union string_desc_buf str;
	int r, si, di;
	uint16_t langid, wdata;

	/* Asking for the zero'th index is special - it returns a string
	 * descriptor that contains all the language IDs supported by the
	 * device. Typically there aren't many - often only one. Language
	 * IDs are 16 bit numbers, and they start at the third byte in the
	 * descriptor. There's also no point in trying to read descriptor 0
	 * with this function. See USB 2.0 specification section 9.6.7 for
	 * more information.
	 */

	if (desc_index == 0)
		return LIBUSB_ERROR_INVALID_PARAM;

	r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
	if (r < 0)
		return r;
	else if (r != 4 || str.desc.bLength < 4)
		return LIBUSB_ERROR_IO;
	else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
		return LIBUSB_ERROR_IO;
	else if (str.desc.bLength & 1)
		usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for string descriptor", str.desc.bLength);

	langid = libusb_le16_to_cpu(str.desc.wData[0]);
	r = libusb_get_string_descriptor(dev_handle, desc_index, langid, str.buf, sizeof(str.buf));
	if (r < 0)
		return r;
	else if (r < DESC_HEADER_LENGTH || str.desc.bLength > r)
		return LIBUSB_ERROR_IO;
	else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
		return LIBUSB_ERROR_IO;
	else if ((str.desc.bLength & 1) || str.desc.bLength != r)
		usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for string descriptor", str.desc.bLength);

	di = 0;
	for (si = 2; si < str.desc.bLength; si += 2) {
		if (di >= (length - 1))
			break;

		wdata = libusb_le16_to_cpu(str.desc.wData[di]);
		if (wdata < 0x80)
			data[di++] = (unsigned char)wdata;
		else
			data[di++] = '?'; /* non-ASCII */
	}

	data[di] = 0;
	return di;
}
