diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-05-10 14:42:43 +0100 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-05-10 15:36:29 +0100 |
commit | c3844f7aeb2176636ce6e6ef697659fdb0b30048 (patch) | |
tree | 8b5f0a9f1d3f07a0de8289f146422cb0e0e01ec8 /libusb | |
parent | d77052c0d630e33737c38d601fd633155f6b2229 (diff) | |
download | libusb-c3844f7aeb2176636ce6e6ef697659fdb0b30048.tar.gz |
Fetch configurations by index (not value)
Otherwise there is no way to know which values to look for.
Diffstat (limited to 'libusb')
-rw-r--r-- | libusb/core.c | 1 | ||||
-rw-r--r-- | libusb/descriptor.c | 65 | ||||
-rw-r--r-- | libusb/libusb.h | 4 | ||||
-rw-r--r-- | libusb/libusbi.h | 5 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.c | 56 |
5 files changed, 74 insertions, 57 deletions
diff --git a/libusb/core.c b/libusb/core.c index 43491ad..d94d7b8 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -325,6 +325,7 @@ int usbi_sanitize_device(struct libusb_device *dev) return LIBUSB_ERROR_IO; } + dev->num_configurations = num_configurations; return 0; } diff --git a/libusb/descriptor.c b/libusb/descriptor.c index e07711a..8814ced 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -432,6 +432,7 @@ API_EXPORTED int libusb_get_device_descriptor(libusb_device *dev, unsigned char raw_desc[DEVICE_DESC_LENGTH]; int r; + usbi_dbg(""); r = usbi_backend->get_device_descriptor(dev, raw_desc); if (r < 0) return r; @@ -460,6 +461,7 @@ struct libusb_config_descriptor *libusb_get_active_config_descriptor( unsigned char *buf = NULL; int r; + usbi_dbg(""); if (!config) return NULL; @@ -467,7 +469,7 @@ struct libusb_config_descriptor *libusb_get_active_config_descriptor( if (r < 0) goto err; - usbi_parse_descriptor(tmp, "bbw", &config); + usbi_parse_descriptor(tmp, "bbw", config); buf = malloc(config->wTotalLength); if (!buf) goto err; @@ -495,40 +497,45 @@ err: } /** \ingroup desc - * Get the USB configuration descriptor for the currently active configuration. + * 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 bConfigurationValue the bConfigurationValue of the configuration - * you wish to retreive + * \param config_index the index of the configuration you wish to retrieve * \returns the USB configuration descriptor which must be freed with * libusb_free_config_descriptor() when done * \returns NULL on error * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor_by_value() */ API_EXPORTED struct libusb_config_descriptor *libusb_get_config_descriptor( - libusb_device *dev, uint8_t bConfigurationValue) + libusb_device *dev, uint8_t config_index) { - struct libusb_config_descriptor *config = malloc(sizeof(*config)); + struct libusb_config_descriptor *config; unsigned char tmp[8]; unsigned char *buf = NULL; int r; + usbi_dbg("index %d", config_index); + if (config_index >= dev->num_configurations) + return NULL; + + config = malloc(sizeof(*config)); if (!config) return NULL; - r = usbi_backend->get_config_descriptor(dev, bConfigurationValue, tmp, + r = usbi_backend->get_config_descriptor(dev, config_index, tmp, sizeof(tmp)); if (r < 0) goto err; - usbi_parse_descriptor(tmp, "bbw", &config); + usbi_parse_descriptor(tmp, "bbw", config); buf = malloc(config->wTotalLength); if (!buf) goto err; - r = usbi_backend->get_config_descriptor(dev, bConfigurationValue, buf, + r = usbi_backend->get_config_descriptor(dev, config_index, buf, config->wTotalLength); if (r < 0) goto err; @@ -551,6 +558,46 @@ err: } /** \ingroup 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 + * \returns the USB configuration descriptor which must be freed with + * libusb_free_config_descriptor() when done + * \returns NULL on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor() + */ +API_EXPORTED +struct libusb_config_descriptor *libusb_get_config_descriptor_by_value( + libusb_device *dev, uint8_t bConfigurationValue) +{ + int i; + int r; + int found = -1; + + usbi_dbg("value %d", bConfigurationValue); + for (i = 0; i < dev->num_configurations; i++) { + unsigned char tmp[6]; + r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp)); + if (r < 0) + return NULL; + if (tmp[5] == bConfigurationValue) { + found = 1; + break; + } + } + + if (!found) + return NULL; + else + return libusb_get_config_descriptor(dev, i); +} + +/** \ingroup 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 diff --git a/libusb/libusb.h b/libusb/libusb.h index 62ed0ea..f946a27 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -670,7 +670,9 @@ int libusb_get_device_descriptor(libusb_device *dev, struct libusb_config_descriptor *libusb_get_active_config_descriptor( libusb_device *dev); struct libusb_config_descriptor *libusb_get_config_descriptor( - libusb_device *dev, uint8_t config); + libusb_device *dev, uint8_t config_index); +struct libusb_config_descriptor *libusb_get_config_descriptor_by_value( + libusb_device *dev, uint8_t bConfigurationValue); void libusb_free_config_descriptor(struct libusb_config_descriptor *config); uint8_t libusb_get_bus_number(libusb_device *dev); uint8_t libusb_get_device_address(libusb_device *dev); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index e596b86..c807903 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -150,6 +150,7 @@ struct libusb_device { uint8_t bus_number; uint8_t device_address; + uint8_t num_configurations; struct list_head list; unsigned long session_data; @@ -273,8 +274,8 @@ struct usbi_os_backend { unsigned char *buffer); int (*get_active_config_descriptor)(struct libusb_device *device, unsigned char *buffer, size_t len); - int (*get_config_descriptor)(struct libusb_device *device, uint8_t config, - unsigned char *buffer, size_t len); + int (*get_config_descriptor)(struct libusb_device *device, + uint8_t config_index, unsigned char *buffer, size_t len); int (*set_configuration)(struct libusb_device_handle *handle, int config); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 6bebc06..957900a 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -301,49 +301,22 @@ static int op_get_active_config_descriptor(struct libusb_device *dev, /* takes a usbfs fd, attempts to find the requested config and copy a certain * amount of it into an output buffer. a bConfigurationValue of -1 indicates * that the first config should be retreived. */ -static int get_config_descriptor(int fd, int bConfigurationValue, +static int get_config_descriptor(int fd, uint8_t config_index, unsigned char *buffer, size_t len) { unsigned char tmp[8]; - uint8_t num_configurations; off_t off; ssize_t r; - if (bConfigurationValue == -1) { - /* read first configuration */ - off = lseek(fd, DEVICE_DESC_LENGTH, SEEK_SET); - if (off < 0) { - usbi_err("seek failed, ret=%d errno=%d", off, errno); - return LIBUSB_ERROR_IO; - } - r = read(fd, buffer, len); - if (r < 0) { - usbi_err("read failed ret=%d errno=%d", r, errno); - return LIBUSB_ERROR_IO; - } else if (r < len) { - usbi_err("short output read %d/%d", r, len); - return LIBUSB_ERROR_IO; - } - return 0; - } - - /* seek to last byte of device descriptor to determine number of - * configurations */ - off = lseek(fd, DEVICE_DESC_LENGTH - 1, SEEK_SET); + off = lseek(fd, DEVICE_DESC_LENGTH, SEEK_SET); if (off < 0) { - usbi_err("seek failed, ret=%d errno=%d", off, errno); - return LIBUSB_ERROR_IO; - } - - r = read(fd, &num_configurations, 1); - if (r < 0) { - usbi_err("read num_configurations failed, ret=%d errno=%d", off, errno); + usbi_err("seek failed ret=%d errno=%d", off, errno); return LIBUSB_ERROR_IO; } /* might need to skip some configuration descriptors to reach the * requested configuration */ - while (num_configurations) { + while (config_index) { struct libusb_config_descriptor config; /* read first 8 bytes of descriptor */ @@ -357,8 +330,6 @@ static int get_config_descriptor(int fd, int bConfigurationValue, } usbi_parse_descriptor(tmp, "bbwbb", &config); - if (config.bConfigurationValue == bConfigurationValue) - break; /* seek forward to end of config */ off = lseek(fd, config.wTotalLength - sizeof(tmp), SEEK_CUR); @@ -367,21 +338,15 @@ static int get_config_descriptor(int fd, int bConfigurationValue, return LIBUSB_ERROR_IO; } - num_configurations--; + config_index--; } - if (num_configurations == 0) - return LIBUSB_ERROR_NOT_FOUND; - - /* copy config-so-far */ - memcpy(buffer, tmp, sizeof(tmp)); - /* read the rest of the descriptor */ - r = read(fd, buffer + sizeof(tmp), len - sizeof(tmp)); + r = read(fd, buffer, len); if (r < 0) { usbi_err("read failed ret=%d errno=%d", r, errno); return LIBUSB_ERROR_IO; - } else if (r < (len - sizeof(tmp))) { + } else if (r < len) { usbi_err("short output read %d/%d", r, len); return LIBUSB_ERROR_IO; } @@ -389,8 +354,8 @@ static int get_config_descriptor(int fd, int bConfigurationValue, return 0; } -static int op_get_config_descriptor(struct libusb_device *dev, uint8_t config, - unsigned char *buffer, size_t len) +static int op_get_config_descriptor(struct libusb_device *dev, + uint8_t config_index, unsigned char *buffer, size_t len) { char filename[PATH_MAX + 1]; int fd; @@ -406,7 +371,7 @@ static int op_get_config_descriptor(struct libusb_device *dev, uint8_t config, return LIBUSB_ERROR_IO; } - r = get_config_descriptor(fd, config, buffer, len); + r = get_config_descriptor(fd, config_index, buffer, len); close(fd); return r; } @@ -420,6 +385,7 @@ static int cache_active_config(struct libusb_device *dev, int fd, unsigned char *buf; int r; + /* FIXME */ r = get_config_descriptor(fd, active_config, tmp, sizeof(tmp)); if (r < 0) { usbi_err("first read error %d", r); |