"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