Files
Tools_CPP/devices/Validators/Validator.~cpp
2024-11-01 12:23:13 +05:00

329 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//------------------------------------------------------------------------------
#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";
}
//---------------------------------------------------------------------------