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

所以我的守护进程将坐在那里,听udev,等待连接/断开事件,以便它可以通知其他线程附加或停止从/ dev / input / eventX文件读取。

本质上,它正在聆听连接到本地系统(模拟HID键盘)的USB RFID扫描器。

现在我已经得到了/ dev / input / eventX读取代码 – 但是由于我对它进行了线程化,所以UDEV线程崩溃了。

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

您可以添加一个udev规则,该规则可以运行脚本来通知您的程序,也可以使用可预测的名称为设备提供符号链接。 快速搜索在本页面显示了如何创建规则。

那么代码崩溃是另一个完全的结果(vfprintf与fprintf) – 无论如何libdev从版本172有一个漂亮的小函数,当枚举设备它自动绑定搜索(枚举)单个父,并只返回这是小孩:

udev_enumerate_add_match_parent() 

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

 /sys/devices/pci000xyz/000.000.XYZ/usbX/XY 

而我只是在等待udev版本变得与Ubuntu的NATTY精简,因为那么我只是创建一个新的枚举,并把它交给我在前面的枚举中找到的udev_device,并得到所有的孩子; 包括我之后的子设备:

 /sys/devices/pci000xyz/000.000.XYZ/usbX/XY/XY:AB/input/inputX/eventY 

与此同时,我会按照建议做并建立一个符号链接 – 欢呼德米特里。

看看这个文件: /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; } 

这些事件在被插入时进行枚举。拔出USB设备之前和之后的ls /dev/input将显示不同的结果。