1
votes

I'm writing a program that check every /dev/input/eventX and using ioctl I can get it capabilities and check what it is (mouse, keyboard, touch screen).

Now I need to check certain USB out(port) if device connected on it, I open it and do the same what I do with /dev/input/eventX. I find some symlink in /sys/bus/usb/devices/ its seems like here is store info about USB ports, but I'm not sure. I try open it with libudev but it looking for all files in subsystem "USB" but I need for example only /sys/bus/usb/devices/3-2/

What I need:

  1. Check certain USB port (only that which I hardcoded somewhere in define, or pass through command line)
  2. If device connected on it, open fd of dev and get info with ioctl
  3. if it (mouse for example) program start working else it says that device not found...

It would be enough description how to do it I don't need complete code.

Need only plain C can use some lib like libudev

1
Consider listening for the connection event on D-Bus.Ignacio Vazquez-Abrams
Have you tried listening for inotify vents on /dev/input directory?myaut
Thanks for advice I try that out... ionify means listen for all event but I need only certain USB , maybe am wrong and need to read manNick S

1 Answers

3
votes

I Find a solution that suits to my tasks, may be its help someone too so i leave this example here. I use libudev library

I find some example and change it a little:

1) create enumerate and add your subsystem:

enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "input");

You can look for subsystem in ls /sys/class in that folder i didn't see input but just try it to add an its work.

2) Get list entry and list through each using foreach:

list = udev_enumerate_get_list_entry(enumerate);

    udev_list_entry_foreach(node, list) 
    {
        char *str = NULL;
        path = udev_list_entry_get_name(node);
        dev = udev_device_new_from_syspath(udev, path);
        if  (str = strstr(path, REQUESTED_USB_PORT))
        {
             if (str = strstr(str, "event"))
             {
                  dev_path = strdup(udev_device_get_devnode(dev));
                  udev_device_unref(dev);
                  break;
             }
        }
        udev_device_unref(dev);
    }

So here we receive path something like this:

/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9
/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9/event6

Why I show you two path? because as you can see it return string looks like the same, but we need only one, where is eventX is shown.
REQUESTED_USB_PORT its a define with port you need to check in my case "1-1.6:1.0"

It a lot of way to find port what you need I stop on that cat /proc/bus/input/devices

It show output for every device:

I: Bus=0003 Vendor=046d Product=c31c Version=0110
N: Name="Logitech USB Keyboard"
P: Phys=usb-0000:00:1a.0-1.6/input0
S: Sysfs=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9
U: Uniq=
H: Handlers=sysrq kbd event6 leds 
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff9f207ac14057ff febeffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=1f

Another step is to get /dev/input/eventX you can get it using udev_device_get_devnode() function which return string with path.

So i write my get_devinfo_fromusb() with code i post above which return string with /dev/input/eventX or NULL if it not NULL i do something like this:

call another function and pass device_path as arguments

int get_dev_type(char *dev_event_path)
{
    int dev_fd;
    unsigned long eventBits = 0;

    if ((dev_fd = open(dev_event_path, O_RDONLY)) < 0)
    {
        puts("Dont have access to open file {%s}");
        puts("Run as root");
        exit(1);
    }
    ioctl(dev_fd, EVIOCGBIT(0, EV_MAX), &eventBits);

    if (((eventBits >> EV_KEY) & 1) &&
        ((eventBits >> EV_SYN) & 1) &&
        ((eventBits >> EV_REL) & 1) &&
        ((eventBits >> EV_MSC) & 1)) {
        puts("look like mouse");
        close(dev_fd);
        return (MOUSE_TYPE);
    }

    if (((eventBits >> EV_KEY) & 1) &&
        ((eventBits >> EV_LED) & 1) &&
        ((eventBits >> EV_REP) & 1)) {
        puts("looks like kbd");
        close(dev_fd);
        return (KBD_TYPE);
}

}

I think this little examples would be enough to figure out what's is going on. So with this you can check certain usb port and get info about that device (mouse or keyboard) you can also check for headphone touchscreen and so on.