aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Čerman <10187350+ocerman@users.noreply.github.com>2018-11-30 13:59:34 +0100
committerLeandro A. F. Pereira <leandro@hardinfo.org>2018-11-30 04:59:34 -0800
commit5c32c60b3b4bb92fbfd5dd8c465c1f38f063660a (patch)
treea72d011c49b090d0f489231f4105d0d3cd904661
parentb52f767d80719185a62d959be46ba15fdb8f8f85 (diff)
devices/usb: Add USB interfaces and device icons
* devices/usb: Added support for USB interfaces * devices/usb: added icons for usb devices * tabs -> spaces
-rw-r--r--hardinfo/usb_util.c69
-rw-r--r--includes/devices.h1
-rw-r--r--includes/usb_util.h14
-rw-r--r--modules/devices.c2
-rw-r--r--modules/devices/usb.c115
-rw-r--r--pixmaps/camera-photo.pngbin0 -> 1331 bytes
-rw-r--r--pixmaps/camera-web.pngbin0 -> 1314 bytes
-rw-r--r--pixmaps/media-removable.pngbin0 -> 1104 bytes
8 files changed, 194 insertions, 7 deletions
diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c
index 62773e30..827a82c5 100644
--- a/hardinfo/usb_util.c
+++ b/hardinfo/usb_util.c
@@ -21,12 +21,35 @@
#include "hardinfo.h"
#include "usb_util.h"
+usbi *usbi_new() {
+ return g_new0(usbi, 1);
+}
+
+void usbi_free(usbi *s) {
+ if (s) {
+ g_free(s->if_class_str);
+ g_free(s->if_subclass_str);
+ g_free(s->if_protocol_str);
+ g_free(s);
+ }
+}
+
+void usbi_list_free(usbi *s) {
+ usbi *n;
+ while(s != NULL) {
+ n = s->next;
+ usbi_free(s);
+ s = n;
+ }
+}
+
usbd *usbd_new() {
return g_new0(usbd, 1);
}
void usbd_free(usbd *s) {
if (s) {
+ usbi_list_free(s->if_list);
g_free(s->vendor);
g_free(s->product);
g_free(s->usb_version);
@@ -63,6 +86,20 @@ static int usbd_list_append(usbd *l, usbd *n) {
return c;
}
+void usbd_append_interface(usbd *dev, usbi *new_if){
+ usbi *curr_if;
+ if (dev->if_list == NULL){
+ dev->if_list = new_if;
+ return;
+ }
+
+ curr_if = dev->if_list;
+ while(curr_if->next != NULL) {
+ curr_if = curr_if->next;
+ }
+ curr_if->next = new_if;
+}
+
int usbd_list_count(usbd *s) {
return usbd_list_append(s, NULL);
}
@@ -79,6 +116,7 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) {
gboolean spawned;
gchar *out, *err, *p, *l, *t, *next_nl;
gchar *lsusb_cmd = g_strdup_printf("lsusb -s %d:%d -v", bus, dev);
+ usbi *curr_if = NULL; // do not free
s->bus = bus;
s->dev = dev;
@@ -94,6 +132,8 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) {
while(next_nl = strchr(p, '\n')) {
strend(p, '\n');
g_strstrip(p);
+
+ // device info
if (l = lsusb_line_value(p, "idVendor")) {
s->vendor_id = strtol(l, NULL, 0);
if (t = strchr(l, ' '))
@@ -116,9 +156,34 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) {
s->dev_subclass = atoi(l);
if (t = strchr(l, ' '))
s->dev_subclass_str = g_strdup(t + 1);
+
+ // interface info
+ } else if (l = lsusb_line_value(p, "bInterfaceNumber")) {
+ curr_if = usbi_new();
+ curr_if->if_number = atoi(l);
+ usbd_append_interface(s, curr_if);
+ } else if (l = lsusb_line_value(p, "bInterfaceClass")) {
+ if (curr_if != NULL){
+ curr_if->if_class = atoi(l);
+ if (t = strchr(l, ' '))
+ curr_if->if_class_str = g_strdup(t + 1);
+ }
+ } else if (l = lsusb_line_value(p, "bInterfaceSubClass")) {
+ if (curr_if != NULL){
+ curr_if->if_subclass = atoi(l);
+ if (t = strchr(l, ' '))
+ curr_if->if_subclass_str = g_strdup(t + 1);
+ }
+ } else if (l = lsusb_line_value(p, "bInterfaceProtocol")) {
+ if (curr_if != NULL){
+ curr_if->if_protocol = atoi(l);
+ if (t = strchr(l, ' '))
+ curr_if->if_protocol_str = g_strdup(t + 1);
+ }
}
- /* TODO: speed_mbs
- * WISHLIST: interfaces, drivers */
+
+ /* TODO: speed_mbs, improve interfaces
+ * WISHLIST: drivers */
p = next_nl + 1;
}
g_free(out);
diff --git a/includes/devices.h b/includes/devices.h
index fe458c23..4cb0d122 100644
--- a/includes/devices.h
+++ b/includes/devices.h
@@ -86,6 +86,7 @@ extern gchar *sensors;
extern gchar *storage_icons;
extern gchar *storage_list;
extern gchar *usb_list;
+extern gchar *usb_icons;
extern GHashTable *memlabels;
extern GHashTable *_pci_devices;
extern GHashTable *sensor_compute;
diff --git a/includes/usb_util.h b/includes/usb_util.h
index e9130b99..5f7ba47c 100644
--- a/includes/usb_util.h
+++ b/includes/usb_util.h
@@ -39,10 +39,24 @@ typedef struct usbd {
int speed_mbs; /* TODO: */
gboolean user_scan; /* not scanned as root */
+ struct usbi *if_list;
struct usbd *next;
} usbd;
+/* another linked list */
+typedef struct usbi {
+ int if_number;
+ int if_class;
+ int if_subclass;
+ int if_protocol;
+ char *if_class_str;
+ char *if_subclass_str;
+ char *if_protocol_str;
+
+ struct usbi *next;
+} usbi;
+
usbd *usb_get_device_list();
int usbd_list_count(usbd *);
void usbd_list_free(usbd *);
diff --git a/modules/devices.c b/modules/devices.c
index d875aa93..fa474180 100644
--- a/modules/devices.c
+++ b/modules/devices.c
@@ -743,7 +743,7 @@ gchar *callback_usb()
return g_strdup_printf("%s"
"[$ShellParam$]\n"
"ViewType=1\n"
- "ReloadInterval=5000\n", usb_list);
+ "ReloadInterval=5000\n%s", usb_list, usb_icons);
}
diff --git a/modules/devices/usb.c b/modules/devices/usb.c
index fe6ce01d..bf1c1762 100644
--- a/modules/devices/usb.c
+++ b/modules/devices/usb.c
@@ -23,12 +23,87 @@
#include "usb_util.h"
gchar *usb_list = NULL;
+gchar *usb_icons = NULL;
#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)");
+#define IARR_END -2
+#define IARR_ANY -1
+
+static struct {
+ int class;
+ char *icon;
+} usb_class_icons[] = {
+ { 0x1, "audio"}, /* Audio */
+ { 0x2, "modem"}, /* Communications and CDC Control */
+ { 0x3, "inputdevices"}, /* HID (Human Interface Device) */
+ { 0x6, "camera-photo"}, /* Still Imaging */
+ { 0x7, "printer"}, /* Printer */
+ { 0x8, "media-removable"}, /* Mass storage */
+ { 0x9, "module"}, /* Hub */
+ { 0xe, "camera-web"}, /* Video */
+ {IARR_END, NULL}
+};
+
+static struct {
+ int class, subclass, protocol;
+ char *icon;
+} usb_type_icons[] = {
+ { 0x2, 0x6, IARR_ANY, "network-interface"}, /* Ethernet Networking Control Model */
+ { 0x3, 0x1, 0x1, "keyboard"}, /* Keyboard */
+ { 0x3, 0x1, 0x2, "mouse"}, /* Mouse */
+ {0xe0, 0x1, 0x1, "bluetooth"}, /* Bluetooth Programming Interface */
+ {IARR_END, IARR_END, IARR_END, NULL},
+};
+
+static const char* get_class_icon(int class){
+ int i = 0;
+ while (usb_class_icons[i].class != IARR_END) {
+ if (usb_class_icons[i].class == class) {
+ return usb_class_icons[i].icon;
+ }
+ i++;
+ }
+ return NULL;
+}
+
+static const char* get_usbif_icon(const usbi *usbif) {
+ int i = 0;
+ while (usb_type_icons[i].class != IARR_END) {
+ if (usb_type_icons[i].class == usbif->if_class && usb_type_icons[i].subclass == usbif->if_subclass &&
+ (usb_type_icons[i].protocol == IARR_ANY || usb_type_icons[i].protocol == usbif->if_protocol)) {
+
+ return usb_type_icons[i].icon;
+ }
+ i++;
+ }
+
+ return get_class_icon(usbif->if_class);
+}
+
+static const char* get_usbdev_icon(const usbd *u) {
+ const char * icon = NULL;
+ usbi *curr_if;
+
+ curr_if = u->if_list;
+ while (icon == NULL && curr_if != NULL){
+ icon = get_usbif_icon(curr_if);
+ curr_if = curr_if->next;
+ }
+
+ if (icon == NULL){
+ icon = get_class_icon(u->dev_class);
+ }
+
+ return icon;
+}
static void _usb_dev(const usbd *u) {
- gchar *name, *key, *v_str, *str;
+ gchar *name, *key, *v_str, *label, *str;
gchar *product, *vendor, *dev_class_str, *dev_subclass_str; /* don't free */
+ gchar *if_class_str, *if_subclass_str, *if_protocol_str; /* don't free */
+ gchar *interfaces = strdup("");
+ usbi *i;
+ const char* icon;
vendor = UNKIFNULL_AC(u->vendor);
product = UNKIFNULL_AC(u->product);
@@ -37,8 +112,11 @@ static void _usb_dev(const usbd *u) {
name = g_strdup_printf("%s %s", vendor, product);
key = g_strdup_printf("USB%03d:%03d:%03d", u->bus, u->dev, 0);
+ label = g_strdup_printf("%03d:%03d", u->bus, u->dev);
+ icon = get_usbdev_icon(u);
- usb_list = h_strdup_cprintf("$%s$%03d:%03d=%s\n", usb_list, key, u->bus, u->dev, name);
+ usb_list = h_strdup_cprintf("$%s$%s=%s\n", usb_list, key, label, name);
+ usb_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", usb_icons, key, label, icon ? icon: "usb");
const gchar *v_url = vendor_get_url(vendor);
const gchar *v_name = vendor_get_name(vendor);
@@ -48,6 +126,27 @@ static void _usb_dev(const usbd *u) {
v_str = g_strdup_printf("%s", vendor );
}
+ if (u->if_list != NULL) {
+ i = u->if_list;
+ while (i != NULL){
+ if_class_str = UNKIFNULL_AC(i->if_class_str);
+ if_subclass_str = UNKIFNULL_AC(i->if_subclass_str);
+ if_protocol_str = UNKIFNULL_AC(i->if_protocol_str);
+
+ interfaces = h_strdup_cprintf("[%s %d]\n"
+ /* Class */ "%s=[%d] %s\n"
+ /* Sub-class */ "%s=[%d] %s\n"
+ /* Protocol */ "%s=[%d] %s\n",
+ interfaces,
+ _("Interface"), i->if_number,
+ _("Class"), i->if_class, if_class_str,
+ _("Sub-class"), i->if_subclass, if_subclass_str,
+ _("Protocol"), i->if_protocol, if_protocol_str
+ );
+ i = i->next;
+ }
+ }
+
str = g_strdup_printf("[%s]\n"
/* Product */ "%s=[0x%04x] %s\n"
/* Manufacturer */ "%s=[0x%04x] %s\n"
@@ -58,7 +157,8 @@ static void _usb_dev(const usbd *u) {
/* Dev Version */ "%s=%s\n"
"[%s]\n"
/* Bus */ "%s=%03d\n"
- /* Device */ "%s=%03d\n",
+ /* Device */ "%s=%03d\n"
+ /* Interfaces */ "%s",
_("Device Information"),
_("Product"), u->product_id, product,
_("Vendor"), u->vendor_id, v_str,
@@ -69,7 +169,8 @@ static void _usb_dev(const usbd *u) {
_("Device Version"), u->device_version,
_("Connection"),
_("Bus"), u->bus,
- _("Device"), u->dev
+ _("Device"), u->dev,
+ interfaces
);
moreinfo_add_with_prefix("DEV", key, str); /* str now owned by morinfo */
@@ -77,6 +178,8 @@ static void _usb_dev(const usbd *u) {
g_free(v_str);
g_free(name);
g_free(key);
+ g_free(label);
+ g_free(interfaces);
}
void __scan_usb(void) {
@@ -89,6 +192,10 @@ void __scan_usb(void) {
moreinfo_del_with_prefix("DEV:USB");
g_free(usb_list);
}
+ if (usb_icons){
+ g_free(usb_icons);
+ usb_icons = NULL;
+ }
usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
if (c > 0) {
diff --git a/pixmaps/camera-photo.png b/pixmaps/camera-photo.png
new file mode 100644
index 00000000..e3b4e618
--- /dev/null
+++ b/pixmaps/camera-photo.png
Binary files differ
diff --git a/pixmaps/camera-web.png b/pixmaps/camera-web.png
new file mode 100644
index 00000000..5691c549
--- /dev/null
+++ b/pixmaps/camera-web.png
Binary files differ
diff --git a/pixmaps/media-removable.png b/pixmaps/media-removable.png
new file mode 100644
index 00000000..9e1a6636
--- /dev/null
+++ b/pixmaps/media-removable.png
Binary files differ