Add multiple missing descriptor parsing functions to the LibUSB v1.0 API.
Approved by: re (kib) Requested by: swills MFC after: 1 week
This commit is contained in:
parent
498a196b80
commit
37d0636aac
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=301968
@ -109,8 +109,16 @@ MLINKS += libusb.3 libusb_get_string_descriptor.3
|
||||
MLINKS += libusb.3 libusb_get_string_descriptor_ascii.3
|
||||
MLINKS += libusb.3 libusb_parse_ss_endpoint_comp.3
|
||||
MLINKS += libusb.3 libusb_free_ss_endpoint_comp.3
|
||||
MLINKS += libusb.3 libusb_get_ss_endpoint_companion_descriptor.3
|
||||
MLINKS += libusb.3 libusb_free_ss_endpoint_companion_descriptor.3
|
||||
MLINKS += libusb.3 libusb_parse_bos_descriptor.3
|
||||
MLINKS += libusb.3 libusb_free_bos_descriptor.3
|
||||
MLINKS += libusb.3 libusb_get_usb_2_0_extension_descriptor.3
|
||||
MLINKS += libusb.3 libusb_free_usb_2_0_extension_descriptor.3
|
||||
MLINKS += libusb.3 libusb_get_ss_usb_device_capability_descriptor.3
|
||||
MLINKS += libusb.3 libusb_free_ss_usb_device_capability_descriptor.3
|
||||
MLINKS += libusb.3 libusb_get_container_id_descriptor.3
|
||||
MLINKS += libusb.3 libusb_free_container_id_descriptor.3
|
||||
MLINKS += libusb.3 libusb_alloc_transfer.3
|
||||
MLINKS += libusb.3 libusb_free_transfer.3
|
||||
MLINKS += libusb.3 libusb_submit_transfer.3
|
||||
|
@ -376,7 +376,31 @@ freed using the libusb_free_ss_endpoint_comp function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_ss_endpoint_comp "libusb_ss_endpoint_companion_descriptor *ep_comp"
|
||||
This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor.
|
||||
This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor given by
|
||||
.Fa ep_comp .
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_get_ss_endpoint_companion_descriptor "struct libusb_context *ctx" "const struct libusb_endpoint_descriptor *endpoint" "struct libusb_ss_endpoint_companion_descriptor **ep_comp"
|
||||
This function finds and parses the USB 3.0 endpoint companion descriptor given by
|
||||
.Fa endpoint .
|
||||
Returns zero on success and a LIBUSB_ERROR code on failure.
|
||||
On success the parsed USB 3.0 endpoint companion descriptor must be
|
||||
freed using the libusb_free_ss_endpoint_companion_descriptor function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_ss_endpoint_companion_descriptor "struct libusb_ss_endpoint_companion_descriptor *ep_comp"
|
||||
This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor given by
|
||||
.Fa ep_comp .
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_get_bos_descriptor "libusb_device_handle *handle" "struct libusb_bos_descriptor **bos"
|
||||
This function queries the USB device given by
|
||||
.Fa handle
|
||||
and stores a pointer to a parsed BOS descriptor into
|
||||
.Fa bos .
|
||||
Returns zero on success and a LIBUSB_ERROR code on failure.
|
||||
On success the parsed BOS descriptor must be
|
||||
freed using the libusb_free_bos_descriptor function.
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_parse_bos_descriptor "const void *buf" "int len" "libusb_bos_descriptor **bos"
|
||||
@ -392,7 +416,53 @@ libusb_free_bos_descriptor function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_bos_descriptor "libusb_bos_descriptor *bos"
|
||||
This function is NULL safe and frees a parsed BOS descriptor.
|
||||
This function is NULL safe and frees a parsed BOS descriptor given by
|
||||
.Fa bos .
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_get_usb_2_0_extension_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension"
|
||||
This function parses the USB 2.0 extension descriptor from the descriptor given by
|
||||
.Fa dev_cap
|
||||
and stores a pointer to the parsed descriptor into
|
||||
.Fa usb_2_0_extension .
|
||||
Returns zero on success and a LIBUSB_ERROR code on failure.
|
||||
On success the parsed USB 2.0 extension descriptor must be freed using the
|
||||
libusb_free_usb_2_0_extension_descriptor function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_usb_2_0_extension_descriptor "struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension"
|
||||
This function is NULL safe and frees a parsed USB 2.0 extension descriptor given by
|
||||
.Fa usb_2_0_extension .
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_get_ss_usb_device_capability_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability"
|
||||
This function parses the SuperSpeed device capability descriptor from the descriptor given by
|
||||
.Fa dev_cap
|
||||
and stores a pointer to the parsed descriptor into
|
||||
.Fa ss_usb_device_capability .
|
||||
Returns zero on success and a LIBUSB_ERROR code on failure.
|
||||
On success the parsed SuperSpeed device capability descriptor must be freed using the
|
||||
libusb_free_ss_usb_device_capability_descriptor function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_ss_usb_device_capability_descriptor "struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability"
|
||||
This function is NULL safe and frees a parsed SuperSpeed device capability descriptor given by
|
||||
.Fa ss_usb_device_capability .
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn libusb_get_container_id_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_container_id_descriptor **container_id"
|
||||
This function parses the container ID descriptor from the descriptor given by
|
||||
.Fa dev_cap
|
||||
and stores a pointer to the parsed descriptor into
|
||||
.Fa container_id .
|
||||
Returns zero on success and a LIBUSB_ERROR code on failure.
|
||||
On success the parsed container ID descriptor must be freed using the
|
||||
libusb_free_container_id_descriptor function.
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn libusb_free_container_id_descriptor "struct libusb_container_id_descriptor *container_id"
|
||||
This function is NULL safe and frees a parsed container ID descriptor given by
|
||||
.Fa container_id .
|
||||
.Sh USB ASYNCHRONOUS I/O
|
||||
.Ft struct libusb_transfer *
|
||||
.Fn libusb_alloc_transfer "int iso_packets"
|
||||
|
@ -101,6 +101,10 @@ enum libusb_device_capability_type {
|
||||
#define LIBUSB_USB_2_0_EXTENSION_DEVICE_CAPABILITY_SIZE 7
|
||||
#define LIBUSB_SS_USB_DEVICE_CAPABILITY_SIZE 10
|
||||
|
||||
#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7
|
||||
#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10
|
||||
#define LIBUSB_BT_CONTAINER_ID_SIZE 20
|
||||
|
||||
#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f
|
||||
#define LIBUSB_ENDPOINT_DIR_MASK 0x80
|
||||
|
||||
@ -165,6 +169,13 @@ enum libusb_iso_usage_type {
|
||||
LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2,
|
||||
};
|
||||
|
||||
enum libusb_bos_type {
|
||||
LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1,
|
||||
LIBUSB_BT_USB_2_0_EXTENSION = 2,
|
||||
LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3,
|
||||
LIBUSB_BT_CONTAINER_ID = 4,
|
||||
};
|
||||
|
||||
enum libusb_error {
|
||||
LIBUSB_SUCCESS = 0,
|
||||
LIBUSB_ERROR_IO = -1,
|
||||
@ -349,6 +360,13 @@ typedef struct libusb_ss_usb_device_capability_descriptor {
|
||||
uint16_t wU2DevExitLat;
|
||||
} libusb_ss_usb_device_capability_descriptor __aligned(sizeof(void *));
|
||||
|
||||
typedef struct libusb_bos_dev_capability_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t dev_capability_data[0];
|
||||
} libusb_bos_dev_capability_descriptor __aligned(sizeof(void *));
|
||||
|
||||
typedef struct libusb_bos_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
@ -358,6 +376,21 @@ typedef struct libusb_bos_descriptor {
|
||||
struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap;
|
||||
} libusb_bos_descriptor __aligned(sizeof(void *));
|
||||
|
||||
typedef struct libusb_usb_2_0_extension_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint32_t bmAttributes;
|
||||
} libusb_usb_2_0_extension_descriptor __aligned(sizeof(void *));
|
||||
|
||||
typedef struct libusb_container_id_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t bReserved;
|
||||
uint8_t ContainerID[16];
|
||||
} libusb_container_id_descriptor __aligned(sizeof(void *));
|
||||
|
||||
typedef struct libusb_control_setup {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
@ -442,6 +475,8 @@ int libusb_get_active_config_descriptor(libusb_device * dev, struct libusb_confi
|
||||
int libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index, struct libusb_config_descriptor **config);
|
||||
int libusb_get_config_descriptor_by_value(libusb_device * dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config);
|
||||
void libusb_free_config_descriptor(struct libusb_config_descriptor *config);
|
||||
int libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp);
|
||||
void libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp);
|
||||
int libusb_get_string_descriptor(libusb_device_handle * devh, uint8_t desc_index, uint16_t langid, unsigned char *data, int length);
|
||||
int libusb_get_string_descriptor_ascii(libusb_device_handle * devh, uint8_t desc_index, uint8_t *data, int length);
|
||||
int libusb_get_descriptor(libusb_device_handle * devh, uint8_t desc_type, uint8_t desc_index, uint8_t *data, int length);
|
||||
@ -449,6 +484,13 @@ int libusb_parse_ss_endpoint_comp(const void *buf, int len, struct libusb_ss_end
|
||||
void libusb_free_ss_endpoint_comp(struct libusb_ss_endpoint_companion_descriptor *ep_comp);
|
||||
int libusb_parse_bos_descriptor(const void *buf, int len, struct libusb_bos_descriptor **bos);
|
||||
void libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos);
|
||||
int libusb_get_bos_descriptor(libusb_device_handle *handle, struct libusb_bos_descriptor **bos);
|
||||
int libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension);
|
||||
void libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension);
|
||||
int libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability);
|
||||
void libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability);
|
||||
int libusb_get_container_id_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id);
|
||||
void libusb_free_container_id_descriptor(struct libusb_container_id_descriptor *container_id);
|
||||
|
||||
/* Asynchronous device I/O */
|
||||
|
||||
|
@ -409,6 +409,23 @@ libusb_free_ss_endpoint_comp(struct libusb_ss_endpoint_companion_descriptor *ep_
|
||||
free(ep_comp);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx,
|
||||
const struct libusb_endpoint_descriptor *endpoint,
|
||||
struct libusb_ss_endpoint_companion_descriptor **ep_comp)
|
||||
{
|
||||
if (endpoint == NULL)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
return (libusb_parse_ss_endpoint_comp(endpoint->extra, endpoint->extra_length, ep_comp));
|
||||
}
|
||||
|
||||
void
|
||||
libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp)
|
||||
{
|
||||
|
||||
libusb_free_ss_endpoint_comp(ep_comp);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_parse_bos_descriptor(const void *buf, int len,
|
||||
struct libusb_bos_descriptor **bos)
|
||||
@ -520,3 +537,154 @@ libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
|
||||
|
||||
free(bos);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_get_bos_descriptor(libusb_device_handle *handle,
|
||||
struct libusb_bos_descriptor **bos)
|
||||
{
|
||||
uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
|
||||
uint16_t wTotalLength;
|
||||
uint8_t *bos_data;
|
||||
int err;
|
||||
|
||||
err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0,
|
||||
bos_header, sizeof(bos_header));
|
||||
if (err < 0)
|
||||
return (err);
|
||||
|
||||
wTotalLength = bos_header[2] | (bos_header[3] << 8);
|
||||
if (wTotalLength < LIBUSB_DT_BOS_SIZE)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
|
||||
bos_data = calloc(wTotalLength, 1);
|
||||
if (bos_data == NULL)
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
|
||||
err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0,
|
||||
bos_data, wTotalLength);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
/* avoid descriptor length mismatches */
|
||||
bos_data[2] = (wTotalLength & 0xFF);
|
||||
bos_data[3] = (wTotalLength >> 8);
|
||||
|
||||
err = libusb_parse_bos_descriptor(bos_data, wTotalLength, bos);
|
||||
done:
|
||||
free(bos_data);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_get_usb_2_0_extension_descriptor(struct 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 *desc;
|
||||
|
||||
if (dev_cap == NULL || usb_2_0_extension == NULL ||
|
||||
dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE)
|
||||
return (LIBUSB_ERROR_IO);
|
||||
|
||||
desc = malloc(sizeof(*desc));
|
||||
if (desc == NULL)
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
|
||||
desc->bLength = LIBUSB_BT_USB_2_0_EXTENSION_SIZE;
|
||||
desc->bDescriptorType = dev_cap->bDescriptorType;
|
||||
desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
||||
desc->bmAttributes =
|
||||
(dev_cap->dev_capability_data[0]) |
|
||||
(dev_cap->dev_capability_data[1] << 8) |
|
||||
(dev_cap->dev_capability_data[2] << 16) |
|
||||
(dev_cap->dev_capability_data[3] << 24);
|
||||
|
||||
*usb_2_0_extension = desc;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
libusb_free_usb_2_0_extension_descriptor(
|
||||
struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
|
||||
{
|
||||
|
||||
free(usb_2_0_extension);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx,
|
||||
struct libusb_bos_dev_capability_descriptor *dev_cap,
|
||||
struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability)
|
||||
{
|
||||
struct libusb_ss_usb_device_capability_descriptor *desc;
|
||||
|
||||
if (dev_cap == NULL || ss_usb_device_capability == NULL ||
|
||||
dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE)
|
||||
return (LIBUSB_ERROR_IO);
|
||||
|
||||
desc = malloc(sizeof(*desc));
|
||||
if (desc == NULL)
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
|
||||
desc->bLength = LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE;
|
||||
desc->bDescriptorType = dev_cap->bDescriptorType;
|
||||
desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
||||
desc->bmAttributes = dev_cap->dev_capability_data[0];
|
||||
desc->wSpeedSupported = dev_cap->dev_capability_data[1] |
|
||||
(dev_cap->dev_capability_data[2] << 8);
|
||||
desc->bFunctionalitySupport = dev_cap->dev_capability_data[3];
|
||||
desc->bU1DevExitLat = dev_cap->dev_capability_data[4];
|
||||
desc->wU2DevExitLat = dev_cap->dev_capability_data[5] |
|
||||
(dev_cap->dev_capability_data[6] << 8);
|
||||
|
||||
*ss_usb_device_capability = desc;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
libusb_free_ss_usb_device_capability_descriptor(
|
||||
struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability)
|
||||
{
|
||||
|
||||
free(ss_usb_device_capability);
|
||||
}
|
||||
|
||||
int
|
||||
libusb_get_container_id_descriptor(struct libusb_context *ctx,
|
||||
struct libusb_bos_dev_capability_descriptor *dev_cap,
|
||||
struct libusb_container_id_descriptor **container_id)
|
||||
{
|
||||
struct libusb_container_id_descriptor *desc;
|
||||
|
||||
if (dev_cap == NULL || container_id == NULL ||
|
||||
dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID)
|
||||
return (LIBUSB_ERROR_INVALID_PARAM);
|
||||
if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE)
|
||||
return (LIBUSB_ERROR_IO);
|
||||
|
||||
desc = malloc(sizeof(*desc));
|
||||
if (desc == NULL)
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
|
||||
desc->bLength = LIBUSB_BT_CONTAINER_ID_SIZE;
|
||||
desc->bDescriptorType = dev_cap->bDescriptorType;
|
||||
desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
||||
desc->bReserved = dev_cap->dev_capability_data[0];
|
||||
memcpy(desc->ContainerID, dev_cap->dev_capability_data + 1,
|
||||
sizeof(desc->ContainerID));
|
||||
|
||||
*container_id = desc;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
libusb_free_container_id_descriptor(
|
||||
struct libusb_container_id_descriptor *container_id)
|
||||
{
|
||||
|
||||
free(container_id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user