linux读取字符设备-键盘、扫码枪、二维码设备

原理:

1.扫描/proc/bus/input/devices看你的设备是否在系统中

2.解析cat /proc/bus/input/devices输出的信息,查看event的id

3.根据event id去组装/dev/input/event你的id

4.用open和read去读取event里面的输入

5.将二进制数据翻译成字符,翻译方法:input-event-codes.h中的宏定义去匹配

代码见下:

#ifndef CQRDEVICE_H
#define CQRDEVICE_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define ERR printf
#define RTM printf
#define MAXSSDPSIZE 1024

class CQRDevice
{
public:
    CQRDevice();
    void FindQRUsb();
    void ReadQRUsb();
    bool TransKey( bool bShift,unsigned short k,char & c );
    bool m_bQuit;
    bool m_bOpenSerial;
    bool m_bInitSerial;
    bool m_bFindQRUsb;
    string m_strData;
    string m_strEvent;
    std::mutex  m_mx;
    list m_list;
};

#endif // CQRDEVICE_H
#include "cqrdevice.h"

CQRDevice::CQRDevice()
{

}


void CQRDevice::ReadQRUsb()
{

    int keys_fd=open(m_strEvent.c_str(),O_RDONLY);
    if(keys_fd<=0)
    {
        ERR("open %s failed",m_strEvent.c_str());
        return ;
    }
    else
    {
        RTM("Open %s success",m_strEvent.c_str());
    }

    bool bShift=false;
    m_bQuit=false;
    while(!m_bQuit)
    {
        struct input_event ev_temp;
//        ev_temp.time.tv_sec=time(0);
//        ev_temp.time.tv_usec=0;
        ev_temp.type=EV_KEY;
        //this_thread::sleep_for(chrono::milliseconds(1));
        int nRet = read(keys_fd, &ev_temp, sizeof(struct input_event));
        if( nRet <=0 )
        {
            this_thread::sleep_for(chrono::milliseconds(1));
            continue;
        }
        if( ev_temp.type != EV_KEY )
        {
            this_thread::sleep_for(chrono::milliseconds(1));
            continue;
        }
        //printf("ret=%d,t=%d,v=%d,c=%d\n",nRet,ev_temp.type,ev_temp.value,ev_temp.code);
        if( ev_temp.code== KEY_LEFTSHIFT  )
        {
            if( ev_temp.value == 1)
                bShift=true;

            else
                bShift=false;
        }

        if( ev_temp.value== 1 &&ev_temp.code != KEY_LEFTSHIFT )
        {
            char c;
            if( TransKey( bShift,ev_temp.code,c ) )
            {
                //printf("trans key=%c\n",c);
                m_strData += c;
            }
            //RTM("key=0x%d,trans=%c",ev_temp.code,c);
        }

        if( ev_temp.value==1 && ev_temp.code== KEY_ENTER )//回车
        {

            if( m_strData.size()>10 )
            {
                m_mx.lock();
                m_list.push_back(m_strData );
                RTM("data =%s,list=%d",m_strData.c_str(),m_list.size());
                m_mx.unlock();

            }

            m_strData.clear();
        }

    }

    close(keys_fd);
}
void CQRDevice::FindQRUsb()
{
    FILE *fp;
    char path[1035];
    string strDevice;

    /* Open the command for reading. */
    fp = popen("/bin/cat /proc/bus/input/devices", "r");
    if (fp == NULL)
    {
      ERR("Failed to run command\n" );
      return;
    }

    /* Read the output a line at a time - output it. */
    bool bGet1=false;
    while (fgets(path, sizeof(path)-1, fp) != NULL)
    {
        strDevice += path;
        RTM( path );
        if( strstr(path,"N: Name=") )
        {
            if( strstr(path,"dwc2-gadget HID Gadget") )
            {
                RTM("have wc2-gadget HID Gadget str");
                bGet1=true;
            }
            else
            {
                RTM("no wc2-gadget HID Gadget str");

                bGet1=false;
            }
        }
        else
        {
        }


        if( bGet1 )
        {
            char *p1=strstr(path,"kbd");
            char *p2=strstr(path,"leds");
            if(  p1&&p2 )
            {

                string str;
                str.assign(path);
                int nPos3 = str.find("event");
                if( nPos3 >=0 )

                {
                    str = str.substr(nPos3);

                    int nPos4 = str.find(" ");
                    if( nPos4 >=0 )
                    {
                        str = str.substr(0,nPos4);
                        m_strEvent="/dev/input/";
                        m_strEvent+=str;
                        m_bFindQRUsb=true;

                    }
                }

            }
            else
            {

            }
        }

        //printf("%s", path);
    }

    /* close */
    pclose(fp);
}


bool CQRDevice::TransKey( bool bShift,unsigned short k,char & c )
{
    //printf("bshift=%d,k=%d\n",bShift,k);

    switch( k )
    {
    case KEY_1:
         if( bShift ) c='!';else c='1';
        break;
    case KEY_2:
        if( bShift ) c='@';else c='2';
        break;
    case KEY_3:
        if( bShift ) c='#';else c='3';
        break;
    case KEY_4:
        if( bShift ) c='$';else c='4';
        break;
    case KEY_5:
        if( bShift ) c='%';else c='5';
        break;
    case KEY_6:
        if( bShift ) c='^';else c='6';
        break;
    case KEY_7:
        if( bShift ) c='&';else c='7';
        break;
    case KEY_8:
        if( bShift ) c='*';else c='8';
        break;
    case KEY_9:
        if( bShift ) c='(';else c='9';
        break;
    case KEY_0:
        if( bShift ) c=')';else c='0';
        break;
    case KEY_MINUS:
        if( bShift ) c='_';else c='-';
        break;
    case KEY_EQUAL:
        if( bShift ) c='+'; else c='=';
        break;
    case KEY_Q:
        c='q';
        if( bShift ) c -=32;
        break;
    case KEY_W:
        c='w';
        if( bShift ) c -=32;
        break;
    case KEY_E:
        c='e';
        if( bShift ) c -=32;
        break;
    case KEY_R:
        c='r';
        if( bShift ) c -=32;
        break;
    case KEY_T:
        c='t';
        if( bShift ) c -=32;
        break;
    case KEY_Y:
        c='y';
        if( bShift ) c -=32;
        break;
    case KEY_U:
        c='u';
        if( bShift ) c -=32;
        break;
    case KEY_I:
        c='i';
        if( bShift ) c -=32;
        break;
    case KEY_O:
        c='o';
        if( bShift ) c -=32;
        break;
    case KEY_P:
        c='p';
        if( bShift ) c -=32;
        break;
    case KEY_A:
        c='a';
        if( bShift ) c -=32;
        break;
    case KEY_S:
        c='s';
        if( bShift ) c -=32;
        break;
    case KEY_D:
        c='d';
        if( bShift ) c -=32;
        break;
    case KEY_F:
        c='f';
        if( bShift ) c -=32;
        break;
    case KEY_G:
        c='g';
        if( bShift ) c -=32;
        break;
    case KEY_H:
        c='h';
        if( bShift ) c -=32;
        break;
    case KEY_J:
        c='j';
        if( bShift ) c -=32;
        break;
    case KEY_K:
        c='k';
        if( bShift ) c -=32;
        break;
    case KEY_L:
        c='l';
        if( bShift ) c -=32;
        break;
    case KEY_SEMICOLON:
        if( bShift ) c=':';else c=';';
        break;
    case KEY_APOSTROPHE:
        if( bShift ) c='\"';else c='\'';
        break;
    case KEY_BACKSLASH:
        if( bShift ) c='|';else c='\\';
        break;
    case KEY_Z:
        c='z';
        if( bShift ) c -=32;
        break;
    case KEY_X:
        c='x';
        if( bShift ) c -=32;
        break;
    case KEY_C:
        c='c';
        if( bShift ) c -=32;
        break;
    case KEY_V:
        c='v';
        if( bShift ) c -=32;
        break;
    case KEY_B:
        c='b';
        if( bShift ) c -=32;
        break;
    case KEY_N:
        c='n';
        if( bShift ) c -=32;
        break;
    case KEY_M:
        c='m';
        if( bShift ) c -=32;
        break;
    case KEY_COMMA:
        if( bShift ) c='<';c=',';
        break;
    case KEY_DOT:
        if( bShift ) c='>';c='.';
        break;
    case KEY_SLASH:
        if( bShift ) c='?';c='/';
        break;
    default:
        //printf("######################error key code=%d##########################\n",k);
        return false;
    }
    return true;
}

你可能感兴趣的:(Linux,linux)