1

I am searching for a way to dynamically find the system path for HID (USB) devices.

On my Ubuntu machine it's /dev/usb/hiddevX, but I suppose there are distros where hiddevices get mounted elsewhere.

To be more specific: I need this in a C program to open a HID device - this should work on every system, no matter where the devices are mounted.

Current function:

int openDevice(int vendorId, int productId) {

    char devicePath[24];
    unsigned int numIterations = 10, i, handle;

    for (i = 0; i < numIterations; i++) {

        sprintf(devicePath, "/dev/usb/hiddev%d", i);

        if((handle = open(devicePath, O_RDONLY)) >= 0) {

            if(isDesiredDevice(handle, vendorId, productId))
                break;

            close(handle);
        }
    }

    if (i >= numIterations) {
        ThrowException(Exception::TypeError(String::New("Could not find device")));
    }

    return handle;
}

It works well but I don't like the hardcoded /dev/usb/hiddev

Edit: It turned out that some other programmers use fallbacks to /dev/usb/hid/hiddevX and /dev/hiddevX, so I built in those fallbacks too.

Updated method:

/**
 * Returns the correct handle (file descriptor) on success
 *
 * @param int vendorId
 * @param int productId
 * @return int
 */
int IO::openDevice(int vendorId, int productId) {

    char devicePath[24];

    const char *devicePaths[] = {
        "/dev/usb/hiddev\%d",
        "/dev/usb/hid/hiddev\%d",
        "/dev/hiddev\%d",
        NULL
    };

    unsigned int numIterations = 15, i, j, handle;

    for (i = 0; devicePaths[i]; i++) {

        for (j = 0; j < numIterations; j++) {

            sprintf(devicePath, devicePaths[i], j);

            if((handle = open(devicePath, O_RDONLY)) >= 0) {

                if(isDesiredDevice(handle, vendorId, productId))
                    return handle;

                close(handle);
            }
        }
    };

    ThrowException(Exception::Error(String::New("Couldn't find device!")));
    return 0;
};
Alex
  • 12,205
  • 7
  • 42
  • 52
  • C or C++? Those are **different languages**. Please remove one of these tags. – ThiefMaster Dec 19 '12 at 19:33
  • Well, actually I'm using it in a C++ program right now but I previously had it in a C program. – Alex Dec 19 '12 at 19:36
  • Well, if this is always Linux, it's always `/dev/usb/hiddevX` so there's no point guessing. :) – netcoder Dec 19 '12 at 19:39
  • Really? Is this 100% certain? I almost cannot believe that :-) And yes it will always be on linux. – Alex Dec 19 '12 at 19:40
  • 1
    Well according to the [documentation of the 2.6 kernel](http://www.cs.fsu.edu/~baker/devices/lxr/http/source/source/2.6.11.8/linux/Documentation/usb/hiddev.txt?v=..), yes. However, I cannot find the docs about HID devices for the 3.x kernels. :( I know that they introduced a new `hidraw` driver that binds to `/dev/hidrawX`, but I don't know the specifics about communicating with that driver (and can't find the documentation for that one either). – netcoder Dec 20 '12 at 12:46
  • Hi netcoder, /dev/hidraw exists on my machine as well, that is nothing new that will come with the new kernel. Nevertheless, I have now built in a fallback to /dev/usb/hid/hiddevX and /dev/hiddevX in case /dev/usb/hiddevX does not exist. I found those 2 paths by googling and other developers used them as possible paths too. This will be safe enough hopefully. Thanks alot! – Alex Dec 20 '12 at 22:05

0 Answers0