2 * Copyright (c) 2010-2011 Vojtech Horky
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 /** @addtogroup usbinfo
40 #include <str_error.h>
46 #include <usb/dev/pipes.h>
49 static void print_usage(char *app_name
)
52 #define _OPTION(opt, description) \
53 printf(_INDENT opt "\n" _INDENT _INDENT description "\n")
55 printf(NAME
": query USB devices for descriptors\n\n");
56 printf("Usage: %s [options] device [device [device [ ... ]]]\n",
58 printf(_INDENT
"The device can be specified in two ways.\n");
59 printf(_INDENT
" o Using its devman path, e.g. /hw/pci0/.../usb00_a1.\n");
60 printf(_INDENT
" o Or using BUS.ADDR numbers as printed by lsusb.\n");
62 _OPTION("-h --help", "Print this help and exit.");
63 _OPTION("-l --list", "Print a list of host controllers and devices.");
64 _OPTION("-i --identification", "Brief device identification.");
65 _OPTION("-m --match-ids", "Print match ids generated for the device.");
66 _OPTION("-t --descriptor-tree", "Print descriptor tree.");
67 _OPTION("-T --descriptor-tree-full", "Print detailed descriptor tree");
68 _OPTION("-s --strings", "Try to print all string descriptors.");
69 _OPTION("-S --status", "Get status of the device.");
70 _OPTION("-r --hid-report", "Dump HID report descriptor.");
71 _OPTION("-r --hid-report-usages", "Dump usages of HID report.");
74 printf("If no option is specified, `-i' is considered default.\n");
81 static struct option long_options
[] = {
82 { "help", no_argument
, NULL
, 'h' },
83 { "identification", no_argument
, NULL
, 'i' },
84 { "list", no_argument
, NULL
, 'l' },
85 { "match-ids", no_argument
, NULL
, 'm' },
86 { "descriptor-tree", no_argument
, NULL
, 't' },
87 { "descriptor-tree-full", no_argument
, NULL
, 'T' },
88 { "strings", no_argument
, NULL
, 's' },
89 { "status", no_argument
, NULL
, 'S' },
90 { "hid-report", no_argument
, NULL
, 'r' },
91 { "hid-report-usages", no_argument
, NULL
, 'R' },
94 static const char *short_options
= "hilmtTsSrR";
96 static usbinfo_action_t actions
[] = {
99 .action
= dump_short_device_identification
,
104 .action
= dump_device_match_ids
,
109 .action
= dump_descriptor_tree_brief
,
114 .action
= dump_descriptor_tree_full
,
119 .action
= dump_strings
,
124 .action
= dump_status
,
129 .action
= dump_hidreport_raw
,
134 .action
= dump_hidreport_usages
,
142 int main(int argc
, char *argv
[])
145 print_usage(argv
[0]);
149 bool something_active
= false;
151 * Process command-line options. They determine what shall be
152 * done with the device.
157 opt
= getopt_long(argc
, argv
,
158 short_options
, long_options
, NULL
);
166 print_usage(argv
[0]);
169 print_usage(argv
[0]);
173 while (actions
[idx
].opt
!= 0) {
174 if (actions
[idx
].opt
== opt
) {
175 actions
[idx
].active
= true;
176 something_active
= true;
185 /* Set the default action. */
186 if (!something_active
) {
187 actions
[0].active
= true;
191 * Go through all devices given on the command line and run the
195 for (i
= optind
; i
< argc
; i
++) {
196 char *devpath
= argv
[i
];
198 /* The initialization is here only to make compiler happy. */
199 devman_handle_t handle
= 0;
200 errno_t rc
= usb_resolve_device_handle(devpath
, &handle
);
202 fprintf(stderr
, NAME
": device `%s' not found "
203 "or not of USB kind, skipping.\n",
208 usb_device_t
*usb_dev
= usb_device_create(handle
);
210 if (usb_dev
== NULL
) {
211 fprintf(stderr
, NAME
": device `%s' not found "
212 "or not of USB kind, skipping.\n",
217 /* Run actions the user specified. */
218 printf("%s\n", devpath
);
221 while (actions
[action
].opt
!= 0) {
222 if (actions
[action
].active
) {
223 actions
[action
].action(usb_dev
);
228 usb_device_destroy(usb_dev
);