linux keyboard-events hid

linux - Necesidad de interceptar eventos del teclado HID(y luego bloquearlos)



keyboard-events (3)

Tengo un dispositivo USB RFID que se registra como un dispositivo HID (un teclado USB más o menos).

Estoy buscando una forma de capturar esta entrada y bloquearla / filtrarla antes de que llegue al controlador de eventos del teclado (y envía el código RFID de 10 dígitos a la consola).

Por supuesto, tendría que capturar exclusivamente solo este dispositivo y dejar la entrada del teclado real sola (o pasarla).

Mi idea inicial fue bloquear el dispositivo en UDEV (por lo que el módulo del kernel usbhid / event / kbd no se unió a él) y escribir mi propio controlador básico para este dispositivo, pero no sé por dónde empezar, o si Incluso trabajaré.

Lo que sería genial (y no estoy seguro de si se puede hacer tal cosa) es si escribo un módulo de filtro de eventos que pueda estar en línea con el controlador de eventos y capturar (luego filtrar) la entrada apropiada del Unidad RFID, pero deja pasar todo lo demás. Me imagino que un módulo de este tipo no requeriría mucho código y sería el más práctico.

¿Ayuda?

[EDITAR: debo agregar que Xorg NO está instalado - solo consola]

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

Más información:

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)


Así que preparé una aplicación de prueba de concepto de acuerdo con la publicación que encontré here

Hace exactamente lo que necesito, aunque de todos modos compartiría mi solución.

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


Puede usar EVIOCGRAB ioctl en un dispositivo de evento para capturarlo exclusivamente.


Ungrabbing requiere un parámetro de valor "falso", como se muestra a continuación:

result = ioctl(fevdev, EVIOCGRAB, 0);