[Linux] Finding the correct HID device path from /dev/input/by-id/xxx ?


  • BINNED

    Yay, I have "fun" hardware to play with again! So, basically, I have a barcode reader that's connected in the keyboard wedge mode (meaning, it reads a barcode and sends a series of keypresses). Trying to intercept this using any kind of reading /dev/input/by-id/... or /dev/input/eventXX... interfaces basically spouts gibberish. I have, however, found that just reading from /dev/hidraw/hidrawX works like a charm with a bit of bit fiddling. And all is good with the world.

    Other than... I hate the way I'm finding out the path to read from. The solution is written in .NET Core (for reasons other than just reading from the barcode reader). I cannot find a reliable way of reading symlinks in its APIs, so I'm basically doing this now:

    1. Loop through all entries in /dev/input/by-id and find the one containing the substring barcode (because, of course, USB ID is completely useless as it has no vendor ID and a nonsensical device ID, so I'm afraid of relying on that for the future... it will still bite me on the ass sooner or later if there's a different device, I'm sure, but for now this works)
    2. Run readlink on that file and capture its output (because there's apparently no way to read symlinks on Linux from the code itself, hell, even reading Windows junctions looks like a bit of a mess). This gives me something like ../event11
    3. Loop through entries in /sys/class/hidraw/
    4. Within that loop, loop through everything in /sys/class/hidraw/hidrawX/device/input because there might be multiple inputXX entries there (probably won't happen in practice but...)
    5. Somewhere within /sys/class/hidraw/hidrawX/device/input/inputXX there should be my eventXX, which means I should read from /dev/hidraw/hidrawX for my events.

    Yes, it's an unsightly mess, especially since I'm nesting loops instead of going recursive. I don't dare going recursive because /sys/class seems to be full of cyclical symlinks walking you in endless loops and I just don't want to deal.

    So, does anyone know if there's a better way of figuring out which hidraw interface to read? Reading something else in /proc or /sys? I'm trying to avoid having to wrap regular C libraries into this if I can, I don't want it to depend on that if at all possible.



  • @Onyx said in [Linux] Finding the correct HID device path from /dev/input/by-id/xxx ?:

    Run readlink on that file and capture its output (because there's apparently no way to read symlinks on Linux from the code itself

    Have you tried using Mono.Posix ? It has a Syscal.readlink(path) that pinvokes into libc for you. It might be easier than scraping text output from a child process.


  • BINNED

    @robo2 Hmm, sounds like a good plan, have to see if I can incorporate that into a .NET Core project tomorrow (I'm new to the whole ecosystem so I don't know jack about integrating stuff like that yet). Thanks for the tip!


Log in to reply