C (Linux)使用PID:VID从连接的USB设备获取/dev/input/eventX

C (Linux)使用PID:VID从连接的USB设备获取/dev/input/eventX,c,linux,events,input,libusb,C,Linux,Events,Input,Libusb,因此,我的守护进程将坐在那里监听udev,等待connect/disconnect事件,以便通知另一个线程连接或停止读取/dev/input/eventX文件 本质上,它是在监听连接到本地系统(模拟HID键盘)的USB RFID扫描仪 现在我已经开始读取/dev/input/eventX代码了,但是由于我对它进行了线程化,UDEV线程崩溃了 从已知的USB设备(如VID:PID)获取正确的/dev/input/eventX设备的最佳方法是什么?您可以添加一个udev规则,该规则可以运行脚本通知您

因此,我的守护进程将坐在那里监听udev,等待connect/disconnect事件,以便通知另一个线程连接或停止读取/dev/input/eventX文件

本质上,它是在监听连接到本地系统(模拟HID键盘)的USB RFID扫描仪

现在我已经开始读取/dev/input/eventX代码了,但是由于我对它进行了线程化,UDEV线程崩溃了


从已知的USB设备(如VID:PID)获取正确的/dev/input/eventX设备的最佳方法是什么?

您可以添加一个udev规则,该规则可以运行脚本通知您的程序,或者为您提供指向具有可预测名称的设备的符号链接。出现了一个快速搜索,解释了如何创建规则。

代码崩溃完全是由于其他原因造成的(vfprintf vs.fprintf)-无论如何,从172版开始的libudev有一个很好的小功能,在枚举设备时,它会自动将搜索(枚举)绑定到一个父级,并只返回它的子级:

udev_enumerate_add_match_parent()
我已经编写了通过VID/PID查找hidraw设备的代码:

/sys/devices/pci000xyz/000.000.XYZ/usbX/X-Y
我只是在等待UbuntuNatty精简udev版本,因为接下来我将创建一个新的枚举,并将我在上一个枚举中找到的udev_设备交给它,然后获取它的所有子项;包括我正在寻找的子设备:

/sys/devices/pci000xyz/000.000.XYZ/usbX/X-Y/X-Y:A.B/input/inputX/eventY

同时,我将按照建议创建一个符号链接-cheers Dmitri。

查看此文件:
/proc/bus/input/devices

文件中的示例行:

I: Bus=0003 Vendor=1a2c Product=0c23 Version=0110
N: Name="USB USB Keyboard"
P: Phys=usb-0000:00:14.0-3/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/0003:1A2C:0C23.0015/input/input30
U: Uniq=
H: Handlers=sysrq kbd event10 
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff800000000007ff febeffdff3cfffff fffffffffffffffe
B: MSC=10
B: LED=7 
此函数用于从具有匹配VID:PID:

#include <string>
#include <iostream>
#include <fstream>

void open_device (std::string device_vid, std::string device_pid)
{       
    try
    {
        std::ifstream file_input;
        std::size_t pos;
        std::string device_path, current_line, search_str, event_str;
        std::string device_list_file = "/proc/bus/input/devices";
        bool vid_pid_found = false;
        int fd = 0;
        bool debug = true;

        // 1. open device list file
        file_input.open(device_list_file.c_str());
        if (!file_input.is_open())
        {
            std::cerr << "file_input.open >> " << std::strerror(errno) << std::endl;
            throw -2;
        }

        // 2. search for first VID:PID and get event number
        search_str = "Vendor=" + device_vid + " Product=" + device_pid;
        while (getline(file_input, current_line))
        {
            if (!vid_pid_found)
            {
                pos = current_line.find(search_str, 0);
                if (pos != std::string::npos)
                {
                    vid_pid_found = true;
                    search_str = "event";
                }               
            }
            else
            {
                pos = current_line.find(search_str, 0);
                if (pos != std::string::npos)
                {
                    event_str = current_line.substr(pos);
                    // remove spaces from string
                    event_str.erase(std::remove(event_str.begin(), event_str.end(), ' '), event_str.end());
                    break;
                }
            }
        }

        // 3.  build device path
        device_path = "/dev/input/" + event_str;
        if (debug) std::cout << "device_path = " << device_path << std::endl;   
        // 4.  connect to device
        fd = open (device_path.c_str(), O_RDONLY);
        if (fd < 0)
        {
            std::cerr << "open >> errno = " << std::strerror(errno) << std::endl;       
            throw -3;
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "e.what() = " << e.what() << std::endl;
        throw -1;
    }

    return;
}
#包括
#包括
#包括
无效打开设备(标准::字符串设备\u视频,标准::字符串设备\u pid)
{       
尝试
{
std::ifstream文件\u输入;
标准:尺寸和位置;
字符串设备路径、当前行、搜索字符串、事件字符串;
std::string device_list_file=“/proc/bus/input/devices”;
bool vid_pid_found=false;
int-fd=0;
bool debug=true;
//1.打开设备列表文件
打开(设备列表文件.c_str());
如果(!file_input.is_open())
{

这正是我在相同情况下所做的——一个udevd规则,如果VID:PID是正确的,则创建到事件设备的符号链接。