"Fossies" - the Fresh Open Source Software Archive

Member "usbview-3.0/usbtree.c" (22 Jan 2022, 9703 Bytes) of package /linux/misc/usbview-3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // SPDX-License-Identifier: GPL-2.0-only
    2 /*
    3  * usbtree.c for USBView - a USB device viewer
    4  * Copyright (c) 1999, 2000, 2021-2022 by Greg Kroah-Hartman, <greg@kroah.com>
    5  */
    6 #ifdef HAVE_CONFIG_H
    7     #include <config.h>
    8 #endif
    9 
   10 #include <stdio.h>
   11 #include <stdlib.h>
   12 #include <string.h>
   13 #include <ctype.h>
   14 #include <sys/stat.h>
   15 #include <unistd.h>
   16 #include <errno.h>
   17 #include <gtk/gtk.h>
   18 
   19 #include "usbtree.h"
   20 #include "sysfs.h"
   21 
   22 #define MAX_LINE_SIZE   1000
   23 
   24 
   25 static void Init (void)
   26 {
   27     GtkTextIter begin;
   28     GtkTextIter end;
   29 
   30     /* blow away the tree if there is one */
   31     if (rootDevice != NULL) {
   32         gtk_tree_store_clear (treeStore);
   33     }
   34 
   35     /* clean out the text box */
   36     gtk_text_buffer_get_start_iter(textDescriptionBuffer,&begin);
   37     gtk_text_buffer_get_end_iter(textDescriptionBuffer,&end);
   38     gtk_text_buffer_delete (textDescriptionBuffer, &begin, &end);
   39 
   40     return;
   41 }
   42 
   43 
   44 static void PopulateListBox (int deviceId)
   45 {
   46     struct Device *device;
   47     char    *string;
   48     char    *tempString;
   49     int     configNum;
   50     int     interfaceNum;
   51     int     endpointNum;
   52     int     deviceNumber = (deviceId >> 8);
   53     int     busNumber = (deviceId & 0x00ff);
   54     GtkTextIter begin;
   55     GtkTextIter end;
   56 
   57     device = usb_find_device (deviceNumber, busNumber);
   58     if (device == NULL) {
   59         printf ("Can't seem to find device info to display\n");
   60         return;
   61     }
   62 
   63     /* clear the textbox */
   64     gtk_text_buffer_get_start_iter(textDescriptionBuffer,&begin);
   65     gtk_text_buffer_get_end_iter(textDescriptionBuffer,&end);
   66     gtk_text_buffer_delete (textDescriptionBuffer, &begin, &end);
   67 
   68     /* freeze the display */
   69     /* this keeps the annoying scroll from happening */
   70     gtk_widget_freeze_child_notify(textDescriptionView);
   71 
   72     string = (char *)g_malloc (1000);
   73 
   74     /* add the name to the textbox if we have one*/
   75     if (device->name != NULL) {
   76         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, device->name,strlen(device->name));
   77     }
   78 
   79     /* add the manufacturer if we have one */
   80     if (device->manufacturer != NULL) {
   81         sprintf (string, "\nManufacturer: %s", device->manufacturer);
   82         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
   83     }
   84 
   85     /* add the serial number if we have one */
   86     if (device->serialNumber != NULL) {
   87         sprintf (string, "\nSerial Number: %s", device->serialNumber);
   88         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
   89     }
   90 
   91     /* add speed */
   92     switch (device->speed) {
   93         case 1 :        tempString = "1.5Mb/s (low)";   break;
   94         case 12 :       tempString = "12Mb/s (full)";   break;
   95         case 480 :      tempString = "480Mb/s (high)";  break;
   96         case 5000 :     tempString = "5Gb/s (super)";   break;
   97         case 10000 :    tempString = "10Gb/s (super+)"; break;
   98         default :       tempString = "unknown";         break;
   99     }
  100     sprintf (string, "\nSpeed: %s", tempString);
  101     gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  102 
  103     /* Add Bus number */
  104     sprintf (string, "\nBus:%4d", busNumber);
  105     gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  106 
  107     /* Add device address */
  108     sprintf (string, "\nAddress:%4d", deviceNumber);
  109     gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  110 
  111     /* add ports if available */
  112     if (device->maxChildren) {
  113         sprintf (string, "\nNumber of Ports: %i", device->maxChildren);
  114         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  115     }
  116 
  117     /* add the bandwidth info if available */
  118     if (device->bandwidth != NULL) {
  119         sprintf (string, "\nBandwidth allocated: %i / %i (%i%%)", device->bandwidth->allocated, device->bandwidth->total, device->bandwidth->percent);
  120         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  121 
  122         sprintf (string, "\nTotal number of interrupt requests: %i", device->bandwidth->numInterruptRequests);
  123         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  124 
  125         sprintf (string, "\nTotal number of isochronous requests: %i", device->bandwidth->numIsocRequests);
  126         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  127     }
  128 
  129     /* add the USB version, device class, subclass, protocol, max packet size, and the number of configurations (if it is there) */
  130     if (device->version) {
  131         sprintf (string, "\nUSB Version: %s\nDevice Class: %s\nDevice Subclass: %s\nDevice Protocol: %s\n"
  132              "Maximum Default Endpoint Size: %i\nNumber of Configurations: %i",
  133              device->version, device->class, device->subClass, device->protocol,
  134              device->maxPacketSize, device->numConfigs);
  135         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  136     }
  137 
  138     /* add the vendor id, product id, and revision number (if it is there) */
  139     if (device->vendorId) {
  140         sprintf (string, "\nVendor Id: %.4x\nProduct Id: %.4x\nRevision Number: %s",
  141              device->vendorId, device->productId, device->revisionNumber);
  142         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  143     }
  144 
  145     /* display all the info for the configs */
  146     for (configNum = 0; configNum < MAX_CONFIGS; ++configNum) {
  147         if (device->config[configNum]) {
  148             struct DeviceConfig *config = device->config[configNum];
  149 
  150             /* show this config */
  151             sprintf (string, "\n\nConfig Number: %i\n\tNumber of Interfaces: %i\n\t"
  152                  "Attributes: %.2x\n\tMaxPower Needed: %s",
  153                  config->configNumber, config->numInterfaces, 
  154                  config->attributes, config->maxPower);
  155             gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  156 
  157             /* show all of the interfaces for this config */
  158             for (interfaceNum = 0; interfaceNum < MAX_INTERFACES; ++interfaceNum) {
  159                 if (config->interface[interfaceNum]) {
  160                     struct DeviceInterface *interface = config->interface[interfaceNum];
  161 
  162                     sprintf (string, "\n\n\tInterface Number: %i", interface->interfaceNumber);
  163                     gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string, strlen(string));
  164 
  165                     if (interface->name != NULL) {
  166                         sprintf (string, "\n\t\tName: %s", interface->name);
  167                         gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string, strlen(string));
  168                     }
  169 
  170                     sprintf (string, "\n\t\tAlternate Number: %i\n\t\tClass: %s\n\t\t"
  171                          "Sub Class: %.2x\n\t\tProtocol: %.2x\n\t\tNumber of Endpoints: %i",
  172                          interface->alternateNumber, interface->class, 
  173                          interface->subClass, interface->protocol, interface->numEndpoints);
  174                     gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string, strlen(string));
  175 
  176                     /* show all of the endpoints for this interface */
  177                     for (endpointNum = 0; endpointNum < MAX_ENDPOINTS; ++endpointNum) {
  178                         if (interface->endpoint[endpointNum]) {
  179                             struct DeviceEndpoint *endpoint = interface->endpoint[endpointNum];
  180 
  181                             sprintf (string, "\n\n\t\t\tEndpoint Address: %.2x\n\t\t\t"
  182                                  "Direction: %s\n\t\t\tAttribute: %i\n\t\t\t"
  183                                  "Type: %s\n\t\t\tMax Packet Size: %i\n\t\t\tInterval: %s",
  184                                  endpoint->address, 
  185                                  endpoint->in ? "in" : "out", endpoint->attribute,
  186                                  endpoint->type, endpoint->maxPacketSize, endpoint->interval);
  187                             gtk_text_buffer_insert_at_cursor(textDescriptionBuffer, string,strlen(string));
  188                         }
  189                     }
  190                 }
  191             }
  192         }
  193     }
  194 
  195     /* thaw the display */
  196     gtk_widget_thaw_child_notify(textDescriptionView);
  197 
  198     /* clean up our string */
  199     g_free (string);
  200 
  201     return;
  202 }
  203 
  204 
  205 static void SelectItem (GtkTreeSelection *selection, gpointer userData)
  206 {
  207     GtkTreeIter iter;
  208     GtkTreeModel *model;
  209     gint deviceAddr;
  210 
  211     if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
  212         gtk_tree_model_get (model, &iter,
  213                 DEVICE_ADDR_COLUMN, &deviceAddr,
  214                 -1);
  215         PopulateListBox (deviceAddr);
  216     }
  217 }
  218 
  219 
  220 static void DisplayDevice (struct Device *parent, struct Device *device)
  221 {
  222     int     i;
  223     int     configNum;
  224     int     interfaceNum;
  225     gboolean    driverAttached = TRUE;
  226     gint        deviceAddr;
  227     const gchar *color = "black";
  228 
  229     if (device == NULL)
  230         return;
  231 
  232     /* build this node */
  233     deviceAddr = (device->deviceNumber << 8) | device->busNumber;
  234     gtk_tree_store_append (treeStore, &device->leaf,
  235                    (device->level != 0) ? &parent->leaf : NULL);
  236 
  237     /* determine if this device has drivers attached to all interfaces */
  238     for (configNum = 0; configNum < MAX_CONFIGS; ++configNum) {
  239         if (device->config[configNum]) {
  240             struct DeviceConfig *config = device->config[configNum];
  241             for (interfaceNum = 0; interfaceNum < MAX_INTERFACES; ++interfaceNum) {
  242                 if (config->interface[interfaceNum]) {
  243                     struct DeviceInterface *interface = config->interface[interfaceNum];
  244                     if (interface->driverAttached == FALSE) {
  245                         driverAttached = FALSE;
  246                         break;
  247                     }
  248                 }
  249             }
  250         }
  251     }
  252 
  253     /* change the color of this leaf if there are no drivers attached to it */
  254     if (driverAttached == FALSE)
  255         color = "red";
  256 
  257     gtk_tree_store_set (treeStore, &device->leaf,
  258                 NAME_COLUMN, device->name,
  259                 DEVICE_ADDR_COLUMN, deviceAddr,
  260                 COLOR_COLUMN, color,
  261                 -1);
  262 
  263     /* create all of the children's leafs */
  264     for (i = 0; i < MAX_CHILDREN; ++i) {
  265         DisplayDevice (device, device->child[i]);
  266     }
  267 
  268     return;
  269 }
  270 
  271 
  272 void LoadUSBTree (int refresh)
  273 {
  274     static gboolean signal_connected = FALSE;
  275     int             i;
  276 
  277     Init();
  278 
  279     usb_initialize_list ();
  280 
  281     sysfs_parse();
  282     usb_name_devices ();
  283 
  284     /* build our tree */
  285     for (i = 0; i < rootDevice->maxChildren; ++i) {
  286         DisplayDevice (rootDevice, rootDevice->child[i]);
  287     }
  288 
  289     gtk_widget_show (treeUSB);
  290 
  291     gtk_tree_view_expand_all (GTK_TREE_VIEW (treeUSB));
  292 
  293     /* hook up our callback function to this tree if we haven't yet */
  294     if (!signal_connected) {
  295         GtkTreeSelection *select;
  296         select = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeUSB));
  297         g_signal_connect (G_OBJECT (select), "changed",
  298                   G_CALLBACK (SelectItem), NULL);
  299         signal_connected = TRUE;
  300     }
  301 
  302     return;
  303 }
  304 
  305 void initialize_stuff(void)
  306 {
  307     return;
  308 }
  309