2011-10-07 148 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將顯示不同的結果。