Obteniendo el tipo de dispositivo evdev

Obteniendo el tipo de dispositivo evdev

Desde el espacio de usuario de Linux, ¿cómo puedo obtener el tipo (es decir, mouse o teclado) de un dispositivo evdev/input_event?

Sé que puedo enumerarlos leyendo /proc/bus/input/handlerso enumerando, /sys/class/input/pero no está claro qué dispositivos son ratones o teclados.

Las líneas /proc/bus/input/handlerssimilares H: Handlers=sysrq kbd event3 ledsparecen sugerir que se trata de un teclado con la presencia de 'kbd', pero no puedo encontrar ninguna documentación real al respecto.

Respuesta1

El núcleo realmente no razona en términos de tipos de dispositivos, sino más bien en términos de los tipos de eventos que los dispositivos pueden producir (verla documentación de códigos de eventoen el núcleo).

Como resultado, se necesitan algunas heurísticas para identificar los tipos de dispositivos. Muchos dispositivos pueden producir eventos clave; Los teclados tienen la particularidad de producir tanto eventos de teclas ( EV_KEY) como eventos repetidos ( EV_REP). Creo que los ratones son los únicos dispositivos que producen eventos relativos ( EV_REL).

Los dispositivos exponen los tipos de eventos que pueden generar en el evarchivo de su capabilitiesdirectorio de clase. Cada tipo par tiene un desplazamiento de bits determinado, definido en /usr/include/linux/input-event-codes.h; EV_KEYes 1, EV_REP20, EV_REL2. Puede buscar esos bits en los valores dados por /sys/class/input/input*/capabilities/evpara encontrar los dispositivos que le interesan.

Respuesta2

Para encontrar detalles de cualquier dispositivo (yo uso event22), puedes ejecutar esto (en terminal/python/C++):

udevadm info -a -n /dev/input/event22

El resultado es una lista enorme de detalles, de los cuales sólo 2 son importantes: el producto y el proveedor:

ATTRS{idProduct}=="0100"
ATTRS{idVendor}=="04b4"

Cuando usas lsusb en una terminal, también ves estos números mágicos. Al eliminar/agregar, puede encontrar fácilmente los números de su dispositivo, por ejemplo, un mouse, un dispositivo Bluetooth o un lector de códigos de barras. Para mí obtuve el siguiente resultado:

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 8087:0a2b Intel Corp. 
Bus 001 Device 061: ID 04b4:0100 Cypress Semiconductor Corp. Cino FuzzyScan F760-B
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Cuando quito mi lector de código de barras y lo ejecuto nuevamente, el dispositivo Fuzzyscan desaparece. Entonces sé que mi lector de códigos de barras es 04b4:0100.

Ahora en la biblioteca Evdev también puedo encontrar estos números. Primero creo un programa para ejecutar udevadm info para todos y cada uno de los dispositivos. En algún momento encuentro un dispositivo con 04b4 y 0100. El nombre del dispositivo se puede usar para evdev. En C++ puedo ejecutar:

int fd = open("/dev/input/event22", O_RDONLY|O_NONBLOCK)
int rc = libevdev_new_from_fd(fd, &m_evDev);
int vendor = libevdev_get_id_vendor(m_evDev),
int productId = libevdev_get_id_product(m_evDev);
if (vendor == 0x4b4 && productId == 0x100)
    printf("Wooow, you find the barcode scanner!");

Observación: Tal vez este dispositivo no esté permitido para el usuario, entonces necesita agregar derechos de lectura/escritura como este:

sudo chmod a+=wr /dev/input/event22

Me doy cuenta de que no son muy detallados, no dudes en preguntar más.

información relacionada