Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/dump.c

    r5ccb15c rc9d5577  
    4343#include <usb/usb.h>
    4444#include <usb/descriptor.h>
     45#include <usb/classes/classes.h>
    4546
    4647#include "usbinfo.h"
     
    4849
    4950#define INDENT "  "
     51#define PRINTLINE(indent, fmt, ...) printf("%s - " fmt, get_indent(indent), __VA_ARGS__)
    5052#define BYTES_PER_LINE 12
    5153
     
    5658#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    5759
    58 void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
    59 {
    60         printf("%s\n", msg);
     60static void dump_descriptor_by_type(size_t, uint8_t *, size_t);
     61
     62typedef struct {
     63        int descriptor;
     64        void (*dump)(size_t indent, uint8_t *descriptor, size_t length);
     65} descriptor_dump_t;
     66
     67static void dump_descriptor_device(size_t, uint8_t *, size_t);
     68static void dump_descriptor_configuration(size_t, uint8_t *, size_t);
     69static void dump_descriptor_interface(size_t, uint8_t *, size_t);
     70static void dump_descriptor_string(size_t, uint8_t *, size_t);
     71static void dump_descriptor_endpoint(size_t, uint8_t *, size_t);
     72static void dump_descriptor_hid(size_t, uint8_t *, size_t);
     73static void dump_descriptor_hub(size_t, uint8_t *, size_t);
     74static void dump_descriptor_generic(size_t, uint8_t *, size_t);
     75
     76static descriptor_dump_t descriptor_dumpers[] = {
     77        { USB_DESCTYPE_DEVICE, dump_descriptor_device },
     78        { USB_DESCTYPE_CONFIGURATION, dump_descriptor_configuration },
     79        { USB_DESCTYPE_STRING, dump_descriptor_string },
     80        { USB_DESCTYPE_INTERFACE, dump_descriptor_interface },
     81        { USB_DESCTYPE_ENDPOINT, dump_descriptor_endpoint },
     82        { USB_DESCTYPE_HID, dump_descriptor_hid },
     83        { USB_DESCTYPE_HUB, dump_descriptor_hub },
     84        { -1, dump_descriptor_generic },
     85        { -1, NULL }
     86};
     87
     88static const char *get_indent(size_t level)
     89{
     90        static const char *indents[] = {
     91                INDENT,
     92                INDENT INDENT,
     93                INDENT INDENT INDENT,
     94                INDENT INDENT INDENT INDENT,
     95                INDENT INDENT INDENT INDENT INDENT
     96        };
     97        static size_t indents_count = sizeof(indents)/sizeof(indents[0]);
     98        if (level >= indents_count) {
     99                return indents[indents_count - 1];
     100        }
     101        return indents[level];
     102}
     103
     104void dump_buffer(const char *msg, size_t indent,
     105    const uint8_t *buffer, size_t length)
     106{
     107        if (msg != NULL) {
     108                printf("%s\n", msg);
     109        }
    61110
    62111        size_t i;
     112        if (length > 0) {
     113                printf("%s", get_indent(indent));
     114        }
    63115        for (i = 0; i < length; i++) {
    64                 printf("  0x%02X", buffer[i]);
     116                printf("0x%02X", buffer[i]);
    65117                if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
    66118                    || (i + 1 == length)) {
    67119                        printf("\n");
     120                        if (i + 1 < length) {
     121                                printf("%s", get_indent(indent));
     122                        }
     123                } else {
     124                        printf("  ");
    68125                }
    69126        }
    70127}
     128
     129void dump_descriptor_by_type(size_t indent, uint8_t *d, size_t length)
     130{
     131        if (length < 2) {
     132                return;
     133        }
     134        int type = d[1];
     135       
     136        descriptor_dump_t *dumper = descriptor_dumpers;
     137        while (dumper->dump != NULL) {
     138                if ((dumper->descriptor == type) || (dumper->descriptor < 0)) {
     139                        dumper->dump(indent, d, length);
     140                        return;
     141                }
     142                dumper++;
     143        }                       
     144}
     145
     146void dump_usb_descriptor(uint8_t *descriptor, size_t size)
     147{
     148        dump_descriptor_by_type(0, descriptor, size);
     149}
     150
     151void dump_descriptor_device(size_t indent, uint8_t *descr, size_t size)
     152{
     153        usb_standard_device_descriptor_t *d
     154            = (usb_standard_device_descriptor_t *) descr;
     155        if (size != sizeof(*d)) {
     156                return;
     157        }
     158       
     159        PRINTLINE(indent, "bLength = %d\n", d->length);
     160        PRINTLINE(indent, "bDescriptorType = 0x%02x\n", d->descriptor_type);
     161        PRINTLINE(indent, "bcdUSB = %d (" BCD_FMT ")\n", d->usb_spec_version,
     162            BCD_ARGS(d->usb_spec_version));
     163        PRINTLINE(indent, "bDeviceClass = 0x%02x\n", d->device_class);
     164        PRINTLINE(indent, "bDeviceSubClass = 0x%02x\n", d->device_subclass);
     165        PRINTLINE(indent, "bDeviceProtocol = 0x%02x\n", d->device_protocol);
     166        PRINTLINE(indent, "bMaxPacketSize0 = %d\n", d->max_packet_size);
     167        PRINTLINE(indent, "idVendor = %d\n", d->vendor_id);
     168        PRINTLINE(indent, "idProduct = %d\n", d->product_id);
     169        PRINTLINE(indent, "bcdDevice = %d\n", d->device_version);
     170        PRINTLINE(indent, "iManufacturer = %d\n", d->str_manufacturer);
     171        PRINTLINE(indent, "iProduct = %d\n", d->str_product);
     172        PRINTLINE(indent, "iSerialNumber = %d\n", d->str_serial_number);
     173        PRINTLINE(indent, "bNumConfigurations = %d\n", d->configuration_count);
     174}
     175
     176void dump_descriptor_configuration(size_t indent, uint8_t *descr, size_t size)
     177{
     178        usb_standard_configuration_descriptor_t *d
     179            = (usb_standard_configuration_descriptor_t *) descr;
     180        if (size != sizeof(*d)) {
     181                return;
     182        }
     183       
     184        bool self_powered = d->attributes & 64;
     185        bool remote_wakeup = d->attributes & 32;
     186       
     187        PRINTLINE(indent, "bLength = %d\n", d->length);
     188        PRINTLINE(indent, "bDescriptorType = 0x%02x\n", d->descriptor_type);
     189        PRINTLINE(indent, "wTotalLength = %d\n", d->total_length);
     190        PRINTLINE(indent, "bNumInterfaces = %d\n", d->interface_count);
     191        PRINTLINE(indent, "bConfigurationValue = %d\n", d->configuration_number);
     192        PRINTLINE(indent, "iConfiguration = %d\n", d->str_configuration);
     193        PRINTLINE(indent, "bmAttributes = %d [%s%s%s]\n", d->attributes,
     194            self_powered ? "self-powered" : "",
     195            (self_powered & remote_wakeup) ? ", " : "",
     196            remote_wakeup ? "remote-wakeup" : "");
     197        PRINTLINE(indent, "MaxPower = %d (%dmA)\n", d->max_power,
     198            2 * d->max_power);
     199}
     200
     201void dump_descriptor_interface(size_t indent, uint8_t *descr, size_t size)
     202{
     203        usb_standard_interface_descriptor_t *d
     204            = (usb_standard_interface_descriptor_t *) descr;
     205        if (size != sizeof(*d)) {
     206                return;
     207        }
     208       
     209        PRINTLINE(indent, "bLength = %d\n", d->length);
     210        PRINTLINE(indent, "bDescriptorType = 0x%02x\n", d->descriptor_type);
     211        PRINTLINE(indent, "bInterfaceNumber = %d\n", d->interface_number);
     212        PRINTLINE(indent, "bAlternateSetting = %d\n", d->alternate_setting);
     213        PRINTLINE(indent, "bNumEndpoints = %d\n", d->endpoint_count);
     214        PRINTLINE(indent, "bInterfaceClass = %s\n", d->interface_class == 0
     215            ? "reserved (0)" : usb_str_class(d->interface_class));
     216        PRINTLINE(indent, "bInterfaceSubClass = %d\n", d->interface_subclass);
     217        PRINTLINE(indent, "bInterfaceProtocol = %d\n", d->interface_protocol);
     218        PRINTLINE(indent, "iInterface = %d\n", d->str_interface);
     219}
     220
     221void dump_descriptor_string(size_t indent, uint8_t *descr, size_t size)
     222{
     223        dump_descriptor_generic(indent, descr, size);
     224}
     225
     226void dump_descriptor_endpoint(size_t indent, uint8_t *descr, size_t size)
     227{
     228        usb_standard_endpoint_descriptor_t *d
     229           = (usb_standard_endpoint_descriptor_t *) descr;
     230        if (size != sizeof(*d)) {
     231                return;
     232        }
     233       
     234        int endpoint = d->endpoint_address & 15;
     235        usb_direction_t direction = d->endpoint_address & 128
     236            ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
     237       
     238        PRINTLINE(indent, "bLength = %d\n", d->length);
     239        PRINTLINE(indent, "bDescriptorType = 0x%02X\n", d->descriptor_type);
     240        PRINTLINE(indent, "bEndpointAddress = 0x%02X [%d, %s]\n",
     241            d->endpoint_address, endpoint,
     242            direction == USB_DIRECTION_IN ? "in" : "out");
     243        PRINTLINE(indent, "bmAttributes = %d\n", d->attributes);
     244        PRINTLINE(indent, "wMaxPacketSize = %d\n", d->max_packet_size);
     245        PRINTLINE(indent, "bInterval = %dms\n", d->poll_interval);
     246}
     247
     248void dump_descriptor_hid(size_t indent, uint8_t *descr, size_t size)
     249{
     250        dump_descriptor_generic(indent, descr, size);
     251}
     252
     253void dump_descriptor_hub(size_t indent, uint8_t *descr, size_t size)
     254{
     255        dump_descriptor_generic(indent, descr, size);
     256}
     257
     258void dump_descriptor_generic(size_t indent, uint8_t *descr, size_t size)
     259{
     260        dump_buffer(NULL, indent, descr, size);
     261}
     262
    71263
    72264void dump_match_ids(match_id_list_t *matches)
     
    83275}
    84276
    85 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *d)
    86 {
    87         printf("Standard device descriptor:\n");
    88 
    89         printf(INDENT "bLength = %d\n", d->length);
    90         printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
    91         printf(INDENT "bcdUSB = %d (" BCD_FMT ")\n", d->usb_spec_version,
    92             BCD_ARGS(d->usb_spec_version));
    93         printf(INDENT "bDeviceClass = 0x%02x\n", d->device_class);
    94         printf(INDENT "bDeviceSubClass = 0x%02x\n", d->device_subclass);
    95         printf(INDENT "bDeviceProtocol = 0x%02x\n", d->device_protocol);
    96         printf(INDENT "bMaxPacketSize0 = %d\n", d->max_packet_size);
    97         printf(INDENT "idVendor = %d\n", d->vendor_id);
    98         printf(INDENT "idProduct = %d\n", d->product_id);
    99         printf(INDENT "bcdDevice = %d\n", d->device_version);
    100         printf(INDENT "iManufacturer = %d\n", d->str_manufacturer);
    101         printf(INDENT "iProduct = %d\n", d->str_product);
    102         printf(INDENT "iSerialNumber = %d\n", d->str_serial_number);
    103         printf(INDENT "bNumConfigurations = %d\n", d->configuration_count);
    104 }
    105 
    106 void dump_standard_configuration_descriptor(
    107     int index, usb_standard_configuration_descriptor_t *d)
    108 {
    109         bool self_powered = d->attributes & 64;
    110         bool remote_wakeup = d->attributes & 32;
    111        
    112         printf("Standard configuration descriptor #%d\n", index);
    113         printf(INDENT "bLength = %d\n", d->length);
    114         printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
    115         printf(INDENT "wTotalLength = %d\n", d->total_length);
    116         printf(INDENT "bNumInterfaces = %d\n", d->interface_count);
    117         printf(INDENT "bConfigurationValue = %d\n", d->configuration_number);
    118         printf(INDENT "iConfiguration = %d\n", d->str_configuration);
    119         printf(INDENT "bmAttributes = %d [%s%s%s]\n", d->attributes,
    120             self_powered ? "self-powered" : "",
    121             (self_powered & remote_wakeup) ? ", " : "",
    122             remote_wakeup ? "remote-wakeup" : "");
    123         printf(INDENT "MaxPower = %d (%dmA)\n", d->max_power,
    124             2 * d->max_power);
    125         // printf(INDENT " = %d\n", d->);
    126 }
    127 
    128277static void dump_tree_descriptor(uint8_t *descriptor, size_t depth)
    129278{
    130279        if (descriptor == NULL) {
    131280                return;
    132         }
    133         while (depth > 0) {
    134                 printf("  ");
    135                 depth--;
    136281        }
    137282        int type = (int) *(descriptor + 1);
     
    151296#undef _TYPE
    152297        }
    153         printf("0x%02x (%s)\n", type, name);
     298        printf("%s%s (0x%02X):\n", get_indent(depth), name, type);
     299        dump_descriptor_by_type(depth, descriptor, descriptor[0]);
     300       
    154301}
    155302
     
    172319        uint8_t *ptr = data->data;
    173320        printf("Descriptor tree:\n");
    174         dump_tree_internal(parser, data, ptr, 1);
     321        dump_tree_internal(parser, data, ptr, 0);
    175322}
    176323
Note: See TracChangeset for help on using the changeset viewer.