main.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010-2011 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 #include <getopt.h>
00043 #include <devman.h>
00044 #include <devmap.h>
00045 #include <usb/hc.h>
00046 #include <usb/dev/pipes.h>
00047 #include "usbinfo.h"
00048 
00049 static void print_usage(char *app_name)
00050 {
00051 #define _INDENT "      "
00052 #define _OPTION(opt, description) \
00053         printf(_INDENT opt "\n" _INDENT _INDENT description "\n")
00054 
00055         printf(NAME ": query USB devices for descriptors\n\n");
00056         printf("Usage: %s [options] device [device [device [ ... ]]]\n",
00057             app_name);
00058         printf(_INDENT "The device is a devman path to the device.\n");
00059 
00060         _OPTION("-h --help", "Print this help and exit.");
00061         _OPTION("-i --identification", "Brief device identification.");
00062         _OPTION("-m --match-ids", "Print match ids generated for the device.");
00063         _OPTION("-t --descriptor-tree", "Print descriptor tree.");
00064         _OPTION("-T --descriptor-tree-full", "Print detailed descriptor tree");
00065         _OPTION("-s --strings", "Try to print all string descriptors.");
00066         _OPTION("-S --status", "Get status of the device.");
00067 
00068         printf("\n");
00069         printf("If no option is specified, `-i' is considered default.\n");
00070         printf("\n");
00071 
00072 #undef _OPTION
00073 #undef _INDENT
00074 }
00075 
00076 static struct option long_options[] = {
00077         {"help", no_argument, NULL, 'h'},
00078         {"identification", no_argument, NULL, 'i'},
00079         {"match-ids", no_argument, NULL, 'm'},
00080         {"descriptor-tree", no_argument, NULL, 't'},
00081         {"descriptor-tree-full", no_argument, NULL, 'T'},
00082         {"strings", no_argument, NULL, 's'},
00083         {"status", no_argument, NULL, 'S'},
00084         {0, 0, NULL, 0}
00085 };
00086 static const char *short_options = "himtTsS";
00087 
00088 static usbinfo_action_t actions[] = {
00089         {
00090                 .opt = 'i',
00091                 .action = dump_short_device_identification,
00092                 .active = false
00093         },
00094         {
00095                 .opt = 'm',
00096                 .action = dump_device_match_ids,
00097                 .active = false
00098         },
00099         {
00100                 .opt = 't',
00101                 .action = dump_descriptor_tree_brief,
00102                 .active = false
00103         },
00104         {
00105                 .opt = 'T',
00106                 .action = dump_descriptor_tree_full,
00107                 .active = false
00108         },
00109         {
00110                 .opt = 's',
00111                 .action = dump_strings,
00112                 .active = false
00113         },
00114         {
00115                 .opt = 'S',
00116                 .action = dump_status,
00117                 .active = false
00118         },
00119         {
00120                 .opt = 0
00121         }
00122 };
00123 
00124 int main(int argc, char *argv[])
00125 {
00126         if (argc <= 1) {
00127                 print_usage(argv[0]);
00128                 return -1;
00129         }
00130 
00131         /*
00132          * Process command-line options. They determine what shall be
00133          * done with the device.
00134          */
00135         int opt;
00136         do {
00137                 opt = getopt_long(argc, argv,
00138                     short_options, long_options, NULL);
00139                 switch (opt) {
00140                         case -1:
00141                                 break;
00142                         case '?':
00143                                 print_usage(argv[0]);
00144                                 return 1;
00145                         case 'h':
00146                                 print_usage(argv[0]);
00147                                 return 0;
00148                         default: {
00149                                 int idx = 0;
00150                                 while (actions[idx].opt != 0) {
00151                                         if (actions[idx].opt == opt) {
00152                                                 actions[idx].active = true;
00153                                                 break;
00154                                         }
00155                                         idx++;
00156                                 }
00157                                 break;
00158                         }
00159                 }
00160         } while (opt > 0);
00161 
00162         /* Set the default action. */
00163         int idx = 0;
00164         bool something_active = false;
00165         while (actions[idx].opt != 0) {
00166                 if (actions[idx].active) {
00167                         something_active = true;
00168                         break;
00169                 }
00170                 idx++;
00171         }
00172         if (!something_active) {
00173                 actions[0].active = true;
00174         }
00175 
00176         /*
00177          * Go through all devices given on the command line and run the
00178          * specified actions.
00179          */
00180         int i;
00181         for (i = optind; i < argc; i++) {
00182                 char *devpath = argv[i];
00183 
00184                 /* The initialization is here only to make compiler happy. */
00185                 devman_handle_t hc_handle = 0;
00186                 usb_address_t dev_addr = 0;
00187                 int rc = usb_resolve_device_handle(devpath,
00188                     &hc_handle, &dev_addr, NULL);
00189                 if (rc != EOK) {
00190                         fprintf(stderr, NAME ": device `%s' not found "
00191                             "or not of USB kind, skipping.\n",
00192                             devpath);
00193                         continue;
00194                 }
00195 
00196                 usbinfo_device_t *dev = prepare_device(devpath,
00197                     hc_handle, dev_addr);
00198                 if (dev == NULL) {
00199                         continue;
00200                 }
00201 
00202                 /* Run actions the user specified. */
00203                 printf("%s\n", devpath);
00204 
00205                 int action = 0;
00206                 while (actions[action].opt != 0) {
00207                         if (actions[action].active) {
00208                                 actions[action].action(dev);
00209                         }
00210                         action++;
00211                 }
00212 
00213                 /* Destroy the control pipe (close the session etc.). */
00214                 destroy_device(dev);
00215         }
00216 
00217         return 0;
00218 }
00219 
00220 

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