如何在C ++中同时连接2个RFID阅读器?

时间:2014-08-20 10:13:19

标签: c++ rfid

我有2个RFID阅读器。

  • 读者1:port=com4baud=9600
  • 读者2:port=com9baud=9600

我想同时连接2个RFID阅读器,但只能同时连接一个阅读器。

我执行以下操作:

  1. MifareOne.CPP

    MifareOne::MifareOne()
    {
        LoadDll();
    }
    
    MifareOne::~MifareOne()
    {
        CloseComm();
        CloseDll();
    }
    
    bool IsLoadDLL = false;
    bool MifareOne::LoadDll()
    {
        if (IsLoadDLL)
            return true;
    
        // TODO: Add extra initialization here
        TCHAR szBuf[MAX_PATH];
        GetModuleFileName(NULL, (LPTSTR)szBuf, MAX_PATH);
    
        sprintf(szBuf, "../../../CardReader\\MasterRD.dll");
        m_hInstMaster = LoadLibrary(_T(szBuf));
    
    
        if (m_hInstMaster)
        {
            IsLoadDLL = true;
            (FARPROC&)lib_ver = GetProcAddress(m_hInstMaster, _T("lib_ver"));
            (FARPROC&)des_encrypt = GetProcAddress(m_hInstMaster, _T("des_encrypt"));
            (FARPROC&)des_decrypt = GetProcAddress(m_hInstMaster, _T("des_decrypt"));
            (FARPROC&)rf_init_com = GetProcAddress(m_hInstMaster, _T("rf_init_com"));
            (FARPROC&)rf_init_device_number = GetProcAddress(m_hInstMaster, _T("rf_init_device_number"));
            (FARPROC&)rf_get_device_number = GetProcAddress(m_hInstMaster, _T("rf_get_device_number"));
            (FARPROC&)rf_get_model = GetProcAddress(m_hInstMaster, _T("rf_get_model"));
            (FARPROC&)rf_get_snr = GetProcAddress(m_hInstMaster, _T("rf_get_snr"));
            (FARPROC&)rf_beep = GetProcAddress(m_hInstMaster, _T("rf_beep"));
            (FARPROC&)rf_init_sam = GetProcAddress(m_hInstMaster, _T("rf_init_sam"));
            (FARPROC&)rf_sam_rst = GetProcAddress(m_hInstMaster, _T("rf_sam_rst"));
            (FARPROC&)rf_sam_cos = GetProcAddress(m_hInstMaster, _T("rf_sam_cos"));
            (FARPROC&)rf_init_type = GetProcAddress(m_hInstMaster, _T("rf_init_type"));
            (FARPROC&)rf_antenna_sta = GetProcAddress(m_hInstMaster, _T("rf_antenna_sta"));
            (FARPROC&)rf_request = GetProcAddress(m_hInstMaster, _T("rf_request"));
            (FARPROC&)rf_anticoll = GetProcAddress(m_hInstMaster, _T("rf_anticoll"));
            (FARPROC&)rf_select = GetProcAddress(m_hInstMaster, _T("rf_select"));
            (FARPROC&)rf_halt = GetProcAddress(m_hInstMaster, _T("rf_halt"));
            (FARPROC&)rf_download_key = GetProcAddress(m_hInstMaster, _T("rf_download_key"));
            (FARPROC&)rf_M1_authentication1 = GetProcAddress(m_hInstMaster, _T("rf_M1_authentication1"));
            (FARPROC&)rf_M1_authentication2 = GetProcAddress(m_hInstMaster, _T("rf_M1_authentication2"));
            (FARPROC&)rf_M1_read = GetProcAddress(m_hInstMaster, _T("rf_M1_read"));
            (FARPROC&)rf_M1_write = GetProcAddress(m_hInstMaster, _T("rf_M1_write"));
            (FARPROC&)rf_M1_initval = GetProcAddress(m_hInstMaster, _T("rf_M1_initval"));
            (FARPROC&)rf_M1_readval = GetProcAddress(m_hInstMaster, _T("rf_M1_readval"));
            (FARPROC&)rf_M1_decrement = GetProcAddress(m_hInstMaster, _T("rf_M1_decrement"));
            (FARPROC&)rf_M1_increment = GetProcAddress(m_hInstMaster, _T("rf_M1_increment"));
            (FARPROC&)rf_M1_restore = GetProcAddress(m_hInstMaster, _T("rf_M1_restore"));
            (FARPROC&)rf_M1_transfer = GetProcAddress(m_hInstMaster, _T("rf_M1_transfer"));
            (FARPROC&)rf_typea_rst = GetProcAddress(m_hInstMaster, _T("rf_typea_rst"));
            (FARPROC&)rf_cos_command = GetProcAddress(m_hInstMaster, _T("rf_cos_command"));
            (FARPROC&)rf_atqb = GetProcAddress(m_hInstMaster, _T("rf_atqb"));
            (FARPROC&)rf_attrib = GetProcAddress(m_hInstMaster, _T("rf_attrib"));
            (FARPROC&)rf_typeb_cos = GetProcAddress(m_hInstMaster, _T("rf_typeb_cos"));
            (FARPROC&)rf_hltb = GetProcAddress(m_hInstMaster, _T("rf_hltb"));
            (FARPROC&)rf_at020_check = GetProcAddress(m_hInstMaster, _T("rf_at020_check"));
            (FARPROC&)rf_at020_read = GetProcAddress(m_hInstMaster, _T("rf_at020_read"));
            (FARPROC&)rf_at020_write = GetProcAddress(m_hInstMaster, _T("rf_at020_write"));
            (FARPROC&)rf_at020_lock = GetProcAddress(m_hInstMaster, _T("rf_at020_lock"));
            (FARPROC&)rf_at020_count = GetProcAddress(m_hInstMaster, _T("rf_at020_count"));
            (FARPROC&)rf_at020_deselect = GetProcAddress(m_hInstMaster, _T("rf_at020_deselect"));
            (FARPROC&)rf_light = GetProcAddress(m_hInstMaster, _T("rf_light"));
            (FARPROC&)rf_ClosePort = GetProcAddress(m_hInstMaster, _T("rf_ClosePort"));
            (FARPROC&)rf_GetErrorMessage = GetProcAddress(m_hInstMaster, _T("rf_GetErrorMessage"));
    
            if (NULL == lib_ver ||
                NULL == des_encrypt ||
                NULL == des_decrypt ||
                NULL == rf_init_com ||
                NULL == rf_init_device_number ||
                NULL == rf_get_device_number ||
                NULL == rf_get_model ||
                NULL == rf_beep ||
                NULL == rf_init_sam ||
                NULL == rf_sam_rst ||
                NULL == rf_sam_cos ||
                NULL == rf_init_type ||
                NULL == rf_antenna_sta ||
                NULL == rf_request ||
                NULL == rf_anticoll ||
                NULL == rf_select ||
                NULL == rf_halt ||
                NULL == rf_download_key ||
                NULL == rf_M1_authentication1 ||
                NULL == rf_M1_authentication2 ||
                NULL == rf_M1_read ||
                NULL == rf_M1_write ||
                NULL == rf_M1_initval ||
                NULL == rf_M1_readval ||
                NULL == rf_M1_decrement ||
                NULL == rf_M1_increment ||
                NULL == rf_M1_restore ||
                NULL == rf_M1_transfer ||
                NULL == rf_typea_rst ||
                NULL == rf_cos_command ||
                NULL == rf_atqb ||
                NULL == rf_attrib ||
                NULL == rf_typeb_cos ||
                NULL == rf_hltb ||
                NULL == rf_at020_check ||
                NULL == rf_at020_read ||
                NULL == rf_at020_write ||
                NULL == rf_at020_lock ||
                NULL == rf_at020_count ||
                NULL == rf_at020_deselect ||
                NULL == rf_light ||
                NULL == rf_ClosePort ||
                NULL == rf_GetErrorMessage)
            {
                return false;
            }
        }
        else
        {
            int err = GetLastError();
            return false;
        }
    
        return true;
    }
    
    bool MifareOne::CloseDll()
    {
        if(m_hInstMaster)
        {
            FreeLibrary(m_hInstMaster);
            lib_ver = NULL;
            des_encrypt = NULL;
            des_decrypt = NULL;
            rf_init_com = NULL;
            rf_init_device_number = NULL;
            rf_get_device_number = NULL;
            rf_get_model = NULL;
            rf_beep = NULL;
            rf_init_sam = NULL;
            rf_sam_rst = NULL;
            rf_sam_cos = NULL;
            rf_init_type = NULL;
            rf_antenna_sta = NULL;
            rf_request = NULL;
            rf_anticoll = NULL;
            rf_select = NULL;
            rf_halt = NULL;
            rf_download_key = NULL;
            rf_M1_authentication1 = NULL;
            rf_M1_authentication2 = NULL;
            rf_M1_read = NULL;
            rf_M1_write = NULL;
            rf_M1_initval = NULL;
            rf_M1_readval = NULL;
            rf_M1_decrement = NULL;
            rf_M1_increment = NULL;
            rf_M1_restore = NULL;
            rf_M1_transfer = NULL;
            rf_typea_rst = NULL;
            rf_cos_command = NULL;
            rf_atqb = NULL;
            rf_attrib = NULL;
            rf_typeb_cos = NULL;
            rf_hltb = NULL;
            rf_at020_check = NULL;
            rf_at020_read = NULL;
            rf_at020_write = NULL;
            rf_at020_lock = NULL;
            rf_at020_count = NULL;
            rf_at020_deselect = NULL;
            rf_light = NULL;
            rf_ClosePort = NULL;
            rf_GetErrorMessage = NULL;
            m_hInstMaster = NULL;
            return true;
        }
        return false;
    }
    
    bool MifareOne::OpenComm(int com, int baud)
    {
        //save port and baud
        mCommPort = com;
        mBandRate = baud;
    
        //open port
        int state = 1;
        state = rf_init_com(com, baud);
    
        if (state != LIB_SUCCESS){
            rf_ClosePort();
            return false;
        }
    
        return true;  // return TRUE  unless you set the focus to a control
    }
    
    bool IsCloseComm = false;
    void MifareOne::CloseComm()
    {
        if (IsCloseComm)
            return;
    
        rf_ClosePort();
        IsCloseComm = true;
    }
    
    int MifareOne::Write(unsigned char* strData)
    {
        WORD icdev = 0x0000;
        unsigned char mode = 0x60; // key A
        unsigned char secnr = '\x1';
        int state;
        unsigned char strKey[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0 };
        int nSel = 1;   
    
        state = rf_M1_authentication2(icdev, mode, (secnr / 4) * 4, strKey);
        if (state){
            return -1;
        }
    
        unsigned char strEncryptData[MAX_RF_BUFFER];
        state = Encrypt(strEncryptData, strData, (unsigned char*)Encrypt_Key);
        if (state){
            return -1;
        }   
    
        state = rf_M1_write(icdev, secnr, strEncryptData);
        if (state){
            return -1;
        }
    
        return 1;
    }
    
  2. 的main.cpp

    int main(int argc, const char* argv[])
    {
        MifareOne cardReader1;
        MifareOne cardReader2;
    
        cardReader1.OpenComm(4, 9600);
        cardReader2.OpenComm(9, 9600);
    
        cardReader1.Write((unsigned char*) "testing");   // Not work
        cardReader2.Request((unsigned char*) "testing"); // Work fine
    }
    

3 个答案:

答案 0 :(得分:1)

您的问题是,您用于访问RFID设备的DLL仅支持一次访问一个设备。您对MifareOne::OpenComm方法进行的两次调用中的每次调用都会在同一rf_init_com中调用相同的MasterRD.dll函数。 rf_init_com方法不会返回任何类型的句柄,您可以使用它来区分多个连接,因此您的MifareOne::Write方法无法告诉DLL两者中的哪一个你想要使用的连接。

鉴于DLL不允许您一次打开多个设备,因此您只有两种可能的解决方法。第一个在两个不同的进程中使用DLL,每个进程与不同的RFID设备通信。在这种情况下,DLL将在每个进程中具有单独的内部状态,允许您使用它在每个进程中打开不同的设备。然后,您必须使用Windows的许多进程间通信方法之一,以允许这两个进程相互协调或主进程。

第二种是通过串口直接与RFID设备通信。 Windows允许您同时打开在同一进程中打开的多个串行设备。使用此解决方法意味着您必须自己处理与设备通信的所有低级协议详细信息。您使用的DLL的相同低级详细信息旨在使您绝缘。您也可能要么使用异步I / O,要么使用多个线程来避免在从两个设备读取和写入时出现死锁。

答案 1 :(得分:0)

我可以想到三种可能性。

首先,您使用Request()方法测试一个阅读器,使用Write()方法测试另一个阅读器。可能Write()不正确。尝试将Request()用于您的读者,看看会发生什么。

其次是你有错误的COM端口。打开设备管理器并确定设备正在运行的端口。 插入后,确认您使用了正确的端口

第三,另一个程序,也许是您软件的旧版本,正在使用COM端口。尝试重新启动计算机或检查端口是否正在使用。

答案 2 :(得分:0)

读者DLL的界面看起来好像一次只支持一个阅读器。一个明确的指示是API函数不使用可以跟踪两个同时会话的句柄。

所以,例如,

cardReader1.OpenComm(4, 9600);

导致以下API调用:

state = rf_init_com(4, 9600);

成功时state为0。因此,没有“句柄”可用于跟踪此特定rf_init_com电话。

所以如果你下次使用

cardReader2.OpenComm(9, 9600);

打开第二个阅读器的端口。这将导致以下API调用:

state = rf_init_com(9, 9600);

由于DLL没有跟踪多个连接,现在可能会发生两次思考:

  1. 第一个连接被删除而支持第二个连接,或
  2. 第二个连接请求将被忽略,因为与第一个阅读器仍然存在开放连接。
  3. 因此,一旦您对OpenComm个对象使用MifareOne,对两个对象的调用将转到第二个(案例1)或第一个(案例2)读者。具体来说,如果您查看由于

    而执行的API调用
    cardReader1.Write((unsigned char*) "testing");
    

    cardReader2.Write((unsigned char*) "testing");
    

    您将看到这两种方法都会导致 smae API调用:

    state = rf_M1_authentication2(icdev,mode,(secnr / 4)* 4,strKey);    state = rf_M1_write(icdev,secnr,strEncryptData);

    因此DLL无法区分两个读者。

    因此,在我看来,DLL并不是设计用于多个读者。