2016-10-25 1 views
0

바코드 스캐너에서 ASCII 형식으로 바코드 데이터를 받았습니다. Linux에서 바코드 스캐너를 통해 컴퓨터에 수신 된 데이터를 사용하여 키보드를 에뮬레이션하는 프로그램을 작성해야합니다. 나는 리눅스 용 USB-HIDKB 드라이버 (http://lxr.free-electrons.com/source/drivers/hid/usbhid/usbkbd.c)에 대한 소스 코드를 읽었지만, 나는 그것을 역으로해야한다고 생각한다. 정확하게하고 싶은 것은 데이터가 ASCII 형식의 데이터 스트림으로 스캐너에서 수신되고 스캔 된 데이터를 사용하여 키 스트로크를 생성해야한다는 것입니다. 데이터 읽기 부분이 거의 끝났으며 ASCII 데이터를 키 스트로크로 변환하는 방법을 찾아야합니다.Linux에서 C++을 사용하여 원시 ASCII 값을 사용하여 키 스트로크를 생성 할 수 있습니까?

예를 들어 작업 : ctr + z (undo 작업에 대한 단축키)를위한 바코드가있다

, 한 번 바코드 데이터를 받게됩니다 스캔은 08 10 03 00 1a 00 18 0b는 데이터 1a 00 18 0b는 HEX의 데이터로 수신됩니다. 여기서 첫 번째 4 바이트는 헤더이고 나머지는 데이터 부분입니다. 이제 데이터를 인쇄하는 대신 실행 취소 작업을 실행하면됩니다.

모든 코드 예제 나 제안 사항은 코딩을 시작할 준비가되어 있습니다. 감사.

+0

ASCII 문자열 "08 10 03 03 00 1a 00 18 0b"즉, 14 자리, 2 자리 및 7 자리를 포함하여 23 개의 ASCII 문자가 수신된다는 것을 의미합니까? 왜냐하면 8 바이트 스트림 '08 10 03 03 00 1a 00 18 0b'은 ASCII가 아니기 때문입니다. – MSalters

+0

아니요, ASCII 스트림을 HEX 형식으로 변환 한 후 게시물의 데이터가 생성됩니다. 출력 스트림에 인쇄하기 전에 위의 데이터 스트림에 대한 키 스트로크를 생성해야합니다. –

+0

글쎄, ASCII는 "컨트롤 키"또는 Ctrl-Z가 없거나 실행 취소 할 수 없습니다. ASCII는 한 글자 당 1 바이트이고 '1a 00 18 0b'의 4 바이트는'SUB NUL CAN VT' (대체, 널, 취소, 수직 탭)입니다. – MSalters

답변

0

유용 한 코드 조각은 이미 처리 된 데이터를 사용하여 키 스트로크를 에뮬레이트하기 시작하는 데 도움이되었습니다. 유용한 코드 조각은 [1]: http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html 입니다.

그러나 이것은 xwindowing 시스템이있는 시스템에서만 작동합니다. 터미널에서만 사용하는 시스템에서는 작동하지 않습니다. 이 경우 우리는 소프트웨어 키를 생성하기 위해 uinput 서브 시스템을 사용해야합니다. 리눅스에서 uinput 사용하는 방법에 대한

샘플 프로그램은

http://thiemonge.org/getting-started-with-uinput 내가 uinput 사용하여 간단한 프로그램을 작성 여기에서 찾을 수 있습니다. 이것은 작동 중입니다.

예제 코드 :

#include <cstdlib> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <linux/input.h> 
#include <linux/uinput.h> 
#include <iostream> 

#include <time.h> 
#include <string> 

using namespace std; 

int SetupUinputDevice() 
{ 
    // file descriptor for input subsystem device 
    int fd_uinput_device; 
    // read only, non-blocking, no delay file descriptor 
    fd_uinput_device = open("/dev/uinput", O_WRONLY | O_NONBLOCK | O_NDELAY); 
    if(fd_uinput_device < 0) 
    { 
     std::cout << "Error : open file descriptor /dev/uinput : " << strerror(errno) << std::endl; 
     return -1; 
    } 

    // create and initiate uinput_user_dev struct for KeyboardEmulator device 
    struct uinput_user_dev dev_key_board_emulator; 
    memset(&dev_key_board_emulator, 0, sizeof(uinput_user_dev)); 
    snprintf(dev_key_board_emulator.name, UINPUT_MAX_NAME_SIZE, "zebra-scanner-hidkb-emulator"); 
    dev_key_board_emulator.id.bustype = BUS_USB; 
    dev_key_board_emulator.id.vendor = 0x01; 
    dev_key_board_emulator.id.product = 0x02; 
    dev_key_board_emulator.id.version = 1; 

    /** configure the uinput device to key board events, these will inform to 
    * subsystem via ioctl calls which type of events will be handled by 
    * the device 
    */ 
    // configure/set key press and release events 
    if(ioctl(fd_uinput_device, UI_SET_EVBIT, EV_KEY) < 0) 
    { 
     std::cout << "Error : ioctl : UI_SET_EVBIT for EV_KEY " << strerror(errno) << std::endl; 
     return -1; 
    } 

    // enable set of key board events 
    for(int iEvent=0; iEvent < 254; iEvent++) 
    { 
     if(ioctl(fd_uinput_device, UI_SET_KEYBIT, iEvent) < 0) 
     { 
      std::cout << "Error : ioctl : UI_SET_KEYBIT for event ID: " << iEvent << " : " << strerror(errno) << std::endl; 
     } 
    } 

    // enable synchronization events 
    if(ioctl(fd_uinput_device, UI_SET_EVBIT, EV_SYN) < 0) 
    { 
     std::cout << "Error : ioctl : UI_SET_EVBIT for EV_SYN: " << strerror(errno) << std::endl; 
     return -1; 
    } 

    // write the uinput_user_dev structure into the device file descriptor 
    if(write(fd_uinput_device, &dev_key_board_emulator, sizeof(uinput_user_dev)) < 0) 
    { 
     std::cout << "Error : failed to write uinput_user_dev structure into the device file descriptor: " << strerror(errno) << std::endl; 
     return -1; 
    } 

    // Create the end point file descriptor for user input device descriptor. 
    if(ioctl(fd_uinput_device, UI_DEV_CREATE) < 0) 
    { 
     std::cout << "Error : failed to create end point for user input device: " << strerror(errno) << std::endl; 
     return -1; 
    } 

    return fd_uinput_device; 
} 

int CloseUinputDevice(int fd_dev) 
{ 
    if(ioctl(fd_dev, UI_DEV_DESTROY) < 0) 
    { 
     std::cout << "Error : ioctl failed: UI_DEV_DESTROY : " << strerror(errno) << std::endl; 
     return -1; 
    } 

    if(close(fd_dev) < 0) 
    { 
     std::cout << "Error : close device file descriptor : " << strerror(errno) << std::endl; 
     return -1; 
    } 
} 

int SendKeyboardEvents(int fd_dev, int event_type, int key_code, int value) 
{ 
    // input_event struct member for input events 
    struct input_event key_input_event; 
    memset(&key_input_event, 0, sizeof(input_event)); 

    // set event values 
    key_input_event.type = event_type; 
    key_input_event.code = key_code; 
    key_input_event.value = value; 

    if(write(fd_dev, &key_input_event, sizeof(input_event)) < 0) 
    { 
     std::cout << "Error writing input events to the device descriptor: " << strerror(errno) << std::endl; 
     return -1; 
    } 
    return 0; 
} 

int main(int argc, char** argv) { 

    std::cout << "------------key - emulator------------" << std::endl; 
    int fd_keyEmulator = SetupUinputDevice(); 
    sleep(3); 
    if(fd_keyEmulator < 0) 
    { 
     std::cout << "Error in setup file descriptor for uinput device..." << std::endl; 
     return 0; 
    } 

    // start to send events 
    int returnValue; 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_A, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_A, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_B, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_B, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_C, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_C, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_D, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_D, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_E, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_E, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_F, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_F, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_G, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_G, 0); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_H, 1); 
    returnValue = SendKeyboardEvents(fd_keyEmulator, EV_KEY, KEY_H, 0); 

    CloseUinputDevice(fd_keyEmulator); 

    std::cout << "------------end of program------------" << std::endl; 

    return 0; 
} 

프로그램을 실행하고 텍스트 편집기로 전환합니다. 거기에 텍스트를 인쇄하는 것을 볼 수 있습니다.

관련 문제