# HG changeset patch # User Paul Boddie # Date 1364059894 0 # Node ID da210002ee99cb7f991d6cf8fe57acf9b261e839 # Parent 2d44b7f57a012df1966a2e07c9028e1055780460 Tidied up the configuration descriptor reporting, improving the output and defining generic functions for descriptor traversal and separate functions for output. diff -r 2d44b7f57a01 -r da210002ee99 test.c --- a/test.c Thu Mar 14 23:32:30 2013 +0000 +++ b/test.c Sat Mar 23 17:31:34 2013 +0000 @@ -746,6 +746,38 @@ max_control_status(false); } +const char *usb_endpoint_address_str(uint8_t bEndpointAddress) +{ + static char output[] = "255 (127 OUT)"; + + sprintf(output, "%03d (%03d %3s)", bEndpointAddress, + bEndpointAddress & ~USB_ENDPOINT_IN, + bEndpointAddress & USB_ENDPOINT_IN ? "IN" : "OUT"); + + return output; +} + +const char *usb_endpoint_attributes_str(uint8_t bmAttributes) +{ + switch (bmAttributes & USB_ENDPOINT_TYPE_MASK) + { + case USB_ENDPOINT_TYPE_CONTROL: + return "CONTROL"; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + return "ISO"; + + case USB_ENDPOINT_TYPE_BULK: + return "BULK"; + + case USB_ENDPOINT_TYPE_INTERRUPT: + return "INT"; + + default: + return ""; + } +} + void usb_show_device(max_device *device) { printf("bLength: %d\n", device->desc.bLength); @@ -781,28 +813,90 @@ } } -void usb_show_configuration(uint8_t *data) +/** + * Obtain a configuration descriptor with usable structure members. + */ +struct usb_config_descriptor *usb_get_config_descriptor(uint8_t *data) { struct usb_config_descriptor *conf = (struct usb_config_descriptor *) data; - uint8_t *current, *last, total = le16toh(conf->wTotalLength); - struct usb_descriptor_header *desc; - struct usb_interface_descriptor *intf; - struct usb_endpoint_descriptor *endp; + conf->wTotalLength = le16toh(conf->wTotalLength); + return conf; +} + +/** + * Obtain an endpoint descriptor with usable structure members. + */ +struct usb_endpoint_descriptor *usb_get_endpoint_descriptor(uint8_t *data) +{ + struct usb_endpoint_descriptor *endp = (struct usb_endpoint_descriptor *) data; + endp->wMaxPacketSize = le16toh(endp->wMaxPacketSize); + return endp; +} - if (data == NULL) - return; +uint8_t *usb_descriptor_start(struct usb_config_descriptor *conf) +{ + return ((uint8_t *) conf) + conf->bLength; +} + +uint8_t *usb_descriptor_end(struct usb_config_descriptor *conf) +{ + return ((uint8_t *) conf) + conf->wTotalLength; +} +uint8_t *usb_descriptor_next(uint8_t *current) +{ + struct usb_descriptor_header *desc = (struct usb_descriptor_header *) current; + if (desc->bLength) + return current + desc->bLength; + else + return NULL; +} + +void usb_show_configuration(struct usb_config_descriptor *conf) +{ printf("bLength: %d\n", conf->bLength); printf("bDescriptorType: %d\n", conf->bDescriptorType); - printf("wTotalLength: %d\n", total); + printf("wTotalLength: %d\n", conf->wTotalLength); printf("bNumInterfaces: %d\n", conf->bNumInterfaces); printf("bConfigurationValue: %d\n", conf->bConfigurationValue); printf("iConfiguration: %d\n", conf->iConfiguration); printf("bmAttributes: %x\n", conf->bmAttributes); printf("MaxPower: %d\n", conf->MaxPower); +} - current = ((uint8_t *) conf) + conf->bLength; - last = ((uint8_t *) conf) + total; +void usb_show_interface(struct usb_interface_descriptor *intf) +{ + printf("bInterfaceNumber: %d\n", intf->bInterfaceNumber); + printf("bAlternateSetting: %d\n", intf->bAlternateSetting); + printf("bNumEndpoints: %d\n", intf->bNumEndpoints); + printf("bInterfaceClass: %x\n", intf->bInterfaceClass); + printf("bInterfaceSubClass: %x\n", intf->bInterfaceSubClass); + printf("bInterfaceProtocol: %x\n", intf->bInterfaceProtocol); + printf("iInterface: %d\n", intf->iInterface); +} + +void usb_show_endpoint(struct usb_endpoint_descriptor *endp) +{ + printf("bEndpointAddress: %s\n", usb_endpoint_address_str(endp->bEndpointAddress)); + printf("bmAttributes: %s\n", usb_endpoint_attributes_str(endp->bmAttributes)); + printf("wMaxPacketSize: %d\n", endp->wMaxPacketSize); + printf("bInterval: %d\n", endp->bInterval); +} + +void usb_show_configuration_full(uint8_t *data) +{ + struct usb_config_descriptor *conf; + struct usb_descriptor_header *desc; + struct usb_interface_descriptor *intf; + struct usb_endpoint_descriptor *endp; + uint8_t *current, *last; + + if (data == NULL) + return; + + conf = usb_get_config_descriptor(data); + current = usb_descriptor_start(conf); + last = usb_descriptor_end(conf); while (current < last) { @@ -814,30 +908,21 @@ { case USB_DT_INTERFACE: intf = (struct usb_interface_descriptor *) current; - printf("bInterfaceNumber: %d\n", intf->bInterfaceNumber); - printf("bAlternateSetting: %d\n", intf->bAlternateSetting); - printf("bNumEndpoints: %d\n", intf->bNumEndpoints); - printf("bInterfaceClass: %x\n", intf->bInterfaceClass); - printf("bInterfaceSubClass: %x\n", intf->bInterfaceSubClass); - printf("bInterfaceProtocol: %x\n", intf->bInterfaceProtocol); - printf("iInterface: %d\n", intf->iInterface); + usb_show_interface(intf); break; case USB_DT_ENDPOINT: - endp = (struct usb_endpoint_descriptor *) current; - printf("bEndpointAddress: %d\n", endp->bEndpointAddress); - printf("bmAttributes: %x\n", endp->bmAttributes); - printf("wMaxPacketSize: %d\n", le16toh(endp->wMaxPacketSize)); - printf("bInterval: %d\n", endp->bInterval); + endp = usb_get_endpoint_descriptor(current); + usb_show_endpoint(endp); break; default: break; } - if (desc->bLength) - current += desc->bLength; - else + current = usb_descriptor_next(current); + + if (current == NULL) { printf("END (zero length record)\n"); break; @@ -1045,7 +1130,7 @@ printf("DEVICE?\n"); usb_show_languages(max_get_descriptor(&device, USB_DT_STRING, 0, 0, 0)); - usb_show_configuration(max_get_descriptor(&device, USB_DT_CONFIG, 0, 0, 0)); + usb_show_configuration_full(max_get_descriptor(&device, USB_DT_CONFIG, 0, 0, 0)); devstate = MAX_DEVSTATE_READY; printf("READY\n"); }