2011-10-05 25 views
14

Tôi có thiết bị USB RFID đăng ký dưới dạng thiết bị HID (Bàn phím USB nhiều hơn hoặc ít hơn).Cần chặn các sự kiện của Bàn phím HID (và sau đó chặn chúng)

Tôi đang tìm cách nắm bắt đầu vào này và chặn/lọc trước khi nó chạm vào trình xử lý sự kiện bàn phím thông thường (và xuất mã RFID 10 chữ số vào bảng điều khiển).

Tôi dĩ nhiên sẽ phải chỉ chụp riêng thiết bị này và chỉ để riêng một đầu vào bàn phím thực (hoặc vượt qua nó). Ý tưởng ban đầu của tôi là chặn thiết bị trong UDEV (Vì vậy, mô-đun hạt nhân usbhid/event/kbd không liên kết với nó) và viết trình điều khiển cơ bản của riêng tôi cho thiết bị này - nhưng tôi không biết bắt đầu từ đâu , hoặc nếu điều đó thậm chí sẽ hoạt động.

Điều gì sẽ tuyệt vời (và tôi không chắc chắn nếu điều đó có thể được thực hiện) - là nếu tôi viết mô-đun bộ lọc sự kiện có thể ngồi phù hợp với trình điều khiển sự kiện và chụp (sau đó lọc) đầu vào thích hợp từ thiết bị RFID, nhưng để mọi thứ khác đi qua. Tôi tưởng tượng một mô-đun như vậy sẽ không đòi hỏi nhiều mã, và sẽ là thực tế nhất.

Trợ giúp?

[EDIT: Tôi nên thêm rằng Xorg không được cài đặt - giao diện điều khiển duy nhất]

cat /proc/bus/input: 
    I: Bus=0003 Vendor=0419 Product=0912 Version=0100 
    N: Name="NewRoad Sem. NewRoad System PS2 Interface" 
    P: Phys=usb-0000:00:1d.3-2/input0 
    S: Sysfs=/devices/pci0000:00/0000:00:1d.3/usb5/5-2/5-2:1.0/input/input20 
    U: Uniq= 
    H: Handlers=sysrq kbd mouse0 event3 
    B: PROP=0 
    B: EV=120017 
    B: KEY=70000 0 0 e080ffdf01cfffff fffffffffffffffe 
    B: REL=103 
    B: MSC=10 
    B: LED=1f 

Thông tin thêm:

lsusb -d 0419:0912 -v 
Bus 005 Device 019: ID 0419:0912 Samsung Info. Systems America, Inc. 
Device Descriptor: 
    bLength    18 
    bDescriptorType   1 
    bcdUSB    1.00 
    bDeviceClass   0 (Defined at Interface level) 
    bDeviceSubClass   0 
    bDeviceProtocol   0 
    bMaxPacketSize0   8 
    idVendor   0x0419 Samsung Info. Systems America, Inc. 
    idProduct   0x0912 
    bcdDevice   0.01 
    iManufacturer   1 NewRoad Sem. 
    iProduct    2 NewRoad System PS2 Interface 
    iSerial     0 
    bNumConfigurations  1 
    Configuration Descriptor: 
    bLength     9 
    bDescriptorType   2 
    wTotalLength   34 
    bNumInterfaces   1 
    bConfigurationValue  1 
    iConfiguration   4 
    bmAttributes   0xa0 
     (Bus Powered) 
     Remote Wakeup 
    MaxPower    100mA 
    Interface Descriptor: 
     bLength     9 
     bDescriptorType   4 
     bInterfaceNumber  0 
     bAlternateSetting  0 
     bNumEndpoints   1 
     bInterfaceClass   3 Human Interface Device 
     bInterfaceSubClass  1 Boot Interface Subclass 
     bInterfaceProtocol  1 Keyboard 
     iInterface    5 
     HID Device Descriptor: 
      bLength     9 
      bDescriptorType  33 
      bcdHID    1.00 
      bCountryCode   0 Not supported 
      bNumDescriptors   1 
      bDescriptorType  34 Report 
      wDescriptorLength  119 
     Report Descriptors: 
      ** UNAVAILABLE ** 
     Endpoint Descriptor: 
     bLength     7 
     bDescriptorType   5 
     bEndpointAddress  0x81 EP 1 IN 
     bmAttributes   3 
      Transfer Type   Interrupt 
      Synch Type    None 
      Usage Type    Data 
     wMaxPacketSize  0x0008 1x 8 bytes 
     bInterval    10 
Device Status:  0x0000 
    (Bus Powered) 
+0

Tôi nghĩ [này SO bài] (http://stackoverflow.com/questions/1698423/how-can-you -take-ownership-of-a-hid-thiết bị) có thể có câu trả lời tôi đang theo sau ... – Litch

Trả lời

6

Bạn có thể sử dụng EVIOCGRAB ioctl trên một thiết bị sự kiện để nắm bắt nó độc quyền.

16

Vì vậy, tôi whipped lên một ứng dụng proof-of-concept theo bài mà tôi tìm thấy here

Nó thực hiện chính xác những gì tôi yêu cầu - chỉ cần mặc dù tôi muốn chia sẻ giải pháp của tôi anyway.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <dirent.h> 
#include <linux/input.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/select.h> 
#include <sys/time.h> 
#include <termios.h> 
#include <signal.h> 

int main(int argc, char* argv[]) 
{ 
    struct input_event ev[64]; 
    int fevdev = -1; 
    int result = 0; 
    int size = sizeof(struct input_event); 
    int rd; 
    int value; 
    char name[256] = "Unknown"; 
    char *device = "/dev/input/event3"; 


    fevdev = open(device, O_RDONLY); 
    if (fevdev == -1) { 
     printf("Failed to open event device.\n"); 
     exit(1); 
    } 

    result = ioctl(fevdev, EVIOCGNAME(sizeof(name)), name); 
    printf ("Reading From : %s (%s)\n", device, name); 

    printf("Getting exclusive access: "); 
    result = ioctl(fevdev, EVIOCGRAB, 1); 
    printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE"); 

    while (1) 
    { 
     if ((rd = read(fevdev, ev, size * 64)) < size) { 
      break; 
     } 

     value = ev[0].value; 

     if (value != ' ' && ev[1].value == 1 && ev[1].type == 1) { 
      printf ("Code[%d]\n", (ev[1].code)); 
     } 
    } 

    printf("Exiting.\n"); 
    result = ioctl(fevdev, EVIOCGRAB, 1); 
    close(fevdev); 
    return 0; 
} 
+0

nên gọi sleep() trước khi lấy đầu vào, nếu không nó có thể chặn bản phát hành ENTER khi thực thi nhị phân đã biên dịch. – olivervbk

+0

@ Tôi không hiểu cách bạn lọc sự kiện. Bạn vừa chặn chúng, nhưng làm thế nào bạn sẽ tuyên truyền các sự kiện? – WscriChy

+0

@WscriChy Tôi không nghĩ rằng Litch đang cố gắng truyền bá các sự kiện. Codebase của ông là người tiêu dùng để bắt đầu. Tôi đang tìm một giải pháp tương tự. Tuy nhiên, trường hợp của tôi, tôi cần phải ngăn chặn một phần của các sự kiện sắp tắt của nguồn cấp dữ liệu đầu vào, nhưng tuyên truyền những người khác ... vì vậy nhiệm vụ của tôi giống như nhiệm vụ bạn đang suy nghĩ. – Svartalf

0

Ungrabbing đòi hỏi một tham số "false" giá trị, như sau:

result = ioctl(fevdev, EVIOCGRAB, 0); 
Các vấn đề liên quan