Ignore:
File:
1 edited

Legend:

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

    r206f71a rb8e2f93  
    4040#include <usb/recognise.h>
    4141#include <usb/request.h>
     42#include <usb/classes/classes.h>
     43#include <usb/classes/hid.h>
    4244#include "usbinfo.h"
    4345
    44 int dump_device(devman_handle_t hc_handle, usb_address_t address)
    45 {
    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          */
     46void dump_short_device_identification(usbinfo_device_t *dev)
     47{
     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
     53static 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
     88void 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
     108static 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
     117static 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
     124static 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
     134static 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
     147static 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
     156static 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
     203void 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
     214void dump_strings(usbinfo_device_t *dev)
     215{
     216        /* Get supported languages. */
    141217        l18_win_locales_t *langs;
    142218        size_t langs_count;
    143         rc = usb_request_get_supported_languages(&ctrl_pipe,
     219        int rc = usb_request_get_supported_languages(&dev->ctrl_pipe,
    144220            &langs, &langs_count);
    145221        if (rc != EOK) {
     
    147223                    NAME ": failed to get list of supported languages: %s.\n",
    148224                    str_error(rc));
    149                 goto skip_strings;
    150         }
    151 
    152         printf("String languages (%zu):", langs_count);
     225                return;
     226        }
     227
     228        printf("%sString languages (%zu):", get_indent(0), langs_count);
    153229        size_t i;
    154230        for (i = 0; i < langs_count; i++) {
     
    157233        printf(".\n");
    158234
    159         /*
    160          * Dump all strings in all available langages;
    161          */
     235        /* Get all strings and dump them. */
    162236        for (i = 0; i < langs_count; i++) {
    163237                l18_win_locales_t lang = langs[i];
    164238
    165                 printf("%sStrings for language 0x%04x:\n", get_indent(0),
    166                     (int) lang);
    167 
     239                printf("%sStrings in %s:\n", get_indent(0),
     240                    str_l18_win_locale(lang));
    168241                /*
    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.
     242                 * Try only the first 15 strings
     243                 * (typically, device will not have much more anyway).
    173244                 */
    174245                size_t idx;
    175                 size_t failed_count = 0;
    176                 for (idx = 1; idx < 0xFF; idx++) {
     246                for (idx = 1; idx < 0x0F; idx++) {
    177247                        char *string;
    178                         rc = usb_request_get_string(&ctrl_pipe, idx, lang,
     248                        rc = usb_request_get_string(&dev->ctrl_pipe, idx, lang,
    179249                            &string);
    180250                        if (rc != EOK) {
    181                                 failed_count++;
    182                                 if (failed_count > 3) {
    183                                         break;
    184                                 }
    185251                                continue;
    186252                        }
     
    188254                            idx, string);
    189255                        free(string);
    190                         failed_count = 0; /* Reset failed counter. */
    191256                }
    192257        }
    193 
    194 
    195 skip_strings:
    196 
    197         rc = EOK;
    198 
    199 leave:
    200         /* Ignoring errors here. */
    201         usb_endpoint_pipe_end_session(&ctrl_pipe);
    202 
    203         return rc;
    204258}
    205259
Note: See TracChangeset for help on using the changeset viewer.