所以我的守护进程会坐在那里听udev,等待连接/断开事件,这样它就可以通知另一个线程附加或停止从/ dev / input / eventX文件中读取。
基本上,它正在侦听连接到本地系统的USB RFID扫描仪(模拟HID键盘)。
现在我已经有了/ dev / input / eventX读取代码了 - 但是因为我将其线程化,UDEV线程崩溃了。
从已知的USB设备(如VID:PID)获取正确的/ dev / input / eventX设备的最佳方法是什么?
答案 0 :(得分:2)
您可以添加一个udev规则,该规则运行脚本以通知您的程序,或者为您提供具有可预测名称的设备的符号链接。出现了一个快速搜索this page,解释了如何创建规则。
答案 1 :(得分:1)
代码崩溃完全是其他东西的结果(vfprintf与fprintf) - 无论如何,libudev从版本172开始都有一个非常小的功能,当枚举设备时它会自动将搜索(枚举)绑定到单个父代并只返回它的孩子:
udev_enumerate_add_match_parent()
我已经编写了通过VID / PID找到hidraw设备的代码:
/sys/devices/pci000xyz/000.000.XYZ/usbX/X-Y
而我只是在等待udev版本与Ubuntu Natty一起精简,因为那样我只需要创建一个新的枚举,并将它在我之前的枚举中找到的udev_device并获得所有它的孩子;包括我之后的儿童装置:
/sys/devices/pci000xyz/000.000.XYZ/usbX/X-Y/X-Y:A.B/input/inputX/eventY
与此同时,我会按照建议做并创建一个符号链接 - 为Dmitri欢呼。
答案 2 :(得分:0)
查看此文件:/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;
}
事件在插入时被枚举。ls /dev/input
在拔出USB设备之前和之后将显示不同的结果。