2014-03-05 3 views
2

아래 코드는 하나의 입력 장치에서만 올바르게 작동합니다. 불행히도 나는 약 12 ​​개의 다른 HID 장치 (RFID 판독기)를 잡아야하므로 12 개의 입력을 사용하여 코드를 적용하는 방법을 아는 사람이 있는지 알고 싶습니다. 이 장치는 다음 주어진 순간에서 read()가 될 수있는 데이터를 가지고있는 감지 할 수 있도록HID 키보드 이벤트 캡처

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

답변

2

각 장치에 대한 전화 open() 한 다음 select() (또는 (e)poll())이 함께 파일의 모든 설명을 모니터링하는 데 사용합니다. 예를 들면 :

업데이트

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; 
} 
+0

나는 그것을 시도하지만 돌아가신't 작업. 두 개 이상의 장치가 있어도 input_event는 하나 뿐인 것 같습니다. 어떤 장치가 그 정보를 보내는 이벤트 코드 (ev [1] .code)를 확인할 수있는 방법이 있습니까? –

+0

아쉽게도 각 장치를 모니터링하고 각 장치가 이벤트를 제공 할 때이를 감지해야합니다. 이벤트 자체는 이벤트를 보낸 장치를 식별하지 않습니다. 내 대답을 예제로 업데이트했습니다. –

+0

정말 고마워요! 그것은 내가 원했던대로 정말로 작동합니다! –