source: mainline/uspace/app/usbinfo/dump.c@ 0475e13

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0475e13 was b1c6e58, checked in by Vojtech Horky <vojtechhorky@…>, 14 years ago

Refactoring of usbinfo application

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2010 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup usbinfo
30 * @{
31 */
32/**
33 * @file
34 * USB querying.
35 */
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <errno.h>
40#include <str_error.h>
41#include <bool.h>
42
43#include <usb/usb.h>
44#include <usb/descriptor.h>
45#include <usb/debug.h>
46#include <usb/classes/classes.h>
47
48#include "usbinfo.h"
49#include <usb/dp.h>
50
51#define INDENT " "
52#define BYTES_PER_LINE 12
53
54
55const char *get_indent(size_t level)
56{
57 static const char *indents[] = {
58 INDENT,
59 INDENT INDENT,
60 INDENT INDENT INDENT,
61 INDENT INDENT INDENT INDENT,
62 INDENT INDENT INDENT INDENT INDENT
63 };
64 static size_t indents_count = sizeof(indents)/sizeof(indents[0]);
65 if (level >= indents_count) {
66 return indents[indents_count - 1];
67 }
68 return indents[level];
69}
70
71void dump_buffer(const char *msg, size_t indent,
72 const uint8_t *buffer, size_t length)
73{
74 if (msg != NULL) {
75 printf("%s\n", msg);
76 }
77
78 size_t i;
79 if (length > 0) {
80 printf("%s", get_indent(indent));
81 }
82 for (i = 0; i < length; i++) {
83 printf("0x%02X", buffer[i]);
84 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
85 || (i + 1 == length)) {
86 printf("\n");
87 if (i + 1 < length) {
88 printf("%s", get_indent(indent));
89 }
90 } else {
91 printf(" ");
92 }
93 }
94}
95
96void dump_usb_descriptor(uint8_t *descriptor, size_t size)
97{
98 printf("Device descriptor:\n");
99 usb_dump_standard_descriptor(stdout, get_indent(0), "\n",
100 descriptor, size);
101}
102
103void dump_match_ids(match_id_list_t *matches)
104{
105 printf("Match ids:\n");
106 link_t *link;
107 for (link = matches->ids.next;
108 link != &matches->ids;
109 link = link->next) {
110 match_id_t *match = list_get_instance(link, match_id_t, link);
111
112 printf(INDENT "%d %s\n", match->score, match->id);
113 }
114}
115
116static void dump_tree_descriptor(uint8_t *descriptor, size_t depth)
117{
118 if (descriptor == NULL) {
119 return;
120 }
121 int type = (int) *(descriptor + 1);
122 const char *name = "unknown";
123 switch (type) {
124#define _TYPE(descriptor_type) \
125 case USB_DESCTYPE_##descriptor_type: name = #descriptor_type; break
126 _TYPE(DEVICE);
127 _TYPE(CONFIGURATION);
128 _TYPE(STRING);
129 _TYPE(INTERFACE);
130 _TYPE(ENDPOINT);
131 _TYPE(HID);
132 _TYPE(HID_REPORT);
133 _TYPE(HID_PHYSICAL);
134 _TYPE(HUB);
135#undef _TYPE
136 }
137 printf("%s%s (0x%02X):\n", get_indent(depth), name, type);
138 usb_dump_standard_descriptor(stdout, get_indent(depth), "\n",
139 descriptor, descriptor[0]);
140}
141
142static void dump_tree_internal(usb_dp_parser_t *parser, usb_dp_parser_data_t *data,
143 uint8_t *root, size_t depth)
144{
145 if (root == NULL) {
146 return;
147 }
148 dump_tree_descriptor(root, depth);
149 uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
150 do {
151 dump_tree_internal(parser, data, child, depth + 1);
152 child = usb_dp_get_sibling_descriptor(parser, data, root, child);
153 } while (child != NULL);
154}
155
156static void dump_tree(usb_dp_parser_t *parser, usb_dp_parser_data_t *data)
157{
158 uint8_t *ptr = data->data;
159 printf("Descriptor tree:\n");
160 dump_tree_internal(parser, data, ptr, 0);
161}
162
163#define NESTING(parentname, childname) \
164 { \
165 .child = USB_DESCTYPE_##childname, \
166 .parent = USB_DESCTYPE_##parentname, \
167 }
168#define LAST_NESTING { -1, -1 }
169
170static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
171 NESTING(CONFIGURATION, INTERFACE),
172 NESTING(INTERFACE, ENDPOINT),
173 NESTING(INTERFACE, HUB),
174 NESTING(INTERFACE, HID),
175 NESTING(HID, HID_REPORT),
176 LAST_NESTING
177};
178
179static usb_dp_parser_t parser = {
180 .nesting = descriptor_nesting
181};
182
183void dump_descriptor_tree(uint8_t *descriptors, size_t length)
184{
185 usb_dp_parser_data_t data = {
186 .data = descriptors,
187 .size = length,
188 .arg = NULL
189 };
190
191 dump_tree(&parser, &data);
192}
193
194/** @}
195 */
Note: See TracBrowser for help on using the repository browser.