i am posting the source... However, i suspect that the problem has to do with the Release configuration... I use MFC by the way. I am really newbie on this, so if anyone can make any assumptions or suspects anything on the configuration that could have caused this problem...
Thanks
Resource.h
Code:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by RFIDReaderConsole.rc
//
#define IDS_APP_TITLE 103
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
RFIDReaderConsole.h
Code:
#pragma once
#include "resource.h"
#include "RFIDClient.h"
#include "NDKMessage.h"
#include "ChatMessage.h"
#include "mysql++.h"
#define MIFARE_KEYLEN 6
#define MIFARE_KEYNR 0
#define MIFARE_BLOCKNR 4
#define MIFARE_BUFLEN 16
#include <math.h>
#include <winscard.h>
extern "C"{
#include <ok.h>
#include <scardcl.h>
}
class CRFIDReaderConsole
{
public:
CRFIDReaderConsole(CString* host,long port);
~CRFIDReaderConsole();
//start the execution of the daemon
void start();
//read the ID
int ReadID();
//send the ID to the corresponding server
void SendID(int id);
//check if the ID exists in the DB
bool IDExists(int id);
private:
SCARD_READERSTATE sReaderState; //structure storing readers and data being monitored
SCARDHANDLE hSHandle;
SCARDCONTEXT hSContext;
//convert a UCHAR buffer to char buffer
void UcharToStr(UCHAR *ucDataBuffer, ULONG ulDataBufLen, char *str);
private:
//the client network module, that handles
//the communication to the corresponding server
RFIDClient* client;
//the state of the reader (empty,full) before the
//current state; the last state
ULONG lastCardState;
//the host and port the client module will connect to
CString* host;
long port;
};
stdafx.h
Code:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include <iostream>
#include <tchar.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
#include <afx.h>
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
// TODO: reference additional headers your program requires here
RFIDClient.h
Code:
#include "NDKClient.h"
#include "NDKMessage.h"
class RFIDClient : public CNDKClient
{
public:
RFIDClient();
virtual ~RFIDClient();
protected:
// Called when a message is received. The derived class must override this
// method.
virtual void OnMessage(CNDKMessage& message);
// Called whenever a disconnection occurs. The NDKDisconnectionType specify
// how the disconnection occurred. CloseConnection don't need to be called
// when OnDisconnect is used. The derived class must override this method.
virtual void OnDisconnect(NDKClientDisconnection disconnectionType);
private:
};
RFIDReaderConsole.cpp
Code:
// RFIDReaderConsole.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "RFIDReaderConsole.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
// The one and only application object
CWinApp theApp;
using namespace std;
void CRFIDReaderConsole::start()
{
while (true)
{
Sleep(500);
//if there is an event showing insertion or removal of the card
if (SCARD_S_SUCCESS==SCardGetStatusChange(hSContext,INFINITE,&sReaderState,1))
{
//if there is a card now and there wasn't before
if ((sReaderState.dwEventState & SCARD_STATE_PRESENT) &&
(lastCardState==SCARD_STATE_EMPTY))
{
cout << "Card is now present" << endl;
//connect to card
//
DWORD dwAP;
if (SCARD_S_SUCCESS != SCardConnect(hSContext, (LPCTSTR)"OMNIKEY CardMan 5x21-CL 0",
SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&hSHandle,&dwAP ))
{
cerr << "failed to connect to card..." << endl <<
"check the card has been detected by the CL interface! exited" <<endl;
exit(-1);
}
//and authenticate
//
UCHAR ucMifareAuthMode=MIFARE_AUTHENT1A;
UCHAR ucMifareKey[6]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
ULONG ulMifareKeyLen = MIFARE_KEYLEN;
UCHAR ucMifareAccessType=MIFARE_KEY_INPUT;
UCHAR ucMifareKeyNr=MIFARE_KEYNR;
LONG m_longBlockNr=MIFARE_BLOCKNR;
if (NO_ERROR != SCardCLMifareStdAuthent(hSHandle,m_longBlockNr,ucMifareAuthMode,
ucMifareAccessType,ucMifareKeyNr,ucMifareKey, ulMifareKeyLen))
{
cerr << "failed to authenticate... exited" << endl;
exit(-1);
}
//the read the ID from the card, check if it exists in the
//DB and if it does send it to the server
int claimedId=ReadID();
if (IDExists(claimedId))
{
SendID(claimedId);
}
else
{
cout << "Unknown ID" << endl;
}
lastCardState=SCARD_STATE_PRESENT;
}
//if there is no card now, but there was a card before,
//just update the last state
else if ((sReaderState.dwEventState & SCARD_STATE_EMPTY) &&
(lastCardState=SCARD_STATE_PRESENT))
{
cout << "Card is now absent" << endl;
lastCardState=SCARD_STATE_EMPTY;
}
else if (lastCardState==SCARD_STATE_PRESENT)
{
cout << "Card is still present" << endl;
}
else if (lastCardState==SCARD_STATE_EMPTY)
{
cout << "There is no card inserted yet" << endl;
}
else
{
cout << "UNKNOWN CARD STATE!" << endl;
}
}//getStatusChange-succcess
else
{
cerr <<"Failure retrieving the card state"<< endl;
}//getStatusChange-failure
}
}//start
CRFIDReaderConsole::CRFIDReaderConsole(CString* host, long port)
{
//open a connection to the server and if they
//fail print an error message and exit
//
client = ::new RFIDClient();
BOOL bRetVal;
bRetVal = client->OpenConnection(*host,port);
if(!bRetVal)
{
cerr << "card reader daemon failed to establish connection" << endl;
exit(-1);
}
//do card reader initialization procedures
//
lastCardState=SCARD_STATE_EMPTY;
hSHandle = 0x00000000; //initialize card handle
hSContext = 0x00000000; //initialize reader context
CString cs="OMNIKEY CardMan 5x21-CL 0";
//set the name of the reader
sReaderState.szReader = strdup(cs);
//current state of the reader as seen by the app
sReaderState.dwCurrentState = SCARD_STATE_EMPTY;
//current state of the reader as seen by the resource manager
sReaderState.dwEventState = SCARD_STATE_EMPTY;
if (SCARD_S_SUCCESS != SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSContext))
{
cerr << "failed to establish context to reader... exited" <<endl;
exit(-1);
}
}//CReader
CRFIDReaderConsole::~CRFIDReaderConsole()
{
//release reader context
if (SCARD_S_SUCCESS!= SCardReleaseContext(hSContext))
{
cerr << "failed to release context from reader... exited" << endl;
exit(-1);
}
//close connection and destroy the client
client->CloseConnection();
if(client)
{
delete client;
}
}//~CReader
bool CRFIDReaderConsole::IDExists(int id)
{
bool bCon;
CString m_errorInfo;
mysqlpp::Connection m_Connection;
//Create a connection to the DB, execute a query and request all
//"Persons" table tuples with the given ID. If none is retrieved,
//false is returned -no person with the given ID has been registered
//in the DB, otherwise true is returned
try
{
bCon = m_Connection.connect("humabio","localhost","root","123",3306);
if(bCon)
{
TRACE("Succesfully connected to the database\n");
mysqlpp::Query query = m_Connection.query();
char* str=new char[MIFARE_BUFLEN];
CString idQuery="SELECT * from Persons where PersonID=";
itoa(id,str,10);
idQuery.Append(str);
query << idQuery;
mysqlpp::Row row;
mysqlpp::Result result = query.store();
TRACE ("Found:=%d results\n",result.num_rows());
if (result && (result.num_rows() > 0) && (row = result.at(0)))
{
unsigned long length = row.at(0).size();
TRACE("Signature Details\n");
TRACE("Signature-length:%d \n",length);
unsigned char *read_buffer = new unsigned char[length];
memset(read_buffer,0,length);
memcpy(read_buffer,row.at(0).data(),length);
return true;
}
return false;
}
}
catch(mysqlpp::ConnectionFailed cf)
{
m_errorInfo = cf.what();
TRACE("Connection to the database failed\n");
TRACE("%s \n",cf.what());
cerr << "abort or replace card" << endl;
}
catch(mysqlpp::Exception ex)
{
m_errorInfo = ex.what();
TRACE("Generic exception in Mysql Database\n");
TRACE("%s \n",ex.what());
cerr << "abort or replace card" << endl;
}
}//IDExists
int CRFIDReaderConsole::ReadID()
{
//perform a read operation on the given block number
//of the card
LONG m_longBlockNr=MIFARE_BLOCKNR;
UCHAR ucMifareDataRead[16];
ULONG ulMifareNumOfDataRead;
BOOL everythingOK=true;
if (NO_ERROR!=SCardCLMifareStdRead(hSHandle,m_longBlockNr,
ucMifareDataRead,MIFARE_BUFLEN,&ulMifareNumOfDataRead))
{
cerr <<"failed to read data from card... exited"<<endl;
exit(-1);
}
//convert the UCHAR buffer read to an integer
int id=0;
char ch='0';
for (int i=15; i>=0; i--)
{
ch=ucMifareDataRead[i];
id+=atoi(&ch)*pow(10,15-i);
}
return id;
}//ReadID
void CRFIDReaderConsole::SendID(int id)
{
//if(!client->IsConnected())
//{
// cerr <<"card reader daemon was in disconnected state... attempting to reconnect" << endl;
// client->CloseConnection();
// BOOL bRetVal;
// bRetVal = client->OpenConnection(*host,port);
// if(!bRetVal)
// {
// cerr << "card reader daemon failed to establish connection" << endl;
// exit(-1);
// }
// else
// {
// cerr <<"card reader daemon has been reconnected successfully!"<<endl;
// }
//}
//else
//{
//send a ChatUserJoin type message to the server
int ClaimedIDFromRFID = id;
char buf[255];
sprintf(buf,"ClaimedID:=%d",ClaimedIDFromRFID);
CString strMessage = buf;
CNDKMessage message(ChatUserJoin);
message.Add("RFIDReader");
client->SendMessageToServer(message);
//encapsulate the claimed ID in another message
//and send this right afterwards to the server
CNDKMessage message2(ClaimedID);
message2.Add(strMessage);
client->SendMessageToServer(message2);
cerr << "ID has been transmitted" <<endl;
//}
}//SendID
////////////////////////////////////HELPERS/////////////////////////////////////////////
//
//convert a UCHAR buffer to char buffer
void CRFIDReaderConsole::UcharToStr(UCHAR *ucDataBuffer, ULONG ulDataBufLen, char *str)
{
ULONG i = 0;
char bytetochar[3] ="";
char Temp[1024] ="";
for (i=0;i<ulDataBufLen;i++)
{
_itoa(ucDataBuffer[i],bytetochar,16);
if (ucDataBuffer[i]<=0x0F)strcat(Temp,"0");
strcat(Temp,bytetochar);
}
memcpy(str,Temp,ulDataBufLen*2);
str[ulDataBufLen*2] = 0;
}//UcharToStr
////////////////////////////////////HELPERS/////////////////////////////////////////////
//////////////////////////////////////MAIN///////////////////////////////////
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
//check the arguments; if wrong, issue a message showing the
//right usage and exit
if (argc!=3) {
cerr <<"Usage: cardreaderd host port" << endl;
exit(-1);
}
//otherwise start the daemon, using the arguments
CString hostParam=argv[1];
long portParam=atol(argv[2]);
CRFIDReaderConsole* cons=new CRFIDReaderConsole(&hostParam,portParam);
cons->start();
}
return nRetCode;
}
stdafx.cpp
Code:
// stdafx.cpp : source file that includes just the standard includes
// RFIDReaderConsole.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
RFIDClient.cpp
Code:
#include "stdafx.h"
#include "RFIDClient.h"
RFIDClient::RFIDClient()
{
}
RFIDClient::~RFIDClient()
{
}
// Called when a message is received. The derived class must override this
// method.
void RFIDClient::OnMessage(CNDKMessage& message)
{
}
// Called whenever a disconnection occurs. The NDKDisconnectionType specify
// how the disconnection occurred. CloseConnection don't need to be called
// when OnDisconnect is used. The derived class must override this method.
void RFIDClient::OnDisconnect(NDKClientDisconnection disconnectionType)
{
}