Knowledge Base Nr: 00030 OPCServerEx.cpp - http://www.swe-kaiser.de
Downloads:
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;
}