diff options
| author | Ondrej Čerman <10187350+ocerman@users.noreply.github.com> | 2018-11-30 13:59:34 +0100 | 
|---|---|---|
| committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2018-11-30 04:59:34 -0800 | 
| commit | 5c32c60b3b4bb92fbfd5dd8c465c1f38f063660a (patch) | |
| tree | a72d011c49b090d0f489231f4105d0d3cd904661 | |
| parent | b52f767d80719185a62d959be46ba15fdb8f8f85 (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.c | 69 | ||||
| -rw-r--r-- | includes/devices.h | 1 | ||||
| -rw-r--r-- | includes/usb_util.h | 14 | ||||
| -rw-r--r-- | modules/devices.c | 2 | ||||
| -rw-r--r-- | modules/devices/usb.c | 115 | ||||
| -rw-r--r-- | pixmaps/camera-photo.png | bin | 0 -> 1331 bytes | |||
| -rw-r--r-- | pixmaps/camera-web.png | bin | 0 -> 1314 bytes | |||
| -rw-r--r-- | pixmaps/media-removable.png | bin | 0 -> 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 Binary files differnew file mode 100644 index 00000000..e3b4e618 --- /dev/null +++ b/pixmaps/camera-photo.png diff --git a/pixmaps/camera-web.png b/pixmaps/camera-web.png Binary files differnew file mode 100644 index 00000000..5691c549 --- /dev/null +++ b/pixmaps/camera-web.png diff --git a/pixmaps/media-removable.png b/pixmaps/media-removable.png Binary files differnew file mode 100644 index 00000000..9e1a6636 --- /dev/null +++ b/pixmaps/media-removable.png  | 
