문제

The code below works fine for only one input device. Unfortunately I need to capture about 12 different HID devices (RFID readers), so I would like to know if does anyone know how to adapt the code to work with 12 different inputs?

#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;
}
도움이 되었습니까?

해결책

Call open() for each device, and then use select() (or (e)poll()) to monitor all of the file descriptors together so you can detect which devices have data available to then be read() from at any given moment.

Update: For example:

struct event_device
{
    char *device;
    int fd;
};

int main(int argc, char* argv[])
{
    struct input_event ev[64];
    int numevents;
    int result = 0;
    int size = sizeof(struct input_event);
    int rd;
    char name[256];
    char* device[12];
    event_device evdevs[12], *evdev;
    int numevdevs = 0;
    fd_set fds;
    int maxfd;

    device[0] = "/dev/input/event3";
    device[1] = "/dev/input/event4";
    // and so on...

    for (int i = 0; i < 12; ++i) {
        evdev = &evdevs[numevdevs];

        evdev->device = device[i];
        evdev->fd = open(evdev->device, O_RDONLY);
        if (evdev->fd == -1) {
            printf("Failed to open event device: %s.\n", evdev->device);
            continue;
        }
        ++numevdevs;

        memset(name, 0, sizeof(name));
        result = ioctl(evdev->fd, EVIOCGNAME(sizeof(name)), name);
        printf ("Reading From : %s (%s)\n", evdev->device, name);

        printf("Getting exclusive access: ");
        result = ioctl(evdev->fd, EVIOCGRAB, 1);
        printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");
    }

    if (numevdevs == 0) {
        exit(1);
    }

    while (1)
    {
        FD_ZERO(&fds);
        maxfd = -1;

        for (int i = 0; i < numevdevs; ++i) {
            evdev = &evdevs[i];
            FD_SET(evdev->fd, &fds);
            if (maxfd < evdev->fd) maxfd = evdev->fd;
        }

        result = select(maxfd+1, &fds, NULL, NULL, NULL);
        if (result == -1) {
            break;        
        }

        for (int i = 0; i < numevdevs; ++i) {
            evdev = &evdevs[i];

            if (!FD_ISSET(evdev->fd, &fds)) {
                continue;
            }

            if ((rd = read(evdev->fd, ev, size * 64)) < size) {
                continue;
            }

            numevents = rd / size;
            for (int j = 0; j < numevents; ++j) {
                printf ("%s: Type[%d] Code[%d] Value[%d]\n", evdev->device, ev[j].type, ev[j].code, ev[j].value);
            }
        }
    }

    printf("Exiting.\n");

    for (int i = 0; i < numevdevs; ++i) {
        evdev = &evdevs[i];
        result = ioctl(evdev->fd, EVIOCGRAB, 0);
        close(evdev->);
    }

    return 0;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top