"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. For more information about "usbtree.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.2_vs_3.0.

    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