#include "stdafx.h" #include "SpBase.h" #include "SpHelper.h" #include "CardIssuerFSM.h" #include "GetDevInfoHelper.h" #include "EventCode.h" #include "RVCComm.h" //oilyang@20200522 go on using // deprecated!! [4/17/2020 16:15 @Gifur] #include "CardIssuer_UserErrorCode.h" //后续替代EventCode.h,暂时混合使用,时间太紧 #include "CommDevEntityErrorCode.h" #include "CardIssuer_msg_g.h" #include "ModuleMix.h" #include "fileutil.h" #include //CSimpleStringA ambigulous //#include char tmpxx[1024]; char testIC[1024]; #include "CardIssuerClass.h" #include "mod_cardissuer.h" #include "stdafx.h" //oiltest@20200915 temp for GetTickCount #ifdef RVC_OS_WIN #define _ATL_NO_AUTOMATIC_NAMESPACE #include #include // Link to Bthprops.lib #include #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Bthprops.lib") #else #include #include #endif //RVC_OS_WIN unsigned long long GetTickCountRVC() { #ifdef RVC_OS_WIN return GetTickCount64(); #else struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); #endif //RVC_OS_WIN } #define CARDREADER_INIT_COUNT 3 #define GET_DEV_STATUS_COUNT 1//oilyang@20180104 change from 3 to 1,no need to test 3 times const int TIMER1 = 1; const int TIMER_EJECT = 2; const int INSERT_INTERVAL = 300; const int EJECT_INTERVAL = 300; const int INSERT_TRY_NUM = 200; const int READ_TRY_NUM = 1;//oiltmp const int RESET_TRY_NUM = 3; const int WAIT_TRY_NUM = 120; const int WAIT_INTERVAL = 500; const int MAX_RESET_TIMEROUT = 5000; const int MAX_RESET_TIMES_PERIOD = 0;//oiltmp configure to ini file? const int READ_TRY_INTERVAL = 300; const int INIT_TRY_NUM = 3; const int ACCEPT_TRY_INTERVAL = 500; const int ACCEPT_TRY_NUM = 110; //const int MAX_TEST_SHOW = 1024; CRITICAL_SECTION g_sciRecord; const unsigned char hextable[] = { "0123456789ABCDEF" }; void ConvAscii(unsigned char* Hex, char* Ascii, unsigned int len) { unsigned int i; for (i = 0; i < len; i++) { Ascii[2 * i] = hextable[Hex[i] >> 4]; Ascii[2 * i + 1] = hextable[Hex[i] & 0xf]; } Ascii[2 * len] = 0; } //******************************************************************************* void AsciiToHex(char* Ascii, unsigned char* Hex, int len) { int i; unsigned char ch; for (i = 0; i < len; i = i + 2) { ch = (Ascii[i] & 0xf); if (Ascii[i] > '9') ch += 9; Hex[i / 2] = ch << 4; ch = Ascii[i + 1] & 0xf; if (Ascii[i + 1] > '9') ch += 9; Hex[i / 2] += ch; } } class CCardIssuerEntity; void CCardIssuerFSM::s0_on_entry() { LOG_FUNCTION(); m_currentFSMState = 0; SetDevStateAndSendMsg(DEVICE_STATUS_NOT_READY); FSMEvent *e; //经典大机 或者卡库 //oilyang@20200426 add "Desk2S 2.1","Desk1S 1.0" if (!_strnicmp("RVC.Stand2S", m_csMachineType, strlen("RVC.Stand2S")) || !_strnicmp("RVC.CardStore", m_csMachineType, strlen("RVC.CardStore")) || !_strnicmp("RVC.CardPrinter", m_csMachineType, strlen("RVC.CardPrinter")) || (_strnicmp("RVC.Desk2S", m_csMachineType, strlen("RVC.Desk2S")) == 0 && m_majorVerion == 2 && m_minorVerion == 1) || (_strnicmp("RVC.Desk1S", m_csMachineType, strlen("RVC.Desk1S")) == 0 && m_majorVerion == 1 && m_minorVerion == 0)) { e = new FSMEvent(USER_EVT_INIT); } //如果配置了便携发卡机 else if (QueryIfCfgSCI() >= 1) { m_machineType = 2;//oiltmp e = new FSMEvent(USER_EVT_CONNECT); } //不是经典大机,又没有配置便携发卡机,转到NoCfgDev状态 else { m_machineType = 3;//oiltmp e = new FSMEvent(USER_EVT_TRANSFER_TO_NOCFGDEV); } PostEventFIFO(e); } void CCardIssuerFSM::s0_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s0_on_event(FSMEvent* pEvt) { LOG_FUNCTION(); Dbg("s0 evt %d",pEvt->iEvt); switch (pEvt->iEvt) { case USER_EVT_INIT: { InitTask* task = new InitTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } break; case USER_EVT_CONNECT: break; case USER_EVT_TRANSFER_TO_NOCFGDEV: break; case USER_EVT_QUIT: break; case USER_EVT_TEST: break; default: break; } return 0; } //Initializing void CCardIssuerFSM::s1_on_entry() { LOG_FUNCTION(); m_currentFSMState = 1; GetEntityBase()->GetFunction()->SetSysVar("CardStoreInUse", "N"); } void CCardIssuerFSM::s1_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s1_on_event(FSMEvent* event) { LOG_FUNCTION(); if (event->iEvt == USER_EVT_INITFINISHED) { event->SetHandled(); int err = event->param1; if (err == 0) { return 0; } else { return 1; } }else if (event->iEvt == USER_EVT_QUIT) { event->SetHandled(); return 0; } return 0; } //Idle void CCardIssuerFSM::s2_on_entry() { LOG_FUNCTION(); m_currentFSMState = 2; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDISSUER_IDLE); SetDevStateAndSendMsg(DEVICE_STATUS_NORMAL, false); m_resetTimes = 0; m_testResult = Error_Succeed; m_bIssuingExit = false; m_scanCount = 0; if (m_connectType == DEV_OPEN_TYPE_BLUETOOTH && 0 == m_bBTChecking) { BluetoothCheckTask* task = new BluetoothCheckTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); Dbg("post bluetooth checking thread."); } else if(m_connectType != DEV_OPEN_TYPE_BLUETOOTH && 2 == m_bBTChecking) { m_bBTChecking = 1; Dbg("cancel bluetooth checking thread."); } //bool bret = FSMSetIssueFlag(8); //Dbg("oiltest20171219 %d",bret); //oiltmp 测试便携厂商发卡 //m_pCardIssuer->SetIssuerCounter(0, 1); //m_pCardIssuer->MoveCard(CI_MOVECARD_FROM_HOPPER); //MagTracks magTracks; //magTracks.eRange = CI_TRACK_RANGE_2_3; //m_pCardIssuer->MagRead(magTracks); //Dbg("%s,%d,%d", magTracks.track[1].data, magTracks.track[1].dwSize, magTracks.track[1].eStatus); //m_pCardIssuer->MoveCard(CI_MOVECARD_FRONT_GATE); //ErrorCodeEnum err = m_pIDCard->SetCardInType(CARD_IN_TYPE_ALL); //Dbg("accept[%d]",err); //Sleep(WAIT_INTERVAL*10); //LPCardAccount* ppCardAccount; ////err = m_pIDCard->GetCardAccount(IDC_TRACK_1|IDC_TRACK_2|IDC_TRACK_3,&ppCardAccount); ////Dbg("read[%d]",err); ////Dbg("%d,%d,%d",ppCardAccount[0]->dataStatus,(ppCardAccount[1])->dataStatus,(ppCardAccount[2])->dataStatus);//,pCardAccount->data); ////Dbg("%d,%d,%d",ppCardAccount[0]->length,(ppCardAccount[1])->length,(ppCardAccount[2])->length);//,pCardAccount->data); ////Dbg("read data[%s][%s][%s]",(char*)(ppCardAccount[0]->data),(char*)(ppCardAccount[1]->data),(char*)(ppCardAccount[2]->data)); //err = m_pIDCard->DectectCardType(m_cardType); //Dbg("detectcardtyp[%d][%d]",err,m_cardType); //err = m_pIDCard->ActiveCard(); //Dbg("activecard[%d]",err); //vector vAIDs; //MessageBoxA(0,0,0,0); //if (m_cardType == CARDTYPE_CPU_T0 || m_cardType == CARDTYPE_CPU_T1) //{ // BuildSupportedAppList(vAIDs); // Dbg("[%s]",testIC); // AppSelected(m_vADFRec.at(0).name,m_vADFRec.at(0).nameLen); //} } void CCardIssuerFSM::s2_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s2_on_event(FSMEvent* pEvt) { Dbg("s2 evt(%d)",pEvt->iEvt); int ret = 0; switch (pEvt->iEvt) { case USER_EVT_ACCEPT: { CardAcceptEvent *cae = dynamic_cast(pEvt); m_bCancelAccept = false; AcceptTask* task = new AcceptTask(this); task->ctx = cae->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_ISSUE: case USER_EVT_ISSUE_EX: { IssueTask* task = new IssueTask(this); CardIssueEvent *cie = NULL; CardIssueExEvent *ciee = NULL; if (pEvt->iEvt == USER_EVT_ISSUE) { cie = dynamic_cast(pEvt); task->ctx = cie->ctx; task->ctxEx = NULL; } else { ciee = dynamic_cast(pEvt); task->ctxEx = ciee->ctx; task->ctx = NULL; } GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_EXIT: { m_captureReason = "4001"; m_bExit = true; pEvt->SetHandled(); DoExitWhenIdleTask *task = new DoExitWhenIdleTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_QUIT: pEvt->SetHandled(); break; case USER_EVT_GET_MATERIAL: { pEvt->SetHandled(); GetMaterialEvent *pGME = dynamic_cast(pEvt); pGME->ctx->Ans.captured = m_CardCaptured; pGME->ctx->Ans.remains = m_remainsEx[0]; pGME->ctx->Ans.issued = m_issuedEx[0]; pGME->ctx->Ans.mixed = m_mixedEx[0]; Dbg("to answer get material suc."); pGME->ctx->Answer(Error_Succeed); } break; case USER_EVT_SET_MATERIAL: { m_bSettingMaterial = true; pEvt->SetHandled(); bool bR, bC, bI, bM; bR = bC = bI = bM = true; SetMaterialEvent *pSME = dynamic_cast(pEvt); if (pSME->ctx->Req.bRemains) { m_CardInitEx[0] = m_remainsEx[0] = pSME->ctx->Req.remains; bR = SetCardRemains(pSME->ctx->Req.remains, 1, true); } if (pSME->ctx->Req.bCaptured) { m_CardCaptured = pSME->ctx->Req.captured; bC = SetCardCaptured(pSME->ctx->Req.captured); } if (pSME->ctx->Req.bIssued) { m_issuedEx[0] = pSME->ctx->Req.issued; bI = SetCardIssued(pSME->ctx->Req.issued, 1); } if (pSME->ctx->Req.bMixed) { m_mixedEx[0] = pSME->ctx->Req.mixed; bM = SetCardMixed(pSME->ctx->Req.mixed, 1); } if (bR && bC && bI && bM) pSME->ctx->Answer(Error_Succeed); else { Dbg("set material failed.r(%d),c(%d),i(%d),m(%d)", bR, bC, bI, bM); pSME->ctx->Answer(Error_Unexpect); } m_bSettingMaterial = false; } break; case USER_EVT_GET_MATERIAL_EX: { pEvt->SetHandled(); GetMaterialExEvent *pGMEE = dynamic_cast(pEvt); pGMEE->ctx->Ans.captured = m_CardCaptured; pGMEE->ctx->Ans.hasHopper.Init(m_hopperNum); pGMEE->ctx->Ans.CardBoxNo.Init(m_hopperNum); pGMEE->ctx->Ans.PsbCode.Init(m_hopperNum); pGMEE->ctx->Ans.PsbName.Init(m_hopperNum); pGMEE->ctx->Ans.Maintainer.Init(m_hopperNum); pGMEE->ctx->Ans.CardInit.Init(m_hopperNum); pGMEE->ctx->Ans.CardPercent.Init(m_hopperNum); pGMEE->ctx->Ans.remains.Init(m_hopperNum); pGMEE->ctx->Ans.issued.Init(m_hopperNum); pGMEE->ctx->Ans.mixed.Init(m_hopperNum); pGMEE->ctx->Ans.MaintainTime.Init(m_hopperNum); pGMEE->ctx->Ans.reserved1.Init(m_hopperNum); pGMEE->ctx->Ans.reserved2.Init(m_hopperNum); for (int i = 0; i < m_hopperNum; ++i) { pGMEE->ctx->Ans.hasHopper[i] = m_bHasHopper[i]; if (m_bHasHopper[i]) { pGMEE->ctx->Ans.CardBoxNo[i] = m_CardBoxNoEx[i]; pGMEE->ctx->Ans.PsbCode[i] = m_PsbCodeEx[i]; pGMEE->ctx->Ans.PsbName[i] = m_PsbNameEx[i]; pGMEE->ctx->Ans.Maintainer[i] = m_MaintainerEx[i]; pGMEE->ctx->Ans.CardInit[i] = m_CardInitEx[i]; pGMEE->ctx->Ans.CardPercent[i] = m_CardPercentEx[i]; pGMEE->ctx->Ans.remains[i] = m_remainsEx[i]; pGMEE->ctx->Ans.issued[i] = m_issuedEx[i]; pGMEE->ctx->Ans.mixed[i] = m_mixedEx[i]; //to be added maintain time oiltmp pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } else { pGMEE->ctx->Ans.CardBoxNo[i] = ""; pGMEE->ctx->Ans.PsbCode[i] = ""; pGMEE->ctx->Ans.PsbName[i] = ""; pGMEE->ctx->Ans.Maintainer[i] = ""; pGMEE->ctx->Ans.CardInit[i] = 0; pGMEE->ctx->Ans.CardPercent[i] = 0; pGMEE->ctx->Ans.remains[i] = 0; pGMEE->ctx->Ans.issued[i] = 0; pGMEE->ctx->Ans.mixed[i] = 0; pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } Dbg("%s,%d,%d,%d", (const char*)pGMEE->ctx->Ans.CardBoxNo[i], pGMEE->ctx->Ans.CardInit[i], pGMEE->ctx->Ans.mixed[i], pGMEE->ctx->Ans.remains[i]); } pGMEE->ctx->Ans.reserved2[0] = m_devCat.szVendor; pGMEE->ctx->Answer(Error_Succeed); } break; case USER_EVT_SET_MATERIAL_EX: { m_bSettingMaterial = true; pEvt->SetHandled(); //SetCardRemains???oiltmp CSmallDateTime currTime = CSmallDateTime::GetNow(); SetMaterialExEvent *pSMEE = dynamic_cast(pEvt); if (pSMEE->ctx->Req.SetCaptured == 1) { m_CardCaptured = pSMEE->ctx->Req.captured; m_MaintainerEx[0] = pSMEE->ctx->Req.Maintainer[0]; m_MaintainTimeEx[0] = (DWORD)currTime; SetCardCaptured(pSMEE->ctx->Req.captured,true); } Dbg("Req.SetHopper:count:%d,value:%s", pSMEE->ctx->Req.SetHopper.GetCount(), (const int*)pSMEE->ctx->Req.SetHopper); bool bMaintain[12]; memset(bMaintain, 0, 12); bool bNeedToSyncData = false; for (int i = 0; i < pSMEE->ctx->Req.SetHopper.GetCount(); ++i) { bMaintain[i] = false; if (pSMEE->ctx->Req.SetHopper[i] == 1) { Dbg("do %d",i); bMaintain[i] = true; bNeedToSyncData = true; m_CardBoxNoEx[i] = pSMEE->ctx->Req.CardBoxNo[i]; m_PsbCodeEx[i] = pSMEE->ctx->Req.PsbCode[i]; m_PsbNameEx[i] = pSMEE->ctx->Req.PsbName[i]; m_MaintainerEx[i] = pSMEE->ctx->Req.Maintainer[i]; m_CardInitEx[i] = pSMEE->ctx->Req.CardInit[i]; m_CardPercentEx[i] = pSMEE->ctx->Req.CardPercent[i]; m_remainsEx[i] = pSMEE->ctx->Req.remains[i]; m_issuedEx[i] = pSMEE->ctx->Req.issued[i]; m_mixedEx[i] = pSMEE->ctx->Req.mixed[i]; m_MaintainTimeEx[i] = (DWORD)currTime; m_csMaintainTimeEx[i] = currTime.GetNow().ToTimeString(); } } Dbg("set set result."); pSMEE->ctx->Ans.reserved1.Init(1); pSMEE->ctx->Ans.reserved2.Init(1); pSMEE->ctx->Ans.reserved1[0] = 1; pSMEE->ctx->Ans.reserved2[0] = ""; UpdateLocalRunCfg(pSMEE->ctx->Req.SetHopper); pSMEE->ctx->Answer(Error_Succeed); m_bSettingMaterial = false; if (bNeedToSyncData) { if (pSMEE->ctx->Req.SetCaptured == 1) SyncDataToDB(bMaintain); else SyncDataToDB(bMaintain, false); } } break; case USER_EVT_OPEN_SAFELOCK: { pEvt->SetHandled(); OpenSafeLockEvent *osle = dynamic_cast(pEvt); OpenSafeLockTask* task = new OpenSafeLockTask(this); task->ctx = osle->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_BLUETOOTH_DISCONNECT: pEvt->SetHandled(); ret = 0; break; case USER_EVT_QUERY_SCI_LIST: { pEvt->SetHandled(); QuerySCIListEvent *qsl = dynamic_cast(pEvt); QuerySCIListTask *pTask = new QuerySCIListTask(this); pTask->ctx = qsl->ctx; pTask->fsmState = 2; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } break; case USER_EVT_BIND_SCI: { pEvt->SetHandled(); BindSCIEvent *bsl = dynamic_cast(pEvt); BindSCITask *pTask = new BindSCITask(this); pTask->ctx = bsl->ctx; pTask->fsmState = 2; ErrorCodeEnum ec = GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); Dbg("post thread task returned: %d", ec); } break; case USER_EVT_PREONLINE: { pEvt->SetHandled(); PreOnlineEvent* poe = dynamic_cast(pEvt); if (poe->ctx->Req.reserved1.GetLength() > 0 && _strnicmp("kaku#", (const char*)poe->ctx->Req.reserved1, 5) == 0) { PreOnlineTask* task = new PreOnlineTask(this); task->ctx = poe->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); ret = 16; } break; } case USER_EVT_PREONLINE_ON_STORE: { pEvt->SetHandled(); PreOnlineOnStoreEvent *bsl = dynamic_cast(pEvt); PreOnlineOnStoreTask *pTask = new PreOnlineOnStoreTask(this); pTask->ctx = bsl->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } break; case USER_EVT_QUERYCARDINFO_ON_STORE: { pEvt->SetHandled(); QueryCardInfoOnStoreEvent* qce = dynamic_cast(pEvt); QueryCardInfoOnStoreTask* qTask = new QueryCardInfoOnStoreTask(this); qTask->ctx = qce->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(qTask); } break; default: break; } return ret; } //Accepting void CCardIssuerFSM::s3_on_entry() { LOG_FUNCTION(); m_currentFSMState = 3; } void CCardIssuerFSM::s3_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s3_on_event(FSMEvent* pEvt) { Dbg("s3 evt(%d,%d)", pEvt->iEvt, pEvt->param1); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_ACCEPTFINISHED: { pEvt->SetHandled(); switch(pEvt->param1) { case 0: case 1: case 2: case 3: case 4: ret = pEvt->param1; break; default: ret = 1; break; } } break; case USER_EVT_ACCEPT_CANCEL: m_bCancelAccept = true; m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); pEvt->SetHandled(); ret = 3; break; case USER_EVT_EXIT: m_captureReason = "4001"; m_bExit = true; pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; default: break; } return ret; } //Hold void CCardIssuerFSM::s4_on_entry() { LOG_FUNCTION(); m_currentFSMState = 4; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDISSUER_HOLD); } void CCardIssuerFSM::s4_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s4_on_event(FSMEvent* pEvt) { Dbg("s4 evt(%d,%d)",pEvt->iEvt,pEvt->param1); switch(pEvt->iEvt){ //case USER_EVT_READ: // { // CardReadEvent* cre = dynamic_cast(pEvt); // ReadTask* task = new ReadTask(this); // task->ctx = cre->ctx; // GetEntityBase()->GetFunction()->PostThreadPoolTask(task); // pEvt->SetHandled(); // return 0; // } case USER_EVT_READEX: { CardReadExEvent* cre = dynamic_cast(pEvt); ReadExTask* task = new ReadExTask(this); task->ctx = cre->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_READ_NEW: { CardReadEvent* crne = dynamic_cast(pEvt); ReadTask* task = new ReadTask(this); task->ctx = crne->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_PREONLINE: { PreOnlineEvent* poe = dynamic_cast(pEvt); PreOnlineTask* task = new PreOnlineTask(this); task->ctx = poe->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_POSTONLINE: { PostOnlineEvent* poe = dynamic_cast(pEvt); PostOnlineTask* task = new PostOnlineTask(this); task->ctx = poe->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_CAPTURE: { CardCaptureEvent *cce = dynamic_cast(pEvt); CaptureTask *task= new CaptureTask(this); task->ctx = cce->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); //oilyang@20171215 经与郭丹汪磊东宋锐讨论,目前不存在4022的情况,暂时以4019代替 //m_captureReason = "4022"; m_captureReason = "4019"; return 0; } case USER_EVT_EXIT: case USER_EVT_EJECT: case USER_EVT_ACCEPT: case USER_EVT_ACCEPT_CANCEL: { if (pEvt->iEvt == USER_EVT_ACCEPT) { Dbg("call insert card in holding state.capture it"); CardAcceptEvent *cae = dynamic_cast(pEvt); CaptureTask *task= new CaptureTask(this); task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); cae->ctx->Answer(Error_Duplication); return 0; } if ((pEvt->iEvt == USER_EVT_EXIT) && m_issueStatus) { m_captureReason = "4001"; CardCaptureEvent *cce = dynamic_cast(pEvt); CaptureTask *task= new CaptureTask(this); task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 1; } CardEjectEvent *cee; if (pEvt->iEvt == USER_EVT_EJECT) cee = dynamic_cast(pEvt); EjectTask *task= new EjectTask(this); if (pEvt->iEvt == USER_EVT_EJECT) task->ctx = cee->ctx; else task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } case USER_EVT_GET_MATERIAL: { pEvt->SetHandled(); GetMaterialEvent *pGME = dynamic_cast(pEvt); pGME->ctx->Ans.captured = m_CardCaptured; pGME->ctx->Ans.remains = m_remainsEx[0]; pGME->ctx->Ans.issued = m_issuedEx[0]; pGME->ctx->Ans.mixed = m_mixedEx[0]; pGME->ctx->Answer(Error_Succeed); } break; case USER_EVT_SET_MATERIAL: { m_bSettingMaterial = true; pEvt->SetHandled(); bool bR, bC, bI, bM; bR = bC = bI = bM = true; SetMaterialEvent *pSME = dynamic_cast(pEvt); if (pSME->ctx->Req.bRemains) { m_CardInitEx[0] = m_remainsEx[0] = pSME->ctx->Req.remains; bR = SetCardRemains(pSME->ctx->Req.remains, 1, true); } if (pSME->ctx->Req.bCaptured) { m_CardCaptured = pSME->ctx->Req.captured; bC = SetCardCaptured(pSME->ctx->Req.captured); } if (pSME->ctx->Req.bIssued) { m_issuedEx[0] = pSME->ctx->Req.issued; bI = SetCardIssued(pSME->ctx->Req.issued, 1); } if (pSME->ctx->Req.bMixed) { m_mixedEx[0] = pSME->ctx->Req.mixed; bM = SetCardMixed(pSME->ctx->Req.mixed, 1); } if (bR && bC && bI && bM) pSME->ctx->Answer(Error_Succeed); else { Dbg("set material failed.r(%d),c(%d),i(%d),m(%d)", bR, bC, bI, bM); pSME->ctx->Answer(Error_Unexpect); } m_bSettingMaterial = false; } break; case USER_EVT_GET_MATERIAL_EX: { pEvt->SetHandled(); GetMaterialExEvent *pGMEE = dynamic_cast(pEvt); pGMEE->ctx->Ans.captured = m_CardCaptured; pGMEE->ctx->Ans.hasHopper.Init(m_hopperNum); pGMEE->ctx->Ans.CardBoxNo.Init(m_hopperNum); pGMEE->ctx->Ans.PsbCode.Init(m_hopperNum); pGMEE->ctx->Ans.PsbName.Init(m_hopperNum); pGMEE->ctx->Ans.Maintainer.Init(m_hopperNum); pGMEE->ctx->Ans.CardInit.Init(m_hopperNum); pGMEE->ctx->Ans.CardPercent.Init(m_hopperNum); pGMEE->ctx->Ans.remains.Init(m_hopperNum); pGMEE->ctx->Ans.issued.Init(m_hopperNum); pGMEE->ctx->Ans.mixed.Init(m_hopperNum); pGMEE->ctx->Ans.MaintainTime.Init(m_hopperNum); pGMEE->ctx->Ans.reserved1.Init(m_hopperNum); pGMEE->ctx->Ans.reserved2.Init(m_hopperNum); for (int i = 0; i < m_hopperNum; ++i) { pGMEE->ctx->Ans.hasHopper[i] = m_bHasHopper[i]; if (m_bHasHopper[i]) { pGMEE->ctx->Ans.CardBoxNo[i] = m_CardBoxNoEx[i]; pGMEE->ctx->Ans.PsbCode[i] = m_PsbCodeEx[i]; pGMEE->ctx->Ans.PsbName[i] = m_PsbNameEx[i]; pGMEE->ctx->Ans.Maintainer[i] = m_MaintainerEx[i]; pGMEE->ctx->Ans.CardInit[i] = m_CardInitEx[i]; pGMEE->ctx->Ans.CardPercent[i] = m_CardPercentEx[i]; pGMEE->ctx->Ans.remains[i] = m_remainsEx[i]; pGMEE->ctx->Ans.issued[i] = m_issuedEx[i]; pGMEE->ctx->Ans.mixed[i] = m_mixedEx[i]; //to be added maintain time oiltmp pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } else { pGMEE->ctx->Ans.CardBoxNo[i] = ""; pGMEE->ctx->Ans.PsbCode[i] = ""; pGMEE->ctx->Ans.PsbName[i] = ""; pGMEE->ctx->Ans.Maintainer[i] = ""; pGMEE->ctx->Ans.CardInit[i] = 0; pGMEE->ctx->Ans.CardPercent[i] = 0; pGMEE->ctx->Ans.remains[i] = 0; pGMEE->ctx->Ans.issued[i] = 0; pGMEE->ctx->Ans.mixed[i] = 0; pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } } pGMEE->ctx->Ans.reserved2[0] = m_devCat.szVendor; pGMEE->ctx->Answer(Error_Succeed); } break; case USER_EVT_SET_MATERIAL_EX: { m_bSettingMaterial = true; pEvt->SetHandled(); //SetCardRemains???oiltmp CSmallDateTime currTime = CSmallDateTime::GetNow(); SetMaterialExEvent *pSMEE = dynamic_cast(pEvt); if (pSMEE->ctx->Req.SetCaptured == 1) { m_CardCaptured = pSMEE->ctx->Req.captured; m_MaintainerEx[0] = pSMEE->ctx->Req.Maintainer[0]; m_MaintainTimeEx[0] = (DWORD)currTime; SetCardCaptured(pSMEE->ctx->Req.captured,true); } Dbg("Req.SetHopper:count:%d,value:%s", pSMEE->ctx->Req.SetHopper.GetCount(), (const int*)pSMEE->ctx->Req.SetHopper); bool bMaintain[12]; memset(bMaintain, 0, 12); bool bNeedToSyncData = false; for (int i = 0; i < pSMEE->ctx->Req.SetHopper.GetCount(); ++i) { bMaintain[i] = false; if (pSMEE->ctx->Req.SetHopper[i] == 1) { bMaintain[i] = true; bNeedToSyncData = true; m_CardBoxNoEx[i] = pSMEE->ctx->Req.CardBoxNo[i]; m_PsbCodeEx[i] = pSMEE->ctx->Req.PsbCode[i]; m_PsbNameEx[i] = pSMEE->ctx->Req.PsbName[i]; m_MaintainerEx[i] = pSMEE->ctx->Req.Maintainer[i]; m_CardInitEx[i] = pSMEE->ctx->Req.CardInit[i]; m_CardPercentEx[i] = pSMEE->ctx->Req.CardPercent[i]; m_remainsEx[i] = pSMEE->ctx->Req.remains[i]; m_issuedEx[i] = pSMEE->ctx->Req.issued[i]; m_mixedEx[i] = pSMEE->ctx->Req.mixed[i]; m_MaintainTimeEx[i] = (DWORD)currTime; m_csMaintainTimeEx[i] = currTime.GetNow().ToTimeString(); } } pSMEE->ctx->Ans.reserved1.Init(1); pSMEE->ctx->Ans.reserved2.Init(1); pSMEE->ctx->Ans.reserved1[0] = 0; pSMEE->ctx->Ans.reserved2[0] = ""; UpdateLocalRunCfg(pSMEE->ctx->Req.SetHopper); pSMEE->ctx->Answer(Error_Succeed); m_bSettingMaterial = false; if (bNeedToSyncData) { if (pSMEE->ctx->Req.SetCaptured == 1) SyncDataToDB(bMaintain); else SyncDataToDB(bMaintain, false); } } break; case USER_EVT_WRITE: { CardWriteEvent* cwe = dynamic_cast(pEvt); WriteTask* task = new WriteTask(this); task->ctx = cwe->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_BLUETOOTH_DISCONNECT: pEvt->SetHandled(); break; case USER_EVT_SAM_IC: { SAMICCommandEvent* sice = dynamic_cast(pEvt); SAMICCommandTask* task = new SAMICCommandTask(this); task->ctx = sice->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_PRINT: { pEvt->SetHandled(); PrintEvent* pe = dynamic_cast(pEvt); PrintTask* task = new PrintTask(this); task->ctx = pe->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_PRINT_FINISHED: { pEvt->SetHandled(); } break; case USER_EVT_ISSUE_EX: { IssueTask* task = new IssueTask(this); CardIssueExEvent *ciee = NULL; ciee = dynamic_cast(pEvt); task->ctxEx = ciee->ctx; task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return pEvt->param1; } break; case USER_EVT_ISSUE_EX_FINISHED: pEvt->SetHandled(); return pEvt->param1; case USER_EVT_PRINT_CARD_IM: { pEvt->SetHandled(); PrintCardImEvent* pcie = dynamic_cast(pEvt); PrintCardImTask* qTask = new PrintCardImTask(this); qTask->ctx = pcie->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(qTask); } break; default: break; } return 0; } //Reading void CCardIssuerFSM::s5_on_entry() { LOG_FUNCTION(); m_currentFSMState = 5; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDISSUER_READING); } void CCardIssuerFSM::s5_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s5_on_event(FSMEvent* pEvt) { Dbg("s5 event(%d)",pEvt->iEvt); switch(pEvt->iEvt) { //case USER_EVT_READFINISHED: // { // pEvt->SetHandled(); // CardReadFinishedEvent *pCRFE = dynamic_cast(pEvt); // int err = pCRFE->param1; // Dbg("readfinish(%d)",err); // if (err == 0) // { // pCRFE->ctx->Answer(Error_Succeed); // return 0; // }else if (err == 2) // return 2; // else // return 1; // } // break; case USER_EVT_READEX_FINISHED: { pEvt->SetHandled(); CardReadExFinishedEvent *pCRFE = dynamic_cast(pEvt); int err = pCRFE->param1; Dbg("read ex finish(%d)",err); if (err == 0) { pCRFE->ctx->Answer(Error_Succeed); return 0; }else if (err == 2) return 2; else { pCRFE->ctx->Answer(Error_Unexpect); return 1; } } break; case USER_EVT_READ_NEW_FINISHED: { pEvt->SetHandled(); CardReadFinishedEvent *pCRNFE = dynamic_cast(pEvt); int err = pCRNFE->param1; Dbg("read new finish(%d)",err); if (err == 0) { pCRNFE->ctx->Answer(Error_Succeed); return 0; }else if (err == 2) { pCRNFE->ctx->Answer(Error_Unexpect); return 2; } else { pCRNFE->ctx->Answer(Error_Unexpect, AlarmDECToBusiness("Read finished,", Error_Unexpect,MEC_DEVAPI_CARDISSUER_GetDevStatus)); return 1; } } break; case USER_EVT_EXIT: { pEvt->SetHandled(); m_captureReason = "4001"; //CardEjectEvent *cee = dynamic_cast(pEvt); //EjectTask *task= new EjectTask(this); //task->ctx = NULL; //GetEntityBase()->GetFunction()->PostThreadPoolTask(task); //pEvt->SetHandled(); //return 0; } break; case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } default: break; } return 0; } //Ejecting void CCardIssuerFSM::s6_on_entry() { LOG_FUNCTION(); m_currentFSMState = 6; } void CCardIssuerFSM::s6_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s6_on_event(FSMEvent* pEvt) { Dbg("s6 evt(%d)",pEvt->iEvt); if (pEvt->iEvt == USER_EVT_EJECTFINISHED){ pEvt->SetHandled(); int err = pEvt->param1; if (err == 0) return 0; else return 1; }else if (pEvt->iEvt == USER_EVT_QUIT) { pEvt->SetHandled(); return 0; } return 0; } //Waiting fetch void CCardIssuerFSM::s7_on_entry() { LOG_FUNCTION(); m_currentFSMState = 7; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDISSUER_WAITFETCHING); WaitFetchingTask* task = new WaitFetchingTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CCardIssuerFSM::s7_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s7_on_event(FSMEvent* pEvt) { Dbg("s7 evt(%d)", pEvt->iEvt); switch (pEvt->iEvt) { case USER_EVT_WAITFINISHED: { pEvt->SetHandled(); if (pEvt->param1 == 0) { FetchCard evt; evt.status = 0; SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(FetchCard), SP_MSG_SIG_OF(FetchCard), evt); LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_OP, "CardIssuer op."); m_currCardNo = ""; Dbg("客户取走卡片msg发送"); return 0; } else if (pEvt->param1 == 1) { FetchCard evt; evt.status = 1; SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(FetchCard), SP_MSG_SIG_OF(FetchCard), evt); Dbg("取卡时设备故障"); return 1; } else { FetchCard evt; evt.status = 2; SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(FetchCard), SP_MSG_SIG_OF(FetchCard), evt); Dbg("客户未取卡超时msg发送"); m_captureReason = "4019"; LogWarn(Severity_Low, Error_NotInit, CardIssuer_UserErrorCode_Customer_Forget_Fectch_Card, "Customer forget fetch card."); CaptureTask *task = new CaptureTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 2; } } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } case USER_EVT_GET_MATERIAL: { pEvt->SetHandled(); GetMaterialEvent *pGME = dynamic_cast(pEvt); pGME->ctx->Ans.captured = m_CardCaptured; pGME->ctx->Ans.remains = m_remainsEx[0]; pGME->ctx->Ans.issued = m_issuedEx[0]; pGME->ctx->Ans.mixed = m_mixedEx[0]; pGME->ctx->Answer(Error_Succeed); } break; case USER_EVT_GET_MATERIAL_EX: { pEvt->SetHandled(); GetMaterialExEvent *pGMEE = dynamic_cast(pEvt); pGMEE->ctx->Ans.captured = m_CardCaptured; pGMEE->ctx->Ans.hasHopper.Init(m_hopperNum); pGMEE->ctx->Ans.CardBoxNo.Init(m_hopperNum); pGMEE->ctx->Ans.PsbCode.Init(m_hopperNum); pGMEE->ctx->Ans.PsbName.Init(m_hopperNum); pGMEE->ctx->Ans.Maintainer.Init(m_hopperNum); pGMEE->ctx->Ans.CardInit.Init(m_hopperNum); pGMEE->ctx->Ans.CardPercent.Init(m_hopperNum); pGMEE->ctx->Ans.remains.Init(m_hopperNum); pGMEE->ctx->Ans.issued.Init(m_hopperNum); pGMEE->ctx->Ans.mixed.Init(m_hopperNum); pGMEE->ctx->Ans.MaintainTime.Init(m_hopperNum); pGMEE->ctx->Ans.reserved1.Init(m_hopperNum); pGMEE->ctx->Ans.reserved2.Init(m_hopperNum); for (int i = 0; i < m_hopperNum; ++i) { pGMEE->ctx->Ans.hasHopper[i] = m_bHasHopper[i]; if (m_bHasHopper[i]) { pGMEE->ctx->Ans.CardBoxNo[i] = m_CardBoxNoEx[i]; pGMEE->ctx->Ans.PsbCode[i] = m_PsbCodeEx[i]; pGMEE->ctx->Ans.PsbName[i] = m_PsbNameEx[i]; pGMEE->ctx->Ans.Maintainer[i] = m_MaintainerEx[i]; pGMEE->ctx->Ans.CardInit[i] = m_CardInitEx[i]; pGMEE->ctx->Ans.CardPercent[i] = m_CardPercentEx[i]; pGMEE->ctx->Ans.remains[i] = m_remainsEx[i]; pGMEE->ctx->Ans.issued[i] = m_issuedEx[i]; pGMEE->ctx->Ans.mixed[i] = m_mixedEx[i]; //to be added maintain time oiltmp pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } else { pGMEE->ctx->Ans.CardBoxNo[i] = ""; pGMEE->ctx->Ans.PsbCode[i] = ""; pGMEE->ctx->Ans.PsbName[i] = ""; pGMEE->ctx->Ans.Maintainer[i] = ""; pGMEE->ctx->Ans.CardInit[i] = 0; pGMEE->ctx->Ans.CardPercent[i] = 0; pGMEE->ctx->Ans.remains[i] = 0; pGMEE->ctx->Ans.issued[i] = 0; pGMEE->ctx->Ans.mixed[i] = 0; pGMEE->ctx->Ans.MaintainTime[i] = ""; pGMEE->ctx->Ans.reserved1[i] = 0; pGMEE->ctx->Ans.reserved2[i] = ""; } } pGMEE->ctx->Ans.reserved2[0] = m_devCat.szVendor; pGMEE->ctx->Answer(Error_Succeed); } break; case USER_EVT_SET_MATERIAL_EX: { m_bSettingMaterial = true; pEvt->SetHandled(); //SetCardRemains???oiltmp CSmallDateTime currTime = CSmallDateTime::GetNow(); SetMaterialExEvent *pSMEE = dynamic_cast(pEvt); if (pSMEE->ctx->Req.SetCaptured == 1) { m_CardCaptured = pSMEE->ctx->Req.captured; m_MaintainerEx[0] = pSMEE->ctx->Req.Maintainer[0]; m_MaintainTimeEx[0] = (DWORD)currTime; SetCardCaptured(pSMEE->ctx->Req.captured,true); } Dbg("Req.SetHopper:count:%d,value:%s", pSMEE->ctx->Req.SetHopper.GetCount(), (const int*)pSMEE->ctx->Req.SetHopper); bool bMaintain[12]; memset(bMaintain, 0, 12); bool bNeedToSyncData = false; for (int i = 0; i < pSMEE->ctx->Req.SetHopper.GetCount(); ++i) { bMaintain[i] = false; if (pSMEE->ctx->Req.SetHopper[i] == 1) { bMaintain[i] = true; bNeedToSyncData = true; m_CardBoxNoEx[i] = pSMEE->ctx->Req.CardBoxNo[i]; m_PsbCodeEx[i] = pSMEE->ctx->Req.PsbCode[i]; m_PsbNameEx[i] = pSMEE->ctx->Req.PsbName[i]; m_MaintainerEx[i] = pSMEE->ctx->Req.Maintainer[i]; m_CardInitEx[i] = pSMEE->ctx->Req.CardInit[i]; m_CardPercentEx[i] = pSMEE->ctx->Req.CardPercent[i]; m_remainsEx[i] = pSMEE->ctx->Req.remains[i]; m_issuedEx[i] = pSMEE->ctx->Req.issued[i]; m_mixedEx[i] = pSMEE->ctx->Req.mixed[i]; m_MaintainTimeEx[i] = (DWORD)currTime; m_csMaintainTimeEx[i] = currTime.GetNow().ToTimeString(); } } pSMEE->ctx->Ans.reserved1.Init(1); pSMEE->ctx->Ans.reserved2.Init(1); pSMEE->ctx->Ans.reserved1[0] = 0; pSMEE->ctx->Ans.reserved2[0] = ""; UpdateLocalRunCfg(pSMEE->ctx->Req.SetHopper); pSMEE->ctx->Answer(Error_Succeed); m_bSettingMaterial = false; if (bNeedToSyncData) { if (pSMEE->ctx->Req.SetCaptured == 1) SyncDataToDB(bMaintain); else SyncDataToDB(bMaintain, false); } } break; default: break; } return 0; } void CCardIssuerFSM::s8_on_entry() { LOG_FUNCTION(); m_currentFSMState = 8; } void CCardIssuerFSM::s8_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s8_on_event(FSMEvent* pEvt) { Dbg("s8 evt(%d)",pEvt->iEvt); if (pEvt->iEvt == USER_EVT_CAPTUREFINISHED){ pEvt->SetHandled(); int err = pEvt->param1; if (err == 0) return 0; else return 1; }else if (pEvt->iEvt == USER_EVT_QUIT) { pEvt->SetHandled(); return 0; } return 0; } //Failed void CCardIssuerFSM::s9_on_entry() { LOG_FUNCTION(); m_currentFSMState = 9; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_FAILED); SetDevStateAndSendMsg(DEVICE_STATUS_FAULT); FSMEvent *e = new FSMEvent(USER_EVT_RESET); PostEventFIFO(e); } void CCardIssuerFSM::s9_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s9_on_event(FSMEvent* pEvt) { Dbg("s9 evt(%d)",pEvt->iEvt); switch(pEvt->iEvt) { case USER_EVT_RESET: { pEvt->SetHandled(); m_resetTimes++; if (_strnicmp("RVC.Stand2S", m_csMachineType, strlen("RVC.Stand2S")) == 0 && m_resetTimes > MAX_RESET_TIMES_PERIOD) { Dbg("restart tried %d times,give up",m_resetTimes); m_testResult = Error_InvalidState; return 0; } ResetDeviceEvent* rde = dynamic_cast(pEvt); ResetTask* task = new ResetTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } break; case USER_EVT_RESETFINISHED: { ResetFinishedEvent *rfe = dynamic_cast(pEvt); Dbg("err,reset result %d",rfe->param1); if (rfe->param1 == 0) return 0; else { m_testResult = Error_InvalidState; return 1; } } case USER_EVT_QUIT: pEvt->SetHandled(); return 0; case USER_EVT_ACCEPT_CANCEL: m_bCancelAccept = true; pEvt->SetHandled(); break; case USER_EVT_BLUETOOTH_DISCONNECT: pEvt->SetHandled(); return 0; break; default: break; } return 0; } //Issuing void CCardIssuerFSM::s10_on_entry() { LOG_FUNCTION(); m_currentFSMState = 10; } void CCardIssuerFSM::s10_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s10_on_event(FSMEvent* pEvt) { Dbg("s10 evt(%d,%d)", pEvt->iEvt, pEvt->param1); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_ISSUE_FINISHED: pEvt->SetHandled(); ret = pEvt->param1; break; case USER_EVT_ISSUE_EX_FINISHED: pEvt->SetHandled(); ret = pEvt->param1; break; case USER_EVT_EXIT: pEvt->SetHandled(); m_captureReason = "4001"; m_bIssuingExit = true; break; case USER_EVT_ACCEPT_CANCEL: pEvt->SetHandled(); m_bForHangzhouSongruiMenjinka = true; break; default: break; } return ret; } //Writing void CCardIssuerFSM::s11_on_entry() { LOG_FUNCTION(); m_currentFSMState = 11; } void CCardIssuerFSM::s11_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s11_on_event(FSMEvent* pEvt) { Dbg("s11(writing) evt(%d)",pEvt->iEvt); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_WRITE_FINISHED: pEvt->SetHandled(); ret = pEvt->param1; break; case USER_EVT_EXIT: pEvt->SetHandled(); m_captureReason = "4001"; m_bIssuingExit = true; break; default: break; } return ret; } //Connecting void CCardIssuerFSM::s12_on_entry() { LOG_FUNCTION(); m_currentFSMState = 12; SetDevStateAndSendMsg(DEVICE_STATUS_CONNECTING, false); if (!m_bBTConnected && !m_bBTConncting) { ConnectTask *task = new ConnectTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } else { Dbg("do nothing to connect sci: btconnected: %d, btconnecting: %d", m_bBTConnected, m_bBTConncting); } } void CCardIssuerFSM::s12_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s12_on_event(FSMEvent* pEvt) { int ret = 0; switch (pEvt->iEvt) { case USER_EVT_CONNECT_FINISHED: { pEvt->SetHandled(); if (QueryIfCfgSCI() == 0)//if remove bind relation { FSMEvent *e = new FSMEvent(USER_EVT_BACK_TO_INIT); PostEventFIFO(e); ret = 2; } else { if (pEvt->param1 != 0) { m_scanCount++; if (m_scanCount > 4) { SetDevStateAndSendMsg(DEVICE_STATUS_CONNECTING); m_scanCount = 0; } PeirodConnectTask *task = new PeirodConnectTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); ret = 1; } } } break; case USER_EVT_QUERY_SCI_LIST: { pEvt->SetHandled(); QuerySCIListEvent *qsl = dynamic_cast(pEvt); QuerySCIListTask *pTask = new QuerySCIListTask(this); pTask->ctx = qsl->ctx; pTask->fsmState = 12; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } break; case USER_EVT_BIND_SCI: { pEvt->SetHandled(); BindSCIEvent *bsl = dynamic_cast(pEvt); BindSCITask *pTask = new BindSCITask(this); pTask->ctx = bsl->ctx; pTask->fsmState = 12; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } case USER_EVT_BACK_TO_INIT: pEvt->SetHandled(); break; default: break; } return ret; } //NoCfgDev void CCardIssuerFSM::s13_on_entry() { LOG_FUNCTION(); m_currentFSMState = 13; SetDevStateAndSendMsg(DEVICE_STATUS_NOCFG); } void CCardIssuerFSM::s13_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s13_on_event(FSMEvent* pEvt) { int ret = 0; switch (pEvt->iEvt) { case USER_EVT_CONNECT: { m_scanCount = 0; PeirodConnectTask *task = new PeirodConnectTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_QUERY_SCI_LIST: { pEvt->SetHandled(); QuerySCIListEvent *qsl = dynamic_cast(pEvt); QuerySCIListTask *pTask = new QuerySCIListTask(this); pTask->ctx = qsl->ctx; pTask->fsmState = 13; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } break; case USER_EVT_BIND_SCI: { pEvt->SetHandled(); BindSCIEvent *bsl = dynamic_cast(pEvt); BindSCITask *pTask = new BindSCITask(this); pTask->ctx = bsl->ctx; pTask->fsmState = 13; ErrorCodeEnum ec = GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); Dbg("post thread task returned: %d", ec); } break; case USER_EVT_PREONLINE_ON_STORE: { pEvt->SetHandled(); PreOnlineOnStoreEvent *bsl = dynamic_cast(pEvt); PreOnlineOnStoreTask *pTask = new PreOnlineOnStoreTask(this); pTask->ctx = bsl->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } break; default: break; } return ret; } //SAMIC void CCardIssuerFSM::s14_on_entry() { LOG_FUNCTION(); m_currentFSMState = 14; } void CCardIssuerFSM::s14_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s14_on_event(FSMEvent* pEvt) { Dbg("s14(SAMIC) evt:%d",pEvt->param1); int ret = 0; switch (pEvt->iEvt) { case USER_EVT_SAM_IC_FINISHED: pEvt->SetHandled(); break; default: break; } return ret; } //Other void CCardIssuerFSM::s15_on_entry() { m_currentFSMState = 15; } void CCardIssuerFSM::s15_on_exit() { } unsigned int CCardIssuerFSM::s15_on_event(FSMEvent* pEvt) { Dbg("s15 %d,%d",pEvt->iEvt,pEvt->param1); switch (pEvt->iEvt) { case USER_EVT_QUERY_SCI_LIST_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; case USER_EVT_BIND_SCI_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; default: break; } return 0; } //PreOnlineOnStore void CCardIssuerFSM::s16_on_entry() { m_currentFSMState = 16; } void CCardIssuerFSM::s16_on_exit() { } unsigned int CCardIssuerFSM::s16_on_event(FSMEvent* pEvt) { Dbg("s16 %d,%d", pEvt->iEvt, pEvt->param1); switch (pEvt->iEvt) { case USER_EVT_PREONLINE_ON_STORE_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; default: break; } return 0; } void CCardIssuerFSM::s17_on_entry() { LOG_FUNCTION(); m_currentFSMState = 17; } void CCardIssuerFSM::s17_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s17_on_event(FSMEvent* pEvt) { Dbg("s17 evt(%d)", pEvt->iEvt); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_QUERYCARDINFO_ON_STORE_FINISHED: pEvt->SetHandled(); ret = pEvt->param1; break; default: break; } return ret; } //PrintCardIm void CCardIssuerFSM::s18_on_entry() { LOG_FUNCTION(); m_currentFSMState = 18; } void CCardIssuerFSM::s18_on_exit() { LOG_FUNCTION(); } unsigned int CCardIssuerFSM::s18_on_event(FSMEvent* pEvt) { Dbg("s18 evt(%d)", pEvt->iEvt); int ret = 0; switch (pEvt->iEvt) { case USER_EVT_PRINT_CARD_IM_FINISHED: pEvt->SetHandled(); break; default: break; } return ret; } ErrorCodeEnum CCardIssuerFSM::OnInit() { LOG_FUNCTION(); GET_DEV_ENTITY_BASE_POINTER()->InitializeVendorLogSwitch(); #ifdef TWINKLE_LOCAL_DEBUG LOG_CARDISSUER_ERROR_MSG_MACRO(Error_Unexpect, QuerySlotsStatus); #endif //MessageBoxA(0, 0, 0, 0); m_pCardProcess = new CCardProcess(); if (m_pCardProcess == NULL)//almost no use... { Dbg("create card process failed."); return Error_Resource; } Load(); CSystemStaticInfo sysInfo; //oilyang 20160331 //so many function always return Error_Succeed,so is useless to process it. m_csMachineType = m_csSite = m_terminalNo = ""; GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo); m_csMachineType = sysInfo.strMachineType; m_csSite = sysInfo.strSite; m_terminalNo = sysInfo.strTerminalID; m_majorVerion = sysInfo.MachineVersion.GetMajor(); m_minorVerion = sysInfo.MachineVersion.GetMinor(); Dbg("machineType:%s,site:%s,terminalNo:%s,machineVersion:%d.%d", (const char*)m_csMachineType, (const char*)m_csSite , (const char*)m_terminalNo, m_majorVerion, m_minorVerion); m_devStatus.eMedia = CI_MEDIA_NOTPRESENT; m_bHasHopper[0] = false; m_bHasHopper[1] = false; m_bHasHopper[2] = false; InitializeCriticalSectionAndSpinCount(&g_sciRecord, 100); return Error_Succeed; } ErrorCodeEnum CCardIssuerFSM::OnExit() { LOG_FUNCTION(); ErrorCodeEnum eExit; if (m_pCardIssuer != NULL) { eExit = m_pCardIssuer->GetDevStatus(m_devStatus); if (eExit == Error_Succeed) { if (m_devStatus.eMedia == CI_MEDIA_PRESENT){ if (m_issueStatus) { eExit = MachineMoveCardBackNotHold(); m_CardCaptured++; SetCardCaptured(m_CardCaptured); Dbg("entity quit to capture card(%d).",eExit); } else { eExit = MachineMoveCardFrontGate(); if (eExit != Error_Succeed) AlarmDEC("OnExit::MachineMoveCardFrontGate", eExit, CardIssuer_UserErrorCode_MoveCardToGate_Failed); Dbg("entity quit to eject card(%d).",eExit); } } } eExit = m_pCardIssuer->DevClose(); if (eExit == Error_Succeed) Dbg("读卡器关闭成功"); else Dbg("读卡器关闭失败(%d)",eExit); } FSMImpl::OnExit(); return Error_Succeed; } void TestShowRecvData(PBYTE hexBuf,DWORD len) { char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(hexBuf,&show,len); delete[] show; } int FindHexCharPosition(LPBYTE data, BYTE hexChar, int len) { int notExist = -1,ret = 1,pos = 0; for (; pos < len; ++pos) { BYTE high = (*(data+pos))&0xf0; BYTE low = (*(data+pos))&0x0f; if ((high>>4) != hexChar) ret++; else return ret; if (low != hexChar) ret++; else return ret; } ret = notExist; return ret; } bool CCardIssuerFSM::GetDevStatus() { //LOG_FUNCTION(); int getDevInfoCount = 0; static unsigned int lightStatus = 0; ErrorCodeEnum err; do{ err = m_pCardIssuer->GetDevStatus(m_devStatus); if (Error_Succeed == err) { Dbg("GetDevStatus::eMedia: %d", m_devStatus.eMedia); if (_strnicmp("RVC.CardPrinter", m_csMachineType, strlen("RVC.CardPrinter")) == 0) Dbg("kaku tape(flat%d,concave:%d,gold:%d,silver:%d", m_devStatus.eKakuTape[0] , m_devStatus.eKakuTape[1], m_devStatus.eKakuTape[2], m_devStatus.eKakuTape[3]); if(m_devStatus.eMedia == CI_MEDIA_ENTERING) { } return true; } else { //LogWarn(Severity_Low, Error_Unexpect, CardIssuer_UserErrorCode_GetDevStatus_Failed, // "GetDevStatus获取设备状态失败"); //DevErrorInfo devErrInfo; //m_pCardIssuer->GetLastErr(devErrInfo); //Dbg("GetDevStatus:[%s]",devErrInfo.szErrMsg); AlarmDEC("GetDevStatus::GetDevStatus", err, MEC_DEVAPI_CARDISSUER_GetDevStatus); getDevInfoCount++; Sleep(3000); } } while (getDevInfoCount < GET_DEV_STATUS_COUNT); //Dbg("getdevstatus to reset"); //err = m_pCardIssuer->Reset(); //Sleep(MAX_RESET_TIMEROUT); //if (err == Error_Succeed) //{ // err = m_pCardIssuer->GetDevStatus(devStatus); // if (err == Error_Succeed) // return true; //} return false; } int CCardIssuerFSM::Reset() { LOG_FUNCTION(); if (m_pCardIssuer == NULL) { Dbg("Maybe the m_pCardIssuer have been released,switch to s0 to restart."); return 2; } ErrorCodeEnum ec = m_pCardIssuer->Reset(); if (ec == Error_Succeed) { //if (Error_Succeed == m_pCardIssuer->GetDevStatus(m_devStatus)) if(GetDevStatus()) { Dbg("media pos:%d", m_devStatus.eMedia); if (m_devStatus.eMedia == CI_MEDIA_PRESENT || m_devStatus.eMedia == CI_MEDIA_ENTERING) { ErrorCodeEnum eMoveErr; if (m_issueStatus) { //oiltmp to add 20131212 eMoveErr = MachineMoveCardBackNotHold(); Dbg("fsm reset capture card."); m_CardCaptured++; if (!SetCardCaptured(m_CardCaptured)) Dbg("set card captured failed."); } else { //oiltmp to add 20131212 eMoveErr = MachineMoveCardFrontGate(); } if (eMoveErr == Error_Succeed) { return 0; } else { AlarmDEC("Reset::MachineMoveCardFrontGate", eMoveErr, CardIssuer_UserErrorCode_MoveCardToGate_Failed); Dbg("after reset,move front failed(%d).",eMoveErr); } } else if (m_devStatus.eMedia == CI_MEDIA_NOTPRESENT) { return 0; } else { Dbg("media position %d",m_devStatus.eMedia); return 1; } } else { return 1; } } else { AlarmDEC("Reset:", ec, MEC_DEVAPI_CARDISSUER_Reset); return 1; } return 0; } bool isnostr(const char *str) { int len = strlen(str); if (len == 0) return true; for (int i = 0; i < len; ++i) { if (*(str+i) != ' ') return false; } return true; } bool CCardIssuerFSM::LoadCMBPrint(CSimpleStringA csBinPath) { if (cmdDecodeEx == NULL) { CSimpleStringA csCMBPrint(""); #ifdef RVC_OS_LINUX csCMBPrint = "CMBPrint.so"; csCMBPrint = csBinPath + "/" + csCMBPrint; Dbg("cmbpath %s", (const char*)csCMBPrint); void* hr = NULL; hr = dlopen(csCMBPrint, RTLD_LAZY); if (hr == NULL) { Dbg("Load CMBPrint failed(%s).", dlerror()); return false; } //pfunc_unpack = (PF_unpack)dlsym(hLib, "_Z6unpackPcS_i"); if ((cmdDecodeMag2 = (lpCMBdecodeMag2)dlsym(hr, "CMBdecodeMag2")) == NULL) { Dbg("Get Mag2 address failed."); return false; } if ((cmdDecodeEx = (lpCMBdecodeEx)dlsym(hr, "CMBdecodeEx")) == NULL) { Dbg("Get Mag23Ex address failed."); cmdDecodeMag2 = NULL; return false; } #else csCMBPrint = "CMBPrint.dll"; csCMBPrint = csBinPath + SPLIT_SLASH_STR + csCMBPrint; Dbg("cmbpath %s", (const char*)csCMBPrint); HMODULE hr = LoadLibraryA(csCMBPrint); if (hr == NULL) { Dbg("Load CMBPrint failed(%d).", hr); return false; } if ((cmdDecodeMag2 = (lpCMBdecodeMag2)GetProcAddress(hr, "CMBdecodeMag2")) == NULL) { Dbg("Get Mag2 address failed."); return false; } if ((cmdDecodeEx = (lpCMBdecodeEx)GetProcAddress(hr, "CMBdecodeEx")) == NULL) { Dbg("Get Mag23Ex address failed."); cmdDecodeMag2 = NULL; return false; } #endif Dbg("Load %s suc.", (const char*)csCMBPrint); } return true; } ErrorCodeEnum CCardIssuerFSM::OpenDevice(BYTE btOpenType, const char *pDevSN) { LOG_FUNCTION(); m_devOpenFailedCount++; ErrorCodeEnum eErrDev; //HRESULT hr; int initTries = 0; CSimpleStringA dllName; GetVendorDllName(dllName); Dbg("to load:%s",(const char*)dllName); #ifdef RVC_OS_WIN // [9/29/2019 14:13 @Gifur] CloseAndClearDevObj(false); m_hVerdorDll = LoadLibraryA(dllName); Dbg("load vendor dll %s", (const char*)dllName); if (m_hVerdorDll == NULL) { Dbg("Load dll failed.%d", GetLastError()); GetEntityBase()->GetFunction()->ShowFatalError("加载厂商适配器失败!请检查root.ini配置是否正确。"); return Error_DevLoadFileFailed; } if ((CreateDevComponent = (lpCreateDevCom)GetProcAddress(m_hVerdorDll, "CreateDevComponent")) == NULL) { Dbg("Get CreateDevComponent failed."); return Error_DevLoadFileFailed; } if ((ReleaseDevComponent = (lpReleaseDevCom)GetProcAddress(m_hVerdorDll, "ReleaseDevComponent")) == NULL) { Dbg("Get ReleaseDevComponent failed."); return Error_DevLoadFileFailed; } Dbg("Get vendor function suc."); #else Dbg("To test CardIssuer"); m_hVerdorDll = dlopen(dllName, RTLD_LAZY); if (m_hVerdorDll == NULL) { Dbg("load failed:%s,%s",(const char*)dllName,dlerror()); return Error_DevLoadFileFailed; } CreateDevComponent = (lpCreateDevCom)dlsym(m_hVerdorDll, "CreateDevComponent"); if (CreateDevComponent == NULL) { Dbg("load CreateDevCom failed:"); return Error_DevLoadFileFailed; } ReleaseDevComponent = (lpReleaseDevCom)dlsym(m_hVerdorDll, "ReleaseDevComponent"); if (ReleaseDevComponent == NULL) { Dbg("load ReleaseDevComponent failed:"); return Error_DevLoadFileFailed; } Dbg("Get vendor function suc."); #endif CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; CSimpleStringA csBinPath, csBackslash("\\"); ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Bin", csBinPath); if (eErrPath != Error_Succeed) { Dbg("GetBasePath failed (%d).", eErrPath); return Error_Param; } for (int i = 0; i < HOPPER_NUM; ++i) { m_CardBoxNoEx[i] = ""; m_PsbCodeEx[i] = ""; m_PsbNameEx[i] = ""; m_MaintainerEx[i] = ""; m_CardInitEx[i] = 0; m_CardPercentEx[i] = 0; m_remainsEx[i] = 0; m_issuedEx[i] = 0; m_mixedEx[i] = 0; m_csMaintainTimeEx[i] = ""; m_MaintainTimeEx[i] = 0; } m_pCardIssuer = NULL; do{ if (m_pCardIssuer == NULL) { if ((eErrDev = CreateDevComponent((DeviceBaseClass*&)m_pCardIssuer)) != Error_Succeed) { AlarmDEC("OpenDevice:CreateDevComponent", eErrDev, MEC_DEV_OBJECT_CREATE_FAILED); initTries++; m_pCardIssuer = NULL; continue; } else Dbg("CreateDevComponent suc."); } if(m_bUnbindType3) { Dbg("Detect unbind type is true, return previously"); return Error_Cancel; } Dbg("Start to invoke DevOpenEx func with %d, %d, %s...", m_port, m_baudRate, pDevSN); eErrDev = m_pCardIssuer->DevOpenEx(m_port, m_baudRate, btOpenType, pDevSN, m_connectType); Dbg("DevOpenEx returned hr[%d], %d, connectType[%d]", eErrDev, btOpenType, m_connectType); if (eErrDev == Error_Succeed) { m_bOpened = true; m_devOpenFailedCount = 0; LOG_TRACE("读卡器打开成功"); //DevCategoryInfo devCat; ZeroMemory(m_devCat.szModel, sizeof(m_devCat.szModel)); ZeroMemory(m_devCat.szType, sizeof(m_devCat.szType)); ZeroMemory(m_devCat.szVendor, sizeof(m_devCat.szVendor)); eErrDev = m_pCardIssuer->GetDevCategory(m_devCat); if (eErrDev == Error_Succeed) { Dbg("szVendor:%s", m_devCat.szVendor); Dbg("szType:%s", m_devCat.szType); Dbg("szModel:%s", m_devCat.szModel); Dbg("version:%d.%d.%d.%d", m_devCat.version.wMajor, m_devCat.version.wMinor, m_devCat.version.wRevision, m_devCat.version.wBuild); int ret = SplitDevModelInfo(); Dbg("SplitDevModelInfo ret:%d",ret); } else { AlarmDEC("GetDevCategory:",eErrDev, MEC_DEVAPI_CARDISSUER_GetDevCategory); //LogWarn(Severity_Low, Error_Unexpect, CardIssuer_UserErrorCode_GetDevCategory_Failed, "获取设备信息失败"); //Dbg("GetDevCategory failed.%d",eErrDev); //LogDevErrorInfo(); return Error_Unexpect; } if (m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) { eErrDev = m_pCardIssuer->GetSlotSum(m_maxSlot); if (m_maxSlot < 0) { Dbg("Get slot num failed.%d,%d",eErrDev,m_maxSlot); m_maxSlot = 0; } Dbg("max slot num:%d",m_maxSlot); } else { char *pDevSN = new char[128]; ZeroMemory(pDevSN, 128); ErrorCodeEnum eErr; eErr = m_pCardIssuer->GetDeviceSN(pDevSN); if (eErr == Error_Succeed) { //m_csDevSN only for SCI/CIA (bluetooth) if (IsValidSCIName(pDevSN, strlen(pDevSN)) > 0) m_csDevSN = pDevSN; Dbg("GetDeviceSN:%s", pDevSN); if (pDevSN != NULL) delete[]pDevSN; } else { AlarmDEC("获取设备唯一号失败", eErr, MEC_DEVAPI_CARDISSUER_GetDeviceSN); //LogWarn(Severity_Low, Error_Unexpect, CardIssuer_UserErrorCode_GetDeviceSN_Failed, "获取设备唯一号失败"); //Dbg("GetDeviceSN failed.%d", eErr); if (pDevSN != NULL) { delete[]pDevSN; } return Error_Unexpect; } } if (!LoadCMBPrint(csBinPath)) { Dbg("load CMBPrint failed."); AlarmDEC("OpenDevice::DevOpenEx", Error_DevLoadFileFailed, CardIssuer_UserErrorCode_Load_CMBPrint_Failed); return Error_DevLoadFileFailed; } initTries = 0; break; } else { //LogDevErrorInfo(); AlarmDEC("OpenDevice::DevOpenEx", eErrDev, MEC_DEVAPI_CARDISSUER_DevOpenEx); initTries++; } }while(initTries < INIT_TRY_NUM); Dbg("inittries[%d]",initTries); if (initTries != 0) { return Error_DevCommFailed; } else { LoadCMBBin();//load cmb bin for detect card type info eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("open run cfg file failed!"); CloseAndClearDevObj(false); return eErrDev; } int ret = 0,isIssue = 99; spConfig->ReadConfigValueInt("all", "IsIssue", isIssue); spConfig->ReadConfigValueInt("all", "HopperNum", m_hopperNum); spConfig->ReadConfigValueInt("all", "CardCaptured", m_CardCaptured); //Dbg("IssueFlag:%d,HopperNum:%d,CardCaptured:%d",isIssue,m_hopperNum,m_CardCaptured); //if (m_hopperNum == 0) { if (btOpenType == DEV_OPEN_TYPE_COM) { //oiltest@20201118 for songrui if (m_csMachineType.Compare("RVC.CardPrinter") == 0) m_hopperNum = 5; else { if (m_connectType >= 1 && m_connectType <= 3) m_hopperNum = m_connectType; else { //oiltmp if "RVC.CardPrinter" the m_hopperNum is 6,where can this num come from? if (m_csMachineType.Compare("RVC.CardPrinter") == 0) m_hopperNum = 5; else m_hopperNum = 3; } } for (int i = 0; i < m_hopperNum; ++i) m_bHasHopper[i] = true; } else { if(IsValidSCIName(pDevSN, strlen(pDevSN)) == 2) { m_hopperNum = 1; m_bHasHopper[0] = true; } else { //oiltmp 便携发卡目前都为2个 m_hopperNum = 2; m_bHasHopper[0] = true; m_bHasHopper[1] = true; } } } char sec[2]; for (int i = 0; i < m_hopperNum; ++i) { ZeroMemory(sec, 2); _itoa(i + 1, (char*)sec, 10); Dbg("sec:%s",sec); spConfig->ReadConfigValue(sec, "CardBoxNo", m_CardBoxNoEx[i]); spConfig->ReadConfigValue(sec, "PsbCode", m_PsbCodeEx[i]); spConfig->ReadConfigValue(sec, "PsbName", m_PsbNameEx[i]); spConfig->ReadConfigValueInt(sec, "CardInit", m_CardInitEx[i]); spConfig->ReadConfigValueInt(sec, "CardRemains", m_remainsEx[i]); spConfig->ReadConfigValueInt(sec, "CardIssued", m_issuedEx[i]); spConfig->ReadConfigValueInt(sec, "CardMixed", m_mixedEx[i]); spConfig->ReadConfigValueInt(sec, "CardPercent", m_CardPercentEx[i]); spConfig->ReadConfigValue(sec, "Maintainer", m_MaintainerEx[i]); spConfig->ReadConfigValue(sec, "MaintainTime", m_csMaintainTimeEx[i]); } if (m_hopperNum == 1 && btOpenType == DEV_OPEN_TYPE_COM)//oilyang 如果没有配置,使用原来的配置 { Dbg("use old record."); spConfig->ReadConfigValueInt("RunInfo", "CardRemains", m_remainsEx[0]); spConfig->ReadConfigValueInt("RunInfo", "CardIssued", m_issuedEx[0]); spConfig->ReadConfigValueInt("RunInfo", "CardCaptured", m_CardCaptured); spConfig->ReadConfigValueInt("RunInfo", "IsIssue", isIssue); spConfig->ReadConfigValueInt("RunInfo", "CardMixed", m_mixedEx[0]); spConfig->ReadConfigValueInt("RunInfo", "CardInit", m_CardInitEx[0]); spConfig->ReadConfigValueInt("RunInfo", "CardPercent", m_CardPercentEx[0]); } //oilyang 回写卡机配置 spConfig->WriteConfigValueInt("all", "IsIssue", isIssue); spConfig->WriteConfigValueInt("all", "HopperNum", m_hopperNum); spConfig->WriteConfigValueInt("1", "CardPercent", m_CardPercentEx[0]); spEntityFunction->OpenConfig(Config_CenterSetting, spConfig); { int tmpValue = 0; //oilyang 20160520 //no need now according to Song Rui & xkm m_bCaptureCfgFlag = true; spConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "ScanSlot", tmpValue); if (tmpValue > 0 && tmpValue <= 60) { Dbg("ScanSlot:%d", m_scanSlot); m_scanSlot = tmpValue; } } { if (btOpenType != DEV_OPEN_TYPE_COM) { int rt = -1; //oilyang@20201126 comment the following line for nantian sci //if (m_csCM.GetLength() > 3 && _strnicmp(m_csCM, "V2.0", strlen("V2.0")) == 0) { rt = DataTransferInitEx(); } Dbg("DataTransferInit(Ex) rt:%d", rt); if (rt == 0) { Dbg("安全通道建立成功。"); m_bChannelOK = true; } else { Dbg("安全通道建立失败。"); return Error_Unexpect; } } LoadSafeLockDll(); Dbg("in %d cycle",isIssue); m_issueStatusFromFile = m_issueStatus = isIssue; ret = UnAcceptCard(); } if (ret == 0) { if (m_hasCardWhileDevOpen && m_issueStatusFromFile > 0) { //oilyang@20171220 遗留卡片已经被吞,重置数据 Dbg("left card have been processed,to reset data."); m_issueStatusFromFile = 0; m_currCardNo = m_addCardNo = ""; FSMSetIssueFlag(0); } if (m_connectType == DEV_OPEN_TYPE_BLUETOOTH) { m_bBTConnected = true; } //oilyang@20191219 获取吞卡箱容量,目前有便携卡机,大机 //超过5,认为是脏数据,用默认值3 CardIssuerStatus cis; if ((eErrDev = m_pCardIssuer->GetDevStatus(cis)) != Error_Succeed) { AlarmDEC("GetDevStatus(OpenDevice)", eErrDev, MEC_DEVAPI_CARDISSUER_GetDevStatus); } else { Dbg("max retain count:%d",cis.dwRetainCount); if (cis.dwRetainCount > 0 && cis.dwRetainCount <= 5) m_maxRetainCount = cis.dwRetainCount; else m_maxRetainCount = 3; if (cis.eRetainBin == CI_RETAINBIN_FULL) { Dbg("(sensor)retain bin is full!回收箱满了,请及时清理!"); LogWarn(Severity_Middle, Error_Unexpect, LOG_ERR_CARDISSUER_RETAIN_BIN_IS_FULL_SENSOR, "(sensor)retain bin is full!回收箱满了,请及时清理!"); } } return Error_Succeed; } else { return Error_Unexpect; } } } void CCardIssuerFSM::LoadCMBBin() { CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Software, spConfig); if (eErrDev != Error_Succeed) { Dbg("open module cfg file failed!"); return; } int dmCount,diCount,cmCount,ciCount; dmCount=diCount=cmCount=ciCount=0; spConfig->ReadConfigValueInt("CMBDebitMag","count",dmCount); spConfig->ReadConfigValueInt("CMBDebitIC","count",diCount); spConfig->ReadConfigValueInt("CMBCreditMag","count",cmCount); spConfig->ReadConfigValueInt("CMBCreditIC","count",ciCount); for (int i = 1; i <= dmCount; ++i) { CMBBin bin; char tmp[64] = {0}; _itoa(i,tmp,10); spConfig->ReadConfigValue("CMBDebitMag",tmp,bin.bin); bin.bDC = true; bin.bIC = false; m_vBin.push_back(bin); } for (int i = 1; i <= diCount; ++i) { CMBBin bin; char tmp[64] = {0}; _itoa(i,tmp,10); spConfig->ReadConfigValue("CMBDebitIC",tmp,bin.bin); bin.bDC = true; bin.bIC = true; m_vBin.push_back(bin); } for (int i = 1; i <= cmCount; ++i) { CMBBin bin; char tmp[64] = {0}; _itoa(i,tmp,10); spConfig->ReadConfigValue("CMBCreditMag",tmp,bin.bin); bin.bDC = false; bin.bIC = false; m_vBin.push_back(bin); } for (int i = 1; i <= ciCount; ++i) { CMBBin bin; char tmp[64] = {0}; _itoa(i,tmp,10); spConfig->ReadConfigValue("CMBCreditIC",tmp,bin.bin); bin.bDC = false; bin.bIC = true; m_vBin.push_back(bin); } } void CCardIssuerFSM::Load() { LOG_FUNCTION(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfig); if (spConfig == NULL) { Dbg("open root.ini failed."); return; } int smflag, onlineOnly; CSimpleStringA csVendor(""); spConfig->ReadConfigValueInt("Device.CardIssuer", "Baudrate", m_baudRate); spConfig->ReadConfigValueInt("Device.CardIssuer", "Port", m_port); spConfig->ReadConfigValue("Device.CardIssuer", "Vendor", csVendor); HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, csVendor); //oiltmp 20161116 余下两项有必要迁移到运行时配置? spConfig->ReadConfigValueInt("Device.Utility", "SMSupport", smflag); spConfig->ReadConfigValueInt("Device.Utility", "OnlineOnly", onlineOnly); m_bSM = smflag; //oiltmp 20160506 no offline business now //m_bOnlineOnly = onlineOnly; m_bOnlineOnly = true; m_csDevSN = ""; //for data migrate after dynamic bind SCI CSmartPointer spConfigRun; eErrDev = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (eErrDev != Error_Succeed) { Dbg("(set sci name)open cfg file failed!"); } else { CSimpleStringA tmpNameRun(""), tmpNameRoot(""), tmpVendor(""); spConfigRun->ReadConfigValue("SCI", "name", tmpNameRun); spConfig->ReadConfigValue("Terminal", "DevSN", tmpNameRoot); Dbg("runcfg:%s,root.ini:%s", (const char*)tmpNameRun, (const char*)tmpNameRoot); spConfigRun->ReadConfigValue("SCI", "Vendor", tmpVendor); // 如果运行时没有厂商名称,则将Root配置的厂商名称写到运行时,后面应该会改变? if (tmpVendor.IsNullOrEmpty()) { if (!csVendor.IsNullOrEmpty()) spConfigRun->WriteConfigValue("SCI", "Vendor", csVendor); } // 处理设备序列号,只有运行时有设备名称才赋值 if (tmpNameRun.GetLength() > 2)//runcfg has sci name { Dbg("runcfg has sci name"); m_csDevSN = tmpNameRun; //after migrate from root.ini to runcfg,clear the setting in root.ini //no privilege,hehe if (tmpNameRoot.GetLength() > 2) spConfig->WriteConfigValue("Terminal", "DevSN", ""); //清空掉配置? } else { //oilyang@20181129 no need to move data to RunCfg now... //if (IsValidSCIName(tmpNameRoot,tmpNameRoot.GetLength()))//root.ini has DevSN //{ // m_csDevSN = tmpNameRoot; // spConfigRun->WriteConfigValue("SCI", "name", m_csDevSN); //} } } } int CCardIssuerFSM::Initial() { Dbg("to open RVC.Stand2S..."); ErrorCodeEnum errCode = OpenDevice(DEV_OPEN_TYPE_COM,""); if (errCode != Error_Succeed) { Dbg("Load failed(%d).", errCode); CloseAndClearDevObj(false); return errCode; } return 0; } int CCardIssuerFSM::UnAcceptCard() { LOG_FUNCTION(); ErrorCodeEnum eErr; if (GetDevStatus()){ if (m_devStatus.eMedia == CI_MEDIA_PRESENT){ m_hasCardWhileDevOpen = true; Dbg("读卡器有卡(%d)",m_issueStatus); JustReadCardNo(); if (m_currCardNo.GetLength() > 1) m_captureReason = "4014"; else m_captureReason = "0000"; if (m_issueStatus) return CaptureCard(NULL); else return EjectCard(NULL); } else{ //hr = m_pIDCard->IDC_CloseShutter(); eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (Error_Succeed == eErr){ //Dbg("CloseShutter(%d)",hr); //close shutter successful process. } else{ AlarmDEC("after open,close shutter", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); //close shutter failed process. } if (GetDevStatus()) return 0; else return 1; } } else { //Dbg("获取读卡器设备状态失败(%d)",m_devStatus.eMedia); } return 1; } int CCardIssuerFSM::IssueCard(SpReqAnsContext::Pointer ctx, SpReqAnsContext::Pointer ctxEx) { LOG_FUNCTION(); //#ifdef TWINKLE_LOCAL_DEBUG //oiltest@20190725 便携卡机压力测试,仅供开发环境测试 if (ctxEx != NULL) { if (ctxEx->Req.hopper == 199) { Dbg("issue card no-stop begin"); oiltestSCI(false); Dbg("issue card no-stop end"); return 0; } } //#endif if ((_strnicmp("RVC.PAD", m_csMachineType, strlen("RVC.PAD")) == 0 || (_strnicmp("RVC.Desk2S", m_csMachineType, strlen("RVC.Desk2S")) == 0 && m_majorVerion == 1 && m_minorVerion == 0)) && !m_bChannelOK) { Dbg("未建立安全通道。"); if (ctxEx != NULL) ctxEx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_No_Encryted_Channel); else if (ctx != NULL) ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_No_Encryted_Channel); return 2; } //如果有盘库记录则清理掉(@zjw20190809) if (m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) { ErrorCodeEnum eErr = Error_Succeed; CSmartPointer spConfigRun; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if(eErr != Error_Succeed) { Dbg("Open runcfg failed(%d).", eErr); ctx->Answer(Error_Unexpect, AlarmDECToBusiness("Open runcfg failed:",eErr,MEC_CFG_RUN_POINTER_FAILED)); return 2; } if(CheckHasPanKuRecord(spConfigRun)) { ClearLocalRecord(spConfigRun); } } if (ctxEx != NULL) { Dbg("issue type:%d", ctxEx->Req.hopper); ctxEx->Ans.reserved1.Init(2); //oiltmp@20180521 //from 宋锐:存储门禁卡 if (ctxEx->Req.hopper == 86) { ErrorCodeEnum eGateForbid = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_ALL); if (eGateForbid != Error_Succeed) { AlarmDEC("SetCardInType(CI_CARD_IN_TYPE_ALL)", eGateForbid, MEC_DEVAPI_CARDISSUER_SetCardInType); ctxEx->Answer(Error_Unexpect); m_bForHangzhouSongruiMenjinka = false; return 2; } INT64 start = GetTickCountRVC(); while (1) { if (m_bForHangzhouSongruiMenjinka) { Dbg("front cancel insert card."); m_bForHangzhouSongruiMenjinka = false; ctxEx->Answer(Error_Cancel); return 2; } if (QueryCardInfo() == 2) { //oiltest@20180704 for songrui CardNo cardtmp; m_pCardIssuer->ReadAccount(cardtmp); ctxEx->Ans.reserved1[1] = 0; ctxEx->Answer(Error_Succeed); Dbg("add gate forbid card suc."); m_bForHangzhouSongruiMenjinka = false; return 0; } Sleep(1000); INT64 end = GetTickCountRVC(); if ((end - start) > 60 * 1000) { Dbg("time elapsed,but can't find card."); m_bForHangzhouSongruiMenjinka = false; ctxEx->Answer(Error_TimeOut); return 2; } } } m_bForHangzhouSongruiMenjinka = false; if (ctxEx->Req.hopper == 100 || ctxEx->Req.hopper == 99 || ctxEx->Req.hopper == 98 ||ctxEx->Req.hopper == 97)//卡库 { if (!IsValidSlotNum(ctxEx->Req.reserved1[0])) { Dbg("Issue card invalid slot."); ctxEx->Ans.reserved1[0] = 1; ctxEx->Answer(Error_Succeed); return 2; } if (!IsSlotHasCard(ctxEx->Req.reserved1[0])) { Dbg("Issue card the slot has no card"); ctxEx->Ans.reserved1[0] = 2; ctxEx->Answer(Error_Succeed); return 2; } FSMSetIssueFlag(1); bool bSpec = false; if (ctxEx->Req.hopper == 98 || ctxEx->Req.hopper == 100) bSpec = true; return IssueCardFromStore(ctxEx,bSpec); } else if (ctxEx->Req.hopper == 89)//加卡步骤一 { FSMSetIssueFlag(1); return AddCardToStoreStepFirst(ctxEx); } else if (ctxEx->Req.hopper == 88)//加卡步骤二 { return AddCardToStoreStepLast(ctxEx); } else if (ctxEx->Req.hopper == 87)//签发失败,吞卡 { RegistCardWhileCaptureCard(); MachineMoveCardBackNotHold(); ctxEx->Answer(Error_Succeed); return 2; } Dbg("IssueCard from the %d hopper.", ctxEx->Req.hopper); //param Req.hopper is wrong if (ctxEx->Req.hopper < 1 || ctxEx->Req.hopper > 3) return Error_Param; if (!m_bHasHopper[ctxEx->Req.hopper - 1]) { if (ctxEx->Req.hopper == 1) { ctxEx->Answer(Error_DevMedia, CardIssuer_UserErrorCode_NotHas_Hopper1); } else if (ctxEx->Req.hopper == 2) { ctxEx->Answer(Error_DevMedia, CardIssuer_UserErrorCode_NotHas_Hopper2); } else if (ctxEx->Req.hopper == 3) { ctxEx->Answer(Error_DevMedia, CardIssuer_UserErrorCode_NotHas_Hopper3); } return 2; } m_currentHopper = ctxEx->Req.hopper; } else m_currentHopper = 1; Dbg("current hopper:%d", m_currentHopper); m_pCardProcess->DataInit(); if (m_mixedEx[m_currentHopper-1] >= 3) { //all of the hoppers are wrong if (((m_bHasHopper[0] && m_mixedEx[0] >= 3) || !m_bHasHopper[0]) && ((m_bHasHopper[1] && m_mixedEx[1] >= 3) || !m_bHasHopper[1]) && ((m_bHasHopper[2] && m_mixedEx[2] >= 3) || !m_bHasHopper[2])) SetDevStateAndSendMsg(DEVICE_STATUS_MAINTAINCE); Dbg("%d,%d,%d;%d,%d,%d", m_bHasHopper[0], m_bHasHopper[1], m_bHasHopper[2],m_mixedEx[0],m_mixedEx[1],m_mixedEx[2]); Dbg("the current card hopper may be wrong."); if (ctx != NULL) ctx->Answer(Error_DevMedia, CardIssuer_UserErrorCode_Hopper_Mixed_Too_Much); else ctxEx->Answer(Error_DevMedia, CardIssuer_UserErrorCode_Hopper_Mixed_Too_Much); return 2; } ErrorCodeEnum errCode; CardIssuerStatus cis; memset(&cis, 0, sizeof(CardIssuerStatus)); bool bEmpty = false; if ((errCode = m_pCardIssuer->GetDevStatus(cis)) != Error_Succeed) { AlarmDEC("IssueCard::GetDevStatus", errCode, MEC_DEVAPI_CARDISSUER_GetDevStatus); } else { if (cis.eIssuerBin[m_currentHopper - 1] == CI_ISSUEHOPPER_EMPTY || cis.eIssuerBin[m_currentHopper - 1] == CI_ISSUEHOPPER_NOTSUPP) bEmpty = true; } if (bEmpty || m_remainsEx[m_currentHopper - 1] <= 0) { Dbg("hopper %d no more cards to issue(%d),has Issuer bin:(%d),remains:(%d),(%d)", m_currentHopper,bEmpty, cis.eIssuerBin[m_currentHopper - 1], m_remainsEx[m_currentHopper - 1], cis.dwIssuerCount[m_currentHopper - 1]); DWORD dwUsrErrCode = 0; if (cis.eIssuerBin[m_currentHopper - 1] == CI_ISSUEHOPPER_NOTSUPP) { if (m_currentHopper == 1) dwUsrErrCode = CardIssuer_UserErrorCode_NotHas_Hopper1; else if (m_currentHopper == 2) dwUsrErrCode = CardIssuer_UserErrorCode_NotHas_Hopper2; else if (m_currentHopper == 3) dwUsrErrCode = CardIssuer_UserErrorCode_NotHas_Hopper3; } else if (cis.eIssuerBin[m_currentHopper - 1] == CI_ISSUEHOPPER_EMPTY) { if (m_currentHopper == 1) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardInHopper1; else if (m_currentHopper == 2) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardInHopper2; else if (m_currentHopper == 3) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardInHopper3; } else if (m_remainsEx[m_currentHopper - 1] <= 0) { if (m_currentHopper == 1) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardRemains_Hopper1; else if (m_currentHopper == 2) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardRemains_Hopper2; else if (m_currentHopper == 3) dwUsrErrCode = CardIssuer_UserErrorCode_NoCardRemains_Hopper3; } if (ctx != NULL) ctx->Answer(Error_Unexpect, dwUsrErrCode); else ctxEx->Answer(Error_Unexpect, dwUsrErrCode); return 2; } //forbid front enter Dbg("forbid front enter"); errCode = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (errCode != Error_Succeed) { if (ctx != NULL) ctx->Answer(Error_Unexpect, AlarmDECToBusiness("SetCardInType:",errCode,MEC_DEVAPI_CARDISSUER_SetCardInType)); else ctxEx->Answer(Error_Unexpect, AlarmDECToBusiness("SetCardInType:", errCode, MEC_DEVAPI_CARDISSUER_SetCardInType)); return 1; } Dbg("move card to holder"); FSMSetIssueFlag(1); //move card to holder errCode = m_pCardIssuer->MoveCard(CI_MOVECARD_FROM_HOPPER,m_currentHopper); Dbg("move card result %d.",errCode); if (errCode != Error_Succeed) { //LogErrMsg("Move card from hopper to position", errCode, MEC_DEVAPI_CARDISSUER_CI_MOVECARD_FROM_HOPPER, TRUE); //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_MoveCardFromHopper_Failed, "从卡槽发卡失败"); //DevErrorInfo errMove; //m_pCardIssuer->GetLastErr(errMove); //Dbg("Move card from hopper to position failed(%d),(%s).",errCode,errMove.szErrMsg); FSMSetIssueFlag(2); if (ctx != NULL) ctx->Answer(Error_Unexpect, AlarmDECToBusiness("IssueCard::MoveCard", errCode,MEC_DEVAPI_CARDISSUER_CI_MOVECARD_FROM_HOPPER)); else ctxEx->Answer(Error_Unexpect, AlarmDECToBusiness("IssueCard::MoveCard", errCode, MEC_DEVAPI_CARDISSUER_CI_MOVECARD_FROM_HOPPER)); return 1; } Dbg("set issue data"); m_issuedEx[m_currentHopper - 1]++; m_remainsEx[m_currentHopper - 1]--; //oilyang@20180809 增加对单卡槽多卡槽机器的使用及闲置的适配 if ((!m_bHasHopper[0] || m_CardPercentEx[0] == 0 || m_CardInitEx[0] == 0 || (100 * m_remainsEx[0] < m_CardPercentEx[0] * m_CardInitEx[0])) && (!m_bHasHopper[1] || m_CardPercentEx[1] == 0 || m_CardInitEx[1] == 0 || (100 * m_remainsEx[1] < m_CardPercentEx[1] * m_CardInitEx[1])) && (!m_bHasHopper[2] || m_CardPercentEx[2] == 0 || m_CardInitEx[2] == 0 || (100 * m_remainsEx[2] < m_CardPercentEx[2] * m_CardInitEx[2]))) { Dbg("few card remains."); LogWarn(Severity_Low, Error_Unexpect, LOG_ERR_CARDISSUER_FEW_CARD_REMAINS, "Few card remains."); } m_bSettingMaterial = true;//oilyang 借用于延迟同步,紧接着设置remains时更新到后台数据库 if (!SetCardIssued(m_issuedEx[m_currentHopper - 1], m_currentHopper)) Dbg("Set card issued failed."); m_bSettingMaterial = false; if (!SetCardRemains(m_remainsEx[m_currentHopper - 1], m_currentHopper)) Dbg("Set card remains failed."); Dbg("issue suc."); ctxEx->Ans.reserved1[0] = ctxEx->Ans.reserved1[1] = 0; //oilyang@20170929 根据讨论结果,去掉调用 //GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; //errCode = Error_Unexpect; //pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); //if (pGuiConsoleClient != NULL) // errCode = pGuiConsoleClient->Connect(); //else // Dbg("pGuiConsoleClient is null?"); //if (errCode == Error_Succeed) //{ // if (pGuiConsoleClient) // { // GUIConsoleService_AddMaterialCounter_Req req; // GUIConsoleService_AddMaterialCounter_Ans ans; // req.strMaterialCode = "DebitCard"; // errCode = pGuiConsoleClient->AddMaterialCounter(req, ans, 10000); // Dbg("%d",errCode); // if (pGuiConsoleClient != NULL) // { // pGuiConsoleClient->GetFunction()->CloseSession(); // pGuiConsoleClient->SafeDelete(); // pGuiConsoleClient = NULL; // } // } //} if (m_bIssuingExit) { Dbg("Issuing exit."); CaptureCard(NULL); } if (ctx != NULL) ctx->Answer(Error_Succeed); else ctxEx->Answer(Error_Succeed); return 0; } int CCardIssuerFSM::CaptureCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum eErr; int ret = 0; //hr = m_pIDCard->IDC_Capture(); eErr = MachineMoveCardBackNotHold(); Dbg("asked to capture %d",eErr); if (eErr == Error_Succeed) { bool bCaptured = RegistCardWhileCaptureCard(); Dbg("to capture card.regist %d", bCaptured); m_currCardNo = m_addCardNo = ""; } else ret = 1; m_CardCaptured++; if (!SetCardCaptured(m_CardCaptured)) Dbg("set card captured failed."); m_pCardProcess->DataInit(); if (Error_Succeed == eErr){ eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (eErr != Error_Succeed) { AlarmDEC("after capture,close shutter", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); } if (ctx != NULL) ctx->Answer(Error_Succeed); } else { //DevErrorInfo devErrInfo; //m_pCardIssuer->GetLastErr(devErrInfo); //Dbg("capture err %s",devErrInfo.szErrMsg); if (ctx != NULL) ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_CaptureCard_Failed); } return ret; //if (GetDevStatus()){ // //device ok // return 0; //} //else { // //device error // return 1 ; //} } int CCardIssuerFSM::EjectCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum eErr; eErr = MachineMoveCardFrontGate(); m_pCardProcess->DataInit(); if (Error_Succeed == eErr){ eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (eErr != Error_Succeed) { AlarmDEC("EjectCard::SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN)", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); } if (ctx != NULL) ctx->Answer(Error_Succeed); return 0; } else { //DevErrorInfo devErrInfo; //m_pCardIssuer->GetLastErr(devErrInfo); //Dbg("ejectcard err:%s",devErrInfo.szErrMsg); if (ctx != NULL) ctx->Answer(Error_Exception, AlarmDECToBusiness("ReadCard::MachineMoveCardFrontGate", eErr,CardIssuer_UserErrorCode_MoveCardToGate_Failed)); //if (GetDevStatus()) // return 0; //else return 1; } } int CCardIssuerFSM::WaitFetchingCard() { LOG_FUNCTION(); //int waitTries = 0; DWORD dwStart, dwEnd; dwStart = GetTickCountRVC(); LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_ON,"CardReader(fetch) warning on"); do { if (GetDevStatus()){ dwEnd = GetTickCountRVC(); if (m_devStatus.eMedia == CI_MEDIA_ENTERING){ Sleep(WAIT_INTERVAL); //waitTries++; } else{ //waitTries = 0; LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_OFF,"CardReader(fetch) warning off"); return 0; } }else { LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_OFF,"CardReader(fetch) warning off"); return 1; } }while ((dwEnd-dwStart) < 60*1000); LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_OFF,"CardReader(fetch) warning off"); return 2; } int CCardIssuerFSM::InternalAcceptCard() { LOG_FUNCTION(); ErrorCodeEnum eErr = Error_Unexpect; int acceptTries = 0, err = 0; DWORD64 dwStart = GetTickCountRVC(); DWORD64 dwEnd = dwStart; m_bWaitingAccept = true; bool bHasSetCardInType = false; //if (Error_Succeed == hr){ do { if (m_bExit) { m_bCancelAccept = true; break; } if (m_bCancelAccept) { err = 3; goto Err; } if (m_bWaitAccepteMore) { acceptTries = 0; dwEnd = dwStart = GetTickCountRVC(); m_bWaitAccepteMore = false; } if (GetDevStatus()) { if (m_devStatus.eMedia == CI_MEDIA_PRESENT) { LogEvent(Severity_Middle,LOG_EVT_CARDISSUER_OP,"CardIssuer op."); acceptTries = 0; goto Err; } if (m_devStatus.eMedia == CI_MEDIA_NOTPRESENT) { acceptTries++; Sleep(ACCEPT_TRY_INTERVAL); //hr = m_pIDCard->IDC_Accept(IDC_ALL_CARD,&lpCardData); if (!m_bCancelAccept && !bHasSetCardInType) eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_ALL); if (Error_Succeed != eErr) { AlarmDEC("InternalAcceptCard::SetCardInType(CI_CARD_IN_TYPE_ALL)", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); } else bHasSetCardInType = true; //LogErrInfo("err while accepting card,open shutter"); } } else { err = 1; goto Err; } dwEnd = GetTickCountRVC(); }while ((dwEnd - dwStart) < 58*1000); err = 2; Err: m_bExit = false; m_bWaitingAccept = false; eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (Error_Succeed != eErr) { AlarmDEC("InternalAcceptCard::SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN)", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); //LogErrInfo("after accept,close shutter"); //LOG_TRACE("Close shuttle"); //err = 2; } if (m_bCancelAccept && err != 1) { //oilyang@20181210 add "if (!m_bCancelByRFIC)" //oilyang@20170612 if (!m_bCancelByRFIC) Sleep(500); if (GetDevStatus()) { if (m_devStatus.eMedia == CI_MEDIA_PRESENT) { err = 4; Dbg("cancel eject......"); eErr = MachineMoveCardFrontGate(); Dbg("cancel eject.result[%d].....",eErr); if (Error_Succeed == eErr){ eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (eErr != Error_Succeed) { AlarmDEC("InternalAcceptCard::SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN)", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); } //LogErrInfo("cancel&else eject,close shutter"); } else { AlarmDECToBusiness("InternalAcceptCard::MachineMoveCardFrontGate", eErr, CardIssuer_UserErrorCode_MoveCardToGate_Failed); err = 2; } } } else err = 2; } return err; } int CCardIssuerFSM::AcceptCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_pCardProcess->DataInit(); m_bCancelByRFIC = false; LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_ON,"CardReader warning on"); m_bWaitAccepteMore = false; //GpioService_Set_Req Req; //GpioService_Set_Ans Ans; //Req.devseq = CARDREADER; //Req.mode = 1; //Req.close = 0; //CCardReaderEntity* pEntity = dynamic_cast(m_pEntity); //pEntity->SetGpio(Req,Ans); int rc = InternalAcceptCard(); //Req.devseq = CARDREADER; //Req.mode = 1; //Req.close = 1; //pEntity->SetGpio(Req,Ans); LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_GREEN_OFF,"CardReader warning off"); if (rc == 0) { FSMSetIssueFlag(0); if (ctx != NULL) { Dbg("insert error_succeed"); ctx->Answer(Error_Succeed); } } else if(rc == 2) { if (ctx != NULL) ctx->Answer(Error_TimeOut); } else if(rc == 3 || rc == 4) { if (ctx != NULL) { Dbg("insert cancel (%d)",rc); ctx->Answer(Error_Cancel); } }else { if (ctx != NULL) ctx->Answer(Error_Unexpect, AlarmDECToBusiness("AcceptCard:", Error_Unexpect,MEC_DEVAPI_CARDISSUER_GetDevStatus)); } return rc; } static CSimpleStringA GetStrData(TrackInfo trackInfo) { //LOG_FUNCTION(); CSimpleStringA strRet; switch (trackInfo.eStatus) { case CI_DATA_OK: strRet = (char*)trackInfo.data; break; case CI_DATA_INVALID: strRet = "无效数据"; break; //case CI_DATA_MISSING: default: strRet = "数据丢失"; } return strRet; } int CCardIssuerFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData) { LOG_FUNCTION(); if (pTrack2.GetLength() == 0) return -1; int dataLen = strlen(pTrack2); Dbg("pT2.len:%d",dataLen); switch(dataLen) { case 28: decodeData.t2Region = CSimpleString(pTrack2,4); decodeData.t2Account = pTrack2.SubString(4,8); decodeData.t2CardSerial = pTrack2.SubString(14,8);//oilyang for 8 onecard decodeData.t2CVC = pTrack2.SubString(22,6); decodeData.t2ExpireDate = ""; break; case 31: decodeData.t2Account = CSimpleString(pTrack2,16); decodeData.t2CardSerial = pTrack2.SubString(16,1); decodeData.t2CVC = pTrack2.SubString(17,6); decodeData.t2Region = pTrack2.SubString(23,4); decodeData.t2ExpireDate = pTrack2.SubString(27,4); break; case 38: break; default: return -1; } decodeData.status = 0; return 0; } int SplitUnionPayTrack2(CSimpleStringA pTrack2,Track2Data &decodeData) { if (strlen(pTrack2) != 37) { Dbg("wrong track2 len %d[%s]",strlen(pTrack2),(LPCTSTR)pTrack2); return -1; } //“16位卡号(19A)” + “=” + “expiry_date YYMM(4N)” + //“106(3N,服务代码)” + “PVV(5N)” + “00(2N)” + “CVV(3A)” //6225885710172339=49121200541300175361 //oiltmp //decodeData.t2Account = CSimpleString(pTrack2,16); //decodeData.t2CardSerial = pTrack2.SubString(16,1); //decodeData.t2CVC = pTrack2.SubString(17,6); //decodeData.t2Region = pTrack2.SubString(23,4); //decodeData.t2ExpireDate = pTrack2.SubString(27,4); return 0; } //0:unknown 1:本行借记磁卡;2 本行借记IC;3 本行贷记磁卡;4 本行贷记IC;5 他行卡 int CCardIssuerFSM::DetectCardTypeInfoByAccount(char *pAccount, int len, char *pT3, int t3Len) { if (len < 6) return 0; if (!memcmp(pAccount,"95555",5)) return 1; if (pT3 != NULL) { char tmpMag2_3[512] = {0},tmpMag2[256] = {0}; memcpy(tmpMag2_3,pAccount,len); memcpy(tmpMag2_3+len,"A",1); memcpy(tmpMag2_3+len+1,pT3,t3Len); char cardType[8] = {0}; cmdDecodeEx(tmpMag2_3,cardType,tmpMag2); if (_strnicmp(cardType,"ODCD",4) == 0) { Dbg("old one card tong..."); return 1; } } char bin[7] = {0}; memcpy(bin,pAccount,6); vector::iterator it; for (it = m_vBin.begin(); it != m_vBin.end(); ++it) { if (!memcmp(bin,it->bin,6)) { if (it->bDC) { if (it->bIC) return 2; else return 1; } else { if (it->bIC) return 4; else return 3; } } } return 5;//all the other cards } //ReadCardEx 废弃不用 oilyang int CCardIssuerFSM::ReadCardEx(SpReqAnsContext::Pointer ctx) { return 0; } int CCardIssuerFSM::ReadCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_currCardNo = ""; ctx->Ans.ICType = 0; ErrorCodeEnum eErr; int activeCardType; bool bIC(false), bICSuc(false), bReadCardInfo(false); Dbg("reserved1 for lightPos:%d", ctx->Req.reserved1); if ((ctx->Req.reserved1&0x32) == 0x32)//只需要磁条 { } else { bIC = m_pCardProcess->DetectIfICCard(CARD_MACHINE_ISSUER, m_pCardIssuer, activeCardType); if (bIC) { m_pCardIssuer->DeactivateICCard(); m_pCardIssuer->ReleaseIC(); } } DWORD dwStart = GetTickCountRVC(); MagTracks magTracks; int readTries = 0; memset(magTracks.track[0].data, 0, sizeof(magTracks.track[0].data)); memset(magTracks.track[1].data, 0, sizeof(magTracks.track[1].data)); memset(magTracks.track[2].data, 0, sizeof(magTracks.track[3].data)); { magTracks.eRange = CI_TRACK_RANGE_2_3; do { eErr = m_pCardIssuer->MagRead(magTracks); Dbg("MAGread(%d)...",eErr); ctx->Ans.t2Account = ctx->Ans.ICData = ""; //DevErrorInfo devErrInfo; //m_pCardIssuer->GetLastErr(devErrInfo); readTries++; Dbg("t2,t3:%d,%d",magTracks.track[1].eStatus,magTracks.track[2].eStatus); if (magTracks.track[1].dwSize > sizeof(magTracks.track[1].data) || magTracks.track[2].dwSize > sizeof(magTracks.track[2].data)) { Dbg("Wrong dwSize %d,%d",magTracks.track[1].dwSize,magTracks.track[2].dwSize); break; } if (Error_Succeed == eErr && magTracks.track[1].eStatus == CI_DATA_OK) { if (bIC) ctx->Ans.ICType = 1; else ctx->Ans.ICType = 2; LogEvent(Severity_Middle,LOG_EVT_CARDISSUER_OP,"CardIssuer op."); if (magTracks.track[1].dwSize > 40) { Dbg("mag track 2 length wrong."); ctx->Ans.status = 1; break; } ctx->Ans.track2 = (char*)magTracks.track[1].data; bool bT3OK = false; if (magTracks.track[2].eStatus == CI_DATA_OK) { bT3OK = true; ctx->Ans.track3 = (char*)magTracks.track[2].data; } Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; char *tmpMag2 = new char[256]; ZeroMemory(tmpMag2, 256); DecodeTracksData((const char*)magTracks.track[1].data, magTracks.track[1].dwSize, (const char*)magTracks.track[2].data, magTracks.track[2].dwSize, tmpMag2,true,bT3OK); //char tmpMag2_3[512] = {0},tmpMag2[256] = {0}; //memcpy(tmpMag2_3,GetStrData(magTracks.track[1]).GetData(),magTracks.track[1].dwSize); //char cardType[8]; //ZeroMemory(cardType, 8); //if (magTracks.track[2].eStatus == CI_DATA_OK) //{ // Dbg("do track 3"); // ctx->Ans.track3 = (char*)magTracks.track[2].data; // memcpy(tmpMag2_3+magTracks.track[1].dwSize,"A",1); // memcpy(tmpMag2_3+magTracks.track[1].dwSize+1,GetStrData(magTracks.track[2]).GetData(),magTracks.track[2].dwSize); // cmdDecodeEx(tmpMag2_3,cardType,tmpMag2); //} //if (magTracks.track[2].eStatus != CI_DATA_OK || strlen(cardType) < 4) //{ // Dbg("no or wrong track 3.%d,%s", magTracks.track[2].eStatus,cardType); // cmdDecodeMag2(tmpMag2_3,tmpMag2); //} //decode account from track 2 int pos = 0; for (int i = 0; i < magTracks.track[1].dwSize; ++i,++pos) { if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e) break; } Dbg("pos:%d,%d",pos,magTracks.track[1].dwSize); if (pos <= 0 || pos == magTracks.track[1].dwSize) { ctx->Ans.status = 1; if (tmpMag2 != NULL) { delete[]tmpMag2; tmpMag2 = NULL; } break; } char *ddd = new char[40]; memset(ddd,0,40); memcpy(ddd,magTracks.track[1].data,pos); if (SplitTrack2(tmpMag2,track2Data) == 0) { ctx->Ans.status = track2Data.status; ctx->Ans.t2Account = track2Data.t2Account; ctx->Ans.t2Region = track2Data.t2Region; ctx->Ans.t2CardSerial = track2Data.t2CardSerial; ctx->Ans.t2CVC = track2Data.t2CVC; ctx->Ans.t2ExpireDate = track2Data.t2ExpireDate; Dbg("done."); bReadCardInfo = true; if (m_issueStatus) { m_mixedEx[m_currentHopper - 1] = 0; bool bSetMix = SetCardMixed(m_mixedEx[m_currentHopper - 1], m_currentHopper); Dbg("set %d card mixed %d,%d", m_currentHopper, bSetMix, m_mixedEx[m_currentHopper - 1]); } //break; } if (_strnicmp(track2Data.t2Account,ddd,strlen(ddd)) && (track2Data.t2Account.GetLength() != 8)) { ctx->Ans.status = 0; ctx->Ans.t2Account = (char*)ddd; ctx->Ans.t2Region = ""; ctx->Ans.t2CardSerial = ""; ctx->Ans.t2CVC = ""; ctx->Ans.t2ExpireDate = ""; //Dbg("%s,%s",(LPCTSTR)track2Data.t2Account,ctx->Ans.t2Account); bReadCardInfo = true; delete []ddd; } if (tmpMag2 != NULL) { delete[]tmpMag2; tmpMag2 = NULL; } Dbg("%s,%s", (LPCTSTR)ctx->Ans.t2Account.SubString(0, 6), (LPCTSTR)ctx->Ans.t2Account.SubString(ctx->Ans.t2Account.GetLength() - 4, 4)); break; } else { if (bIC) { bReadCardInfo = true; ctx->Ans.ICType = 3; Dbg("maybe ic only."); } else { AlarmDEC("ReadCard::MagRead", eErr, MEC_DEVAPI_CARDISSUER_MagRead); //LogWarn(Severity_Low, Error_DevCommFailed, CardIssuer_UserErrorCode_ReadMagTrack_Failed, "CardIssuer read failed."); /*DevErrorInfo devErrInfo; m_pCardIssuer->GetLastErr(devErrInfo);*/ Dbg("idc_read [%d][%d]", magTracks.track[1].eStatus, magTracks.track[2].eStatus); } } }while(readTries < READ_TRY_NUM); } Dbg("ic type %d",ctx->Ans.ICType); m_currCardNo = ctx->Ans.t2Account; DWORD dwEnd = GetTickCountRVC(); DWORD dwCollapse = dwEnd-dwStart; if ((dwCollapse < 8000) && (!bReadCardInfo)) { bReadCardInfo = true; ctx->Ans.status = 1; //maybe cannot read mag if (m_issueStatus) { m_mixedEx[m_currentHopper - 1]++; bool bSetMix = SetCardMixed(m_mixedEx[m_currentHopper - 1], m_currentHopper); Dbg("set %d card mixed %d,%d", m_currentHopper, bSetMix, m_mixedEx[m_currentHopper - 1]); } } bool bEjectSelf = false; if (!bReadCardInfo) { ctx->Ans.status = 1; if (!m_issueStatus) { ErrorCodeEnum errEject = MachineMoveCardFrontGate(); if (errEject == Error_Succeed) { Dbg("read failed.eject self"); bEjectSelf = true; } else AlarmDECToBusiness("ReadCard::MachineMoveCardFrontGate", errEject, CardIssuer_UserErrorCode_MoveCardToGate_Failed); } } if (GetDevStatus()) { if (bEjectSelf) return 2; else return 0; }else return 1; } int CCardIssuerFSM::WriteCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum eErr; int ret = 0; if (ctx->Req.track1.GetLength() <= 0 && ctx->Req.track2.GetLength() <= 0 && ctx->Req.track3.GetLength() <= 0) { Dbg("write card param is null."); ctx->Answer(Error_Param); return ret; } else { eErr = m_pCardIssuer->MoveCard(CI_MOVECARD_MAG_POSITION); if (eErr != Error_Succeed) { //LogErrMsg("WriteCard::MoveCard", eErr, MEC_DEVAPI_CARDISSUER_CI_MOVECARD_MAG_POSITION, TRUE); //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_MoveCardToMagPosition_Failed, "移动卡片到磁卡位失败"); //Dbg("move card to mag position failed."); ctx->Answer(Error_Unexpect, AlarmDECToBusiness("WriteCard::MoveCard",eErr,MEC_DEVAPI_CARDISSUER_CI_MOVECARD_MAG_POSITION)); return ret; } } MagTracks magTrack; ZeroMemory(magTrack.track[0].data,MAX_MAG_TRACK_SIZE); ZeroMemory(magTrack.track[1].data,MAX_MAG_TRACK_SIZE); ZeroMemory(magTrack.track[2].data,MAX_MAG_TRACK_SIZE); magTrack.track[0].dwSize = magTrack.track[1].dwSize = magTrack.track[2].dwSize = 0; magTrack.track[0].eStatus = magTrack.track[1].eStatus = magTrack.track[2].eStatus = CI_DATA_INVALID; TrackRange iT1,iT2,iT3; iT1 = iT2 = iT3 = CI_TRACK_RANGE_START; if (ctx->Req.track1.GetLength() > 0) { iT1 = CI_TRACK_RANGE_1; CSimpleStringA csT1 = CSimpleStringW2A(ctx->Req.track1); strncpy((char*)magTrack.track[0].data,csT1,csT1.GetLength()); magTrack.track[0].eSource = CI_TRACK_SOURCE_1; magTrack.track[0].eStatus = CI_DATA_OK; magTrack.track[0].dwSize = csT1.GetLength(); } if (ctx->Req.track2.GetLength() > 0) { iT2 = CI_TRACK_RANGE_2; CSimpleStringA csT2 = CSimpleStringW2A(ctx->Req.track2); strncpy((char*)magTrack.track[1].data,csT2,csT2.GetLength()); magTrack.track[1].eSource = CI_TRACK_SOURCE_2; magTrack.track[1].eStatus = CI_DATA_OK; magTrack.track[1].dwSize = csT2.GetLength(); } if (ctx->Req.track3.GetLength() > 0) { iT3 = CI_TRACK_RANGE_3; CSimpleStringA csT3 = CSimpleStringW2A(ctx->Req.track3); strncpy((char*)magTrack.track[2].data,csT3,csT3.GetLength()); magTrack.track[2].eSource = CI_TRACK_SOURCE_3; magTrack.track[2].eStatus = CI_DATA_OK; magTrack.track[2].dwSize = csT3.GetLength(); } //TrackRange eAll = iT2 | iT2; magTrack.eRange = TrackRange(iT1|iT2|iT3); Dbg("to write...(%d)",magTrack.eRange); eErr = m_pCardIssuer->MagWrite(magTrack,AUTO_CO); Dbg("after write %d",eErr); if (eErr != Error_Succeed) { AlarmDEC("WriteCard::MagWrite", eErr, MEC_DEVAPI_CARDISSUER_MagWrite); //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_WriteMagTrack_Failed, "写磁卡失败"); //Dbg("MagWrite failed(%d).",eErr); //LogDevErrorInfo(); ret = 1; } ctx->Ans.result = ret; ctx->Answer(Error_Succeed); return ret; } int CCardIssuerFSM::PreOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_findCard = m_cardPos = 0;//just for RVC.CardStore bool bCrossPreOnline = false; //如果有盘库记录则清理掉(@zjw20190809) if (m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) { ErrorCodeEnum eErr = Error_Succeed; CSmartPointer spConfigRun; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if(eErr != Error_Succeed) { Dbg("Open runcfg failed(%d).", eErr); ctx->Answer(Error_Unexpect, AlarmDECToBusiness("Open runcfg failed",eErr,MEC_CFG_RUN_POINTER_FAILED)); return 2; } if(CheckHasPanKuRecord(spConfigRun)) { ClearLocalRecord(spConfigRun); } } Dbg("bus data[%s]",(LPCTSTR)ctx->Req.businessData); CSimpleStringA csMagT2Track(""), csMagT3Track(""), csMagAccout(""), csMagRegion(""), csMagCardSerial(""), csMagCVC(""), csMagExpireDate(""); int slot = 0; if (ctx->Req.reserved1.GetLength() > 0 && _strnicmp("kaku#",(const char*)ctx->Req.reserved1,5) == 0) { bCrossPreOnline = true; GetEntityBase()->GetFunction()->SetSysVar("CardStoreInUse", "Y"); CSimpleStringA csSlot(""); csSlot = ctx->Req.reserved1.SubString(5, ctx->Req.reserved1.GetLength() - 5); slot = atoi((const char*)csSlot); Dbg("slot:%d,%s", slot, (const char*)ctx->Req.reserved1); if (!IsValidSlotNum(slot)) { Dbg("invalid slot."); m_findCard = 1; GetEntityBase()->GetFunction()->SetSysVar("CardStoreInUse", "N"); ctx->Answer(Error_Succeed); return 0; } if (!IsSlotHasCard(slot)) { Dbg("the slot has no card"); m_findCard = 2; GetEntityBase()->GetFunction()->SetSysVar("CardStoreInUse", "N"); ctx->Answer(Error_Succeed); return 0; } ErrorCodeEnum eErr = Error_Unexpect; eErr = m_pCardIssuer->MoveCardFromSlot(slot); CardNo card; ZeroMemory(card.account, sizeof(card.account)); ZeroMemory(card.track2, sizeof(card.track2)); ZeroMemory(card.track3, sizeof(card.track3)); if (eErr == Error_Succeed && m_pCardIssuer->ReadAccount(card) == Error_Succeed) { Dbg("move card from slot to cardreader and ReadAccount suc.magT2.size:%d(%d),magT3.size:%d(%d)" ,card.dwTrack2Size,strlen(card.track2),card.dwTrack3Size, strlen(card.track3)); if (ctx->Req.reserved2.GetLength() > 0 && ctx->Req.reserved2.Compare(card.account) != 0) { m_findCard = 3; AfterPreOnlineOnStore(Error_Unexpect, slot); ctx->Answer(Error_Succeed); return 0; } if (card.dwTrack2Size > 0 && card.dwTrack2Size < 41) { if (card.track2[card.dwTrack2Size - 1] == 'F') card.track2[card.dwTrack2Size - 1] = '\0'; csMagT2Track = card.track2; } if (card.dwTrack3Size > 0 && card.dwTrack3Size < 108) { if (card.track3[card.dwTrack3Size - 1] == 'F') card.track3[card.dwTrack3Size - 1] = '\0'; csMagT3Track = card.track3; } //oilyang@20180516 add for kaku //split track 2&3 data char *pTmpMag2 = new char[128]; ZeroMemory(pTmpMag2, 128); Track2Data track2Data; bool bT2OK, bT3OK; bT2OK = bT3OK = false; if (card.dwTrack2Size > 8 && strlen(card.track2) > 8) bT2OK = true; if (card.dwTrack3Size > 8 && strlen(card.track3) > 8) bT3OK = true; DecodeTracksData((const char*)csMagT2Track, card.dwTrack2Size, (const char*)csMagT3Track, card.dwTrack3Size, pTmpMag2, bT2OK, bT3OK); if ((SplitTrack2(pTmpMag2, track2Data) == 0)) { csMagAccout = track2Data.t2Account; csMagRegion = track2Data.t2Region; csMagCardSerial = track2Data.t2CardSerial; csMagCVC = track2Data.t2CVC; csMagExpireDate = track2Data.t2ExpireDate; Dbg("done track 2(/&)3."); } delete[]pTmpMag2; m_pCardProcess->DataInit(); } else { AlarmDEC("PreOnline::MoveCardFromSlot", eErr, MEC_DEVAPI_CARDISSUER_MoveCardFromSlot); //Dbg("move card from slot failed.ret:%d",eErr); m_findCard = 4; AfterPreOnlineOnStore(Error_Unexpect, slot); ctx->Answer(Error_Succeed); return 0; } } m_pCardProcess->SplitBusinessData(ctx->Req.businessData,ctx->Req.businessData.GetLength()); if (m_bSM) { Dbg("We support sm."); m_pCardProcess->SplitBusinessData("DF690101",strlen("DF690101")); } int activeCardType; //oilyang@20201014 add emv card support int retDetectAndRead = -1; ICData aidFromBus(false, 0x4f, 0x00); if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1) { Dbg("the front BusinessData han't provide aid data."); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333", activeCardType); if (retDetectAndRead < -1)//-1:DetectIfICCard failed; -2:select app failed { Dbg("Can't read pboc record,to try emv..."); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888", activeCardType); } } else { char* pAIDTmp = new char[64]; memset(pAIDTmp, 0, 64); HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth); Dbg("the aid is[%s],len:%d .", pAIDTmp,strlen(pAIDTmp)); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_pCardIssuer, pAIDTmp, activeCardType); if (pAIDTmp != NULL) delete[]pAIDTmp; } if (retDetectAndRead < 0) { if ((m_csMachineType.Compare("RVC.CardStore") == 0|| m_csMachineType.Compare("RVC.CardPrinter") == 0) && bCrossPreOnline) AfterPreOnlineOnStore(Error_Unexpect, slot); if (retDetectAndRead == -1) ctx->Answer(Error_Unexpect, AlarmDECToBusiness("PreOnline:", Error_Unexpect,MEC_DEVAPI_CARDISSUER_ActiveICCard)); else if (retDetectAndRead == -2) ctx->Answer(Error_Unexpect, AlarmDECToBusiness("PreOnline:", Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand)); return 0; } //if (m_cardType == CI_CARDTYPE_IC) //{ // ProcessRestrict(); // CardholderVerify(); m_pCardProcess->TermRiskManage(); CSimpleStringA taaResult; BYTE bt9f27 = 0; int retTAA = m_pCardProcess->TermActionAnalyze(CARD_MACHINE_ISSUER,m_pCardIssuer,taaResult,m_bOnlineOnly,m_bCDA,bt9f27); Dbg("TermActionAnalyze %d",retTAA); switch(retTAA) {//to be added oiltmp 20140929 case -1: //some data may be wrong break; case 1: //terminal trans break; case 2: //to do trans end "TransEnd" break; default: break; } ctx->Ans.result = taaResult; // Dbg("[%d,%d,%d,%d]",m_TVR[0],m_TVR[1],m_TVR[2],m_TVR[3]); //} if (ctx->Ans.result.GetLength() == 0) { if ((m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) && bCrossPreOnline) AfterPreOnlineOnStore(Error_Unexpect, slot); ctx->Answer(Error_Succeed); return 0; } Dbg("term action analyze result[%s]", (const char*)ctx->Ans.result); //char tmpResult[1024,]result[1024]; //ZeroMemory(tmpResult,sizeof(tmpResult)); //ZeroMemory(result,sizeof(result)); //memcpy(tmpResult,ctx->Ans.result,ctx->Ans.result.GetLength()); string tmpResult,actionType,result = "",baseICData = ""; tmpResult = ctx->Ans.result; char *pSomeICData = new char[ONE_K]; ZeroMemory(pSomeICData, ONE_K); int lenRet = m_pCardProcess->ConstructARQCData(tmpResult.substr(6,4).c_str(),m_pDataToARQC,pSomeICData); baseICData = pSomeICData; if (pSomeICData != NULL) delete []pSomeICData; char arqcLen[8]; ZeroMemory(arqcLen,sizeof(arqcLen)); _itoa(lenRet,arqcLen,10); ICData appExpiryDate(false,0x5f,0x24); if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,appExpiryDate,false,0) == -1) { Dbg("can't find expire date"); if ((m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) && bCrossPreOnline) AfterPreOnlineOnStore(Error_Unexpect, slot); return 0; } char *pExpireDate = new char[12]; ZeroMemory(pExpireDate,12); HexBuf2StrBuf(appExpiryDate.value,&pExpireDate,appExpiryDate.lenth); ICData track2(false,0x57,0x00),ICCardSerial(false,0x5f,0x34); ErrorCodeEnum eErr = Error_Unexpect; string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType("0"); char *pICCardSerial = new char[4]; ZeroMemory(pICCardSerial,4); if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,ICCardSerial,false) == -1) { Dbg("can't find card serial."); } else { HexBuf2StrBuf(ICCardSerial.value,&pICCardSerial,ICCardSerial.lenth); } if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,track2,false,0) == -1) { Dbg("[ic]no track2 data"); eErr = m_pCardIssuer->ReleaseIC(); Dbg("ic failed,release it %d",eErr); } else { int pos = FindHexCharPosition(track2.value,0x0d,track2.lenth); char *pICTrack2 = new char[128]; ZeroMemory(pICTrack2,128); HexBuf2StrBuf(track2.value,&pICTrack2,track2.lenth); pICTrack2[37] = '\0'; Dbg("ic.track2,pos:%d",pos); Dbg("pos:%d",pos); char *ddd = new char[40]; memset(ddd,0,40); memcpy(ddd,pICTrack2,pos-1); //int cardCat = DetectCardTypeInfoByAccount(pICTrack2,strlen(pICTrack2)); //Dbg("card category %d",cardCat); //char chCat = cardCat + '0'; //cardType = chCat; //if (cardCat == 2 || cardCat == 4) //{ char icTrack2Data[128]; ZeroMemory(icTrack2Data,sizeof(icTrack2Data)); Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; cmdDecodeMag2(pICTrack2,icTrack2Data); if (SplitTrack2(icTrack2Data,track2Data) == 0) { t2ICAccount = track2Data.t2Account; //t2ICCardSerial = track2Data.t2CardSerial; t2ICCVC = track2Data.t2CVC; t2ICTrack2 = pICTrack2; Dbg("done(ic)."); if (m_issueStatus) { m_mixedEx[m_currentHopper - 1] = 0; bool bSetMix = SetCardMixed(m_mixedEx[m_currentHopper - 1], m_currentHopper); Dbg("set %d card mixed %d,%d", m_currentHopper, bSetMix, m_mixedEx[m_currentHopper - 1]); } } if (_strnicmp(track2Data.t2Account,ddd,strlen(ddd))) { t2ICCVC = ""; t2ICTrack2 = pICTrack2; t2ICAccount = (char*)ddd; Dbg("count:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length()-4, 4).c_str()); } t2ICCardSerial = pICCardSerial; delete []ddd; delete []pICTrack2; } //80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000 if (m_pCardProcess->GetP1() == 0x1) actionType = "ARQC"; else actionType = ""; //【55域】 // 基本域: // 9F26 8b 应用密文AC // 9F27 1b 密文信息数据 // 9F10 max.32b 发卡行应用数据IAD // 9F37 4b 不可预知数 // 9F36 2b 应用交易计数器ATC // 95 5b 终端验证结果TVR // 9A 3cn 交易日期(6位有效数字,YYMMDD) // 9C 1cn 交易类型(2位有效数字) // 9F02 6cn 授权金额(12位有效数字) // 5F2A 2cn 交易货币代码(3位有效数字) // 82 2b 应用交互特征AIP // 9F1A 2cn 终端国家代码(3位有效数字) // 9F03 6cn 其他金额(12位有效数字) // 9F33 3b 终端性能 "E0C900" // 可选域: //添加9F26,9F27,9F10,9F33的数据 char *pCID = new char[4]; ZeroMemory(pCID, 4); HexBuf2StrBuf(&bt9f27, &pCID, 1); char *pIssueBankLen = new char[4]; ZeroMemory(pIssueBankLen, 4); int len9f10 = tmpResult.length() - 26 - 4; int lenHigh, lenLow; len9f10 = len9f10 / 2; lenHigh = len9f10 / 16; lenLow = len9f10 % 16; BYTE bt9f10; bt9f10 = (lenHigh<<4) + lenLow; HexBuf2StrBuf(&bt9f10, &pIssueBankLen, 1); baseICData += "9F2608" + tmpResult.substr(10, 16) + "9F2701" + pCID +"9F10" + pIssueBankLen + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "9F3303" + "E0C900"; result = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6,4) + "|" + "ARQCCODE," + tmpResult.substr(10,16) + "|" + "MAC," + tmpResult.substr(26,tmpResult.length()-26-4) + "|" + "ARQCSIZE," + string(arqcLen) + "|" + "ARQCDATA," + m_pDataToARQC + "|EXPIREDATE," + pExpireDate + "|T2ACCOUNT," + t2ICAccount + "|T2CARDSERIAL," + t2ICCardSerial + "|T2CVC," + t2ICCVC + "|T2TRACK2," + t2ICTrack2 + "|CARDCAT," + cardType + "|ICTAGS," + baseICData + "|MAGT2," + (const char*)csMagT2Track + "|MAGT3," + (const char*)csMagT3Track + "|MAGACCOUNT," + (const char*)csMagAccout + "|MAGREGION," + (const char*)csMagRegion + "|MAGCARDSERIAL," + (const char*)csMagCardSerial+ "|MAGCVC," + (const char*)csMagCVC+ "|MAGEXPIREDATAE," + (const char*)csMagExpireDate; ctx->Ans.result = result.c_str(); string txtresult = ""; txtresult = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6,4) + "|" + "ARQCCODE," + tmpResult.substr(10,16) + "|" + "MAC," + tmpResult.substr(26,tmpResult.length()-26-4) + "|" + "ARQCSIZE," + string(arqcLen) + "|" + "ARQCDATA," + m_pDataToARQC + "|T2ACCOUNT(F6)," + t2ICAccount.substr(0, 6) + "|T2ACCOUNT(L4)," + t2ICAccount.substr(t2ICAccount.length()-4, 4) + "|T2CARDSERIAL(len)," + t2ICCardSerial + "|CARDCAT," + cardType; m_currCardNo = t2ICAccount.c_str(); Dbg("data to host(less)[%s],baseICData length:%d",txtresult.c_str(),baseICData.length()); if (pCID != NULL) delete[]pCID; if (pIssueBankLen != NULL) delete[]pIssueBankLen; if (pExpireDate != NULL) delete []pExpireDate; if (m_pDataToARQC != NULL) { delete []m_pDataToARQC; m_pDataToARQC = NULL; } if ((m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0) && bCrossPreOnline) AfterPreOnlineOnStore(Error_Succeed, slot); ctx->Answer(Error_Succeed); return 0; } int CCardIssuerFSM::PostOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_pCardProcess->DataInit(); Dbg("post online data[%s]",(LPCTSTR)ctx->Req.data); m_pCardProcess->SplitOnlineReplyData(ctx->Req.data,strlen(ctx->Req.data)); int issBnkAuth = m_pCardProcess->IssueBankAuth(CARD_MACHINE_ISSUER,m_pCardIssuer); CSimpleStringA csTransEnd; if (issBnkAuth == 0) { int transEnd = m_pCardProcess->TransEnd(CARD_MACHINE_ISSUER,m_pCardIssuer,m_bCDA); if (transEnd == 0) csTransEnd = "TRANSEND,0"; else if (transEnd == 1) csTransEnd = "TRANSEND,1"; } else csTransEnd = "TRANSEND,1"; ctx->Ans.result = csTransEnd; //PBYTE pData = new BYTE[MAX_IC_BUFFER_SIZE]; //ZeroMemory(pData,MAX_IC_BUFFER_SIZE); //int size = StrBuf2HexBuf(ctx->Req.data,&pData); //if (size > 0) //m_pCardProcess->ExecuteIssuerScript(CARD_MACHINE_ISSUER,m_pCardIssuer); //else //{ // Dbg("Wrong post on line data[%s]",ctx->Req.data); // ctx->Answer(Error_Unexpect); //} ctx->Answer(Error_Succeed); return 0; } void CCardIssuerFSM::SelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { //for simple pTransactionContext->SendAnswer(m_testResult); } //void CCardIssuerFSM::LogErrInfo(const char* msgHead) //{ // DevErrorInfo errInfo; // ErrorCodeEnum eErr = m_pCardIssuer->GetLastErr(errInfo); // if (eErr == Error_Succeed) // Dbg("%s,%s",msgHead,errInfo.szErrMsg); //} bool CCardIssuerFSM::FSMSetIssueFlag(int value) { Dbg("to set issue flag,value:%d,from file:%d", value, m_issueStatusFromFile); if (value == 0 && m_issueStatusFromFile >1) { //oilyang@20171220 如果曾经卡片卡住,但启动时没有发现卡片,则更新本次发卡方向但不写文件,以防后续卡片被移动到卡槽 if (!m_hasCardWhileDevOpen) { Dbg("card jamed havn't been process."); m_issueStatus = 0; } else Dbg("insert succeed,but there maybe some card jamed..."); return true; } m_issueStatus = value; CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set issue)open cfg file failed!"); return false; } if (spConfig->WriteConfigValueInt("RunInfo", "IsIssue", value) == Error_Succeed && spConfig->WriteConfigValueInt("all", "IsIssue", value) == Error_Succeed) return true; else return false; } bool CCardIssuerFSM::SetCardCaptured(const int num,bool bClear) { Dbg("set captured:%d,(bClear)%d",num,bClear); if (num < 0) { Dbg("wrong reset card captured %d",num); return false; } CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set captured)open cfg file failed!"); return false; } m_CardCaptured = num; if (num >= m_maxRetainCount) { //oilyang@20201223 according to rongyiheng,if is RVC.CardPrinter,no need to judge on retain count if (m_csMachineType.Compare("RVC.CardPrinter") != 0) { Dbg("retain bin is full!回收箱满了,请及时清理!"); LogWarn(Severity_High, Error_Unexpect, LOG_ERR_CARDISSUER_RETAIN_BIN_IS_FULL, "retain bin is full!回收箱满了,请及时清理!"); } } if (spConfig->WriteConfigValueInt("RunInfo", "CardCaptured", num) == Error_Succeed && spConfig->WriteConfigValueInt("all", "CardCaptured", num) == Error_Succeed) { if (bClear && !m_bSettingMaterial) { bool bMaintain[12]; memset(bMaintain, 0, 12); SyncDataToDB(bMaintain); } return true; } else return false; } bool CCardIssuerFSM::SetCardIssued(const int num, const int hopper) { Dbg("set issued:%d,(hopper)%d",num,hopper); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set issued)open cfg file failed!"); return false; } char buf[8]; memset(buf, 0, 8); _itoa(hopper, (char*)buf, 10); CSimpleStringA section(buf); Dbg("hopper:%d,%s",hopper,(const char*)section); if (spConfig->WriteConfigValueInt(section, "CardIssued", num) == Error_Succeed) { if (section.Compare("1") == 0) spConfig->WriteConfigValueInt("RunInfo", "CardIssued", num); //oilyang 回写新section if (hopper == 1) { int xNum = 0; spConfig->ReadConfigValueInt("all", "HopperNum", xNum); if (xNum == 0) spConfig->WriteConfigValueInt("all", "HopperNum", 1); } //oilyang@20170428 汪磊东要求单卡箱也要同步数据 //if (m_hopperNum != 1 && !m_bSettingMaterial) if (!m_bSettingMaterial) { bool bMaintain[12]; memset(bMaintain, 0, 12); SyncDataToDB(bMaintain,false); } return true; } else { Dbg("write CardIssued err:%d", eErrDev); return false; } } bool CCardIssuerFSM::SetCardRemains(const int num, const int hopper,bool bInit) { Dbg("remains:num %d,%d,(hopper)%d",num,bInit,hopper); if (num == 0) { Dbg("hopper %d no card remains.",m_currentHopper); switch (hopper) { case 1: LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_NoCardRemains_Hopper1, "Hopper 1 No card remains."); break; case 2: LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_NoCardRemains_Hopper2, "Hopper 2 No card remains."); break; case 3: LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_NoCardRemains_Hopper3, "Hopper 3 No card remains."); break; default: break; } } CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set remains)open cfg file failed!"); return false; } char buf[8]; memset(buf, 0, 8); _itoa(hopper, (char*)buf, 10); CSimpleStringA section(buf); Dbg("hopper:%d,%s", hopper, (const char*)section); if ((eErrDev = spConfig->WriteConfigValueInt(section, "CardRemains", num)) == Error_Succeed) { if (bInit) { if (section.Compare("1") == 0) spConfig->WriteConfigValueInt("RunInfo", "CardInit", num); eErrDev = spConfig->WriteConfigValueInt(section, "CardInit", num); } if (section.Compare("1") == 0) spConfig->WriteConfigValueInt("RunInfo", "CardRemains", num); if (eErrDev != Error_Succeed) { Dbg("write CardInit err:%d", eErrDev); return false; } //oilyang@20170428 汪磊东要求单卡箱也要同步数据 //if (m_hopperNum != 1 && !m_bSettingMaterial) if (!m_bSettingMaterial) { bool bMaintain[12]; memset(bMaintain, 0, 12); SyncDataToDB(bMaintain,false); } } else { Dbg("write CardRemains err:%d",eErrDev); return false; } return true; } bool CCardIssuerFSM::SetCardMixed(const int num, const int hopper) { Dbg("set mixed:%d,(hopper)%d",num,hopper); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set mixed)open cfg file failed!"); return false; } if (num == 0) SetDevStateAndSendMsg(DEVICE_STATUS_NORMAL); char buf[8]; memset(buf, 0, 8); _itoa(hopper, (char*)buf, 10); CSimpleStringA section(buf); Dbg("hopper:%d,%s", hopper, (const char*)section); eErrDev = spConfig->WriteConfigValueInt(section, "CardMixed", num); if (section.Compare("1") == 0) spConfig->WriteConfigValueInt("RunInfo", "CardMixed", num); if (eErrDev != Error_Succeed) { Dbg("write CardMixed err:%d", eErrDev); return false; } //oilyang@20170428 汪磊东要求单卡箱也要同步数据 //if (m_hopperNum != 1 && !m_bSettingMaterial) if (!m_bSettingMaterial) { bool bMaintain[12]; memset(bMaintain, 0, 12); SyncDataToDB(bMaintain,false); } return true; } ErrorCodeEnum CCardIssuerFSM::MachineMoveCardBackNotHold() { LOG_FUNCTION(); ErrorCodeEnum eMoveNotHold = m_pCardIssuer->MoveCard(CI_MOVECARD_BACK_NOT_HOLD); Dbg("capture card:%d",eMoveNotHold); //2016-11-10 14:30:54 joseph if (eMoveNotHold != Error_Succeed) { AlarmDEC("MachineMoveCardBackNotHold", eMoveNotHold, MEC_DEVAPI_CARDISSUER_CI_MOVECARD_BACK_NOT_HOLD); //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_CaptureCard_Failed, "吞卡失败"); //DevErrorInfo devErrInfo; //ErrorCodeEnum err = m_pCardIssuer->GetLastErr(devErrInfo); //if (err == Error_Succeed) //{ // Dbg("MoveCard back not hold failed [%s].", devErrInfo.szErrMsg); //} //else //{ // Dbg("MoveCard back not hold failed, get lastErr failed."); //} return eMoveNotHold; } //oilyang@20170929 根据讨论结果,去掉调用 //2016-11-10 14:34:44 joseph //GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; //pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); //ErrorCodeEnum eAddMaterial = pGuiConsoleClient->Connect(); //if (eAddMaterial == Error_Succeed) //{ // if (pGuiConsoleClient) // { // Dbg("to add material counter."); // GUIConsoleService_AddMaterialCounter_Req req; // GUIConsoleService_AddMaterialCounter_Ans ans; // req.strMaterialCode = "RetainCard"; // eAddMaterial = pGuiConsoleClient->AddMaterialCounter(req, ans, 10000); // Dbg("%d", eAddMaterial); // if (pGuiConsoleClient != NULL) // { // pGuiConsoleClient->GetFunction()->CloseSession(); // pGuiConsoleClient->SafeDelete(); // pGuiConsoleClient = NULL; // } // } //} return eMoveNotHold; } ErrorCodeEnum CCardIssuerFSM::MachineMoveCardFrontGate() { LOG_FUNCTION(); ErrorCodeEnum eMoveFrontGate = m_pCardIssuer->MoveCard(CI_MOVECARD_FRONT_GATE); //if (eMoveFrontGate != Error_Succeed) // LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_MoveCardToGate_Failed, "吐卡失败"); return eMoveFrontGate; } int CCardIssuerFSM::QueryCardInfo() { if (m_pCardIssuer == NULL) return 1; //ErrorCodeEnum eErr = m_pCardIssuer->GetDevStatus(m_devStatus); //if (eErr == Error_Succeed) if(GetDevStatus()) { Dbg("m_devStatus.eMedia %d",m_devStatus.eMedia); if (m_devStatus.eMedia == CI_MEDIA_PRESENT) { return 2; } else { return 0; } } else { return 1; } } //void CCardIssuerFSM::LogDevErrorInfo() //{ // WORD wdErrCode = 0; // CSimpleStringA csErrMsg(true); // ErrorCodeEnum ec = DeviceBaseHelper::GetAndSplitDevErrInfo(m_pCardIssuer, csErrMsg, wdErrCode); //} int CCardIssuerFSM::ConnectSCI() { LOG_FUNCTION(); if (m_bDoingQueryListOrBindSCI || m_bUnbindType3) { //while doing QuerySCIList or BindSCI,we pretend to doing sth and return Dbg("in doing query list or bind sci or have unbind:(doingOrBind)%d,(unbind)%d", m_bDoingQueryListOrBindSCI,m_bUnbindType3); return Error_InvalidState; } ErrorCodeEnum errCode = Error_Unexpect; BYTE btOpenType = DEV_OPEN_TYPE_BLUETOOTH | DEV_OPEN_TYPE_USB;//oiltmp for change if ((btOpenType & DEV_OPEN_TYPE_BLUETOOTH) == DEV_OPEN_TYPE_BLUETOOTH) { m_bBTConncting = true; } if (IsValidSCIName(m_csDevSN, m_csDevSN.GetLength())) { errCode = OpenDevice(btOpenType, m_csDevSN); if (errCode != Error_Succeed) { Dbg("OpenDevice failed(%d).", errCode); CloseAndClearDevObj(false); } } else { Dbg("invalid device sn name!! %s", m_csDevSN.GetData()); errCode = Error_DataCheck; } m_bBTConncting = false; return errCode; } //判断是否配置了便携发卡机 int CCardIssuerFSM::QueryIfCfgSCI() { if (m_csDevSN.GetLength() > 2) return 1; else return 0; } int CCardIssuerFSM::SetDevStateAndSendMsg(const DevStateEnum eState, bool bForceSend) { if(m_eDevState != eState || bForceSend) { SCIConnect evt; evt.status = m_eDevState = eState; SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(SCIConnect), SP_MSG_SIG_OF(SCIConnect), evt); Dbg("dev state changed: %d", eState); } return 0; } int CCardIssuerFSM::DataTransferInitEx() { LOG_FUNCTION(); AccessAuthService_ClientBase *pAccessAuthClient = new AccessAuthService_ClientBase(GetEntityBase()); if (pAccessAuthClient == NULL) { Dbg("new AccessAuthService_ClientBase failed."); return -1; } ErrorCodeEnum eErr = pAccessAuthClient->Connect(); if (eErr != Error_Succeed) { Dbg("connect to Entity AccessAuth failed.%d", eErr); return -1; } Dbg("Connect to AccessAuth ok."); ZeroMemory(m_priKey, ONE_K / 2); //AsciiToHex("16E532957F1F107F794C1F8157CC768A72BD425B6F425B3C67153DB9082B7F45", m_priKey, strlen("16E532957F1F107F794C1F8157CC768A72BD425B6F425B3C67153DB9082B7F45")); memcpy(m_priKey, "16E532957F1F107F794C1F8157CC768A72BD425B6F425B3C67153DB9082B7F45", strlen("16E532957F1F107F794C1F8157CC768A72BD425B6F425B3C67153DB9082B7F45")); int iStatus; BYTE *Cr1, *Cr3, *dKey; Cr1 = new BYTE[ONE_K / 4]; Cr3 = new BYTE[ONE_K / 4]; dKey = new BYTE[ONE_K / 4]; ZeroMemory(Cr1, ONE_K / 4); ZeroMemory(Cr3, ONE_K / 4); ZeroMemory(dKey, ONE_K / 4); int lenCr1, lenCr3, lenDKey; bool bFirstFailed = false; Dbg("TransferEnInit start..."); eErr = m_pCardIssuer->TransferEnInit(iStatus, Cr1, lenCr1, Cr3, lenCr3, dKey, lenDKey); if (eErr != Error_Succeed) { Dbg("TransferEnInit failed:%d,%d", eErr, iStatus); return 1; } Dbg("TransferEnInit ok.lenCr1:%d,lenCr3:%d,lenDKey:%d", lenCr1, lenCr3, lenDKey); if (lenCr1 < 0 || lenCr3 < 0 || lenDKey < 0) return 1; ZeroMemory(m_r1, ONE_K / 8); char tmpCr1[2048], tmpCr3[2048], tmpDKey[2048]; ZeroMemory(tmpCr1, ONE_K * 2); ConvAscii(Cr1, tmpCr1, lenCr1); ZeroMemory(tmpCr3, ONE_K * 2); ConvAscii(Cr3, tmpCr3, lenCr3); ZeroMemory(tmpDKey, ONE_K * 2); ConvAscii(dKey, tmpDKey, lenDKey); char random_key[128]; unsigned char tbuf[4096]; char encrnd[1024]; int encdatalen; int iloop; //取随机因子 srand((int)time(NULL)); for (iloop = 0; iloop < 32; iloop++) tbuf[iloop] = rand() % 256; ConvAscii(tbuf, random_key, 32); //随机数2 BYTE r2[16]; ZeroMemory(r2, 16); for (int i = 0; i < 15; ++i) { srand((int)time(NULL)); unsigned int ram = rand(); r2[i] = ram % 256; r2[15] ^= r2[i]; m_r2[i] = r2[i]; } m_r2[15] = r2[15]; char *xxxR2 = new char[256]; ZeroMemory(xxxR2, 256); ConvAscii(r2, xxxR2, 16); AccessAuthService_InitDev_Req req; AccessAuthService_InitDev_Ans ans; req.EncR1 = tmpCr1; req.EncR3 = tmpCr3; req.EncDevPubKey = tmpDKey; req.R2 = xxxR2; req.Vendor = m_devCat.szVendor; Dbg("to InitDev(%s).", m_devCat.szVendor); eErr = pAccessAuthClient->InitDev(req, ans, 5000); if (eErr != Error_Succeed) { Dbg("InitDev from AccessAuth returned failed. %d", eErr); if (Cr1 != NULL) delete[]Cr1; if (Cr3 != NULL) delete[]Cr3; if (dKey != NULL) delete[]dKey; return -1; } Dbg("InitDev ok."); if (Cr1 != NULL) delete[]Cr1; if (Cr3 != NULL) delete[]Cr3; if (dKey != NULL) delete[]dKey; //Dbg("Cr2:%d,%s",ans.EncR2.GetLength(),(const char*)ans.EncR2); //Dbg("oiltest %s,%s",(const char*)ans.R1,(const char*)ans.R3); unsigned char *xxxCR2 = new unsigned char[512]; ZeroMemory(xxxCR2, 512); AsciiToHex(const_cast(ans.EncR2.GetData()), xxxCR2, ans.EncR2.GetLength()); eErr = m_pCardIssuer->SetR2(iStatus, xxxCR2, ans.EncR2.GetLength() / 2); if (eErr != Error_Succeed) { Dbg("SetR2 failed:%d, %d", eErr, iStatus); return 3; } Dbg("Set R2 ok."); AsciiToHex(const_cast(ans.R1.GetData()), m_r1, ans.R1.GetLength()); AsciiToHex(const_cast(ans.R3.GetData()), m_r3, ans.R3.GetLength()); int lenrandom1, lenrandom2, lenrandom3; lenrandom1 = lenrandom2 = lenrandom3 = 16; int ilen = 0; char databuf[2048]; char key[128]; memset(databuf, 0, sizeof(databuf)); memset(tbuf, 0, sizeof(tbuf)); memcpy(databuf, m_r2, lenrandom2); for (iloop = 0; iloop < 64; iloop++) databuf[iloop] ^= 0x5C; memcpy(tbuf, m_r2, lenrandom2); for (iloop = 0; iloop < 64; iloop++) tbuf[iloop] ^= 0x36; ilen = 64; memcpy(tbuf + ilen, "KEY", strlen("KEY")); ilen += strlen("KEY"); memcpy(tbuf + ilen, m_r1, lenrandom1); ilen += lenrandom1; memcpy(tbuf + ilen, m_r3, lenrandom3); ilen += lenrandom3; SM3Hash((unsigned char *)tbuf, ilen, (unsigned char *)(databuf + 64)); SM3Hash((unsigned char *)databuf, 96, (unsigned char *)key); char *sessionKey = new char[1024]; ZeroMemory(sessionKey, 1024); HexBuf2StrBuf((unsigned char *)key, &sessionKey, 16); //Dbg("oiltest key[%s]", sessionKey); eErr = m_pCardIssuer->SendWorkingKey(sessionKey); if (eErr != Error_Succeed) { Dbg("SendWorkingKey failed:%d,iStatus", eErr, iStatus); return 4; } return 0; } int CCardIssuerFSM::LoadSafeLockDll() { #ifdef RVC_OS_WIN CSimpleStringA csDepPath, csBackslash("\\"), csSafelockDll, csSafelockDllDukpt; ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath); csSafelockDll = csDepPath + csBackslash + "JNIDUKPT.dll"; csSafelockDllDukpt = csDepPath + csBackslash + "Dukpt.dll"; HMODULE m_hModule = LoadLibraryA(csSafelockDll); if (m_hModule == NULL) { Dbg("load JNIDUKPT.dll failed.%d", GetLastError()); } if ((EncypteDukptHSM = (pfEncryptDukptHSM)GetProcAddress(m_hModule, "EncryptDukptHSM")) == NULL) { Dbg("Get function EncryptDukptHSM failed.%d", GetLastError()); } HMODULE m_hModuleDukpt = LoadLibraryA(csSafelockDllDukpt); if (m_hModuleDukpt == NULL) { Dbg("load Dukpt.dll failed.%d", GetLastError()); } if ((GetEncrypedData = (pfGetEncrypedData)GetProcAddress(m_hModuleDukpt, "GetEncrypedData")) == NULL) { Dbg("Get function GetEncrypedData failed.%d", GetLastError()); } Dbg("Load SafeLock dll ok."); #endif //RVC_OS_WIN return 0; } void two_one(unsigned char *in, int in_len, unsigned char *out) { unsigned char tmpc; int i; for (i = 0; i '9') && (tmpc < 'A' || tmpc > 'F')) tmpc = 'F'; if (tmpc > '9') tmpc = toupper(tmpc) - 'A' + 0x0A; else tmpc -= '0'; tmpc <<= 4; out[i / 2] = tmpc; tmpc = in[i + 1]; tmpc = toupper(tmpc); if ((tmpc < '0' || tmpc > '9') && (tmpc < 'A' || tmpc > 'F')) tmpc = 'F'; if (tmpc > '9') tmpc = toupper(tmpc) - 'A' + 0x0A; else tmpc -= '0'; out[i / 2] |= tmpc; } } void one_two(unsigned char *in, int in_len, unsigned char *out) { unsigned char i; static unsigned char TAB[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; for (i = 0; i < in_len; i++) { out[i * 2] = TAB[in[i] >> 4]; out[i * 2 + 1] = TAB[in[i] & 0x0f]; } } static char DecCh2HexCh(BYTE c) { if (c >= 0x0 && c <= 0x9) return c + '0'; else if (c >= 0xa && c <= 0xf) return c + 'a' - 10; else return 0; } int CCardIssuerFSM::EncryptData(SCITempData ramData, SCITempData bdk, SCITempData curksn, SCITempData &encryptedData) { BYTE ram[64]; ZeroMemory(ram, 64); Dbg("size ram:%d,bdk:%d,curksn:%d", ramData.dwSize, bdk.dwSize,curksn.dwSize); for (int i = 0, j = 0; i < ramData.dwSize; ++i) { ram[j++] = DecCh2HexCh((ramData.data[i] & 0xf0) >> 4); ram[j++] = DecCh2HexCh(ramData.data[i] & 0x0f); } //PBYTE pTmpBDK = new BYTE[64]; //PBYTE pTmpKSN = new BYTE[64]; BYTE pTmpBDK[64], pTmpKSN[64]; ZeroMemory(pTmpBDK, 64); ZeroMemory(pTmpKSN, 64); //HexBuf2StrBuf(bdk.data, (char**)&pTmpBDK, bdk.dwSize); //HexBuf2StrBuf(curksn.data, (char**)&pTmpKSN, curksn.dwSize); //PBYTE pData = new BYTE[64]; one_two(bdk.data, bdk.dwSize, pTmpBDK); one_two(curksn.data, curksn.dwSize, pTmpKSN); BYTE pData[64]; ZeroMemory(pData, 64); Dbg("to EncypteDukptHSM"); if (EncypteDukptHSM != NULL) EncypteDukptHSM(ram, pTmpBDK, pTmpKSN, pData); Dbg("to two_one"); two_one(pData, 16, encryptedData.data); Dbg("end two_one"); //if (pTmpBDK != NULL) //{ // delete[]pTmpBDK; // pTmpBDK = NULL; //} //if (pTmpKSN != NULL) //{ // delete[]pTmpKSN; // pTmpKSN = NULL; //} //if (pData != NULL) //{ // delete[]pData; // pData = NULL; //} Dbg("encrypt ok."); encryptedData.dwSize = 8; return 0; } int CCardIssuerFSM::OpenSafeLock(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); bool bOpenSuc = false; SCITempData ksnData, ramData; ErrorCodeEnum eErr = Error_Succeed; eErr = m_pCardIssuer->SLGetTempData(ksnData, ramData); //ksnData.dwSize = 7; //ksnData.data[0] = 0x00; //ksnData.data[1] = 0x00; //ksnData.data[2] = 0x00; //ksnData.data[3] = 0x01; //ksnData.data[4] = 0x00; //ksnData.data[5] = 0x00; //ksnData.data[6] = 0x2B; //ramData.dwSize = 4; //ramData.data[0] = 0xA8; //ramData.data[1] = 0x25; //ramData.data[2] = 0x36; //ramData.data[3] = 0x84; if (eErr != Error_Succeed) { AlarmDEC("OpenSafeLock:SL_GetTempData ", eErr, MEC_DEVAPI_CARDISSUER_SLGetTempData); Dbg("SLGetTempData failed.%d",eErr); } Dbg("Get temp data ok %d,%d.",ksnData.dwSize,ramData.dwSize); //char *tmpStr = new char[128]; //ZeroMemory(tmpStr, 128); //HexBuf2StrBuf(ksnData.data, (char**)&tmpStr, ksnData.dwSize); //ZeroMemory(tmpStr, 128); //HexBuf2StrBuf(ramData.data, (char**)&tmpStr, ramData.dwSize); const int cmdSize = 26; BYTE tmp[cmdSize] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0x11, 0x22, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }; ZeroMemory(m_bdk, sizeof(m_bdk)); ZeroMemory(m_ksn, sizeof(m_ksn)); memcpy(m_bdk, tmp, 16); memcpy(m_ksn, tmp + 16, 10); //SCITempData bdk, ksn, enData; //memcpy(bdk.data, m_bdk, 16); //bdk.dwSize = 16; //memcpy(ksn.data, m_ksn, 3); //memcpy(ksn.data + 3, ksnData.data, 7); //ksn.dwSize = 10; BYTE ramAllData[64]; ZeroMemory(ramAllData, 64); memcpy(ramAllData, ksnData.data, 7); memcpy(ramAllData + 7, ramData.data, 4); SCITempData enData; int ret; Dbg("to encrypt data"); ZeroMemory(enData.data, 64); //ret = EncryptData(ramData, bdk, ksn, enData); if (GetEncrypedData != NULL) ret = GetEncrypedData(m_bdk, m_ksn, ramAllData, enData.data); enData.dwSize = 8; //if (eErr == Error_Succeed) { Dbg("to open door"); eErr = m_pCardIssuer->SLOpenDoor(enData); if (eErr != Error_Succeed) { AlarmDEC("OpenSafeLock:SLOpenDoor ", eErr, MEC_DEVAPI_CARDISSUER_SLOpenDoor); Dbg("SLOpenDoor failed.%d", eErr); } else { bOpenSuc = true; Dbg("Open SafeLock ok."); } } //else //{ // Dbg("EncryptData failed.%d", eErr); // LogDevErrorInfo(); //} if (ctx != NULL) { if (bOpenSuc) ctx->Answer(Error_Succeed); else ctx->Answer(Error_Unexpect, AlarmDECToBusiness("SLOpenDoor", eErr,MEC_DEVAPI_CARDISSUER_SLOpenDoor)); } return 0; } int CCardIssuerFSM::GetSCIInfo(char *&devSN) { if (m_machineType == 3) { Dbg("No CFG SCI"); return -1; } else if (m_machineType == 2 && !m_bBTConnected) { Dbg("SCI not connected."); return -2; } //if (m_csDevSN.GetLength() > 1) if(QueryIfCfgSCI()) { strncpy(devSN, (const char*)m_csDevSN, m_csDevSN.GetLength()); } else { //devSN = ""; strcpy(devSN, ""); } return 0; } int CCardIssuerFSM::UpdateLocalRunCfg(CAutoArray hopperArr) { LOG_FUNCTION(); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(UpdateLocalRunCfg)open cfg file failed!"); return false; } Dbg("hopperArr num:%d", hopperArr.GetCount()); char sec[2]; for (int i = 0; i < hopperArr.GetCount(); ++i) { ZeroMemory(sec, 2); _itoa(i + 1, (char*)sec, 10); if (hopperArr[i] == 1) { Dbg("sec:%s,CardBoxNo:%s,CardInit:%d,CardRemains:%d,CardIssued:%d", sec,(const char*)m_CardBoxNoEx[i] , m_CardInitEx[i],m_remainsEx[i], m_issuedEx[i]); spConfig->WriteConfigValue(sec, "CardBoxNo", m_CardBoxNoEx[i]); spConfig->WriteConfigValue(sec, "PsbCode", m_PsbCodeEx[i]); spConfig->WriteConfigValue(sec, "PsbName", m_PsbNameEx[i]); spConfig->WriteConfigValueInt(sec, "CardInit", m_CardInitEx[i]); spConfig->WriteConfigValueInt(sec, "CardRemains", m_remainsEx[i]); spConfig->WriteConfigValueInt(sec, "CardIssued", m_issuedEx[i]); spConfig->WriteConfigValueInt(sec, "CardMixed", m_mixedEx[i]); spConfig->WriteConfigValueInt(sec, "CardPercent", m_CardPercentEx[i]); spConfig->WriteConfigValue(sec, "Maintainer", m_MaintainerEx[i]); spConfig->WriteConfigValue(sec, "MaintainTime", m_csMaintainTimeEx[i]); if (i == 0 && hopperArr[0] == 1) { spConfig->WriteConfigValueInt("RunInfo", "CardInit", m_CardInitEx[i]); spConfig->WriteConfigValueInt("RunInfo", "CardRemains", m_remainsEx[i]); spConfig->WriteConfigValueInt("RunInfo", "CardIssued", m_issuedEx[i]); spConfig->WriteConfigValueInt("RunInfo", "CardMixed", m_mixedEx[i]); spConfig->WriteConfigValueInt("RunInfo", "CardPercent", m_CardPercentEx[i]); } } } return 0; } int CCardIssuerFSM::SyncDataToDB(bool bMaintain[12], bool bSetCaptured) { LOG_FUNCTION(); GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; Dbg("to new gui client"); //pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); pGuiConsoleClient = new GUIConsoleService_ClientBase((GetEntityBase())); Dbg("new gui client finish"); ErrorCodeEnum eConn = Error_Unexpect; if (pGuiConsoleClient != NULL) { Dbg("to connect to guiconsole"); eConn = pGuiConsoleClient->Connect(); if(eConn != Error_Succeed) pGuiConsoleClient->SafeDelete(); } else Dbg("new pGuiConsoleClient failed."); if (eConn != Error_Succeed) { Dbg("SyncDataToDB can't connect to GUIConsole."); pGuiConsoleClient = NULL; return -1; } else Dbg("SyncDataToDB GUIConsole connected."); GUIConsoleService_SyncMaterialCount_Info info = {}; info.dwCardBoxNum = m_hopperNum; if (_strnicmp("RVC.Stand2S", m_csMachineType, strlen("RVC.Stand2S")) == 0 || _strnicmp("RVC.CardStore", m_csMachineType, strlen("RVC.CardStore")) == 0 || _strnicmp("RVC.CardPrinter", m_csMachineType, strlen("RVC.CardPrinter")) == 0) { Dbg("%s",(const char*)m_csMachineType); info.strDeviceNo = m_terminalNo; } else info.strDeviceNo = m_csDevSN; //if (pDevSN != NULL) // delete[]pDevSN; Dbg("to init sync info[%d][%s]", info.dwCardBoxNum,(const char*)info.strDeviceNo); info.arrMaintainFlag.Init(m_hopperNum+1); info.arrMaintainer.Init(m_hopperNum+1); info.arrMaintainTime.Init(m_hopperNum+1); info.arrCardBoxNo.Init(m_hopperNum+1); info.arrPsbCode.Init(m_hopperNum+1); info.arrPsbName.Init(m_hopperNum+1); info.arrCardInit.Init(m_hopperNum+1); info.arrCardRemains.Init(m_hopperNum+1); info.arrCardIssued.Init(m_hopperNum+1); info.arrCardMixed.Init(m_hopperNum+1); info.arrCardPercent.Init(m_hopperNum+1); Dbg("to set info"); for (int i = 0; i < m_hopperNum; ++i) { Dbg("<%d>maintain:%d,maintainerEx:%s,maintainTimeEx:%d,CardBoxNoEx:%s,PsbCodeEx:%s,PsbNameEx:%s,CardInitEx:%d,remainsEx:%d,issuedEx:%d,mixedEx:%d,CardPercentEx:%d", i, bMaintain[i], (const char*)m_MaintainerEx[i], m_MaintainTimeEx[i], (const char*)m_CardBoxNoEx[i], (const char*)m_PsbCodeEx[i], (const char*)m_PsbNameEx[i] ,m_CardInitEx[i],m_remainsEx[i], m_issuedEx[i],m_mixedEx[i],m_CardPercentEx[i]); //[17:36 : 30.353][DEBUG] Debug: {0, SP01010101, 0, NX00000002, 47N2, IC金卡2, 100, 10, 1, 0, 10} info.arrMaintainFlag[i] = bMaintain[i]; info.arrMaintainer[i] = m_MaintainerEx[i]; info.arrMaintainTime[i] = m_MaintainTimeEx[i]; info.arrCardBoxNo[i] = m_CardBoxNoEx[i]; info.arrPsbCode[i] = m_PsbCodeEx[i]; info.arrPsbName[i] = m_PsbNameEx[i]; info.arrCardInit[i] = m_CardInitEx[i]; info.arrCardRemains[i] = m_remainsEx[i]; info.arrCardIssued[i] = m_issuedEx[i]; info.arrCardMixed[i] = m_mixedEx[i]; info.arrCardPercent[i] = m_CardPercentEx[i]; } { if (bSetCaptured) info.arrMaintainFlag[m_hopperNum] = 1; else info.arrMaintainFlag[m_hopperNum] = 0; info.arrCardRemains[m_hopperNum] = m_CardCaptured; info.arrMaintainer[m_hopperNum] = m_MaintainerEx[0]; info.arrMaintainTime[m_hopperNum] = m_MaintainTimeEx[0]; info.arrCardBoxNo[m_hopperNum] = ""; info.arrPsbCode[m_hopperNum] = ""; info.arrPsbName[m_hopperNum] = ""; info.arrCardInit[m_hopperNum] = 0; info.arrCardIssued[m_hopperNum] = 0; info.arrCardMixed[m_hopperNum] = 0; info.arrCardPercent[m_hopperNum] = 0; Dbg("bSetCaptured,flag:%d,captured:%d,mter:%s,mtime:%d", info.arrMaintainFlag[m_hopperNum], info.arrCardRemains[m_hopperNum], (const char*)info.arrMaintainer[m_hopperNum], info.arrMaintainTime[m_hopperNum]); } Dbg("to sync data."); if (pGuiConsoleClient != NULL) { eConn = pGuiConsoleClient->SyncMaterialCount(info); Dbg("%d", eConn); pGuiConsoleClient->GetFunction()->CloseSession(); pGuiConsoleClient = NULL; if (eConn != Error_Succeed) return -2; } else { Dbg("pGuiConsoleClient is null? unexpect error."); return -3; } return 0; } void CCardIssuerFSM::SetHopperNum(int hopperNum) { m_hopperNum = hopperNum; } int CCardIssuerFSM::BluetoothCheck() { m_bBTChecking = 2; ErrorCodeEnum eErr = Error_Unexpect; int count = 0; BYTE *pSig = new BYTE[3]; while (2 == m_bBTChecking) { Sleep(5000); if (m_pCardIssuer != NULL && m_bBTConnected && m_bInMainPage) { ZeroMemory(pSig, 3); eErr = m_pCardIssuer->BluetoothGetSignalStrength(pSig); Dbg("%d,%d,%d", eErr, pSig[0],pSig[1]); if (eErr != Error_Succeed) { Dbg("get bluetooth signal strength failed!"); count++; if (count >= 2) { LogWarn(Severity_High, Error_DevConnFailed, GetAlarmDEC(DEC_DEV_DISCONNECTED), "CardIssuer(SCI) device disconnecetd."); m_bBTConnected = false; Dbg("DevClose returned %d", m_pCardIssuer->DevClose()); count = 0; Dbg("send bluetooth disonnect event!"); FSMEvent *pEvt = new FSMEvent(USER_EVT_BLUETOOTH_DISCONNECT); PostEventFIFO(pEvt); assert(m_bBTConncting == FALSE); } } //else // DetectBluetoothSCI(); } } if(pSig) { delete pSig; } m_bBTChecking = 0; return 0; } void CCardIssuerFSM::DoExitWhenIdle() { ErrorCodeEnum eErr = m_pCardIssuer->GetDevStatus(m_devStatus); if (eErr == Error_Succeed) { Dbg("media:%d when receive exit while idle(s2) ", m_devStatus.eMedia); if (m_devStatus.eMedia == CI_MEDIA_PRESENT || m_devStatus.eMedia == CI_MEDIA_ENTERING) { JustReadCardNo(); m_captureReason = "4001"; eErr = MachineMoveCardBackNotHold(); Dbg("capture card result:%d",eErr); if (eErr == Error_Succeed) { bool bCaptured = RegistCardWhileCaptureCard(); Dbg("to capture card.regist %d", bCaptured); m_CardCaptured++; SetCardCaptured(m_CardCaptured); } } } } bool CCardIssuerFSM::JustReadCardNo() { ErrorCodeEnum eErr = Error_Unexpect; m_currCardNo = ""; bool bHasAccount = false; int activeCardType; bool bIC = m_pCardProcess->DetectIfICCard(CARD_MACHINE_ISSUER, m_pCardIssuer, activeCardType); if (bIC) { //oilyang@20201014 add emv support bool bGetICData = false; bGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333"); if (!bGetICData) { bGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888"); } ICData track2(false, 0x57, 0x00); string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType; if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1) { Dbg("can't find track2 in ic data"); } else { int pos = FindHexCharPosition(track2.value, 0x0d, track2.lenth); char *pICTrack2 = new char[128]; ZeroMemory(pICTrack2, 128); HexBuf2StrBuf(track2.value, &pICTrack2, track2.lenth); pICTrack2[37] = '\0'; char *ddd = new char[128]; memset(ddd, 0, 128); memcpy(ddd, pICTrack2, pos - 1); m_currCardNo = ddd; if (m_currCardNo.GetLength() > 1) bHasAccount = true; delete[]ddd; delete[]pICTrack2; } m_pCardIssuer->DeactivateICCard(); m_pCardIssuer->ReleaseIC(); } if (!bHasAccount) { MagTracks magTracks; eErr = m_pCardIssuer->MagRead(magTracks); if (eErr == Error_Succeed) { if (magTracks.track[1].eStatus == CI_DATA_OK) { int pos = 0; for (int i = 0; i < magTracks.track[1].dwSize; ++i, ++pos) { if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e) break; } Dbg("pos:%d", pos); char buf[128]; ZeroMemory(buf, 128); strncpy(buf, (char*)magTracks.track[1].data, pos); m_currCardNo = buf; if (m_currCardNo.GetLength() > 1) bHasAccount = true; } } else { AlarmDEC("JustReadCardNo::MagRead", eErr, MEC_DEVAPI_CARDISSUER_MagRead); } } if (m_currCardNo.GetLength() > 8) Dbg("record the account (%d):%s****%s", m_currCardNo.GetLength() , (const char*)m_currCardNo.SubString(0, 6), (const char*)m_currCardNo.SubString(m_currCardNo.GetLength() - 4, 4)); else Dbg("record the account (%d):%s", m_currCardNo.GetLength(), (const char*)m_currCardNo); return true; } bool CCardIssuerFSM::RegistCardWhileCaptureCard() { CSmallDateTime currTime; CSimpleStringA csCurrTime = currTime.GetNow().ToTimeString(); CAutoArray arrTime; arrTime = csCurrTime.Split(' '); CSimpleStringA csDate, csTime; csDate = arrTime[0].SubString(0, 4) + arrTime[0].SubString(5, 2) + arrTime[0].SubString(8, 2); csTime = arrTime[1].SubString(0, 2) + arrTime[1].SubString(3, 2) + arrTime[1].SubString(6, 2); GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; ErrorCodeEnum eErr = Error_Unexpect; pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); if (pGuiConsoleClient != NULL) eErr = pGuiConsoleClient->Connect(); else { Dbg("pGuiConsoleClient is null?"); return false; } if (eErr == Error_Succeed) { if (pGuiConsoleClient != NULL) { GUIConsoleService_RegistSwallowedCard_Req req; GUIConsoleService_RegistSwallowedCard_Ans ans; req.strCardNo = m_currCardNo; if (IsValidCardNo((const char*)m_currCardNo, m_currCardNo.GetLength())) { if (m_currCardNo.GetLength() > 0) req.strReasonCode = m_captureReason; else req.strReasonCode = "0000"; } else req.strReasonCode = "0001"; req.strSwallowDate = csDate; req.strSwallowTime = csTime; req.strDeviceSciNo = m_csDevSN; Dbg("%s,%s,%s****%s,%s", (LPCTSTR)csDate, (LPCTSTR)csTime, (LPCTSTR)m_currCardNo.SubString(0, 6), (LPCTSTR)m_currCardNo.SubString(m_currCardNo.GetLength()-4, 4),(LPCTSTR)m_captureReason); //if (m_currCardNo.GetLength() > 8) { Dbg("to regist"); Dbg("%s,%s****%s,%s,%s,%s", (LPCTSTR)req.strDeviceSciNo, (LPCTSTR)req.strCardNo.SubString(0, 6), (LPCTSTR)req.strCardNo.SubString(req.strCardNo.GetLength()-4, 4), (LPCTSTR)req.strReasonCode, (LPCTSTR)req.strSwallowDate, (LPCTSTR)req.strSwallowTime); if (m_bCaptureCfgFlag) { eErr = pGuiConsoleClient->RegistSwallowedCard(req, ans, 10000); Dbg("RegistSwallowedCard:%d", eErr); } else Dbg("no capture regist flag."); if (pGuiConsoleClient != NULL) { pGuiConsoleClient->GetFunction()->CloseSession(); pGuiConsoleClient = NULL; } } Dbg("after regist swallow card..."); } } else return false; return true; } bool CCardIssuerFSM::IsValidCardNo(const char *pCardNo,int len) { //oilyang@20170207 卡号长度有限 len = (len > 32) ? 32 : len; for (int i = 0; i < len; ++i) { if (pCardNo[i] < 0x30 || pCardNo[i] > 0x39) { //not '0'-'9' return false; } } return true; } int CCardIssuerFSM::IsValidSCIName(const char *pSCIName, int len) { //设备唯一标识:10位,厂商简称(两个字母,需报备行方) + SCI + 5位顺序序号 //怡化:YH;广电:YT;中航:ZH;南天:NT,中世顺:ZS; //如:YHSCI00001 if (len < 10 || len > 11) return 0; //oiltmp 20170713 需要增加配置,然后格式判断 if ((*(pSCIName + 2) == 'S') && (*(pSCIName + 3) == 'C') && (*(pSCIName + 4) == 'I')) return 1; else if((*(pSCIName + 2) == 'C') && (*(pSCIName + 3) == 'I') && (*(pSCIName + 4) == 'L')) { //设备唯一标识:10位,厂商简称(两个字母,需报备行方)+ CIL +5位顺序序号 return 2; } else return 0; } int CCardIssuerFSM::SAMICCommand(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum eErr = Error_Unexpect; Dbg("cmd %d",ctx->Req.cmdType); switch (ctx->Req.cmdType) { case SAMICCommand_SAM_Select: eErr = m_pCardIssuer->SAMSelect(ctx->Req.param1[0]); if(eErr) { AlarmDEC("SAMICCommand::SAMSelect", eErr, MEC_DEVAPI_CARDISSUER_SAMSelect); } break; case SAMICCommand_SAM_Active: eErr = m_pCardIssuer->SAMActive(ctx->Req.param1[0]); if(eErr) { AlarmDEC("SAMICCommand::SAMActive", eErr, MEC_DEVAPI_CARDISSUER_SAMActive); } break; case SAMICCommand_SAM_Deactivate: eErr = m_pCardIssuer->SAMDeactivate(); if(eErr) { AlarmDEC("SAMICCommand::SAMDeactivate", eErr, MEC_DEVAPI_CARDISSUER_SAMDeactivate); } break; case SAMICCommand_SAM_WarmReset: eErr = m_pCardIssuer->SAMWarmReset(); if(eErr) { AlarmDEC("SAMICCommand::SAMWarmReset", eErr, MEC_DEVAPI_CARDISSUER_SAMWarmReset); } break; case SAMICCommand_SAM_QueryStatus: { SAMStatus samStatus; eErr = m_pCardIssuer->SAMQueryStatus(samStatus); if (eErr == Error_Succeed) { ctx->Ans.ret1.Init(2); ctx->Ans.ret1[0] = samStatus.isActive; ctx->Ans.ret1[1] = samStatus.chosenOfSAM; } else { AlarmDEC("SAMICCommand::SAMQueryStatus", eErr, MEC_DEVAPI_CARDISSUER_SAMQueryStatus); } } break; case SAMICCommand_SAM_Command: { CmdInfo sendBuf, recvBuf; BYTE *pTmp = new BYTE[MAX_IC_BUFFER_SIZE]; ZeroMemory(pTmp, MAX_IC_BUFFER_SIZE); Dbg("%s",(const char*)ctx->Req.param2[0]); int size = StrBuf2HexBuf(ctx->Req.param2[0], &pTmp); memcpy(sendBuf.data, pTmp, size); sendBuf.dwSize = size; eErr = m_pCardIssuer->SAMCommand(sendBuf,recvBuf); if (eErr == Error_Succeed) { char *pRet = new char[MAX_IC_BUFFER_SIZE]; ZeroMemory(pRet, MAX_IC_BUFFER_SIZE); Dbg("%d",recvBuf.dwSize); HexBuf2StrBuf(recvBuf.data, (char**)&pRet, recvBuf.dwSize); ctx->Ans.ret1.Init(1); ctx->Ans.ret2.Init(1); ctx->Ans.ret1[0] = recvBuf.dwSize * 2; ctx->Ans.ret2[0] = pRet; delete[]pRet; } else { AlarmDEC("SAMICCommand::SAMCommand", eErr, MEC_DEVAPI_CARDISSUER_SAMCommand); } delete[]pTmp; } break; case SAMICCommand_IC_Active: { eErr = m_pCardIssuer->ContactIC(); if (eErr == Error_Succeed) { CmdInfo atrBuf; eErr = m_pCardIssuer->ActiveICCardATR(atrBuf); if (eErr == Error_Succeed) { BYTE* pTmp = new BYTE[MAX_IC_BUFFER_SIZE]; if (pTmp == NULL) { Dbg("new MAX_IC_BUFFER_SIZE failed"); eErr = Error_Unexpect; break; } ZeroMemory(pTmp, MAX_IC_BUFFER_SIZE); HexBuf2StrBuf(atrBuf.data, (char**)&pTmp, atrBuf.dwSize); ctx->Ans.ret1.Init(1); ctx->Ans.ret2.Init(1); ctx->Ans.ret1[0] = atrBuf.dwSize * 2; ctx->Ans.ret2[0] = CSimpleStringA((const char*)pTmp); Dbg("AtrCtx: size=%d, content=%s, pTmp=%s", ctx->Ans.ret1[0], (LPCTSTR)ctx->Ans.ret2[0], (LPCTSTR)pTmp); delete[] pTmp; pTmp = NULL; } else { Dbg("ActiveICCardATR failed EC=0x%x", eErr); } } else { AlarmDEC("SAMICCommand::ContactIC", eErr, MEC_DEVAPI_CARDISSUER_ContactIC); } } break; case SAMICCommand_IC_Deactivate: eErr = m_pCardIssuer->DeactivateICCard(); if (eErr != Error_Succeed) eErr = m_pCardIssuer->DeactivateICCard(); break; case SAMICCommand_IC_WarmReset: eErr = m_pCardIssuer->WarmReset(); break; case SAMICCommand_IC_Command: { CmdInfo sendBuf, recvBuf; BYTE *pTmp = new BYTE[MAX_IC_BUFFER_SIZE]; ZeroMemory(pTmp, MAX_IC_BUFFER_SIZE); int size = StrBuf2HexBuf(ctx->Req.param2[0], &pTmp); memcpy(sendBuf.data, pTmp, size); sendBuf.dwSize = size; eErr = m_pCardIssuer->ICCommand(sendBuf, recvBuf); if(false)//oilyang@20201224 before deploy ,comment loging apdu content { char *pRet = new char[MAX_IC_BUFFER_SIZE]; if (pRet != NULL) { ZeroMemory(pRet, MAX_IC_BUFFER_SIZE); HexBuf2StrBuf(sendBuf.data, (char**)&pRet, size); Dbg("%s", (const char*)pRet); delete[] pRet; } } if (eErr == Error_Succeed) { if (recvBuf.dwSize > 0 && recvBuf.dwSize < 1024) { char* pRet = new char[MAX_IC_BUFFER_SIZE]; ZeroMemory(pRet, MAX_IC_BUFFER_SIZE); Dbg("%d", recvBuf.dwSize); HexBuf2StrBuf(recvBuf.data, (char**)&pRet, recvBuf.dwSize); ctx->Ans.ret1.Init(1); ctx->Ans.ret2.Init(1); ctx->Ans.ret1[0] = recvBuf.dwSize * 2; ctx->Ans.ret2[0] = pRet; delete[]pRet; } } else { AlarmDEC("IC Channel(APDU) failed.",Error_Unexpect, CardIssuer_UserErrorCode_ICChannel_Failed); Dbg("ICCommand failed:%d", eErr); } delete[]pTmp; } break; case SAMICCommand_RFIC_Active: { char chType = 0; eErr = m_pCardIssuer->ActiveContactlessICCard('A', 'B', 'M', chType); ctx->Ans.ret1.Init(1); if (eErr == Error_Succeed) { Dbg("ActiveContactlessICCard:%d",chType); ctx->Ans.ret1[0] = chType; } else { AlarmDEC("SAMICCommand::ActiveContactlessICCard", eErr, MEC_DEVAPI_CARDISSUER_ActiveContactlessICCard); } } break; case SAMICCommand_RFIC_Deactivate: eErr = m_pCardIssuer->DeactContactlessICCard(); if (eErr != Error_Succeed) eErr = m_pCardIssuer->DeactContactlessICCard(); break; case SAMICCommand_RFIC_Command: { CmdInfo sendBuf, recvBuf; BYTE* pTmp = new BYTE[MAX_IC_BUFFER_SIZE]; ZeroMemory(pTmp, MAX_IC_BUFFER_SIZE); int size = StrBuf2HexBuf(ctx->Req.param2[0], &pTmp); memcpy(sendBuf.data, pTmp, size); sendBuf.dwSize = size; eErr = m_pCardIssuer->RFTypeABCommand(sendBuf, recvBuf); if (false)//oilyang@20201224 before deploy ,comment loging apdu content { char* pRet = new char[MAX_IC_BUFFER_SIZE]; if (pRet != NULL) { ZeroMemory(pRet, MAX_IC_BUFFER_SIZE); HexBuf2StrBuf(sendBuf.data, (char**)&pRet, size); Dbg("%s", (const char*)pRet); delete[] pRet; } } if (eErr == Error_Succeed) { if (recvBuf.dwSize > 0 && recvBuf.dwSize < 1024) { char* pRet = new char[MAX_IC_BUFFER_SIZE]; ZeroMemory(pRet, MAX_IC_BUFFER_SIZE); Dbg("%d", recvBuf.dwSize); HexBuf2StrBuf(recvBuf.data, (char**)&pRet, recvBuf.dwSize); ctx->Ans.ret1.Init(1); ctx->Ans.ret2.Init(1); ctx->Ans.ret1[0] = recvBuf.dwSize * 2; ctx->Ans.ret2[0] = pRet; delete[]pRet; } } delete[]pTmp; } break; default: break; } ctx->Answer(eErr); return 0; } int CalcDelayFactor(int failedCount) { if ((failedCount % 7) == 0) { return 1; } else return 1 << (failedCount % 7); } void CCardIssuerFSM::PeriodConnect(BOOL anotherThread) { //便携式蓝牙发卡器5s左右睡眠 Dbg("Fire period connect!"); Sleep(m_scanSlot * ONE_K * CalcDelayFactor(m_devOpenFailedCount)); if (m_bBTConnected || m_bBTConncting || m_currentFSMState != 12) { Dbg("return previously: btconnected: %d, btconnecting: %d, fsm state: %d", m_bBTConnected, m_bBTConncting, m_currentFSMState); return; } Dbg("to connect(by PeriodConnect)"); ConnectTask *task = new ConnectTask(this); if(anotherThread) { GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } else { ConnectTask *task = new ConnectTask(this); task->Process(); task->DecRef(); } } int CCardIssuerFSM::QueryPrinterStatus(SpReqAnsContext::Pointer ctx) { return 0; } int CCardIssuerFSM::Print(SpReqAnsContext::Pointer ctx) { int dataSize = 0; Dbg("print data bitmap of bmp:%d,face:%d,name:%s,%s;size:%d,%d", ctx->Req.reserved1[0], (const char*)ctx->Req.reserved2[0], ctx->Req.reserved1[1] , (const char*)ctx->Req.reserved2[1],ctx->Req.data1.m_iLength,ctx->Req.data2.m_iLength); if (ctx->Req.reserved1[0] > 0xf) { ctx->Answer(Error_Param); return -1; } PBYTE pData = new BYTE[2048]; if (pData == NULL) { Dbg("resource failed."); ctx->Answer(Error_Unexpect); return -1; } CSimpleStringA csDepPath, csBackslash("\\"), csABmp,csBBmp; ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath); ZeroMemory(pData, 2048); pData[dataSize++] = 0x37; pData[dataSize++] = 0x63; pData[dataSize++] = 0x30; //save print A bmp if ((ctx->Req.reserved1[0] & 0x1) == 0x1) { FILE *fp = NULL; csABmp = ctx->Req.reserved2[0]; //csABmp = csDepPath + csBackslash + "PrintImage.bmp"; Dbg("a.bmp:%s",(const char*)csABmp); fp = fopen((const char*)csABmp, "wb+"); if (fp) { fwrite(ctx->Req.data1.m_pData, 1, ctx->Req.data1.m_iLength, fp); fclose(fp); } else { Dbg("save print A file failed."); ctx->Answer(Error_Unexpect); return -1; } memcpy(pData + dataSize, ctx->Req.reserved2[0], ctx->Req.reserved2[0].GetLength()); dataSize += ctx->Req.reserved2[0].GetLength(); //memcpy(pData + dataSize, "PrintImage.bmp", strlen("PrintImage.bmp")); //dataSize += strlen("PrintImage.bmp"); pData[dataSize++] = 0x00; } //save print B bmp if ((ctx->Req.reserved1[0] & 0x2) == 0x2) { pData[2] = 0x31; csBBmp = ctx->Req.reserved2[1]; //csBBmp = csDepPath + csBackslash + ctx->Req.reserved2[1]; //csBBmp = csDepPath + csBackslash + "Overcoat.bmp"; Dbg("b.bmp:%s", (const char*)csBBmp); FILE *fp = fopen((const char*)csBBmp, "wb+"); if (fp) { fwrite(ctx->Req.data2.m_pData, 1, ctx->Req.data2.m_iLength, fp); fclose(fp); } else { Dbg("save print B file failed."); ctx->Answer(Error_Unexpect); return -1; } memcpy(pData + dataSize, ctx->Req.reserved2[1], ctx->Req.reserved2[1].GetLength()); dataSize += ctx->Req.reserved2[1].GetLength(); //memcpy(pData + dataSize, "Overcoat.bmp", strlen("Overcoat.bmp")); //dataSize += strlen("Overcoat.bmp"); pData[dataSize++] = 0x00; } pData[dataSize++] = 0x00; pData[dataSize++] = 0x00; char *tmpShow = new char[1024]; ZeroMemory(tmpShow, 1024); HexBuf2StrBuf(pData, &tmpShow, dataSize); Dbg("print datasize(%d)(%s)",dataSize,tmpShow); delete[]tmpShow; ErrorCodeEnum eErr = Error_Unexpect; //BYTE *pData = new BYTE[ctx->Req.reserved1[0]]; //if (pData != NULL) { eErr = m_pCardIssuer->Print(pData, dataSize,ctx->Req.reserved1[1]); if (eErr != Error_Succeed) { //DevErrorInfo devErrInfo; //ErrorCodeEnum eErrGet = m_pCardIssuer->GetLastErr(devErrInfo); //if (eErrGet == Error_Succeed) //{ // Dbg("Print failed.%s", devErrInfo.szErrMsg); //} ctx->Answer(eErr,AlarmDECToBusiness("Print:",eErr, MEC_DEVAPI_CARDISSUER_Print)); } ctx->Answer(Error_Succeed); } remove((const char*)csABmp); remove((const char*)csBBmp); return 0; } int CCardIssuerFSM::DetectBluetoothSCIOnLinux() { return Error_NotImpl; } int CCardIssuerFSM::DetectBluetoothSCI() { #ifdef RVC_OS_WIN ClearSCIRecords(); WSADATA m_data; SOCKET s; WSAPROTOCOL_INFO protocolInfo; int protocolInfoSize; WSAQUERYSET querySet, *pResults, querySet2; HANDLE hLookup, hLookup2; int result; static int i; BYTE buffer[1000]; BYTE buffer1[2000]; DWORD bufferLength, flags, addressSize, bufferLength1; CSADDR_INFO *pCSAddr; BTH_DEVICE_INFO *pDeviceInfo; char addressAsString[2000]; BLOB *pBlob; GUID protocol; // Load the winsock2 library if (WSAStartup(MAKEWORD(2, 2), &m_data) == 0) { // Create a blutooth socket s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); if (s == INVALID_SOCKET) { Dbg("Failed to get bluetooth socket with error code %ld", WSAGetLastError()); return 1; } else { Dbg("create socket() suc!"); } protocolInfoSize = sizeof(protocolInfo); // Get the bluetooth device info using getsockopt() if (getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &protocolInfoSize) != 0) { Dbg("getsockopt(SO_PROTOCOL_INFO) failed with error code %ld", WSAGetLastError()); return 1; } else { Dbg("getsockopt(SO_PROTOCOL_INFO) is OK!"); } // Query set criteria memset(&querySet, 0, sizeof(querySet)); querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_BTH; // Set the flags for query //LUP_RETURN_BLOB //flags = LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_NEAREST | // LUP_RETURN_TYPE | LUP_RES_SERVICE; flags = LUP_CONTAINERS| LUP_FLUSHCACHE; Dbg("Start a device in range query..."); result = WSALookupServiceBegin(&querySet, flags, &hLookup); if(WSAGetLastError() == 10108 && m_bBTConncting) { WSASetLastError(10108); const int maxWaitTimes = 12; int currentWaitTimes = 0; do { Dbg("waiting bluetooth connect operation finish..."); Sleep(800); currentWaitTimes++; if(currentWaitTimes >= maxWaitTimes) { Dbg("Timeout break"); break; } } while (m_bBTConncting); memset(&querySet, 0, sizeof(querySet)); querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_BTH; result = WSALookupServiceBegin(&querySet, flags, &hLookup); } Dbg("If OK"); bool bFirst = false;//oilyang@20170802 暂时不用 if (result == 0) { i = 0; //sockaddr *pRemoteAddr = new sockaddr(); while (result == 0) { bufferLength = sizeof(buffer); pResults = (WSAQUERYSET *)&buffer; // Next query... flags = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_NEAREST | LUP_RETURN_TYPE | LUP_RES_SERVICE; result = WSALookupServiceNext(hLookup, flags, &bufferLength, pResults); if (result != 0) { Dbg("WSALookupServiceNext() failed with error code %ld", WSAGetLastError()); } else { // Get the device info, name, address etc // if (IsValidSCIName(pResults->lpszServiceInstanceName, strlen(pResults->lpszServiceInstanceName))) // { // } pCSAddr = (CSADDR_INFO *)pResults->lpcsaBuffer; pDeviceInfo = (BTH_DEVICE_INFO *)pResults->lpBlob; memset(&querySet2, 0, sizeof(querySet2)); querySet2.dwSize = sizeof(querySet2); protocol = L2CAP_PROTOCOL_UUID; querySet2.lpServiceClassId = &protocol; querySet2.dwNameSpace = NS_BTH; if(strlen(pResults->lpszServiceInstanceName) > 0) { Dbg("instance name: %s,protocol:%d,socket type:%d", pResults->lpszServiceInstanceName, pCSAddr->iProtocol, pCSAddr->iSocketType); } // Print the local bluetooth device address... //addressSize = sizeof(addressAsString); //if (WSAAddressToString(pCSAddr->LocalAddr.lpSockaddr, pCSAddr->LocalAddr.iSockaddrLength, // &protocolInfo, (LPSTR)addressAsString, &addressSize) == 0) //{ // Dbg("The local address: %s", addressAsString); //} //else { // Dbg("WSAAddressToString() for local address failed with error code %ld", WSAGetLastError()); //} addressSize = sizeof(addressAsString); // Print the remote bluetooth device address... if (WSAAddressToString(pCSAddr->RemoteAddr.lpSockaddr, pCSAddr->RemoteAddr.iSockaddrLength, &protocolInfo, (LPSTR)addressAsString, &addressSize) == 0) { if (IsValidSCIName(pResults->lpszServiceInstanceName, strlen(pResults->lpszServiceInstanceName))) { Dbg("The remote device address: %s", addressAsString); //oiltest@20200113 去掉socket连接确认蓝牙卡机是否在附近 //Dbg(" add %s\n", pResults->lpszServiceInstanceName); AddToSCIRecords(pResults->lpszServiceInstanceName, addressAsString, bFirst); bFirst = false; #ifndef CancelSocketConfirm SOCKET LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); //sockaddr sockaddr_value; //sockaddr *pRemoteAddr = &sockaddr_value; if (INVALID_SOCKET == LocalSocket) { Dbg("socket() call failed. WSAGetLastError = [%d]", WSAGetLastError()); } else { // 设置为非阻塞的socket int iMode = 1; ioctlsocket(LocalSocket, FIONBIO, (u_long FAR*)&iMode); // 超时时间 struct timeval tm; tm.tv_sec = 7; tm.tv_usec = 0; int ret = -1; // // Connect the socket (pSocket) to a given remote socket represented by address (pServerAddr) // SOCKADDR_BTH xAddr; //CopyMemory(&xAddr,(PSOCKADDR_BTH)pCSAddr->RemoteAddr.lpSockaddr,sizeof(xAddr)); //xAddr.btAddr = 0x0000881b99079464; //ZeroMemory(pRemoteAddr->sa_data, sizeof(pRemoteAddr->sa_data)); //pRemoteAddr->sa_family = AF_BTH; //memcpy(pRemoteAddr->sa_data, addressAsString, strlen(addressAsString)); int iAddrLen = sizeof(xAddr); WSAStringToAddress(addressAsString, AF_BTH, NULL, (LPSOCKADDR)&xAddr, &iAddrLen); xAddr.addressFamily = AF_BTH; xAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; xAddr.port = 0; //if (SOCKET_ERROR == connect(LocalSocket, (const sockaddr*)pRemoteAddr, sizeof(pRemoteAddr))) bool isConnected = false; if (SOCKET_ERROR != connect(LocalSocket,(struct sockaddr *) &xAddr,sizeof(SOCKADDR_BTH))) { isConnected = true; Dbg("connected."); //Dbg("=CRITICAL= | connect() call failed. WSAGetLastError=[%d]\n", WSAGetLastError()); //break; } else { fd_set set; FD_ZERO(&set); FD_SET(LocalSocket, &set); if (select(-1, NULL, &set, NULL, &tm) <= 0) { ret = -1; // 有错误(select错误或者超时) isConnected = false; Dbg("can't connect or timeout."); } else { int error = -1; int optLen = sizeof(int); getsockopt(LocalSocket, SOL_SOCKET, SO_ERROR, (char*)&error, &optLen); if (0 != error) { ret = -1; // 有错误 } else { isConnected = true; Dbg("connected 2."); } } } if (isConnected) { //Dbg(" add %s\n", pResults->lpszServiceInstanceName); AddToSCIRecords(pResults->lpszServiceInstanceName, addressAsString, bFirst); bFirst = false; } Dbg("close socket."); closesocket(LocalSocket); // 设回为阻塞socket iMode = 0; ioctlsocket(LocalSocket, FIONBIO, (u_long FAR*)&iMode); //设置回阻塞模式 } #endif // !CancelSocketConfirm } } else { Dbg("WSAAddressToString() for remote address failed with error code %ld", WSAGetLastError()); } } } // Close handle to the device query if (WSALookupServiceEnd(hLookup) == 0) { Dbg("WSALookupServiceEnd(hLookup) is fine!", WSAGetLastError()); } else { Dbg("WSALookupServiceEnd(hLookup) failed with error code %ld"); } } else { Dbg("WSALookupServiceBegin() failed with error code %ld", WSAGetLastError()); }// end WSALookupServiceBegin() // Cleanup the winsock library startup if (WSACleanup() == 0) { Dbg("WSACleanup() fine!"); } else { Dbg("WSACleanup() failed with error code %ld", WSAGetLastError()); } } // end WSAStartup() return 0; #else return DetectBluetoothSCIOnLinux(); #endif //RVC_OS_WIN } int CCardIssuerFSM::QuerySCIList( SpReqAnsContext::Pointer ctx, const int fsmState) { m_bDoingQueryListOrBindSCI = true; DetectBluetoothSCI(); vector vTmp; //to get SCI list EnterCriticalSection(&g_sciRecord); vector::iterator it; for (it = m_vSCIRecords.begin(); it != m_vSCIRecords.end(); it++) { vTmp.push_back(*it); } LeaveCriticalSection(&g_sciRecord); //query info of each sci GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; ErrorCodeEnum errCode = Error_Unexpect; pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); if (pGuiConsoleClient != NULL) { errCode = pGuiConsoleClient->Connect(); }else { Dbg("pGuiConsoleClient is null?"); } if (errCode == Error_Succeed) { if (pGuiConsoleClient) { for (it = vTmp.begin(); it != vTmp.end(); it++) { GUIConsoleService_QueryMaterialInfo_Req req; GUIConsoleService_QueryMaterialInfo_Ans ans; req.strDeviceNo = it->name; Dbg("sci.name:%s", (const char*)req.strDeviceNo); errCode = pGuiConsoleClient->QueryMaterialInfo(req, ans, 10000); if (errCode == Error_Succeed) { Dbg("QueryMaterialInfo suc,count is:%d", ans.count); //for (int i = 0; i < ans.count; i++) if (ans.count >= 0 && ans.count < 100)//oilyang@20180228 count有时候会异常大,不正常 { int tmpCount = ans.count; if (ans.count == 0) { tmpCount = 1; CSimpleStringA blank(""); unsigned int intZero = 0; ctx->Ans.sciNo.Append(&(req.strDeviceNo), 0, 1); ctx->Ans.arrMateriel.Append(&blank, 0, 1); ctx->Ans.CardGroove.Append(&blank, 0, 1); ctx->Ans.CardBoxNo.Append(&blank, 0, 1); ctx->Ans.PsbCode.Append(&blank, 0, 1); ctx->Ans.PsbName.Append(&blank, 0, 1); ctx->Ans.CardInit.Append(&intZero, 0, 1); ctx->Ans.CardRemains.Append(&intZero, 0, 1); ctx->Ans.CardIssued.Append(&intZero, 0, 1); ctx->Ans.CardMixed.Append(&intZero, 0, 1); ctx->Ans.CardPercent.Append(&intZero, 0, 1); ctx->Ans.Maintainer.Append(&blank, 0, 1); ctx->Ans.MaintainTime.Append(&blank, 0, 1); ctx->Ans.UpdateTime.Append(&blank, 0, 1); } else { ctx->Ans.sciNo.Append(ans.arrDeviceNo, 0, ans.count); ctx->Ans.arrMateriel.Append(ans.arrMateriel, 0, ans.count); ctx->Ans.CardGroove.Append(ans.CardGroove, 0, ans.count); ctx->Ans.CardBoxNo.Append(ans.CardBoxNo, 0, ans.count); ctx->Ans.PsbCode.Append(ans.PsbCode, 0, ans.count); ctx->Ans.PsbName.Append(ans.PsbName, 0, ans.count); ctx->Ans.CardInit.Append(ans.CardInit, 0, ans.count); ctx->Ans.CardRemains.Append(ans.CardRemains, 0, ans.count); ctx->Ans.CardIssued.Append(ans.CardIssued, 0, ans.count); ctx->Ans.CardMixed.Append(ans.CardMixed, 0, ans.count); ctx->Ans.CardPercent.Append(ans.CardPercent, 0, ans.count); ctx->Ans.Maintainer.Append(ans.Maintainer, 0, ans.count); ctx->Ans.MaintainTime.Append(ans.MaintainTime, 0, ans.count); ctx->Ans.UpdateTime.Append(ans.UpdateTime, 0, ans.count); } Dbg("add sci %s,record count:%d,count:%d", (const char*)req.strDeviceNo, ctx->Ans.sciNo.GetCount(), tmpCount); } else Dbg("QueryMaterialInfo ans.count:%d", ans.count); } else Dbg("QueryMaterialInfo failed.%d", errCode); } ctx->Answer(Error_Succeed); } } m_bDoingQueryListOrBindSCI = false; return fsmState; } int CCardIssuerFSM::BindSCI( SpReqAnsContext::Pointer ctx, const int fsmState) { m_bDoingQueryListOrBindSCI = true; Dbg("bindSCI type:%d, name:%s, previous fsm state: %d",ctx->Req.type, (const char*)ctx->Req.sciNo, fsmState); ErrorCodeEnum eErr = Error_Unexpect; int ret = 0; switch (ctx->Req.type) {//绑定类型:1:绑定(从后台同步数据) 2:绑定成功告知终端 3:解绑(终端数据同步到后台) 4:解绑成功 case 1: if (!IsValidSCIName((const char*)ctx->Req.sciNo, ctx->Req.sciNo.GetLength())) { ctx->Answer(Error_Param); } else { eErr = AfterBindSyncData((const char*)ctx->Req.sciNo, true); ctx->Answer(eErr); } ret = fsmState; break; case 2: if (!IsValidSCIName((const char*)ctx->Req.sciNo, ctx->Req.sciNo.GetLength())) { ctx->Answer(Error_Param); } else { AfterBindUpdateSCINameToRunCfg((const char*)ctx->Req.sciNo, true); ret = 1; m_csDevSN = ctx->Req.sciNo; //绑定成功的时候才更新设备名称? Dbg("after bind,to close previous SCI."); CloseAndClearDevObj(); m_bUnbindType3 = false; ctx->Answer(Error_Succeed); } break; case 3: if (!IsValidSCIName((const char*)ctx->Req.sciNo, ctx->Req.sciNo.GetLength())) { ctx->Answer(Error_Param); } else { //解绑操作,同步运行时数据(而不是初始化数据)到后台数据库 //在pad已经绑定多合一,而又没有连上的时候,如果收到解绑操作,去运行时取值再同步数据 CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; eErr = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErr != Error_Succeed) { Dbg("open run cfg file failed!"); ctx->Answer(eErr); } char sec[2]; for (int i = 0; i < 3; ++i) { ZeroMemory(sec, 2); _itoa(i + 1, (char*)sec, 10); Dbg("sec:%s",sec); spConfig->ReadConfigValue(sec, "CardBoxNo", m_CardBoxNoEx[i]); spConfig->ReadConfigValue(sec, "PsbCode", m_PsbCodeEx[i]); spConfig->ReadConfigValue(sec, "PsbName", m_PsbNameEx[i]); spConfig->ReadConfigValueInt(sec, "CardInit", m_CardInitEx[i]); spConfig->ReadConfigValueInt(sec, "CardRemains", m_remainsEx[i]); spConfig->ReadConfigValueInt(sec, "CardIssued", m_issuedEx[i]); spConfig->ReadConfigValueInt(sec, "CardMixed", m_mixedEx[i]); spConfig->ReadConfigValueInt(sec, "CardPercent", m_CardPercentEx[i]); spConfig->ReadConfigValue(sec, "Maintainer", m_MaintainerEx[i]); spConfig->ReadConfigValue(sec, "MaintainTime", m_csMaintainTimeEx[i]); } eErr = AfterBindSyncData((const char*)ctx->Req.sciNo, false); ctx->Answer(eErr); if (eErr == Error_Succeed) { //已经解除绑定,告知OpenDevice退出尝试连接 Dbg("to set m_bUnbindType3 true"); m_bUnbindType3 = true; } } ret = fsmState; break; case 4: AfterBindUpdateSCINameToRunCfg((const char*)ctx->Req.sciNo, false); //if (ctx->Req.sciNo.GetLength() > 0) //{ // AfterBindUpdateSCINameToRunCfg((const char*)ctx->Req.sciNo, false); //} //else //{ // AfterBindUpdateSCINameToRunCfg("", false); //} ret = 0; // AfterBindUpdateSCINameToRunCfg 函数中已经做了清空 [10/10/2019 9:16 @Gifur] // m_csDevSN = ""; //告知解绑成功才清空设备名称,并调用适配器的关闭接口 Dbg("after un bind,to close SCI."); CloseAndClearDevObj(false, true); //if (m_pCardIssuer != NULL && !m_bBTConncting) //{ // eErr = m_pCardIssuer->DevClose(); // Dbg("Close device returned: %d", eErr); // //ReleaseDevComponent((DeviceBaseClass *&)m_pCardIssuer); // //m_pCardIssuer = NULL; //} ctx->Answer(Error_Succeed); break; default: break; } m_bDoingQueryListOrBindSCI = false; return ret; } void CCardIssuerFSM::AddToSCIRecords(const char *name, const char * remoteMac, bool bFirst) { EnterCriticalSection(&g_sciRecord); if (bFirst) { m_vSCIRecords.clear(); } SCIRecord record; record.name = name; record.remoteMac = remoteMac; m_vSCIRecords.push_back(record); Dbg("the %dth sci,name is:%s", m_vSCIRecords.size(),name); LeaveCriticalSection(&g_sciRecord); } void CCardIssuerFSM::ClearSCIRecords() { EnterCriticalSection(&g_sciRecord); m_vSCIRecords.clear(); LeaveCriticalSection(&g_sciRecord); return; } ErrorCodeEnum CCardIssuerFSM::AfterBindSyncData(const char *name, bool bBind) { LOG_FUNCTION(); if (!bBind) { bool bMaintain[12]; memset(bMaintain, 0, 12); bMaintain[0] = bMaintain[1] = true; int ret = SyncDataToDB(bMaintain,false); if (ret != 0) { Dbg("AfterBindSyncData %d",ret); return Error_Unexpect; } } else { GUIConsoleService_ClientBase *pGuiConsoleClient = NULL; ErrorCodeEnum errCode = Error_Unexpect; pGuiConsoleClient = new GUIConsoleService_ClientBase(dynamic_cast(GetEntityBase())); if (pGuiConsoleClient != NULL) errCode = pGuiConsoleClient->Connect(); else { Dbg("AfterBindSyncData pGuiConsoleClient is null?"); return Error_Unexpect; } GUIConsoleService_QueryMaterialInfo_Req req; GUIConsoleService_QueryMaterialInfo_Ans ans; req.strDeviceNo = name; errCode = pGuiConsoleClient->QueryMaterialInfo(req, ans, 10000); if (errCode == Error_Succeed) { CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(AfterBindSyncData)open cfg file failed!"); return Error_Unexpect; } char sec[2]; for (int i = 0; i < ans.count; ++i) { ZeroMemory(sec, 2); _itoa(i + 1, (char*)sec, 10); Dbg("sec:%s", sec); Dbg("box no:%s,name:%s,init:%d,remains:%d,maintainer:%s",(const char*)ans.CardBoxNo[i],(const char*)ans.PsbName[i] ,ans.CardInit[i],ans.CardRemains[i],(const char*)ans.Maintainer[i]); spConfig->WriteConfigValue(sec, "CardBoxNo", ans.CardBoxNo[i]); spConfig->WriteConfigValue(sec, "PsbCode", ans.PsbCode[i]); spConfig->WriteConfigValue(sec, "PsbName", ans.PsbName[i]); spConfig->WriteConfigValueInt(sec, "CardInit", ans.CardInit[i]); spConfig->WriteConfigValueInt(sec, "CardRemains", ans.CardRemains[i]); spConfig->WriteConfigValueInt(sec, "CardIssued", ans.CardIssued[i]); spConfig->WriteConfigValueInt(sec, "CardMixed", ans.CardMixed[i]); spConfig->WriteConfigValueInt(sec, "CardPercent", ans.CardPercent[i]); spConfig->WriteConfigValue(sec, "Maintainer", ans.Maintainer[i]); spConfig->WriteConfigValue(sec, "MaintainTime", ans.MaintainTime[i]); if (i == 0) { spConfig->WriteConfigValueInt("RunInfo", "CardInit", ans.CardInit[i]); spConfig->WriteConfigValueInt("RunInfo", "CardRemains", ans.CardRemains[i]); spConfig->WriteConfigValueInt("RunInfo", "CardIssued", ans.CardIssued[i]); spConfig->WriteConfigValueInt("RunInfo", "CardMixed", ans.CardMixed[i]); spConfig->WriteConfigValueInt("RunInfo", "CardPercent", ans.CardPercent[i]); } } } else { Dbg("QueryMaterialInfo ret:%d",errCode); return errCode; } } return Error_Succeed; } ErrorCodeEnum CCardIssuerFSM::AfterBindUpdateSCINameToRunCfg(const char *name, bool bBind) { LOG_FUNCTION(); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(AfterBindUpdateSCINameToRunCfg)open cfg file failed!"); return eErrDev; } if (bBind) { CSimpleStringA csName(name); spConfig->WriteConfigValue("SCI", "name", name); CSimpleStringA csVendor = csName.SubString(0, 2); Dbg("sci vendor: %s",(const char*)csVendor); //怡化:YH;广电:YT;中航:ZH;南天:NT,中世顺:ZS;中钞科堡 CK,长城:CC,东方通信:DX if (csVendor.Compare("CK") == 0) spConfig->WriteConfigValue("SCI", "Vendor","keba"); else if (csVendor.Compare("YT") == 0) spConfig->WriteConfigValue("SCI", "Vendor", "grg"); else if (csVendor.Compare("NT") == 0) spConfig->WriteConfigValue("SCI", "Vendor", "nantian"); else if (csVendor.Compare("ZS") == 0) spConfig->WriteConfigValue("SCI", "Vendor", "zss"); else if (csVendor.Compare("CC") == 0) spConfig->WriteConfigValue("SCI", "Vendor", "GWI"); else if (csVendor.Compare("DX") == 0) { spConfig->WriteConfigValue("SCI", "Vendor", "EastCom"); } else { spConfig->WriteConfigValue("SCI", "Vendor", (const char*)csVendor); } } else { spConfig->WriteConfigValue("SCI", "Vendor", ""); spConfig->WriteConfigValue("SCI", "name", ""); m_csDevSN = ""; } return Error_Succeed; } void CCardIssuerFSM::GetVendorDllName(CSimpleStringA &strDevAdaptorPath) { if (m_csMachineType.Compare("RVC.Stand2S") == 0 || m_csMachineType.Compare("RVC.CardStore") == 0 || m_csMachineType.Compare("RVC.CardPrinter") == 0 || m_csMachineType.Compare("RVC.Desk1S") == 0 || (m_csMachineType.Compare("RVC.Desk2S") == 0 && m_majorVerion == 2 && (m_minorVerion == 0 || m_minorVerion == 1))) { SpGetDevAdaptorPath(m_pEntity, GetEntityBase()->GetEntityName(), strDevAdaptorPath); return; } CSmartPointer spConfigRoot,spConfigRun; ErrorCodeEnum eErr = Error_Unexpect; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (eErr == Error_Succeed) { CSimpleStringA str(""); strDevAdaptorPath = "CardIssuer"; spConfigRun->ReadConfigValue("SCI", "Vendor", str); if (!str.IsNullOrEmpty()) { strDevAdaptorPath += "."; strDevAdaptorPath += str; } HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, str); //一代便携式发卡器 const int SCIVersion = IsValidSCIName(m_csDevSN, m_csDevSN.GetLength()); if(SCIVersion == 1) { // 南天更换新硬件驱动 [11/6/2019 16:47 @Gifur] if(m_csDevSN.IsStartWith("NTSCIB", true)) { strDevAdaptorPath += ".1.5"; Dbg("nantian new version device."); } else { //oilyang@20171228 根据和邱总讨论结果,便携卡机固定1.4 strDevAdaptorPath += ".1.4"; } } else if(SCIVersion == 2){ // 新发卡器定义版本 [10/21/2019 8:35 @Gifur] strDevAdaptorPath += ".1.20"; } else { Dbg("find the cfg in the root.ini!!!"); eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfigRoot); if (eErr == Error_Succeed) { //当运行时没有厂商名称时 if(strDevAdaptorPath.Compare("CardIssuer", true) == 0) { str.Clear(); spConfigRoot->ReadConfigValue("Device.CardIssuer", "Vendor", str); if (!str.IsNullOrEmpty()) { strDevAdaptorPath += "."; strDevAdaptorPath += str; } HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, str); } str.Clear(); spConfigRoot->ReadConfigValue("Device.CardIssuer", "Version", str); if (!str.IsNullOrEmpty()) { strDevAdaptorPath += "."; strDevAdaptorPath += str; } str.Clear(); spConfigRoot->ReadConfigValue("Device.CardIssuer", "Batch", str); if (!str.IsNullOrEmpty()) { strDevAdaptorPath += "."; strDevAdaptorPath += str; } } else { Dbg("Error occurs when open root config: %d", eErr); } } CSimpleStringA strDepPath; GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath); #ifdef RVC_OS_WIN strDevAdaptorPath = CSimpleStringA::Format("%s\\%s.dll", (const char*)strDepPath, (const char*)strDevAdaptorPath); #else strDevAdaptorPath = CSimpleStringA::Format("%s/%s.so", (const char*)strDepPath, (const char*)strDevAdaptorPath); #endif } return; } void CCardIssuerFSM::GetSCINo(CSimpleStringA &sciNo) { sciNo = m_csDevSN; } bool CCardIssuerFSM::AccountExchange(const char *origAcc, CSimpleStringA &acc, int dir) { int len = strlen(origAcc); if (len < 8) { Dbg("account size error:%d",len); return false; } CSimpleStringA csTmp(' ',len+1); csTmp[len] = '\0'; if (dir) { int size, max; size = max = len / 4; if (len < 16) max = 4; for (int i = 0; i < max; i++) { csTmp[i * size] = *(origAcc + i); csTmp[i * size + 1] = *(origAcc + 4 + i); if (8 + i < len) csTmp[i * size + 2] = *(origAcc + 8 + i); if (12 + i < len) csTmp[i * size + 3] = *(origAcc + 12 + i); } if (len % 4 != 0) { for (int j = 4 * (len / 4); j < len; j++) csTmp[j] = *(origAcc + j); } acc = csTmp; } else { int size, max; size = max = len / 4; if (len < 16) max = 4; for (int i = 0; i < size; i++) { csTmp[i * 4] = *(origAcc + i); csTmp[i * 4 + 1] = *(origAcc + size + i); csTmp[i * 4 + 2] = *(origAcc + 2*size + i); csTmp[i * 4 + 3] = *(origAcc + 3*size + i); } if (len % 4 != 0) { for (int j = 4 * (len / 4); j < len; j++) csTmp[j] = *(origAcc + j); } acc = csTmp; } return true; } bool CCardIssuerFSM::WriteSlotInfo(CSmartPointer &cfgRun, const char *acc, const char *cardSerial, int slot, bool bClear) { char buf[8]; ZeroMemory(buf, 8); int sum = 0; cfgRun->ReadConfigValueInt("SlotInfo", "count", sum); if (bClear) { cfgRun->WriteConfigValue("SlotInfo", _itoa(slot, buf, 10), "0,0,0"); return true; } CSimpleStringA csAcc(""); if (AccountExchange(acc, csAcc)) { csAcc = csAcc + ",1," + cardSerial; cfgRun->WriteConfigValue("SlotInfo", _itoa(slot, buf, 10), csAcc); sum++; cfgRun->WriteConfigValueInt("SlotInfo", "count", sum); return true; } return false; } bool CCardIssuerFSM::ReadSlotInfo(CSmartPointer &cfgRun, CSimpleStringA &acc, CSimpleStringA &cardSerial, int slot, int &hasCard) { char buf[8]; ZeroMemory(buf, 8); CSimpleStringA csAcc(""); cfgRun->ReadConfigValue("SlotInfo", _itoa(slot, buf, 10), csAcc); CAutoArray arr = csAcc.Split(','); if (arr.GetCount() < 3) { //Dbg("data error.size:%d",arr.GetCount()); return false; } if (arr[1].Compare("1") == 0) hasCard = 1; else hasCard = 0; csAcc = arr[0]; cardSerial = arr[2]; Dbg("account length: %d", strlen(csAcc)); if (AccountExchange(csAcc, acc, 0)) { return true; } return false; } bool CCardIssuerFSM::WriteCardInfo(CSmartPointer &cfgRun, const char *acc, const char* serial, int slot, bool bClear, bool bHasCard) { char buf[8]; ZeroMemory(buf, 8); if (bClear || !bHasCard) { cfgRun->WriteConfigValue("OperateCardStore", _itoa(slot, buf, 10), "0,0,0"); return true; } CSimpleStringA csAcc(""); if (AccountExchange(acc, csAcc)) { CSimpleStringA tmp("1,"); csAcc = tmp + csAcc + "," + serial; cfgRun->WriteConfigValue("OperateCardStore", _itoa(slot, buf, 10), (const char*)csAcc); return true; } return false; } bool CCardIssuerFSM::ReadCardInfo(CSmartPointer &cfgRun, CSimpleStringA &acc, CSimpleStringA &serial, int slot) { char buf[8]; ZeroMemory(buf, 8); CSimpleStringA csAcc(""); cfgRun->ReadConfigValue("OperateCardStore", _itoa(slot, buf, 10), csAcc); CAutoArray arr = csAcc.Split(','); if (arr.GetCount() < 3) { //Dbg("data error.size:%d",arr.GetCount()); return false; } csAcc = arr[1]; serial = arr[2]; if(strlen(csAcc) < 8 || serial.GetLength() <= 0) { return false; } if (AccountExchange(csAcc, acc, 0)) { return true; } return false; } bool CCardIssuerFSM::SetSlotFlag(int slot, bool bReset,bool bClear) { return true; } void CCardIssuerFSM::ClearAllLocalSlotInfo() { LOG_FUNCTION(); CSmartPointer spConfigRun; ErrorCodeEnum eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (eErr != Error_Succeed) { Dbg("open runcfg failed.%d", eErr); return; } for (int i = 0; i < m_maxSlot; i++) { WriteSlotInfo(spConfigRun, "", "",i, true); } } int CCardIssuerFSM::PreOnlineOnStore(SpReqAnsContext::Pointer ctx) { HeartBeatService_ClientBase *pHeartBeatClient = NULL; ErrorCodeEnum eErr = Error_Unexpect; pHeartBeatClient = new HeartBeatService_ClientBase(GetEntityBase()); if (pHeartBeatClient != NULL) { eErr = pHeartBeatClient->Connect(); if(eErr != Error_Succeed) pHeartBeatClient->SafeDelete(); } else { Dbg("pGuiConsoleClient is null?"); ctx->Answer(Error_Unexpect); return 0; } m_crossStart = GetTickCountRVC(); if (eErr == Error_Succeed) { if (pHeartBeatClient != NULL) { m_crossCtx = ctx; HeartBeatService_CardActive_Req req; HeartBeatService_CardActive_Ans ans; req.type = 0; req.account = ctx->Req.account; req.term = ctx->Req.termNo; req.data = ctx->Req.businessData; req.slot = ctx->Req.slot; eErr = pHeartBeatClient->CardActive(req, ans, 60000); Dbg("card active result:%x", eErr); pHeartBeatClient->GetFunction()->CloseSession(); pHeartBeatClient = NULL; } } return 0; } void CCardIssuerFSM::NotifyPreOnline(unsigned long errCode, unsigned long findCard, unsigned long cardPos, CSimpleStringA data) { UINT64 crossEnd = GetTickCountRVC(); //in 110 second if (m_crossCtx != NULL) { if ((crossEnd - m_crossStart) < 110 * 1000) { m_crossCtx->Ans.cardPos = cardPos; m_crossCtx->Ans.findCard = findCard; m_crossCtx->Ans.result = data; Dbg("notify result:%d",errCode); m_crossCtx->Answer((ErrorCodeEnum)errCode); } m_crossCtx = NULL; } } int CCardIssuerFSM::IssueCardFromStore(SpReqAnsContext::Pointer ctx,bool bSpec) { LOG_FUNCTION(); ErrorCodeEnum eErr = Error_Unexpect; eErr = m_pCardIssuer->MoveCardFromSlot(ctx->Req.reserved1[0]); if (eErr == Error_Succeed) { //oiltmp 只为杭州中心门禁 if (ctx->Req.hopper == 97) { ctx->Answer(Error_Succeed); return 0; } CardNo card; ctx->Ans.reserved1.Init(3); ctx->Ans.reserved2.Init(2); eErr = m_pCardIssuer->ReadAccount(card); if (eErr == Error_Succeed && ctx->Req.reserved2[0].GetLength() == card.dwSize && strncmp(card.account, ctx->Req.reserved2[0], card.dwSize) == 0) { Dbg("ReadAccount ok."); m_currCardNo = card.account; if (card.dwSize > 6) Dbg("acc:%s****%s", (const char*)m_currCardNo.SubString(0, 6), (const char*)m_currCardNo.SubString(m_currCardNo.GetLength() - 4, 4)); ctx->Ans.reserved1[0] = 0; ctx->Ans.reserved1[1] = 0; if (bSpec) { ctx->Ans.reserved1[1] = 4; if (eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 32) ctx->Ans.reserved2[0] = card.account; else ctx->Ans.reserved2[0] = ""; //oilyang@20171214 直接吐卡 @宋锐 EjectTask *task = new EjectTask(this); task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); ctx->Answer(Error_Succeed); return 6; } } else { ctx->Ans.reserved1[0] = 3; if (bSpec) { if (eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 32) ctx->Ans.reserved2[0] = card.account; else ctx->Ans.reserved2[0] = ""; if (ctx->Req.hopper == 98) { ctx->Ans.reserved1[1] = 4; //oilyang@20171214 直接吐卡 @宋锐 EjectTask *task = new EjectTask(this); task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); ctx->Answer(Error_Succeed); return 6; } if (ctx->Req.hopper == 100) { int ret = 2; ctx->Ans.reserved1[1] = 5; //zjw@20190506 直接吞卡 @宋锐 //这里改为同步,因为清卡操作要循环调用,以防本次还未吞卡结束又调用下一次清卡,导致流程混乱 eErr = MachineMoveCardBackNotHold(); if(eErr == Error_Succeed) { bool bCaptured = RegistCardWhileCaptureCard(); Dbg("to capture card.regist %d", bCaptured); } else ret = 1; m_CardCaptured++; if(!SetCardCaptured(m_CardCaptured)) Dbg("set card captured failed."); m_pCardProcess->DataInit(); if(Error_Succeed == eErr) { eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if(eErr != Error_Succeed) { //LogErrInfo("after capture,close shutter"); AlarmDEC("IssueCardFromStore::SetCardInType", eErr, MEC_DEVAPI_CARDISSUER_SetCardInType); } if(ctx != NULL) ctx->Answer(Error_Succeed); } else { AlarmDEC("IssueCardFromStore::MachineMoveCardBackNotHold", eErr, CardIssuer_UserErrorCode_CaptureCard_Failed); //DevErrorInfo devErrInfo; //m_pCardIssuer->GetLastErr(devErrInfo); //Dbg("capture err %s",devErrInfo.szErrMsg); if (ctx != NULL) ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_CaptureCard_Failed); } return ret; } } else { eErr = m_pCardIssuer->MoveCardToSlot(ctx->Req.reserved1[0]); if (eErr == Error_Succeed) { ctx->Ans.reserved1[1] = 1; Dbg("accout not eqaul,card have been move back to slot."); ctx->Answer(Error_Succeed); return 2; } else { RegistCardWhileCaptureCard(); eErr = MachineMoveCardBackNotHold(); if (eErr == Error_Succeed) { ctx->Ans.reserved1[1] = 2; Dbg("accout not eqaul,card move back to slot failed,capture card suc."); ctx->Answer(Error_Succeed); return 2; } else { ctx->Ans.reserved1[1] = 3; Dbg("accout not eqaul,card move back to slot failed,capture card failed."); } } } } ctx->Answer(Error_Succeed); } else { //Dbg("MoveCardFromSlot failed.%d",eErr); ctx->Answer(Error_Unexpect, AlarmDECToBusiness("IssueCardFromStore::MoveCardFromSlot", eErr , MEC_DEVAPI_CARDISSUER_MoveCardFromSlot)); return 2; } return 0; } int CCardIssuerFSM::AddCardToStoreStepFirst(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_addCardNo = ""; m_addCardSerial = ""; ErrorCodeEnum eErr = Error_Unexpect; eErr = m_pCardIssuer->MoveCard(CI_MOVECARD_FROM_HOPPER,99); Dbg("add card first result:%d",eErr); ctx->Ans.reserved1.Init(4); ctx->Ans.reserved2.Init(2); //oiltest@20180704 for songrui //ctx->Ans.reserved1[2] = 0; //CardNo cardtmp; //m_pCardIssuer->ReadAccount(cardtmp); //if (eErr != Error_Succeed) //ctx->Ans.reserved1[2] = 3; //else //ctx->Ans.reserved1[2] = 0; //ctx->Answer(Error_Succeed); //return 0; if (eErr == Error_Succeed) { CardNo card; ctx->Ans.reserved2[0] = ""; eErr = m_pCardIssuer->ReadAccount(card); bool bDataOK = true;//oilyang@20171213 是否读卡失败,是否解析出卡序号,否则吞卡 @宋锐 if (eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 64) { Dbg("read account ok.card.dwTrack2Size:%d,card.dwTrack3Size:%d", card.dwTrack2Size, card.dwTrack3Size); //oilyang@20201217 if only ic if (card.dwTrack3Size == 2) { Dbg("maybe only ic card."); ctx->Ans.reserved2[1] = m_addCardSerial = (const char*)card.track3; } else { Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; char* tmpMag2 = new char[256]; ZeroMemory(tmpMag2, 256); bool bT2OK = false, bT3OK = false; if (card.dwTrack2Size > 0 && card.dwTrack2Size < 41) { //oilyang@20171129 IC卡等效二磁道数据可能存在补F的情况 if (card.track2[card.dwTrack2Size - 1] == 'F') { card.track2[card.dwTrack2Size - 1] = '\0'; card.dwTrack2Size--; } bT2OK = true; } if (card.dwTrack3Size > 0 && card.dwTrack3Size < 150) bT3OK = true; DecodeTracksData(card.track2, card.dwTrack2Size, card.track3, card.dwTrack3Size, tmpMag2, bT2OK, bT3OK); if (SplitTrack2(tmpMag2, track2Data) == 0) { Dbg("set card serial %s", (const char*)track2Data.t2CardSerial); ctx->Ans.reserved2[1] = track2Data.t2CardSerial; m_addCardSerial = track2Data.t2CardSerial; } } Dbg("account size:%d", card.dwSize); ctx->Ans.reserved1[2] = 0; m_currCardNo = m_addCardNo = ctx->Ans.reserved2[0] = CSimpleStringA(card.account, card.dwSize); if (card.dwSize > 6) Dbg("acc:%s****%s", (const char*)ctx->Ans.reserved2[0].SubString(0, 6), (const char*)ctx->Ans.reserved2[0].SubString(ctx->Ans.reserved2[0].GetLength() - 4, 4)); if (m_addCardSerial.GetLength() > 0) { ctx->Answer(Error_Succeed); } else bDataOK = false; } else bDataOK = false; if (!bDataOK) { Dbg("read card failed,to capture card.%d,serial:%s",eErr,(const char*)m_addCardSerial); ctx->Ans.reserved1[2] = 1; RegistCardWhileCaptureCard(); eErr = MachineMoveCardBackNotHold(); ctx->Answer(Error_Succeed); if (eErr == Error_Succeed) return 2; } } else { //oiltest need to add Dbg("move card from card box to card reader failed.%d",eErr); ctx->Ans.reserved1[2] = 3; ctx->Answer(Error_Succeed); return 2; } return 0; } int CCardIssuerFSM::AddCardToStoreStepLast(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum eErr = Error_Unexpect; int slot = FindFirstEmptySlot(); if (slot < 0) { ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_KakuFindEmptySlot_Failed); return 0; } ctx->Ans.reserved1.Init(4); ctx->Ans.reserved2.Init(2); eErr = m_pCardIssuer->MoveCardToSlot(slot); if (eErr == Error_Succeed) { Dbg("move card to slot %d suc.",slot); m_currCardNo = ""; ctx->Ans.reserved1[0] = slot; ctx->Ans.reserved1[2] = 0; ctx->Ans.reserved2[0] = ""; CSmartPointer spConfigRun; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (eErr != Error_Succeed) { Dbg("open runcfg to write slot info failed.%d",eErr); } else WriteSlotInfo(spConfigRun, (const char*)m_addCardNo,(const char*)m_addCardSerial, slot); ctx->Answer(Error_Succeed); return 2; } else { Dbg("move card to slot failed.to capture card."); ctx->Ans.reserved1[2] = 2; RegistCardWhileCaptureCard(); MachineMoveCardBackNotHold(); ctx->Answer(Error_Succeed,AlarmDECToBusiness("AddCardToStoreStepLast::MoveCardToSlot" , eErr, MEC_DEVAPI_CARDISSUER_MoveCardToSlot)); return 2; } ctx->Answer(Error_Succeed); return 0; } int CCardIssuerFSM::FindFirstEmptySlot() { LOG_FUNCTION(); SlotStatus status; ErrorCodeEnum eErr = m_pCardIssuer->QuerySlotsStatus(status, 0,true); if (eErr != Error_Succeed) { AlarmDEC("FindFirstEmptySlot::QuerySlotsStatus", eErr, MEC_DEVAPI_CARDISSUER_QuerySlotsStatus); return -1; } for (int i = 0; i < status.dwSize; i++) { if (status.status[i] == 0) { Dbg("find slot %d ok.",i); return i; } } Dbg("can't find a empty slot in %d",status.dwSize); return -1; } bool CCardIssuerFSM::IsValidSlotNum(const int slot) { if (m_maxSlot == 0 || slot < 0 || slot >= m_maxSlot) return false; return true; } bool CCardIssuerFSM::IsSlotHasCard(const int slot) { if (m_pCardIssuer != NULL) { SlotStatus status; ErrorCodeEnum eErr = m_pCardIssuer->QuerySlotsStatus(status, slot); Dbg("slot:%d,ret:%d,status:%d", slot,eErr, status.status[slot]); if (eErr == Error_Succeed && status.status[slot] == 1) return true; } return false; } void CCardIssuerFSM::AfterPreOnlineOnStore(ErrorCodeEnum err, const int slot) { LOG_FUNCTION(); ErrorCodeEnum eErr = Error_Unexpect; if (err == Error_Param)//oilyang@20171201 暂时不会进这里了,根据郭丹说明,所有跨机操作优先把卡移回卡槽 { RegistCardWhileCaptureCard(); eErr = MachineMoveCardBackNotHold(); if (eErr == Error_Succeed) m_cardPos = 2; else m_cardPos = 3; } else { eErr = m_pCardIssuer->MoveCardToSlot(slot); if (eErr == Error_Succeed) { Dbg("move card back to slot %d suc.",slot); m_cardPos = 1; } else { AlarmDECToBusiness("GetDevStatus::AfterPreOnlineOnStore", eErr, MEC_DEVAPI_CARDISSUER_MoveCardToSlot); //Dbg("move card back to slot failed.%d",eErr); RegistCardWhileCaptureCard(); eErr = MachineMoveCardBackNotHold(); if (eErr == Error_Succeed) m_cardPos = 2; else m_cardPos = 3; } } GetEntityBase()->GetFunction()->SetSysVar("CardStoreInUse", "N"); } bool CCardIssuerFSM::OperateCardStore(CSmartPointer &spConfigRun, int slot, int& status) { ErrorCodeEnum eErr = Error_Unexpect; DevErrorInfo devErrorInfo; eErr = m_pCardIssuer->MoveCardFromSlot(slot); if(eErr == Error_Succeed) { CardNo card; ZeroMemory(card.account, sizeof(card.account)); eErr = m_pCardIssuer->ReadAccount(card); bool bDataOK = true; //读卡成功并解析出卡序号,才算成功,卡序号也要返回 if(eErr == Error_Succeed && card.dwSize > 0 && card.dwSize < 64) { Dbg("read account OK."); //oilyang@20201217 if only ic if (card.dwTrack3Size == 2) { Dbg("maybe only ic card."); m_addCardSerial = (const char*)card.track3; } else { Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; char* tmpMag2 = new char[256]; ZeroMemory(tmpMag2, 256); bool bT2OK = false, bT3OK = false; if (card.dwTrack2Size > 0 && card.dwTrack2Size < 41) { //IC卡等效二磁道数据可能存在补F的情况(参考oilyang@20171129) if (card.track2[card.dwTrack2Size - 1] == 'F') { card.track2[card.dwTrack2Size - 1] = '\0'; card.dwTrack2Size--; } bT2OK = true; } if (card.dwTrack3Size > 0 && card.dwTrack3Size < 150) bT3OK = true; DecodeTracksData(card.track2, card.dwTrack2Size, card.track3, card.dwTrack3Size, tmpMag2, bT2OK, bT3OK); if (SplitTrack2(tmpMag2, track2Data) == 0) { Dbg("set card serial %s", (const char*)track2Data.t2CardSerial); m_addCardSerial = track2Data.t2CardSerial; } } m_currCardNo = card.account; Dbg("account size:%d", card.dwSize); /*if(card.dwSize > 6) Dbg("account: %s", (const char*)m_currCardNo);*/ if(card.dwSize > 6) Dbg("account: %s****%s", (const char*)m_currCardNo.SubString(0, 6), (const char*)m_currCardNo.SubString(m_currCardNo.GetLength() - 4, 4)); if(m_addCardSerial.GetLength() <= 0) bDataOK = false; } else { bDataOK = false; } if(!bDataOK) { AlarmDECToBusiness("OperateCardStore::ReadAccount", eErr, MEC_DEVAPI_CARDISSUER_ReadAccount); //m_pCardIssuer->GetLastErr(devErrorInfo); //Dbg("read card(slot %d) info failed: %s(%d).", slot, devErrorInfo.szErrMsg, eErr); Dbg("capture card..."); status = 2; RegistCardWhileCaptureCard(); eErr = MachineMoveCardBackNotHold(); } else { eErr = m_pCardIssuer->MoveCardToSlot(slot); if(eErr == Error_Succeed) { if(WriteCardInfo(spConfigRun, m_currCardNo, m_addCardSerial, slot, false, true)) { spConfigRun->WriteConfigValueInt("OperateCardStore", "SlotNum", slot);//记录已盘库到哪个槽 Dbg("operate slot(%d) success.", slot); status = 0; return true; } else { Dbg("operate slot(%d) success, but write card info to cardissuer.ini failed."); } } else { //移回卡槽不成功,登记并吞卡 AlarmDECToBusiness("OperateCardStore::MoveCardToSlot", eErr, MEC_DEVAPI_CARDISSUER_MoveCardToSlot); //m_pCardIssuer->GetLastErr(devErrorInfo); //Dbg("move card to slot(%d) failed: %s(%d).", slot, devErrorInfo.szErrMsg, eErr); Dbg("capture card..."); status = 3; RegistCardWhileCaptureCard(); MachineMoveCardBackNotHold(); } } } else { //m_pCardIssuer->GetLastErr(devErrorInfo); Dbg("move card from slot(%d) to cardreader failed!", slot); AlarmDECToBusiness("OperateCardStore::MoveCardFromSlot", eErr, MEC_DEVAPI_CARDISSUER_MoveCardFromSlot); status = 1; } return false; } int CCardIssuerFSM::QueryCardInfoOnStore(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); if(!ctx->Req.reserved1) { //原有业务 ctx->Ans.findCard = m_findCard; ctx->Ans.cardPos = m_cardPos; Dbg("query findCard:%d,cardPos:%d",ctx->Ans.findCard,ctx->Ans.cardPos); ctx->Answer(Error_Succeed); return 2; } else { //新增盘库操作@20190422 by zjw ErrorCodeEnum eErr = Error_Unexpect; DevErrorInfo devErrorInfo; bool bRet; CSmartPointer spConfigRun; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if(eErr != Error_Succeed) { Dbg("Open runcfg failed(%d).", eErr); ctx->Answer(Error_Unexpect); return 2; } //开始盘库 if(ctx->Req.reserved1[0] == 1) { //检查是否有旧的盘库记录,若有,则返回给业务确定继续盘库or终止盘库;若无,则进行正常盘库 if(CheckHasPanKuRecord(spConfigRun)) { Dbg("Has operation cardstore record, please make sure continue or break!"); ctx->Answer(Error_Param, CardIssuer_UserErrorCode_KakuHaveOldPanKuRecord); return 2; } //如果没有旧的盘库操作,则重新开始盘库(先清理本地记录) ClearLocalRecord(spConfigRun); SlotStatus slotstatus; eErr = m_pCardIssuer->QuerySlotsStatus(slotstatus, 0, true); if(eErr != Error_Succeed) { //m_pCardIssuer->GetLastErr(devErrorInfo); //Dbg("query slots status failed: %s(%d).", devErrorInfo.szErrMsg, eErr); ctx->Answer(Error_Unexpect,AlarmDECToBusiness("QueryCardInfoOnStore::QuerySlotsStatus", eErr,MEC_DEVAPI_CARDISSUER_QuerySlotsStatus)); return 2; } spConfigRun->WriteConfigValueInt("OperateCardStore", "OperationFlag", 1);//设置盘库标志 int i = 0; int status = 0; for (; i < m_maxSlot; ++i) { Dbg("slot[%d] status: %d.", i, slotstatus.status[i]); if(slotstatus.status[i] == 1) { bRet = OperateCardStore(spConfigRun, i, status); if(!bRet) break; } else { //该卡槽无卡 WriteCardInfo(spConfigRun, "", "", i); } } //将卡信息返回给业务端 ReturnCardInfo(i, status, spConfigRun, ctx); } else if(ctx->Req.reserved1[0] == 2) { //有旧的盘库记录,继续接着盘库 SlotStatus slotstatus; eErr = m_pCardIssuer->QuerySlotsStatus(slotstatus,0,true); int slotNum; spConfigRun->ReadConfigValueInt("OperateCardStore", "SlotNum", slotNum); if(slotNum >= 0) { int status = 0; int i = slotNum; for(; i < m_maxSlot; ++i) { Dbg("slot[%d] status: %d.", i, slotstatus.status[i]); if(slotstatus.status[i] == 1) { bRet = OperateCardStore(spConfigRun, i, status); if(!bRet) break; } else { //该卡槽无卡 WriteCardInfo(spConfigRun, "", "", i); } } //将卡信息返回给业务端 ReturnCardInfo(i, status, spConfigRun, ctx); } else { Dbg("No operate cardstore record, please make sure!"); ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_KakuHaveNoPanKuRecord); } } else if(ctx->Req.reserved1[0] == 3) { //有旧的盘库记录,终止盘库(清空本地记录) ClearLocalRecord(spConfigRun); ctx->Answer(Error_Succeed); } else if(ctx->Req.reserved1[0] = 4) { //查询是否有盘库记录 if(CheckHasPanKuRecord(spConfigRun)) { Dbg("Has operation cardstore record!"); ctx->Ans.findCard = 1; ctx->Answer(Error_Succeed); } else { Dbg("Has no operation cardstore record!"); ClearLocalRecord(spConfigRun); ctx->Ans.findCard = 0; ctx->Answer(Error_Succeed); } } } return 2; } bool CCardIssuerFSM::CheckHasPanKuRecord(CSmartPointer&spConfigRun) { int operFlag, slotNum; spConfigRun->ReadConfigValueInt("OperateCardStore", "OperationFlag", operFlag); spConfigRun->ReadConfigValueInt("OperateCardStore", "SlotNum", slotNum); if(operFlag == 1 && slotNum >= 0) { return true; } return false; } void CCardIssuerFSM::ClearLocalRecord(CSmartPointer&spConfigRun) { spConfigRun->WriteConfigValueInt("OperateCardStore", "OperationFlag", 0); spConfigRun->WriteConfigValueInt("OperateCardStore", "SlotNum", -1); for (int i = 0; i < m_maxSlot; ++i) { WriteCardInfo(spConfigRun, "", "", i, true); } } void CCardIssuerFSM::ReturnCardInfo(int slotNum, int status, CSmartPointer&spConfigRun, SpReqAnsContext::Pointer ctx) { bool bRet; if(slotNum == m_maxSlot && status == 0) { ctx->Ans.reserved1.Init(1); ctx->Ans.reserved3.Init(m_maxSlot); ctx->Ans.reserved4.Init(m_maxSlot); Dbg("Operate CardStore success."); for (int i = 0; i < m_maxSlot; ++i) { CSimpleStringA csAcc(""); CSimpleStringA serial(""); bRet = ReadCardInfo(spConfigRun, csAcc, serial, i); if(bRet) { ctx->Ans.reserved3[i] = csAcc; ctx->Ans.reserved4[i] = serial; } else { ctx->Ans.reserved3[i] = "0"; ctx->Ans.reserved4[i] = "0"; } } ctx->Ans.reserved1[0] = m_maxSlot; //返回完成,清空本地记录 spConfigRun->WriteConfigValueInt("OperateCardStore", "OperationFlag", 0); spConfigRun->WriteConfigValueInt("OperateCardStore", "SlotNum", -1); for (int i = 0; i < m_maxSlot; ++i) { WriteCardInfo(spConfigRun, "", "", i, true); } ctx->Answer(Error_Succeed); } else { Dbg("operate cardstore failed in slot(%d).", slotNum); ctx->Ans.reserved1.Init(2); ctx->Ans.reserved1[0] = slotNum; ctx->Ans.reserved1[1] = status; ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_KakuPanKu_Failed); } return; } void CCardIssuerFSM::GetAddCardInfo(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); ErrorCodeEnum eErr; if(!ctx->Req.reserved1) { //原有业务 CSmartPointer spConfigRun; eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (eErr != Error_Succeed) { Dbg("open runcfg failed.%d", eErr); ctx->Answer(Error_Unexpect); return; } ctx->Ans.count = 0; CSimpleStringA csAcc(""), csCardSerial(""); int hasCard = 0; bool bRet = false; Dbg("ctx->Req.isSync = %d.", ctx->Req.isSync); if (ctx->Req.isSync == 1)//clear local record { for (int i = 0; i < m_maxSlot; i++) { bRet = ReadSlotInfo(spConfigRun, csAcc, csCardSerial, i, hasCard); if (bRet) WriteSlotInfo(spConfigRun, "", "", i, true); } spConfigRun->WriteConfigValueInt("SlotInfo", "count",0); ctx->Answer(Error_Succeed); return; } int sum = 0; spConfigRun->ReadConfigValueInt("SlotInfo", "count", sum); Dbg("count = %d", sum); if (sum > 0) { //ctx->Ans.slot.Init(sum); //ctx->Ans.account.Init(sum); //ctx->Ans.cardSerial.Init(sum); //ctx->Ans.count = sum; /*ctx->Ans.account.Init(m_maxSlot); ctx->Ans.cardSerial.Init(m_maxSlot); ctx->Ans.slot.Init(m_maxSlot);*/ for (int i = 0; i < m_maxSlot; i++) { bRet = ReadSlotInfo(spConfigRun, csAcc, csCardSerial, i, hasCard); if (bRet) { ctx->Ans.account.Append(&csAcc, 0, 1); ctx->Ans.cardSerial.Append(&csCardSerial, 0, 1); ctx->Ans.slot.Append(&i, 0, 1); } } ctx->Ans.count = ctx->Ans.account.GetCount(); if (ctx->Ans.count != sum) Dbg("sum %d is not equals to real added recored %d.", sum, ctx->Ans.count); Dbg("add record count:%d", ctx->Ans.account.GetCount()); } } else if(ctx->Req.reserved1[0] == 1) { ctx->Ans.reserved1.Init(1); //获取卡库总容量 if(m_maxSlot > 0) { Dbg("CardStore account is: %d.", m_maxSlot); ctx->Ans.reserved1[0] = m_maxSlot; } else { Dbg("CardStore account is less zero."); } //卡库数量盘点 DevErrorInfo devErrInfo; int numOfHasCard = 0; vector slotNoOfHasCard; SlotStatus slotstatus; eErr = m_pCardIssuer->QuerySlotsStatus(slotstatus,0,true); if (eErr == Error_Succeed) { for(int i = 0; i < m_maxSlot; ++i) { if(slotstatus.status[i] == 1) { Dbg("slot %d has card.", i); slotNoOfHasCard.push_back(i); numOfHasCard++; } } Dbg("num of card in cardstore: %d.", numOfHasCard); ctx->Ans.reserved2.Init(numOfHasCard + 1); ctx->Ans.reserved2[0] = numOfHasCard; for(int j = 0; j < numOfHasCard; ++j) { ctx->Ans.reserved2[j+1] = slotNoOfHasCard[j]; } } else { AlarmDECToBusiness("GetAddCardInfo::QuerySlotsStatus", eErr, MEC_DEVAPI_CARDISSUER_QuerySlotsStatus); //m_pCardIssuer->GetLastErr(devErrInfo); //Dbg("Query slot status failed: %s(%d).", devErrInfo.szErrMsg, eErr); } } ctx->Answer(Error_Succeed); return; } void CCardIssuerFSM::DecodeTracksData(const char *track2, DWORD dwT2size, const char *track3, DWORD dwT3size, char *&magData, bool bT2OK, bool bT3OK) { if (!bT2OK) { Dbg("track2 isn't ok."); return; } if (dwT2size <= 0 || strlen(track2) < 16) { Dbg("t2.size %d,strlen(t2):%d",dwT2size,strlen(track2)); return; } Dbg("track2.size:%d,track3.size:%d",dwT2size,dwT3size); char tmpMag2_3[512] = { 0 };// , tmpMag2[256] = { 0 }; memcpy(tmpMag2_3, track2, dwT2size); char cardType[8]; ZeroMemory(cardType, 8); if (bT3OK && strlen(track3) > 1) { Dbg("do track 3(%d)",dwT3size); memcpy(tmpMag2_3 + dwT2size, "A", 1); memcpy(tmpMag2_3 + dwT2size + 1, track3, dwT3size); cmdDecodeEx(tmpMag2_3, cardType, magData); } if (!bT3OK || strlen(cardType) < 4) { Dbg("no(%d) or wrong track 3(size:%d,strlen(%d)),%s",bT3OK,dwT3size,strlen(track3),cardType); cmdDecodeMag2(tmpMag2_3, magData); } } int CCardIssuerFSM::SplitDevModelInfo() { LOG_FUNCTION(); if (strlen(m_devCat.szModel) < 3) { Dbg("Wrong szModel:%s", m_devCat.szModel); return -1; } m_csCM = ""; CSimpleStringA csTmpModel(m_devCat.szModel); CAutoArray arrParam; arrParam.Init(16); arrParam = csTmpModel.Split('#'); for (int i = 0; i < arrParam.GetCount(); ++i) { if (_strnicmp(arrParam[i], "CM", 2) == 0) { m_csCM = arrParam[i].SubString(3, arrParam[i].GetLength() - 3); } } Dbg("CM=%s", (const char*)m_csCM); return 0; } void CCardIssuerFSM::CloseAndClearDevObj(bool bCheckConnecting, bool bCloseOnly) { LOG_FUNCTION(); if(bCheckConnecting) { Dbg("check connecting flag"); } if(bCloseOnly) { Dbg("only to close device"); } ErrorCodeEnum ec = Error_Unexpect; if(m_bBTConncting) { if(m_pCardIssuer != NULL) { ec = m_pCardIssuer->DevClose(); Dbg("Try to invoke DevClose when connecting returned %d", ec); } if(bCheckConnecting) { const int maxWaitTimes = 20; int currentWaitTimes = 0; do { Dbg("waiting bluetooth connect operation finish..."); Sleep(500); currentWaitTimes++; if(currentWaitTimes >= maxWaitTimes) { Dbg("Timeout break"); break; } } while (m_bBTConncting); } } if(m_bBTConnected || m_bOpened) { if(m_pCardIssuer != NULL) { ec = m_pCardIssuer->DevClose(); Dbg("DevClose returned %d", ec); } else { Dbg("device adapter object is null?"); } m_bBTConnected = false; m_bOpened = false; } if (m_pCardIssuer != NULL && !bCloseOnly) { if(m_hVerdorDll != NULL) { if(ReleaseDevComponent != NULL) { Dbg("ReleaseDevComponent()..."); ec = ReleaseDevComponent((DeviceBaseClass*&)m_pCardIssuer); if(ec != Error_Succeed) { Dbg("ReleaseDevComponent failed: EC=%u", ec); } m_pCardIssuer = NULL; } else { assert(FALSE && "ReleaseDevComponent is null!"); } CreateDevComponent = NULL; ReleaseDevComponent = NULL; Dbg("FreeLibrary returned %d", FreeLibrary(m_hVerdorDll)); m_hVerdorDll = NULL; } else { assert(FALSE && "vendor dll is null!!"); } } } void CCardIssuerFSM::LogErrMsg( const char *pMsgHead, ErrorCodeEnum eErrCode, const char* pMsgBody, DWORD finalErrCode /*= 0*/, BOOL bAlarm /*= FALSE*/,BOOL bError /*= FALSE*/) { m_csAlarmMsg = CSimpleStringA::Format("(%s)%s failed EC= 0x%x : %s", (LPCTSTR)m_csDevSN, pMsgHead, eErrCode, pMsgBody); if(bAlarm) LogWarn(Severity_High, eErrCode, finalErrCode, (LPCTSTR)m_csAlarmMsg); if (bError) LogError(Severity_High, eErrCode, finalErrCode, (LPCTSTR)m_csAlarmMsg); return; } int CCardIssuerFSM::PrintCardIm(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); int ret = 0; KakuPrintInfo kakuInfo; memset(kakuInfo.formPath, 0, sizeof(kakuInfo.formPath)); memset(kakuInfo.fields, 0, sizeof(kakuInfo.fields)); //oiltest where is the file locate? CSimpleStringA csDepPath, csBackslash("\\"), filePath; ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath); filePath = csDepPath + csBackslash + m_devCat.szVendor + "-" + ctx->Req.formFile; Dbg("form file path:%s", (const char*)filePath); strncpy(kakuInfo.formPath,(const char*)filePath, filePath.GetLength()); strncpy(kakuInfo.fields, (const char*)ctx->Req.printData, ctx->Req.printData.GetLength()); ErrorCodeEnum eErr = Error_Unexpect; eErr = m_pCardIssuer->PrintCardFaceRightNow(kakuInfo); if (eErr != Error_Succeed) { AlarmDECToBusiness("PrintCardFaceRightNow::", eErr, MEC_DEVAPI_CARDISSUER_PrintCardFaceRightNow); ret = 1; } ctx->Ans.ret = ret; Dbg("print ret:%d",ret); ctx->Answer(Error_Succeed); return 0; } void CCardIssuerFSM::oiltest() { if (m_pCardIssuer != NULL) { ErrorCodeEnum eErr = Error_Unexpect; int sum = 0; eErr = m_pCardIssuer->GetSlotSum(sum); if (eErr == Error_Succeed) Dbg("max slot:%d",sum); SlotStatus slotstatus; eErr = m_pCardIssuer->QuerySlotsStatus(slotstatus,0,true); if (eErr == Error_Succeed) { for (int i = 0; i < 10; ++i) { Dbg("slot %d,status %d",i,slotstatus.status[i]); if (slotstatus.status[i] == 1) { eErr = m_pCardIssuer->MoveCardFromSlot(i); if (eErr == Error_Succeed) { CardNo card; ZeroMemory(card.account, sizeof(card.account)); eErr = m_pCardIssuer->ReadAccount(card); if (eErr == Error_Succeed) { Dbg("slot %d,account:%s", i, card.account); } else Dbg("read slot %d failed.%d", i, eErr); if (i % 3 == 0) { Dbg("move card in slot %d to front gate.", i); eErr = m_pCardIssuer->MoveCard(CI_MOVECARD_FRONT_GATE); } else if (i % 3 == 1) { //oiltest@20171114 for dx Dbg("capture card in slot %d 22.", i); eErr = m_pCardIssuer->MoveCard(CI_MOVECARD_FRONT_GATE); //eErr = m_pCardIssuer->MoveCard(CI_MOVECARD_BACK_NOT_HOLD); } if (i % 3 == 2) { Dbg("move card in slot %d back to slot.", i); eErr = m_pCardIssuer->MoveCardToSlot(i); } Sleep(5000); } else Dbg("move card from slot failed.%d",eErr); } } } } } void CCardIssuerFSM::oiltestSCI(bool bSCI) { LOG_FUNCTION(); if (bSCI && !m_bChannelOK) { Dbg("SCI压力测试,安全通道建立不成功,终止测试"); return; } CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { Dbg("(set issue)open cfg file failed!"); return; } //三步循环:发卡,读卡,吐卡/吞卡 //第一步:发卡 ErrorCodeEnum errCode = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); if (errCode != Error_Succeed) { //LogErrInfo("before issue,close shutter"); return; } int hopperRemains = 0, hopperSN = 1; int captureCount = 0;//SCI测试,吞卡计数,吞够3张不再吞(看各厂商吞卡箱容量?) while (true) { spConfig->ReadConfigValueInt("SCITest", "Hopper1Remains", hopperRemains); if (hopperRemains == 0) { spConfig->ReadConfigValueInt("SCITest", "Hopper2Remains", hopperRemains); if (hopperRemains == 0) { Dbg("卡箱1,卡箱2都没有卡片了"); Dbg("hopper 1 & 2 no more card."); return; } else { hopperSN = 2; } } Dbg("move card to holder"); //move card to holder errCode = m_pCardIssuer->MoveCard(CI_MOVECARD_FROM_HOPPER, hopperSN); Dbg("move card result %d.", errCode); if (errCode != Error_Succeed) { //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_MoveCardFromHopper_Failed, "从卡槽发卡失败"); DevErrorInfo errMove; m_pCardIssuer->GetLastErr(errMove); Dbg("Move card from hopper to position failed(%d),(%s).", errCode, errMove.szErrMsg); Dbg("从卡槽发卡失败"); return; } Dbg("issue suc."); if (hopperSN == 1) spConfig->WriteConfigValueInt("SCITest", "Hopper1Remains", hopperRemains - 1); else spConfig->WriteConfigValueInt("SCITest", "Hopper2Remains", hopperRemains - 1); //第二步:读卡 ErrorCodeEnum eErr; int activeCardType; bool bIC(false), bICSuc(false), bReadCardInfo(false); { bIC = m_pCardProcess->DetectIfICCard(CARD_MACHINE_ISSUER, m_pCardIssuer, activeCardType); if (bIC) { m_pCardIssuer->DeactivateICCard(); m_pCardIssuer->ReleaseIC(); } } DWORD dwStart = GetTickCountRVC(); MagTracks magTracks; int readTries = 0; magTracks.eRange = CI_TRACK_RANGE_2_3; eErr = m_pCardIssuer->MagRead(magTracks); Dbg("MAGread(%d)...", eErr); Dbg("t2,t3:%d,%d", magTracks.track[1].eStatus, magTracks.track[2].eStatus); if (magTracks.track[1].dwSize > sizeof(magTracks.track[1].data) || magTracks.track[2].dwSize > sizeof(magTracks.track[2].data)) { Dbg("Wrong dwSize %d,%d", magTracks.track[1].dwSize, magTracks.track[2].dwSize); } if (bIC) { //read card no 20140625 int activeCardType; m_pCardProcess->DetectIfICCard(CARD_MACHINE_ISSUER, m_pCardIssuer, activeCardType); //oilyang@20201014 add emv support int retGetICData = -1; retGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A000000333"); if (retGetICData < -1)//-1:DetectIfICCard failed; -2:select app failed { retGetICData = m_pCardProcess->GetICDataFromCard(CARD_MACHINE_ISSUER, m_pCardIssuer, "A0000000108888"); } ICData track2(false, 0x57, 0x00); string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType; if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1) { Dbg("no track2 data (ic only)"); } else { int pos = FindHexCharPosition(track2.value, 0x0d, track2.lenth); char *pICTrack2 = new char[128]; ZeroMemory(pICTrack2, 128); HexBuf2StrBuf(track2.value, &pICTrack2, track2.lenth); pICTrack2[37] = '\0'; { char *ddd = new char[128]; memset(ddd, 0, 128); memcpy(ddd, pICTrack2, pos - 1); t2ICTrack2 = pICTrack2; t2ICAccount = (char*)ddd; Dbg("count:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str()); delete[]ddd; } delete[]pICTrack2; } m_pCardIssuer->DeactivateICCard(); m_pCardIssuer->ReleaseIC(); bReadCardInfo = true; if (magTracks.track[1].eStatus == CI_DATA_INVALID) { Dbg("may be ic only..."); } } if (Error_Succeed == eErr && magTracks.track[1].eStatus == CI_DATA_OK) { LogEvent(Severity_Middle, LOG_EVT_CARDISSUER_OP, "CardIssuer op."); bool bT3OK = false; if (magTracks.track[2].eStatus == CI_DATA_OK) { bT3OK = true; } Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; char *tmpMag2 = new char[256]; ZeroMemory(tmpMag2, 256); DecodeTracksData((const char*)magTracks.track[1].data, magTracks.track[1].dwSize, (const char*)magTracks.track[2].data, magTracks.track[2].dwSize, tmpMag2, true, bT3OK); int pos = 0; for (int i = 0; i < magTracks.track[1].dwSize; ++i, ++pos) { if (magTracks.track[1].data[i] == 0x3d || magTracks.track[1].data[i] == 0x3e) break; } Dbg("pos:%d,%d", pos, magTracks.track[1].dwSize); char *ddd = new char[40]; memset(ddd, 0, 40); memcpy(ddd, magTracks.track[1].data, pos); if (SplitTrack2(tmpMag2, track2Data) == 0) { Dbg("done."); bReadCardInfo = true; } delete[]ddd; if (tmpMag2 != NULL) { delete[]tmpMag2; tmpMag2 = NULL; } } //第三步:吐卡/吞卡 srand((int)time(NULL)); int tmpNum = rand() % 7; if (captureCount < 5 && tmpNum == 5)//吞卡箱容量优先,超过了就不再吞了,随意选择一个数,假定能实现1/7的概率吞卡 { ErrorCodeEnum eErr; eErr = MachineMoveCardBackNotHold(); Dbg("asked to capture %d", eErr); if (eErr != Error_Succeed) { Dbg("capture card failed."); DevErrorInfo devErrInfo; m_pCardIssuer->GetLastErr(devErrInfo); Dbg("capture err %s", devErrInfo.szErrMsg); } captureCount++; Dbg("capture card suc,the %d", captureCount); m_pCardProcess->DataInit(); if (Error_Succeed == eErr) { eErr = m_pCardIssuer->SetCardInType(CI_CARD_IN_TYPE_FORBIDDEN); } } else { EjectCard(NULL); //等待取卡 DWORD dwStart, dwEnd; dwStart = GetTickCountRVC(); do { if (GetDevStatus()) { dwEnd = GetTickCountRVC(); if (m_devStatus.eMedia == CI_MEDIA_ENTERING) { Sleep(WAIT_INTERVAL); //waitTries++; } else { Dbg("Card have been fetched."); break; } } else { Dbg("GetDevStatus faied."); break; } } while ((dwEnd - dwStart) < 60 * 1000); } } }