dump.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Vojtech Horky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <errno.h>
00040 #include <str_error.h>
00041 #include <bool.h>
00042 
00043 #include <usb/usb.h>
00044 #include <usb/descriptor.h>
00045 #include <usb/debug.h>
00046 #include <usb/classes/classes.h>
00047 
00048 #include "usbinfo.h"
00049 #include <usb/dev/dp.h>
00050 
00051 #define INDENT "  "
00052 #define BYTES_PER_LINE 12
00053 
00054 
00055 const char *get_indent(size_t level)
00056 {
00057         static const char *indents[] = {
00058                 INDENT,
00059                 INDENT INDENT,
00060                 INDENT INDENT INDENT,
00061                 INDENT INDENT INDENT INDENT,
00062                 INDENT INDENT INDENT INDENT INDENT
00063         };
00064         static size_t indents_count = sizeof(indents)/sizeof(indents[0]);
00065         if (level >= indents_count) {
00066                 return indents[indents_count - 1];
00067         }
00068         return indents[level];
00069 }
00070 
00071 void dump_buffer(const char *msg, size_t indent,
00072     const uint8_t *buffer, size_t length)
00073 {
00074         if (msg != NULL) {
00075                 printf("%s\n", msg);
00076         }
00077 
00078         size_t i;
00079         if (length > 0) {
00080                 printf("%s", get_indent(indent));
00081         }
00082         for (i = 0; i < length; i++) {
00083                 printf("0x%02X", buffer[i]);
00084                 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
00085                     || (i + 1 == length)) {
00086                         printf("\n");
00087                         if (i + 1 < length) {
00088                                 printf("%s", get_indent(indent));
00089                         }
00090                 } else {
00091                         printf("  ");
00092                 }
00093         }
00094 }
00095 
00096 void dump_usb_descriptor(uint8_t *descriptor, size_t size)
00097 {
00098         printf("Device descriptor:\n");
00099         usb_dump_standard_descriptor(stdout, get_indent(0), "\n",
00100             descriptor, size);
00101 }
00102 
00103 void dump_match_ids(match_id_list_t *matches, const char *line_prefix)
00104 {
00105         link_t *link;
00106         for (link = matches->ids.next;
00107             link != &matches->ids;
00108             link = link->next) {
00109                 match_id_t *match = list_get_instance(link, match_id_t, link);
00110 
00111                 printf("%s%3d %s\n", line_prefix, match->score, match->id);
00112         }
00113 }
00114 
00115 static void dump_tree_descriptor(uint8_t *descriptor, size_t depth)
00116 {
00117         if (descriptor == NULL) {
00118                 return;
00119         }
00120         int type = (int) *(descriptor + 1);
00121         const char *name = "unknown";
00122         switch (type) {
00123 #define _TYPE(descriptor_type) \
00124                 case USB_DESCTYPE_##descriptor_type: name = #descriptor_type; break
00125                 _TYPE(DEVICE);
00126                 _TYPE(CONFIGURATION);
00127                 _TYPE(STRING);
00128                 _TYPE(INTERFACE);
00129                 _TYPE(ENDPOINT);
00130                 _TYPE(HID);
00131                 _TYPE(HID_REPORT);
00132                 _TYPE(HID_PHYSICAL);
00133                 _TYPE(HUB);
00134 #undef _TYPE
00135         }
00136         printf("%s%s (0x%02X):\n", get_indent(depth), name, type);
00137         usb_dump_standard_descriptor(stdout, get_indent(depth), "\n",
00138             descriptor, descriptor[0]);
00139 }
00140 
00141 static void dump_tree_internal(usb_dp_parser_t *parser, usb_dp_parser_data_t *data,
00142     uint8_t *root, size_t depth)
00143 {
00144         if (root == NULL) {
00145                 return;
00146         }
00147         dump_tree_descriptor(root, depth);
00148         uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
00149         do {
00150                 dump_tree_internal(parser, data, child, depth + 1);
00151                 child = usb_dp_get_sibling_descriptor(parser, data, root, child);
00152         } while (child != NULL);
00153 }
00154 
00155 static void dump_tree(usb_dp_parser_t *parser, usb_dp_parser_data_t *data)
00156 {
00157         uint8_t *ptr = data->data;
00158         printf("Descriptor tree:\n");
00159         dump_tree_internal(parser, data, ptr, 0);
00160 }
00161 
00162 #define NESTING(parentname, childname) \
00163         { \
00164                 .child = USB_DESCTYPE_##childname, \
00165                 .parent = USB_DESCTYPE_##parentname, \
00166         }
00167 #define LAST_NESTING { -1, -1 }
00168 
00169 static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
00170         NESTING(CONFIGURATION, INTERFACE),
00171         NESTING(INTERFACE, ENDPOINT),
00172         NESTING(INTERFACE, HUB),
00173         NESTING(INTERFACE, HID),
00174         NESTING(HID, HID_REPORT),
00175         LAST_NESTING
00176 };
00177 
00178 static usb_dp_parser_t parser = {
00179         .nesting = descriptor_nesting
00180 };
00181 
00182 void dump_descriptor_tree(uint8_t *descriptors, size_t length)
00183 {
00184         usb_dp_parser_data_t data = {
00185                 .data = descriptors,
00186                 .size = length,
00187                 .arg = NULL
00188         };
00189 
00190         dump_tree(&parser, &data);
00191 }
00192 

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7