Knowledge Base Nr: 00030 OPCServerEx.cpp - http://www.swe-kaiser.de

Downloads: Server

OPC: Beispiel für einen OPC Server der mit dem FactorySoft OPC Server Rapid Development Toolkit entwickelt wurde.

  
// Das Beispiel implementiert eine Zugangskennung mittels ChipKarten-Lesegerät.

//*******************************************************************
// Used to handle the chipdrive interface
class CMyCardServer;

class CInterface : public CObject
{
private:
BOOL m_bCardInserted;
CString m_strName, m_strPassword;

CRITICAL_SECTION m_cs;

CListBox* m_pListBox;

public:
CInterface();
virtual ~CInterface() ;

CMyCardServer* m_pCardServer;

void SetListBox(CListBox* pListBox) { m_pListBox = pListBox; }
void OnStatusChanged();
BOOL GetCardInfo(CString& strName, CString& strPassword);
void AddLogEntry(LPCTSTR lpszLog);

BOOL IsCardInserted() { return m_bCardInserted; }
void GetName(CString& strName);
void GetPassword(CString& strPassword);
}
;


/////////////////////////////////////////////////////////////////////////////
// CMyCardServer (Nachrichten überladen und an den Dialog weitergeben)
class CMyCardServer : public CCardServer
{
public:
CMyCardServer(CInterface* pIF)
{
m_pIF = pIF;
}

protected:
virtual void OnStatusChanged()
{
m_pIF->OnStatusChanged();
}

private:
CInterface* m_pIF;
};

//*******************************************************************
// Used to handle the OPC interface

#define NAME_ITEM "AccessName"
#define PASSWORD_ITEM "Password"
#define CARD_ITEM "Card_inserted"

class COPCServerEx : public CObject
{
public:
COPCServerEx();
virtual ~COPCServerEx();

BOOL InitServer(HINSTANCE hInstance, LPCSTR lpszCmdLine);
BOOL ExitServer();
};


#include "stdafx.h"
#include "OPCServerEx.h"
#include "OPCDa.h"
#include "OPCError.h"
#include "OPCProps.h"
#include "FSServer.h"

CInterface::CInterface()
{
m_bCardInserted = FALSE;

InitializeCriticalSection(&m_cs);

m_pCardServer = new CMyCardServer(this);

m_pListBox = NULL;
}

CInterface::~CInterface()
{
delete m_pCardServer;
}

void CInterface::GetName(CString& strName)
{
CSLock wait(&m_cs);

strName = m_bCardInserted ? m_strName : "";
}

void CInterface::GetPassword(CString& strPassword)
{
CSLock wait(&m_cs);

strPassword = m_bCardInserted ? m_strPassword : "";
}


void CInterface::OnStatusChanged()
{
CString strLog;

m_pCardServer->GetStatusText(strLog);

int nStatus = m_pCardServer->GetStatus();
CTime now = CTime::GetCurrentTime();
strLog.Format("%d.%d.%d %d:%d:%d "
, now.GetDay(), now.GetMonth(), now.GetYear()
, now.GetHour(), now.GetMinute(), now.GetSecond());

switch (nStatus)
{
case MsgActive: //150 Karte bereit
{
strLog += "Karte erkannt :";

//Chipkarte auslesen
CSLock wait(&m_cs);

if (GetCardInfo(m_strName, m_strPassword))
{
strLog += m_strName;
m_bCardInserted = TRUE;
}
else
{
strLog += "Chipkarte hat illegale Daten!";
m_strName = m_strPassword = "";
m_bCardInserted = FALSE;
}

AddLogEntry(strLog);
}

break;

case MsgWait: //110 Warten auf Karte
strLog += "Karte entfernt.";

AddLogEntry(strLog);

CSLock wait(&m_cs);
m_strName = m_strPassword = "";
m_bCardInserted = FALSE;

break;

}
}

BOOL CInterface::GetCardInfo(CString& strName, CString& strPassword)
{
char buf[2048];
DWORD dwResult = m_pCardServer->SCardCommand("Card,MemRead", NULL, 0, buf, sizeof(buf));

strName = strPassword = "";

if (dwResult == 0)
{
CString strData(buf);

int nTrennPos = strData.FindOneOf("#");
if (nTrennPos > 0)
{
strName = strData.Left(nTrennPos);
strPassword = strData.Mid(nTrennPos + 1);

return TRUE;
}
}

return FALSE;
}

void CInterface::AddLogEntry(LPCTSTR lpszLog)
{
TRACE("%s\n", lpszLog);

if (m_pListBox)
{
m_pListBox->AddString(lpszLog);

//anzahl der Listbox-Einträge begrenzen
if (m_pListBox->GetCount() > 200)
m_pListBox->DeleteString(0);
}
}


//the one and only interface
CInterface g_interface;


//*********************************************************
// FSServer stuff
#include "OPCDa.h"
#include "OPCError.h"
#include "OPCProps.h"
#include "FSServer.h"

#include "Callback.h" // FSServer callback class


// Also put this GUID into the OPCServer.rgs file
//*********************************************************
// {3CD20D71-E45A-11d3-B4A2-0000E83A0185}
CLSID CLSID_OPCServer =
{ 0x3cd20d71, 0xe45a, 0x11d3, { 0xb4, 0xa2, 0x0, 0x0, 0xe8, 0x3a, 0x1, 0x85 } };

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

COPCServerEx::COPCServerEx()
{

}

COPCServerEx::~COPCServerEx()
{

}


BOOL COPCServerEx::InitServer(HINSTANCE hInstance, LPCSTR lpszCmdLine)
{
OleInitialize(NULL);
if( !StartFSServer(hInstance, &CLSID_OPCServer) )
{
ASSERT(FALSE);
return FALSE;
}

// Modify registry based on the command line
// If this happens, ExitInstance is not called,
// so don't initialize much before this
TCHAR szTokens[] = _T("-/ ");
// copy m_lpCmdLine because _tcstok modifies the string
LPTSTR lpszToken = _tcstok((LPSTR)lpszCmdLine, szTokens);
while (lpszToken != NULL)
{
if (_tcsicmp(lpszToken, _T("UnregServer"))==0)
{
if( FAILED(UnregisterServer()) )
AfxMessageBox(_T("UnregisterServer Failed"));
return FALSE;
}
else if (_tcsicmp(lpszToken, _T("RegServer"))==0)
{
if( FAILED(RegisterServer()) )
AfxMessageBox(_T("RegisterServer Failed"));
return FALSE;
}

lpszToken = _tcstok(NULL, szTokens);
}

SetCallbackObject(new ShellCallback);

return TRUE;
}

BOOL COPCServerEx::ExitServer()
{
StopFSServer();
OleUninitialize();

return TRUE;
}

//*******************************************************************
ShellCallback::ShellCallback() : m_root("Root")
{
//setup item address space
// create a static tree of tags

Branch* pBranch = new Branch("ZugangsKontrolle");
m_root.AddBranch(pBranch);

AddServerItem(NAME_ITEM , VT_BSTR, pBranch);
AddServerItem(PASSWORD_ITEM , VT_BSTR, pBranch);
AddServerItem(CARD_ITEM , VT_BOOL, pBranch);
}

//*******************************************************************
HRESULT ShellCallback::ReadTag(CTag * pTag)
{
CSLock wait( &m_CS ); // protect tag access

VariantClear( &pTag->m_value );
pTag->m_value.vt = pTag->m_nativeType;
pTag->m_quality = g_interface.IsCardInserted() ? OPC_QUALITY_GOOD : OPC_QUALITY_BAD;

HRESULT hr = S_OK;

CString strName = ((ShellTag*)pTag)->m_name;

if (!strName.Compare(NAME_ITEM))
{
CString strVal;
g_interface.GetName(strVal);
pTag->m_value.bstrVal = strVal.AllocSysString();
}
else if (!strName.Compare(PASSWORD_ITEM))
{
CString strVal;
g_interface.GetPassword(strVal);
pTag->m_value.bstrVal = strVal.AllocSysString();
}
else if (!strName.Compare(CARD_ITEM))
{
pTag->m_value.boolVal = g_interface.IsCardInserted() ? TRUE : FALSE;
}
else //write only or unknown item
{
hr = OPC_E_NOTFOUND;
}

CoFileTimeNow( &pTag->m_timestamp );

return hr;
}

//*******************************************************************
// The variant may contain data in any format the client sent.
// Use VariantChangeType to convert to a usable format.
HRESULT ShellCallback::WriteTag(
CTag * pTag,
VARIANT & value)
{
HRESULT hr = VariantChangeType(&pTag->m_value, &value, 0, pTag->m_nativeType);

CString strName = ((ShellTag*)pTag)->m_name;
COleVariant oleVar(value);
oleVar.ChangeType(pTag->m_nativeType);

pTag->m_quality = OPC_QUALITY_GOOD;

/* if (!strName.Compare(NAME_ITEM))
{
}
else if (!strName.Compare(PASSWORD_ITEM))
{
}
else if (!strName.Compare(CARD_ITEM))
{
}
else //read only or unknown item
*/
{
hr = OPC_E_NOTFOUND;
}

return hr;
}