From 36f4722f05c8a2e089d42f41904b9d984f802182 Mon Sep 17 00:00:00 2001 From: Ondrej Čerman Date: Sun, 4 Aug 2019 20:04:12 +0200 Subject: usb: added usb.ids parsing --- hardinfo/usb_util.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'hardinfo') diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c index cc839b9a..e4b0b2fd 100644 --- a/hardinfo/usb_util.c +++ b/hardinfo/usb_util.c @@ -21,9 +21,12 @@ #include "hardinfo.h" #include "usb_util.h" +#include "util_ids.h" #define SYSFS_DIR_USB_DEVICES "/sys/bus/usb/devices" +gchar *usb_ids_file = NULL; + usbi *usbi_new() { return g_new0(usbi, 1); } @@ -254,6 +257,7 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) { static gboolean usb_get_interface_sysfs(int conf, int number, const char* devpath, usbi *intf){ gchar *ifpath, *drvpath, *tmp; + ids_query_result result = {}; ifpath = g_strdup_printf("%s:%d.%d", devpath, conf, number); if (!g_file_test(ifpath, G_FILE_TEST_EXISTS)){ @@ -279,17 +283,53 @@ static gboolean usb_get_interface_sysfs(int conf, int number, if (intf->if_label == NULL) intf->if_label = h_sysfs_read_string(ifpath, "interface"); + if (intf->if_class_str == NULL && intf->if_subclass_str == NULL + && intf->if_protocol_str == NULL) { + tmp = g_strdup_printf("C %02x/%02x/%02x", intf->if_class, + intf->if_subclass, intf->if_protocol); + scan_ids_file(usb_ids_file, tmp, &result, -1); + if (result.results[0]) + intf->if_class_str = g_strdup(result.results[0]); + if (result.results[1]) + intf->if_subclass_str = g_strdup(result.results[1]); + if (result.results[2]) + intf->if_protocol_str = g_strdup(result.results[2]); + g_free(tmp); + } + g_free(ifpath); return TRUE; } +void find_usb_ids_file() { + if (usb_ids_file) return; + char *file_search_order[] = { + g_build_filename(g_get_user_config_dir(), "hardinfo", "usb.ids", NULL), + g_build_filename(params.path_data, "usb.ids", NULL), + NULL + }; + int n; + for(n = 0; file_search_order[n]; n++) { + if (!access(file_search_order[n], R_OK)) + usb_ids_file = file_search_order[n]; + else + g_free(file_search_order[n]); + } +} + static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, usbd *s) { usbi *intf; gboolean ok; - int i, if_count = 0, conf = 0; + int i, if_count = 0, conf = 0, ver; + ids_query_result result = {}; + gchar *qpath; + if (sysfspath == NULL) return FALSE; + if (!usb_ids_file) + find_usb_ids_file(); + s->bus = bus; s->dev = dev; s->dev_class = h_sysfs_read_hex(sysfspath, "bDeviceClass"); @@ -300,8 +340,29 @@ static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, us s->max_curr_ma = h_sysfs_read_int(sysfspath, "bMaxPower"); s->dev_class = h_sysfs_read_hex(sysfspath, "bDeviceClass"); s->dev_subclass = h_sysfs_read_hex(sysfspath, "bDeviceSubClass"); + s->dev_protocol = h_sysfs_read_hex(sysfspath, "bDeviceProtocol"); s->speed_mbs = h_sysfs_read_int(sysfspath, "speed"); + if (s->product == NULL && s->vendor == NULL) { + qpath = g_strdup_printf("%04x/%04x", s->vendor_id, s->product_id); + scan_ids_file(usb_ids_file, qpath, &result, -1); + if (result.results[0]) + s->vendor = g_strdup(result.results[0]); + if (result.results[1]) + s->product = g_strdup(result.results[1]); + g_free(qpath); + } + + if (s->dev_class_str == NULL && s->dev_subclass_str == NULL) { + qpath = g_strdup_printf("C %02x/%02x", s->dev_class, s->dev_subclass); + scan_ids_file(usb_ids_file, qpath, &result, -1); + if (result.results[0]) + s->dev_class_str = g_strdup(result.results[0]); + if (result.results[1]) + s->dev_subclass_str = g_strdup(result.results[1]); + g_free(qpath); + } + conf = h_sysfs_read_hex(sysfspath, "bConfigurationValue"); if (s->usb_version == NULL) -- cgit v1.2.3 From 7efea8df3316180be625309d52ce34475d924071 Mon Sep 17 00:00:00 2001 From: Ondrej Čerman Date: Sun, 4 Aug 2019 21:11:26 +0200 Subject: usb: added more properties --- hardinfo/usb_util.c | 34 +++++++++++++++++++++++++++++++--- includes/usb_util.h | 3 +++ modules/devices/usb.c | 31 +++++++++++++------------------ 3 files changed, 47 insertions(+), 21 deletions(-) (limited to 'hardinfo') diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c index e4b0b2fd..792750a6 100644 --- a/hardinfo/usb_util.c +++ b/hardinfo/usb_util.c @@ -64,8 +64,10 @@ void usbd_free(usbd *s) { g_free(s->device); g_free(s->usb_version); g_free(s->device_version); + g_free(s->serial); g_free(s->dev_class_str); g_free(s->dev_subclass_str); + g_free(s->dev_protocol_str); g_free(s); } } @@ -206,6 +208,19 @@ 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); + } else if (l = lsusb_line_value(p, "bDeviceProtocol")) { + s->dev_protocol = atoi(l); + if (t = strchr(l, ' ')) + s->dev_protocol_str = g_strdup(t + 1); + } else if (l = lsusb_line_value(p, "iManufacturer")) { + if (t = strchr(l, ' ')) + s->manufacturer = g_strdup(t + 1); + } else if (l = lsusb_line_value(p, "iProduct")) { + if (t = strchr(l, ' ')) + s->device = g_strdup(t + 1); + } else if (l = lsusb_line_value(p, "iSerial")) { + if (t = strchr(l, ' ')) + s->serial = g_strdup(t + 1); // interface info } else if (l = lsusb_line_value(p, "bInterfaceNumber")) { @@ -353,13 +368,17 @@ static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, us g_free(qpath); } - if (s->dev_class_str == NULL && s->dev_subclass_str == NULL) { - qpath = g_strdup_printf("C %02x/%02x", s->dev_class, s->dev_subclass); + if (s->dev_class_str == NULL && s->dev_subclass_str == NULL + && s->dev_protocol_str == NULL) { + qpath = g_strdup_printf("C %02x/%02x/%02x", s->dev_class, + s->dev_subclass, s->dev_protocol); scan_ids_file(usb_ids_file, qpath, &result, -1); if (result.results[0]) s->dev_class_str = g_strdup(result.results[0]); if (result.results[1]) s->dev_subclass_str = g_strdup(result.results[1]); + if (result.results[2]) + s->dev_protocol_str = g_strdup(result.results[2]); g_free(qpath); } @@ -368,6 +387,16 @@ static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, us if (s->usb_version == NULL) s->usb_version = h_sysfs_read_string(sysfspath, "version"); + if (s->serial == NULL) + s->serial = h_sysfs_read_string(sysfspath, "serial"); + + if (s->device_version == NULL) { + ver = h_sysfs_read_int(sysfspath, "bcdDevice"); + if (ver > 0){ + s->device_version = g_strdup_printf("%d.%02d", ver/100, ver%100); + } + } + if (s->if_list == NULL){ // create interfaces list if_count = h_sysfs_read_int(sysfspath, "bNumInterfaces"); for (i = 0; i <= if_count; i++){ @@ -402,7 +431,6 @@ usbd *usb_get_device(int bus, int dev, const gchar* sysfspath) { ok = usb_get_device_lsusb(bus, dev, s); /* try sysfs */ ok |= usb_get_device_sysfs(bus, dev, sysfspath, s); - if (!ok) { usbd_free(s); s = NULL; diff --git a/includes/usb_util.h b/includes/usb_util.h index 1b92a34c..045f07e4 100644 --- a/includes/usb_util.h +++ b/includes/usb_util.h @@ -27,11 +27,14 @@ typedef struct usbd { char *product; char *manufacturer; char *device; + char *serial; int dev_class; int dev_subclass; + int dev_protocol; char *dev_class_str; char *dev_subclass_str; + char *dev_protocol_str; char *usb_version; char *device_version; /* bcdDevice */ diff --git a/modules/devices/usb.c b/modules/devices/usb.c index f01bee5a..d8909efc 100644 --- a/modules/devices/usb.c +++ b/modules/devices/usb.c @@ -25,7 +25,7 @@ gchar *usb_list = NULL; gchar *usb_icons = NULL; -#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)"); +#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)") #define IARR_END -2 #define IARR_ANY -1 @@ -99,9 +99,7 @@ static const char* get_usbdev_icon(const usbd *u) { static void _usb_dev(const usbd *u) { gchar *name, *key, *v_str, *label, *str, *speed; - gchar *product, *vendor, *dev_class_str, *dev_subclass_str; /* don't free */ - gchar *manufacturer, *device, *if_driver, *if_class_str; /* don't free */ - gchar *if_subclass_str, *if_protocol_str; /* don't free */ + gchar *product, *vendor, *manufacturer, *device; /* don't free */ gchar *interfaces = strdup(""); usbi *i; const char* icon; @@ -110,8 +108,6 @@ static void _usb_dev(const usbd *u) { product = UNKIFNULL_AC(u->product); manufacturer = UNKIFNULL_AC(u->manufacturer); device = UNKIFNULL_AC(u->device); - dev_class_str = UNKIFNULL_AC(u->dev_class_str); - dev_subclass_str = UNKIFNULL_AC(u->dev_subclass_str); name = g_strdup_printf("%s %s", u->vendor? vendor: manufacturer, u->product? product: device); key = g_strdup_printf("USB%03d:%03d:%03d", u->bus, u->dev, 0); @@ -126,11 +122,6 @@ static void _usb_dev(const usbd *u) { 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); - if_driver = UNKIFNULL_AC(i->driver); - interfaces = h_strdup_cprintf("[%s %d %s]\n" /* Class */ "%s=[%d] %s\n" /* Sub-class */ "%s=[%d] %s\n" @@ -138,10 +129,10 @@ static void _usb_dev(const usbd *u) { /* Driver */ "%s=%s\n", interfaces, _("Interface"), i->if_number, i->if_label? i->if_label: "", - _("Class"), i->if_class, if_class_str, - _("Sub-class"), i->if_subclass, if_subclass_str, - _("Protocol"), i->if_protocol, if_protocol_str, - _("Driver"), if_driver + _("Class"), i->if_class, UNKIFNULL_AC(i->if_class_str), + _("Sub-class"), i->if_subclass, UNKIFNULL_AC(i->if_subclass_str), + _("Protocol"), i->if_protocol, UNKIFNULL_AC(i->if_protocol_str), + _("Driver"), UNKIFNULL_AC(i->driver) ); i = i->next; } @@ -164,7 +155,9 @@ static void _usb_dev(const usbd *u) { /* Speed */ "%s=%s\n" /* Class */ "%s=[%d] %s\n" /* Sub-class */ "%s=[%d] %s\n" + /* Protocol */ "%s=[%d] %s\n" /* Dev Version */ "%s=%s\n" + /* Serial */ "%s=%s\n" "[%s]\n" /* Bus */ "%s=%03d\n" /* Device */ "%s=%03d\n" @@ -177,9 +170,11 @@ static void _usb_dev(const usbd *u) { _("Max Current"), u->max_curr_ma, _("mA"), _("USB Version"), u->usb_version, _("Speed"), speed, - _("Class"), u->dev_class, dev_class_str, - _("Sub-class"), u->dev_subclass, dev_subclass_str, - _("Device Version"), u->device_version, + _("Class"), u->dev_class, UNKIFNULL_AC(u->dev_class_str), + _("Sub-class"), u->dev_subclass, UNKIFNULL_AC(u->dev_subclass_str), + _("Protocol"), u->dev_protocol, UNKIFNULL_AC(u->dev_protocol_str), + _("Device Version"), UNKIFNULL_AC(u->device_version), + _("Serial Number"), UNKIFNULL_AC(u->serial), _("Connection"), _("Bus"), u->bus, _("Device"), u->dev, -- cgit v1.2.3 From 9592e1fcab84dd9b5ab3af6c2e2623269ba47ecf Mon Sep 17 00:00:00 2001 From: Ondrej Čerman Date: Sun, 4 Aug 2019 21:14:15 +0200 Subject: usb: use sysfs by default (that is usually faster than lsusb) --- hardinfo/usb_util.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'hardinfo') diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c index 792750a6..c908eec4 100644 --- a/hardinfo/usb_util.c +++ b/hardinfo/usb_util.c @@ -427,10 +427,12 @@ usbd *usb_get_device(int bus, int dev, const gchar* sysfspath) { usbd *s = usbd_new(); int ok = 0; if (s) { - /* try lsusb */ - ok = usb_get_device_lsusb(bus, dev, s); /* try sysfs */ - ok |= usb_get_device_sysfs(bus, dev, sysfspath, s); + ok = usb_get_device_sysfs(bus, dev, sysfspath, s); + if (!ok) { + /* try lsusb */ + ok = usb_get_device_lsusb(bus, dev, s); + } if (!ok) { usbd_free(s); s = NULL; -- cgit v1.2.3 From 7db082583f72598e2118553faf1ba3206d7c3ee7 Mon Sep 17 00:00:00 2001 From: Ondrej Čerman Date: Sat, 10 Aug 2019 09:30:17 +0200 Subject: usb: bug fix for usb.ids file search --- hardinfo/usb_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hardinfo') diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c index c908eec4..a758026f 100644 --- a/hardinfo/usb_util.c +++ b/hardinfo/usb_util.c @@ -325,7 +325,7 @@ void find_usb_ids_file() { }; int n; for(n = 0; file_search_order[n]; n++) { - if (!access(file_search_order[n], R_OK)) + if (!usb_ids_file && !access(file_search_order[n], R_OK)) usb_ids_file = file_search_order[n]; else g_free(file_search_order[n]); -- cgit v1.2.3