329 lines
11 KiB
Plaintext
329 lines
11 KiB
Plaintext
//------------------------------------------------------------------------------
|
||
|
||
#pragma hdrstop
|
||
|
||
#include <IniFiles.hpp>
|
||
#include "Validator.h"
|
||
#include "ud_Module.h"
|
||
|
||
//---------------------------------------------------------------------------
|
||
Validator* validator=NULL;
|
||
//---------------------------------------------------------------------------
|
||
|
||
#pragma package(smart_init)
|
||
//---------------------------------------------------------------------------
|
||
#define POLYNOMIAL 0x08408
|
||
unsigned int GetCRC16(unsigned char* bufData, unsigned int sizeData)
|
||
{
|
||
unsigned int CRC, i;
|
||
unsigned char j;
|
||
CRC = 0;
|
||
for(i=0; i < sizeData; i++)
|
||
{
|
||
CRC ^= bufData[i];
|
||
for(j=0; j < 8; j++)
|
||
{
|
||
if(CRC & 0x0001) {CRC >>= 1; CRC ^= POLYNOMIAL;}
|
||
else CRC >>= 1;
|
||
}
|
||
}
|
||
return CRC;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
/*unsigned int GetCRC16(char* bufData, unsigned int sizeData)
|
||
{ return GetCRC16((unsigned char*)bufData, sizeData);
|
||
}*/
|
||
//---------------------------------------------------------------------------
|
||
//Äîáàâèòü íóëè ê öèôðå
|
||
int addZero(int val,int cnt)
|
||
{
|
||
for(int i=0;i<cnt;i++)
|
||
val=val*10;
|
||
return val;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
Validator::Validator()
|
||
{
|
||
Pay=0;
|
||
cPort=new ComPort();
|
||
bNominals=false;
|
||
vThread=NULL;
|
||
|
||
LoadSetup();
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
Validator::~Validator()
|
||
{
|
||
delete cPort;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Çàãðóçèòü íàñòðîéêè èç ini ôàéëà
|
||
void Validator::LoadSetup()
|
||
{
|
||
TIniFile* ini=new TIniFile(ExtractFilePath(ParamStr(0))+"\\Setup.ini");
|
||
cPort->ComNumber=ini->ReadInteger("Validator","Port",0);
|
||
cPort->BaudRate=ini->ReadInteger("Validator","BaudRate",0);
|
||
delete ini;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
void Validator::SaveSetup()
|
||
{
|
||
TIniFile* ini=new TIniFile(ExtractFilePath(ParamStr(0))+"\\Setup.ini");
|
||
ini->WriteInteger("Validator","Port",cPort->ComNumber);
|
||
ini->WriteInteger("Validator","BaudRate",cPort->BaudRate);
|
||
delete ini;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
bool Validator::startPay() //Ñòàðòóåì ïîòîê
|
||
{
|
||
if(vThread!=NULL) vThread->Stop(); //Íà âñÿê ñëó÷àé
|
||
vThread = new ValidatorThread(false);
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
bool Validator::stopPay() //Ñòîïèì ïîòîê
|
||
{
|
||
if(vThread!=NULL)
|
||
vThread->Stop();
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ñðàâíèòü ïîñëåäíèå 2 áàéòà ñ CRC äàííûõ
|
||
bool Validator::CheckOnCRC(unsigned char* lpBuffer,unsigned long nSize)
|
||
{
|
||
if(nSize<2) return false;
|
||
unsigned int CRC=GetCRC16(lpBuffer,nSize-2);
|
||
WORD* pCRC=(WORD*)&lpBuffer[nSize-2];
|
||
return (CRC==*pCRC);
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//req - Ñòðîêà çàïðîñà áåç CRC
|
||
//ans - Îòâåò íà êîìàíäó
|
||
//Ðåçóëüòàòà ñîâïàë CRC èëè íåò
|
||
bool Validator::SendCommand(std::string req, std::string &ans)
|
||
{
|
||
unsigned short crc=GetCRC16((unsigned char*)req.c_str(),req.size());
|
||
req+=((char*)(&crc))[0]; req+=((char*)(&crc))[1];
|
||
DWORD BytesWritten=cPort->Write(req.c_str(),req.size());
|
||
//×òåíèå îòâåòà
|
||
ans="";
|
||
for(int i=0;i<255;i++)
|
||
{
|
||
Sleep(10);
|
||
char ch;
|
||
DWORD BytesRead=cPort->Read(&ch,1);
|
||
if (BytesRead>0) ans+=ch; else break;
|
||
}
|
||
//Ïðîâåðêà îòâåòà íà CRC
|
||
if(ans.size()>=2)
|
||
{
|
||
crc=GetCRC16((unsigned char*)ans.c_str(),ans.size()-2);
|
||
if(crc==((unsigned short*)(&ans.c_str()[ans.size()-2]))[0]) return true;
|
||
}
|
||
return false;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Èíèöèàëèçàöèÿ ïåðåìåííûõ âàëèäàòîðà
|
||
bool Validator::Start()
|
||
{
|
||
if(cPort->Open(cPort->ComNumber))
|
||
{
|
||
cPort->BaudRate=cPort->BaudRate;
|
||
if(!cPort->Setup(2)) return false;
|
||
|
||
if(!Reset()) return false; //Ïåðåçàãðóçèòü âàëèäàòîð
|
||
if(!getSerialNumber()) return false; //Ïîëó÷èòü ñåðèéíûé íîìåð
|
||
if(!getNominals()) return false; //Ïîëó÷èòü íîìèíàëû ïðîøèòûõ êóïþð
|
||
if(!SetEnableBillTypes(true)) return false; //Ðàçðåøèòü ïðè¸ì âñåõ ïðîøèòûõ êóïþð
|
||
}else return false;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ïåðåçàãðóçèòü âàëèäàòîð (RESET 30H Command for Bill-to-Bill unit to self-reset)
|
||
bool Validator::Reset()
|
||
{
|
||
std::string req,ans;
|
||
req+=(char)0x02; req+=(char)0x03; req+=(char)0x06; req+=(char)0x30;
|
||
return SendCommand(req,ans);
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ïîëó÷èòü ñòàòóñ âàëèäàòîðà (GET STATUS 31H Request for Bill-to-Bill unit set-up status)
|
||
bool Validator::GetStatus()
|
||
{
|
||
std::string req,ans;
|
||
req+=(char)0x02; req+=(char)0x03; req+=(char)0x06; req+=(char)0x31; //req+=(char)0x41; req+=(char)0xB3;
|
||
bool r=SendCommand(req,ans);
|
||
if(r && ans.length()>6) //Ïî÷åìó òî âñåãäà áåç äàííûõ
|
||
{
|
||
//Ïåðâûå 3 áàéòà ïîêàçûâàþò êàêèå òèïû ïëàòèæåé ðàçðåøåíû
|
||
//Ñëåäóþùèå 3 áàéòà óêàçûâàþò êàêîé óðîâåíü çàùèòû óñòàíîâëåí
|
||
//Ñëåäóþùèå 3 Ïî ìîåìó êàêèå êàñåòû ãîòîâû ïðèíèìàòü äåíüãè
|
||
}
|
||
return r;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ðàçðåøèòü ëèáî çàïðåòèòü ïðè¸ì çàäàííûõ âèäîâ êóïþð
|
||
//enable - true ðàçðåøèòü âñ¸, false çàïðåòèòü âñ¸
|
||
bool Validator::SetEnableBillTypes(bool enable)
|
||
{
|
||
std::string req,ans;
|
||
if(enable)
|
||
{ req+=(char)0x02; req+=(char)0x03; req+=(char)0x0C; req+=(char)0x34;
|
||
req+=(char)0xFF; req+=(char)0xFF; req+=(char)0xFF; //24 áèòà
|
||
req+=(char)0x00; req+=(char)0x00; req+=(char)0x00; //24 áèòà
|
||
}else
|
||
{ req+=(char)0x02; req+=(char)0x03; req+=(char)0x0C; req+=(char)0x34;
|
||
req+=(char)0x00; req+=(char)0x00; req+=(char)0x00; //24 áèòà
|
||
req+=(char)0x00; req+=(char)0x00; req+=(char)0x00; //24 áèòà
|
||
}
|
||
bool r=SendCommand(req,ans);
|
||
return r;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
bool Validator::getSerialNumber()
|
||
{
|
||
DWORD BytesWritten=cPort->Write(ConIdent,sizeof(ConIdent));
|
||
DWORD BytesRead=cPort->Read(ReadAr,sizeof(ReadAr));
|
||
if(!CheckOnCRC(ReadAr,BytesRead)) return false;
|
||
//Íóæíûé ëè íàì îòâåò
|
||
if(BytesRead!=39)
|
||
{
|
||
saveLog(1,"Íå óäàëîñü ïîëó÷èòü íîìåð ïàðòèè âàëèäàòîðà");
|
||
return false;
|
||
}
|
||
//Âûáèðàåì ¹ ïàðòèè
|
||
AnsiString str1((char*)&ReadAr[3],15);
|
||
BatchNumber=str1.Trim();
|
||
|
||
AnsiString str2((char*)&ReadAr[18],12);
|
||
SerialNumber=str2.Trim();
|
||
|
||
Sleep(100);
|
||
return true;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ïîëó÷èòü íîìèíàëûû êóïþð ïðèíèìàåìûå âàëèäàòîðîì
|
||
bool Validator::getNominals()
|
||
{
|
||
bNominals=false;
|
||
Sleep(100); //íà âñÿê
|
||
DWORD BytesWritten=cPort->Write(ConGetBT,sizeof(ConGetBT));
|
||
DWORD BytesRead=cPort->Read(ReadAr,sizeof(ReadAr));
|
||
if(!CheckOnCRC(ReadAr,BytesRead)) return bNominals;
|
||
Sleep(100); //íà âñÿê
|
||
for(unsigned char i=0;i<23;i++)
|
||
{
|
||
bt[i].val=addZero(ReadAr[3+i*5],ReadAr[3+i*5+4]);
|
||
//Êîä ñòðàíû 3 áóêâû
|
||
bt[i].country[0]=ReadAr[3+i*5+1];
|
||
bt[i].country[1]=ReadAr[3+i*5+2];
|
||
bt[i].country[2]=ReadAr[3+i*5+3];
|
||
bt[i].val=addZero(ReadAr[3+i*5],ReadAr[3+i*5+4]);
|
||
}
|
||
bNominals=true;
|
||
return bNominals;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Ïîïûòêà ïðè¸ìà ïëàòåæà, âûïîëíÿåòñÿ â öèêëå â îòäåëüíîì ïîòîêå.
|
||
//state - òåêóùåå ñîñòîÿíèå âàëèäàòîðà (Ñì. äîêóìåíòàöèþ)
|
||
//ðåçóëüòàò ïðèíÿòàÿ ñóììà èëè 0 åñëè íè÷åãî íå ïðèíÿòî
|
||
int Validator::getPay(int &state)
|
||
{
|
||
state=0;
|
||
if(!cPort->bOpen){Sleep(1000); return 0;}
|
||
|
||
int result=0;
|
||
DWORD BytesWritten=0;
|
||
DWORD BytesRead=0;
|
||
|
||
BytesWritten=cPort->Write(ConReACK, sizeof(ConReACK)); //Îòâåò âàëèäàòîðó ÷òî âñ¸ íîðìàëüíî
|
||
Sleep(10);
|
||
|
||
BytesWritten=cPort->Write(ConStPoll, sizeof(ConStPoll)); //Ïåðåéòè â ðåæèì ïîëó÷åíèÿ ïëàòåæåé
|
||
BytesRead=cPort->Read(ReadAr,sizeof(ReadAr));
|
||
if(CheckOnCRC(ReadAr,BytesRead))
|
||
{
|
||
if(ReadAr[3] == 0x13) //19 Åù¸ â ðåæèìå èíèöèàëèçàöèè ïîñëå âûïîëíåíèÿ êîìàíäû RESET
|
||
{
|
||
//saveLog(1,"(State)0x13 Èíèöèàëèçàöèÿ");
|
||
}else
|
||
if(ReadAr[3]==0x14) //20 Îçíà÷àåò ÷òî íàõîäèìñÿ â ðåæèìå îæèäàíèÿ ïðè¸ìà ïëàòåæà (IDLING – The state in which Bill-to-Bill is ready accept bills)
|
||
{
|
||
//saveLog(1,"(State)0x14 Â ðåæèìå îæèäàíèÿ êóïþðû");
|
||
}else
|
||
if(ReadAr[3]==0x15) //21 Ïðîèçâîäèò ñêàíèðîâàíèå êóïþðû è îïðåäåëÿåòñÿ íàìèíàë (Ó ìåíÿ 3 ðàçà íà êóïþðó)
|
||
{
|
||
state=0x15;
|
||
//saveLog(1,"(State)21 Ïðîøëà 1 èç ïðîâåðîê");
|
||
}else
|
||
if(ReadAr[3]==0x17) //23 Ïðè¸ì êóïþðû â îòñåê åñëè íå ïîëó÷èòñÿ ïîëîæèòü òî âåðí¸ò êóïþðó îáðàòíî
|
||
{
|
||
//saveLog(1,"(State)23 Ïðè¸ì êóïþðû!");
|
||
}else
|
||
if(ReadAr[3]==0x19) //25 DISABLED – The Bill-to-Bill unit has been disabled by the Controller and also the state in which Bill-to-Bill unit is after initialization.
|
||
{
|
||
state=0x19;
|
||
//saveLog(1,"(State)25 îòìåí¸í ïðè¸ì!!!");
|
||
|
||
SetEnableBillTypes(true);
|
||
}else
|
||
if(ReadAr[3]==0x1c) //28 Èçâëå÷åíà êóïþðà
|
||
{
|
||
//saveLog(1,"(State)28 Êóïþðà èçâëå÷åíà");
|
||
}else
|
||
if(ReadAr[3]==0x41) //41H Çàïîëíèëñÿ ìåøîê ïîä çàâÿçêó...
|
||
{
|
||
//saveLog(1,"(State)0x41 Çàïîëíèëñÿ ìåøîê ïîä çàâÿçêó...");
|
||
}else
|
||
if(ReadAr[3]==0x45) //69 Îáíàðóæåíà ïîïûòêà îáìàíà "ôàëüøèâêà".
|
||
{
|
||
//saveLog(1,"(State)69 Íåçíàþ");
|
||
}else
|
||
if(ReadAr[3]==0x81) //129 Â êàêóþ êàñåòó ïîïàëà êóïþðà
|
||
{
|
||
state=0x81;
|
||
//saveLog(1,"(State)129 Ïðèíÿòà êóïþðà");
|
||
|
||
if(ReadAr[4]<23)
|
||
{
|
||
result=bt[ReadAr[4]].val; //Â êàñåòå ReadAr[5]
|
||
saveLog(1,"(Pay)"+IntToStr(result));
|
||
}
|
||
}else
|
||
saveLog(1,"(State???)"+IntToStr(ReadAr[3]));
|
||
saveLog(1,"(State???)"+IntToStr(ReadAr[3]));
|
||
}
|
||
Sleep(100);
|
||
|
||
return result;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
//Çàâåðøåíèå ðàáîòû ïî ïðè¸ìó ïëàòåæåé
|
||
void Validator::endPay()
|
||
{
|
||
SetEnableBillTypes(false);
|
||
|
||
DWORD BytesWritten,BytesRead;
|
||
BytesWritten=cPort->Write(ConReACK , sizeof(ConReACK));
|
||
|
||
BytesWritten=cPort->Write(ConStPoll , sizeof(ConStPoll));
|
||
BytesRead=cPort->Read(ReadAr,sizeof(ReadAr));
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
int Validator::GetState() //Åñëè 0 òî âñ¸ â ïîðÿäêå
|
||
{
|
||
//if(! bNominals) getNominals(); //todo íå ïîäõîäèò äëÿ ïðîâåðêè
|
||
if(! bNominals) return 1;
|
||
|
||
return 0;
|
||
}
|
||
//---------------------------------------------------------------------------
|
||
AnsiString Validator::GetStatusDescription(BYTE StatusCode) //Îïèñàíèå ñòàòóñà
|
||
{
|
||
if (StatusCode == 0x00)
|
||
return "OK";
|
||
else
|
||
if (StatusCode == 1)
|
||
return "Íå óäàëîñü ïîëó÷èòü íîìèíàëû êóïþð";
|
||
else
|
||
return "Error";
|
||
}
|
||
//---------------------------------------------------------------------------
|