summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2008-05-10 14:42:43 +0100
committerDaniel Drake <dsd@gentoo.org>2008-05-10 15:36:29 +0100
commitc3844f7aeb2176636ce6e6ef697659fdb0b30048 (patch)
tree8b5f0a9f1d3f07a0de8289f146422cb0e0e01ec8
parentd77052c0d630e33737c38d601fd633155f6b2229 (diff)
downloadlibusb-c3844f7aeb2176636ce6e6ef697659fdb0b30048.tar.gz
Fetch configurations by index (not value)
Otherwise there is no way to know which values to look for.
-rw-r--r--libusb/core.c1
-rw-r--r--libusb/descriptor.c65
-rw-r--r--libusb/libusb.h4
-rw-r--r--libusb/libusbi.h5
-rw-r--r--libusb/os/linux_usbfs.c56
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);