Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usb_util.c [v2] #178

Merged
merged 2 commits into from
Mar 12, 2018
Merged

usb_util.c [v2] #178

merged 2 commits into from
Mar 12, 2018

Conversation

bp0
Copy link
Collaborator

@bp0 bp0 commented Aug 19, 2017

A set of functions for getting information for a single USB device,
or a list of all devices.

The only implemented method is using lsusb, which is slow. A
method using sysfs would be much better. The existing sysfs and
procfs methods in devices/usb.c do not appear to work, so it would
have to be something new.

devices/usb.c modified to use usb_util, but all the old code is
still there.

Solves #162 for devices/usb.c
Before it was common for lsusb to leak the message below once for each device.
Couldn't open device, some information will be missing

Fixed a problem with #175.

@bp0
Copy link
Collaborator Author

bp0 commented Aug 21, 2017

Rebased.

Copy link
Owner

@lpereira lpereira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice that you're breaking out these things into separate files. However, there are some questions/comments that I'd like to see addressed first before merging this patch.

return usbd_list_append(s, NULL);
}

char *_lsusb_lv(char *line, const char *prefix) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal functions should always be marked as static. There's no need to prepend an underscore in their names. I'd prefer if their names were more descriptive as well: I have no idea what lv means here.

}

char *_lsusb_lv(char *line, const char *prefix) {
if ( g_str_has_prefix(line, prefix) ) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No spaces after or before parenthesis: if (g_str_has_prefix(...)) {.

int 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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we would benefit from a h_popen_printf() that worked pretty much like a printf() function. Maybe with fopencookie(), this could be used like popen():

    FILE *lsusb = h_popen_printf("lsusb -s %d:%d -v", bus, dev);
    char buffer[1024];

    if (!lsusb)
        return -errno;

    while (fgets(buffer, sizeof(buffer), lsusb)) {
         ...
    }

    h_popen_close(lsusb);

This would simplify a lot all these places where strchr() and strend() are used inside a loop: these could be moved to one of the cookie functions.

(No need to do this for this patch, just thinking out loud.)

}
g_free(out);
g_free(err);
return 1;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a function is returning only 1 or 0, it should return a boolean value instead.

__scan_usb_lsusb();
#define UNKIFNULL_AC(f) (f != NULL) ? f : _("(Unknown)");

void _usb_dev(const usbd *u) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

p = out;
while(next_nl = strchr(p, '\n')) {
strend(p, '\n');
if (ec = sscanf(p, "Bus %d Device %d: ID %x:%x", &bus, &dev, &vend, &prod) ) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this issue a warning? You're likely to need two parenthesis here. Or, better yet, just write in two lines:

ec = sscanf(...);
if (ec == 4) {
    ...
}

}

/* returns number of items after append */
int usbd_list_append(usbd *l, usbd *n) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use a GSList?

#include "usb_util.h"

usbd *usbd_new() {
usbd *s = malloc(sizeof(usbd));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use g_new0() instead. It already checks if the allocation fails and will most likely allocate memory from a pool that has been memset() to zero already (usually fresh from the kernel). Be sure to use g_free() for things allocated with g_new().

g_strstrip(p);
if (l = _lsusb_lv(p, "idVendor")) {
s->vendor_id = strtol(l, NULL, 0);
if (t = strchr(l, ' '))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will generate a warning. You need two parenthesis enclosing the expression here: if ((t = strchr(...)))

if (l = _lsusb_lv(p, "idVendor")) {
s->vendor_id = strtol(l, NULL, 0);
if (t = strchr(l, ' '))
s->vendor = strdup(t + 1);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use g_strdup(), it already NULL-checks the return value and aborts the program if allocation fails

A set of functions for getting information for a single USB device,
or a list of all devices.

The only implemented method is using `lsusb`, which is slow. A
method using sysfs would be much better. The existing sysfs and
procfs methods in devices/usb.c do not appear to work, so it would
have to be something new.

devices/usb.c modified to use usb_util, but all the old code is
still there.

Signed-off-by: Burt P <pburt0@gmail.com>
Signed-off-by: Burt P <pburt0@gmail.com>
Copy link
Owner

@lpereira lpereira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some nits, and this can be merged. :)

return c;
}

int usbd_list_count(usbd *s) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very surprising that a function to count the elements of a linked list actually modifies it. This should really be just a wrapper around GSList.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because usbd_list_append() appends an element and returns the length, usbd_list_count() can just call it without a new element and get the length. append is already stepping through the list, so I just re-used it.

#define __USB_UTIL_H__

/* this is a linked list */
typedef struct usbd {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For things that are global identifiers, it's better to have "namespaces", or at least longer names. Shorter names are useful for static functions or local symbols within functions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would something like usb_device_info be enough?

@mckaygerhard
Copy link
Contributor

hi now that some review was made .. this will be compatible with some older hardware? i mean this uses sysfs, what happened with those older systems that are kernel usage << 3.0.24 ? for some embebed linux

@bp0
Copy link
Collaborator Author

bp0 commented Nov 25, 2017

@mckaygerhard, this adds a new method, but falls back to the previously existing methods. If they ever worked, which I have not been able to confirm, then they should still work.

@lpereira lpereira merged commit 6f0a3e0 into lpereira:master Mar 12, 2018
@lpereira
Copy link
Owner

Merged, thanks!

@bp0 bp0 deleted the usb2 branch March 12, 2018 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants