Ignore:
File:
1 edited

Legend:

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

    rb8e2f93 r206f71a  
    4040#include <usb/recognise.h>
    4141#include <usb/request.h>
    42 #include <usb/classes/classes.h>
    43 #include <usb/classes/hid.h>
    4442#include "usbinfo.h"
    4543
    46 void dump_short_device_identification(usbinfo_device_t *dev)
     44int dump_device(devman_handle_t hc_handle, usb_address_t address)
    4745{
    48         printf("%sDevice 0x%04x by vendor 0x%04x\n", get_indent(0),
    49             (int) dev->device_descriptor.product_id,
    50             (int) dev->device_descriptor.vendor_id);
    51 }
    52 
    53 static void dump_match_ids_from_interface(uint8_t *descriptor, size_t depth,
    54     void *arg)
    55 {
    56         if (depth != 1) {
    57                 return;
    58         }
    59         size_t descr_size = descriptor[0];
    60         if (descr_size < sizeof(usb_standard_interface_descriptor_t)) {
    61                 return;
    62         }
    63         int descr_type = descriptor[1];
    64         if (descr_type != USB_DESCTYPE_INTERFACE) {
    65                 return;
    66         }
    67 
    68         usbinfo_device_t *dev = (usbinfo_device_t *) arg;
    69 
    70         usb_standard_interface_descriptor_t *iface
    71             = (usb_standard_interface_descriptor_t *) descriptor;
    72 
    73         printf("%sInterface #%d match ids (%s, 0x%02x, 0x%02x)\n",
    74             get_indent(0),
    75             (int) iface->interface_number,
    76             usb_str_class(iface->interface_class),
    77             (int) iface->interface_subclass,
    78             (int) iface->interface_protocol);
    79 
    80         match_id_list_t matches;
    81         init_match_ids(&matches);
    82         usb_device_create_match_ids_from_interface(&dev->device_descriptor,
    83             iface, &matches);
    84         dump_match_ids(&matches, get_indent(1));
    85         clean_match_ids(&matches);
    86 }
    87 
    88 void dump_device_match_ids(usbinfo_device_t *dev)
    89 {
    90         match_id_list_t matches;
    91         init_match_ids(&matches);
    92         usb_device_create_match_ids_from_device_descriptor(
    93             &dev->device_descriptor, &matches);
    94         printf("%sDevice match ids (0x%04x by 0x%04x, %s)\n", get_indent(0),
    95             (int) dev->device_descriptor.product_id,
    96             (int) dev->device_descriptor.vendor_id,
    97             usb_str_class(dev->device_descriptor.device_class));
    98         dump_match_ids(&matches, get_indent(1));
    99         clean_match_ids(&matches);
    100 
    101         usb_dp_walk_simple(dev->full_configuration_descriptor,
    102             dev->full_configuration_descriptor_size,
    103             usb_dp_standard_descriptor_nesting,
    104             dump_match_ids_from_interface,
    105             dev);
    106 }
    107 
    108 static void dump_descriptor_tree_brief_device(const char *prefix,
    109     usb_standard_device_descriptor_t *descriptor)
    110 {
    111         printf("%sDevice (0x%04x by 0x%04x, %s)\n", prefix,
    112             (int) descriptor->product_id,
    113             (int) descriptor->vendor_id,
    114             usb_str_class(descriptor->device_class));
    115 }
    116 
    117 static void dump_descriptor_tree_brief_configuration(const char *prefix,
    118     usb_standard_configuration_descriptor_t *descriptor)
    119 {
    120         printf("%sConfiguration #%d\n", prefix,
    121             (int) descriptor->configuration_number);
    122 }
    123 
    124 static void dump_descriptor_tree_brief_interface(const char *prefix,
    125     usb_standard_interface_descriptor_t *descriptor)
    126 {
    127         printf("%sInterface #%d (%s, 0x%02x, 0x%02x)\n", prefix,
    128             (int) descriptor->interface_number,
    129             usb_str_class(descriptor->interface_class),
    130             (int) descriptor->interface_subclass,
    131             (int) descriptor->interface_protocol);
    132 }
    133 
    134 static void dump_descriptor_tree_brief_endpoint(const char *prefix,
    135     usb_standard_endpoint_descriptor_t *descriptor)
    136 {
    137         usb_endpoint_t endpoint_no = descriptor->endpoint_address & 0xF;
    138         usb_transfer_type_t transfer = descriptor->attributes & 0x3;
    139         usb_direction_t direction = descriptor->endpoint_address & 0x80
    140             ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
    141         printf("%sEndpoint #%d (%s %s, %zu)\n", prefix,
    142             endpoint_no, usb_str_transfer_type(transfer),
    143             direction == USB_DIRECTION_IN ? "in" : "out",
    144             (size_t) descriptor->max_packet_size);
    145 }
    146 
    147 static void dump_descriptor_tree_brief_hid(const char *prefix,
    148     usb_standard_hid_descriptor_t *descriptor)
    149 {
    150         printf("%sHID (country %d, %d descriptors)\n", prefix,
    151             (int) descriptor->country_code,
    152             (int) descriptor->class_desc_count);
    153 }
    154 
    155 
    156 static void dump_descriptor_tree_brief_callback(uint8_t *descriptor,
    157     size_t depth, void *arg)
    158 {
    159         const char *indent = get_indent(depth + 1);
    160 
    161         int descr_type = -1;
    162         size_t descr_size = descriptor[0];
    163         if (descr_size > 0) {
    164                 descr_type = descriptor[1];
    165         }
    166 
    167         switch (descr_type) {
    168 
    169 #define _BRANCH(type_enum, descriptor_type, callback) \
    170         case type_enum: \
    171                 if (descr_size >= sizeof(descriptor_type)) { \
    172                         callback(indent, (descriptor_type *) descriptor); \
    173                 } else { \
    174                         descr_type = -1; \
    175                 } \
    176                 break;
    177 
    178                 _BRANCH(USB_DESCTYPE_DEVICE,
    179                     usb_standard_device_descriptor_t,
    180                     dump_descriptor_tree_brief_device);
    181                 _BRANCH(USB_DESCTYPE_CONFIGURATION,
    182                     usb_standard_configuration_descriptor_t,
    183                     dump_descriptor_tree_brief_configuration);
    184                 _BRANCH(USB_DESCTYPE_INTERFACE,
    185                     usb_standard_interface_descriptor_t,
    186                     dump_descriptor_tree_brief_interface);
    187                 _BRANCH(USB_DESCTYPE_ENDPOINT,
    188                     usb_standard_endpoint_descriptor_t,
    189                     dump_descriptor_tree_brief_endpoint);
    190                 _BRANCH(USB_DESCTYPE_HID,
    191                     usb_standard_hid_descriptor_t,
    192                     dump_descriptor_tree_brief_hid);
    193 
    194                 default:
    195                         break;
    196         }
    197 
    198         if (descr_type == -1) {
    199                 printf("%sInvalid descriptor.\n", indent);
    200         }
    201 }
    202 
    203 void dump_descriptor_tree_brief(usbinfo_device_t *dev)
    204 {
    205         dump_descriptor_tree_brief_callback((uint8_t *)&dev->device_descriptor,
    206             (size_t) -1, NULL);
    207         usb_dp_walk_simple(dev->full_configuration_descriptor,
    208             dev->full_configuration_descriptor_size,
    209             usb_dp_standard_descriptor_nesting,
    210             dump_descriptor_tree_brief_callback,
    211             NULL);
    212 }
    213 
    214 void dump_strings(usbinfo_device_t *dev)
    215 {
    216         /* Get supported languages. */
     46        int rc;
     47        usb_device_connection_t wire;
     48        usb_endpoint_pipe_t ctrl_pipe;
     49
     50        /*
     51         * Initialize pipes.
     52         */
     53        rc = usb_device_connection_initialize(&wire, hc_handle, address);
     54        if (rc != EOK) {
     55                fprintf(stderr,
     56                    NAME ": failed to create connection to the device: %s.\n",
     57                    str_error(rc));
     58                goto leave;
     59        }
     60        rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, &wire);
     61        if (rc != EOK) {
     62                fprintf(stderr,
     63                    NAME ": failed to create default control pipe: %s.\n",
     64                    str_error(rc));
     65                goto leave;
     66        }
     67        rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);
     68        if (rc != EOK) {
     69                fprintf(stderr,
     70                    NAME ": probing default control pipe failed: %s.\n",
     71                    str_error(rc));
     72                goto leave;
     73        }
     74        rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
     75        if (rc != EOK) {
     76                fprintf(stderr,
     77                    NAME ": failed to start session on control pipe: %s.\n",
     78                    str_error(rc));
     79                goto leave;
     80        }
     81
     82        /*
     83         * Dump information about possible match ids.
     84         */
     85        match_id_list_t match_id_list;
     86        init_match_ids(&match_id_list);
     87        rc = usb_device_create_match_ids(&ctrl_pipe, &match_id_list);
     88        if (rc != EOK) {
     89                fprintf(stderr,
     90                    NAME ": failed to fetch match ids of the device: %s.\n",
     91                    str_error(rc));
     92                goto leave;
     93        }
     94        dump_match_ids(&match_id_list);
     95
     96        /*
     97         * Get device descriptor and dump it.
     98         */
     99        usb_standard_device_descriptor_t device_descriptor;
     100        rc = usb_request_get_device_descriptor(&ctrl_pipe, &device_descriptor);
     101        if (rc != EOK) {
     102                fprintf(stderr,
     103                    NAME ": failed to fetch standard device descriptor: %s.\n",
     104                    str_error(rc));
     105                goto leave;
     106        }
     107        dump_usb_descriptor((uint8_t *)&device_descriptor, sizeof(device_descriptor));
     108
     109        /*
     110         * Get first configuration descriptor and dump it.
     111         */
     112        usb_standard_configuration_descriptor_t config_descriptor;
     113        int config_index = 0;
     114        rc = usb_request_get_bare_configuration_descriptor(&ctrl_pipe,
     115            config_index, &config_descriptor);
     116        if (rc != EOK) {
     117                fprintf(stderr,
     118                    NAME ": failed to fetch standard configuration descriptor: %s.\n",
     119                    str_error(rc));
     120                goto leave;
     121        }
     122        //dump_standard_configuration_descriptor(config_index, &config_descriptor);
     123
     124        void *full_config_descriptor = malloc(config_descriptor.total_length);
     125        rc = usb_request_get_full_configuration_descriptor(&ctrl_pipe,
     126            config_index,
     127            full_config_descriptor, config_descriptor.total_length, NULL);
     128        if (rc != EOK) {
     129                fprintf(stderr,
     130                    NAME ": failed to fetch full configuration descriptor: %s.\n",
     131                    str_error(rc));
     132                goto leave;
     133        }
     134
     135        dump_descriptor_tree(full_config_descriptor,
     136            config_descriptor.total_length);
     137
     138        /*
     139         * Get supported languages of STRING descriptors.
     140         */
    217141        l18_win_locales_t *langs;
    218142        size_t langs_count;
    219         int rc = usb_request_get_supported_languages(&dev->ctrl_pipe,
     143        rc = usb_request_get_supported_languages(&ctrl_pipe,
    220144            &langs, &langs_count);
    221145        if (rc != EOK) {
     
    223147                    NAME ": failed to get list of supported languages: %s.\n",
    224148                    str_error(rc));
    225                 return;
    226         }
    227 
    228         printf("%sString languages (%zu):", get_indent(0), langs_count);
     149                goto skip_strings;
     150        }
     151
     152        printf("String languages (%zu):", langs_count);
    229153        size_t i;
    230154        for (i = 0; i < langs_count; i++) {
     
    233157        printf(".\n");
    234158
    235         /* Get all strings and dump them. */
     159        /*
     160         * Dump all strings in all available langages;
     161         */
    236162        for (i = 0; i < langs_count; i++) {
    237163                l18_win_locales_t lang = langs[i];
    238164
    239                 printf("%sStrings in %s:\n", get_indent(0),
    240                     str_l18_win_locale(lang));
     165                printf("%sStrings for language 0x%04x:\n", get_indent(0),
     166                    (int) lang);
     167
    241168                /*
    242                  * Try only the first 15 strings
    243                  * (typically, device will not have much more anyway).
     169                 * Try all indexes - we will see what pops-up ;-).
     170                 * However, to speed things up, we will stop after
     171                 * encountering several broken (or nonexistent ones)
     172                 * descriptors in line.
    244173                 */
    245174                size_t idx;
    246                 for (idx = 1; idx < 0x0F; idx++) {
     175                size_t failed_count = 0;
     176                for (idx = 1; idx < 0xFF; idx++) {
    247177                        char *string;
    248                         rc = usb_request_get_string(&dev->ctrl_pipe, idx, lang,
     178                        rc = usb_request_get_string(&ctrl_pipe, idx, lang,
    249179                            &string);
    250180                        if (rc != EOK) {
     181                                failed_count++;
     182                                if (failed_count > 3) {
     183                                        break;
     184                                }
    251185                                continue;
    252186                        }
     
    254188                            idx, string);
    255189                        free(string);
     190                        failed_count = 0; /* Reset failed counter. */
    256191                }
    257192        }
     193
     194
     195skip_strings:
     196
     197        rc = EOK;
     198
     199leave:
     200        /* Ignoring errors here. */
     201        usb_endpoint_pipe_end_session(&ctrl_pipe);
     202
     203        return rc;
    258204}
    259205
Note: See TracChangeset for help on using the changeset viewer.