利用虚拟键盘驱动uinput向系统发送按键指令

因为公司智能终端放置在外面,有一个像ATM机器一样的密码键盘.原本是作为银行卡密码输入确认的。


现在为了方便维护,一些简单的系统操作,就利用这个密码键盘来调用编写好的sh脚本。
但是因为终端机并没有插键盘,所以没有输入设备,这个时候只能利用与密码键盘通讯的支付程序,向系统发送按键指令。
所以,用到了uinput虚拟输入驱动,简单的说:用它可以在用户空间实现输入设备,向系统中注入输入事件。
下面,是我写好的输入按键的程序。


1.将下面的代码保存成 keyinput.c
2.编译:


$ gcc keyinput.c -o keyinput
3.加载 uinput驱动


$ sudo modprobe uinput
$ lsmod |grep uinput
4.将编译好的文件放到/usr/sbin/中


$ sudo cp keyinput /usr/sbin/
$ sudo chmod 755 /usr/sbin/keyinput
5.示例:向Linux桌面系统发送CTRL+ALT+D 清屏蔽指令


$ keyinput  29 56 32
6.keyinput 参数说明:后面跟着的参数全是ASCII码,对应的键盘ASCII码在 /usr/include/linux/input.h 中可以查询。


/*//////////////////////////////////////////
//    Simulated keyboard input program    //
//                by:0x001                //
//////////////////////////////////////////*/
#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>


#define die(str, args...) do { 
        perror(str); 
        exit(EXIT_FAILURE); 
    } while(0)


int fd;
struct uinput_user_dev uidev; // uInput device structure
struct input_event     ev;  // Input device structure


/* Setup the uinput device */
void setup_uinput_device()
{
    int i=0;
    // Open the input device
    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if(fd < 0)
        die("error: open /dev/uinput");


    memset(&uidev, 0, sizeof(uidev)); // Intialize the uInput device to NULL
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-Openkk");
    uidev.id.bustype = BUS_USB;
    uidev.id.vendor  = 0x1;
    uidev.id.product = 0x1;
    uidev.id.version = 1;
    // Setup the driver I/O channels
    ioctl(fd, UI_SET_EVBIT, EV_KEY);
    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
    for (i=0; i < 256; i++) {
        ioctl(fd, UI_SET_KEYBIT, i);
    }
    ioctl(fd, UI_SET_EVBIT, EV_REL);
    ioctl(fd, UI_SET_RELBIT, REL_X);
    ioctl(fd, UI_SET_RELBIT, REL_Y);


    /* Create input device into input sub-system */
    write(fd, &uidev, sizeof(uidev));
    if(ioctl(fd, UI_DEV_CREATE) < 0)
        die("error: create uinput device");
}


// Simulated keyboard input
void simulate_key(int keycode, int keyvalue)
{
    memset(&ev, 0, sizeof(struct input_event));
    gettimeofday(&ev.time, NULL);
    ev.type = EV_KEY;
    ev.code = keycode;
    ev.value = keyvalue;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
    {
            printf("simulate key errorn");
            return;
    }else{
        printf("simulate key %d, %dn", keycode, keyvalue);
    }


}


void simulate_key_end()
{
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_SYN;
    ev.code = 0;
    ev.value = 0;
    write(fd, &ev, sizeof(struct input_event));
}


//  check the key is control key
int check_valid_control_key(int key)
 {
      int control_key[] = {29,42,54,56,97,100,125,126};
      int len = sizeof(control_key) / sizeof(control_key[0]);
      int i;
      int ret = 0;
      for ( i = 0; i < len; i++)
      {
          if (control_key[i] == key)
          {
              ret = 1;
              break;
          }
      }
      return ret;
 }


int main(int argc, char *argv[])
{
    if (argc <=1)
    {
        printf("n  /*//////////////////////////////////////////n");
        printf("  //    Simulated keyboard input program    //n");
        printf("  //                by:0x001                //n");
        printf("  //////////////////////////////////////////*/nn");
        printf("  Usage : keyinput <kye number> [key number...]n");
        printf("          keyinput 29 56 32  /* CTRL + ALT +D */n");
        printf("          keyinput 125 32  /* WIN +D */nn");
        printf("  /* Types of key number are defined in /usr/include/linux/input.h */nn");
        printf("  /* tools need to load the kernel module: uinput */nn");
        printf("  /* $ sudo modprobe uinput */nn");
        return 0;
    }


    setup_uinput_device();


    sleep(1);
    int key;
    int i;


    for (i=1; i < argc; i++)
    {
        key = atoi(argv[i]);
        simulate_key(key,1);
        if (check_valid_control_key(key) == 0)
        {
            simulate_key(key,0);
        }
    }


    for (i=1; i < argc; i++)
    {
        key = atoi(argv[i]);
        if (check_valid_control_key(key) == 1)
        {
            simulate_key(key,0);
        }
    }


    simulate_key_end();
    if(ioctl(fd, UI_DEV_DESTROY) < 0)
        die("error: ioctl");
    close(fd);


    return 0;
}

你可能感兴趣的:(利用虚拟键盘驱动uinput向系统发送按键指令)