2016-10-25 1 views
0

Ich habe Barcode-Daten von einem Barcode-Scanner im ASCII-Format erhalten. Ich muss ein Programm schreiben, um Tastatur zu emulieren, die Daten verwendet, die über den Barcodescanner in Linux zu dem Computer empfangen werden. Ich lese Quellcode, der für den USB-HIDKB-Treiber auch für Linux verfügbar ist (http://lxr.free-electrons.com/source/drivers/hid/usbhid/usbkbd.c), aber ich fühle, dass ich es umgekehrt machen muss. Genau das, was ich tun möchte, ist, dass Daten vom Scanner als Datenstrom im ASCII-Format empfangen werden und Schlüsselstriche mit gescannten Daten generiert werden müssen. Daten lesen Teil ist fast fertig und muss einen Weg finden, um die ASCII-Daten in Tastenanschläge zu konvertieren.Können wir Tastenanschläge unter Verwendung von Raw-ASCII-Werten mit C++ in Linux generieren?

Beispiel Bedienung:

Es ist ein Barcode für ctr + z (Tastatur Abkürzung für undo Betrieb), einmal scannen die Barcode-Daten empfangen werden, 08 10 03 00 1a 00 18 0b als die Daten in HEX empfängt dann Daten 1a 00 18 0b. Hier sind die ersten 4 Bytes Header und der Rest ist der Datenteil. Jetzt muss ich einen Vorgang rückgängig machen, anstatt Daten zu drucken.

Ich bin willkommen, jedes Codebeispiel oder Vorschläge haben einen Anfang zum Codieren. Vielen Dank.

+0

Sie meinen, Sie erhalten buchstäblich die ASCII-Zeichenfolge '" 08 10 03 03 00 1a 00 18 0b "', d. H. 23 ASCII-Zeichen einschließlich 14 Ziffern, zwei Buchstaben und 7 Leerzeichen? Weil der 8-Byte-Stream '08 10 03 03 00 1a 00 18 0b' nicht ASCII ist. – MSalters

+0

Nein, Daten im Post werden generiert, nachdem der ASCII-Stream in das HEX-Format konvertiert wurde. Was ich tun muss, erzeugt die Schlüsselstriche für den obigen Datenstrom vor dem Drucken auf einem Ausgabestrom. –

+0

Nun, ASCII hat keinen "Steuerschlüssel", oder eine Strg-Z, oder rückgängig machen. ASCII ist ein Byte pro Zeichen, und die 4 Bytes "1a 00 18 0b" sind "SUB NUL CAN VT" (Ersatz, Null, Abbrechen, Vertical Tab) – MSalters

Antwort

0

Ein nützliches Stück Code gefunden [1]: http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html , half mir, einen Start zu emulieren, eine Tastenkombination mit bereits verarbeiteten Daten zu emulieren.

aber dies funktioniert nur auf Systemen, die die xwindowing Systeme haben. Dies funktioniert nicht auf Systemen, die nur auf Terminals basieren. In diesem Fall müssen wir das uinput-Subsystem verwenden, um einen Softwareschlüssel zu erzeugen.

Beispielprogramm, wie in Linux verwenden uinput finden sich hier http://thiemonge.org/getting-started-with-uinput

ich ein einfaches Programm mit uinput schrieb. Das funktioniert.

Beispielcode:

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

das Programm ausführen und in einen Texteditor wechseln. Sie werden dort einen Text sehen.

Verwandte Themen