2011-10-07 170 views
3

因此,我的守护程序将坐在那里监听udev,等待连接/断开连接事件,以便它可以通知其他线程连接或停止读取/ dev/input/eventX文件。(Linux)从PID连接的USB设备获取/ dev/input/eventX:VID

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

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

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

回答

2

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

+0

这正是我在相同情况下所做的 - 如果VID:PID正确,则创建符合链接事件设备的udevd规则。 – caf

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精简,因为那时我会j最后创建一个新的枚举,并将它交给我在之前的枚举中找到的udev_device,并获取它的所有子元素;包括孩子设备我后:

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

在平均时间,我会做的建议,并创建一个符号 - 欢呼声德米特里。

0

看本文件:

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; 
} 

从文件/proc/bus/input/devices

实施例线在插入USB设备之前和之后,这些事件将被枚举。ls /dev/input将显示不同的结果。