#include "stdafx.h" #include "SpBase.h" #include "SpHelper.h" #include "CardSwiperFSM.h" #include "GetDevInfoHelper.h" #include "EventCode.h" #include "ModuleMix.h" #include "CardSwiper_UserErrorCode.h" #include "CommDevEntityErrorCode.h" //#include "..\\mod_gpio\\Gpio_def_g.h" #include #define _ATL_NO_AUTOMATIC_NAMESPACE #include #include #include #include #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Bthprops.lib") char tmpxx[1024]; char testIC[1024]; int jxx; char x; CRITICAL_SECTION g_csCntStatus; //For DevConnStatus Joseph CRITICAL_SECTION g_csChannelStatus; //For Building transfer channel Joseph CRITICAL_SECTION g_csAuthAccessStatus; CRITICAL_SECTION g_csFwbRecord; //using namespace Gpio; //#include "../../dev/DeviceBaseClass.h" //#include "CardIssuerClass.h" #include "mod_cardswiper.h" #define CARDREADER_INIT_COUNT 3 #define GET_DEV_STATUS_COUNT 3 const int TIMER1 = 1; const int TIMER_EJECT = 2; const int TIMER_CANCELREAD_CHECK = 3; // --Josephus at 15:11:26 20161129 const int TIMER_KILL = 4; const int TIMER_DIE = 5; const int TIMER_REMOVE = 6; const int TIMER_CHANNEL = 7; 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_KILLFAILED_TIMEOUT = 5000; const int MAX_DIE_TIMEOUT = 10000; const int MAX_REMOVE_TIMEOUT = 15000; const int MAX_CHANNEL_TIMEOUT = 1500; //oiltmp 2010716 change from 0 to 10,configure to ini file? const int MAX_RESET_TIMES_PERIOD = 2; // change from 10 to 2 --Josephus at 14:21:58 2017110 const int READ_TRY_INTERVAL = 300; const int INIT_TRY_NUM = 3; const int ACCEPT_TRY_INTERVAL = 500; const int ACCEPT_TRY_NUM = 110; class CCardIssuerEntity; SelfChekerClient::SelfChekerClient( CEntityBase *pEntity ) : SelfCheckerService_ClientBase(pEntity) { } HealthMngClient::HealthMngClient(CEntityBase* pEntity) : HealthManagerService_ClientBase(pEntity) { } void CCardSwiperFSM::s0_on_entry() { LOG_FUNCTION(); m_eDevState = DEVICE_STATUS_NOT_READY; SendDevStatusMsg(4); FSMEvent *e = new FSMEvent(USER_EVT_INIT); PostEventFIFO(e); } void CCardSwiperFSM::s0_on_exit() { } unsigned int CCardSwiperFSM::s0_on_event(FSMEvent* e) { LOG_FUNCTION(); if (e->iEvt == USER_EVT_INIT) { InitTask* task = new InitTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); e->SetHandled(); return 0; }else if (e->iEvt == USER_EVT_QUIT) { e->SetHandled(); return 0; } return 0; } void CCardSwiperFSM::s1_on_entry() { LOG_FUNCTION(); } void CCardSwiperFSM::s1_on_exit() { } unsigned int CCardSwiperFSM::s1_on_event(FSMEvent* pEvt) { Dbg("s1 initializing evt %d,%d", pEvt->iEvt, pEvt->param1); if (pEvt->iEvt == USER_EVT_INITFINISHED) { pEvt->SetHandled(); int err = pEvt->param1; if (err == 1) { return 1; } //else if(err == 2) //{ // ScheduleTimer(TIMER_CHANNEL, MAX_CHANNEL_TIMEOUT); // return 2; //} else { return 0; } } else if (pEvt->iEvt == USER_EVT_QUIT) { pEvt->SetHandled(); return 0; } //else if(pEvt->iEvt == EVT_TIMER && pEvt->param1 == TIMER_CHANNEL) //{ // pEvt->SetHandled(); // InitTask* task = new InitTask(this); // GetEntityBase()->GetFunction()->PostThreadPoolTask(task); //} return 0; } //Idle void CCardSwiperFSM::s2_on_entry() { LOG_FUNCTION(); SendDevStatusMsg(1); m_testResult = Error_Succeed; } void CCardSwiperFSM::s2_on_exit() { } unsigned int CCardSwiperFSM::s2_on_event(FSMEvent* pEvt) { Dbg("s2 evt(%d)",pEvt->iEvt); 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_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_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } case USER_EVT_EJECT: { pEvt->SetHandled(); EjectTask *pTask = new EjectTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); return 0; } case USER_EVT_MAGDATA_TRANSFER_INIT: { pEvt->SetHandled(); MagDataTransferInitEvent *pMDTIE = dynamic_cast(pEvt); MagTransInitTask* task = new MagTransInitTask(this); task->ctx = pMDTIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_MAGDATA_TRANSFER_INIT_V2: { pEvt->SetHandled(); MagTransInitV2Task* task = new MagTransInitV2Task(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_DEV_DISCONNECTED: pEvt->SetHandled(); return 0; case USER_EVT_QUERY_FWB_LIST: { pEvt->SetHandled(); QueryFWBListEvent* qfl = dynamic_cast(pEvt); QueryFWBListTask* pTask = new QueryFWBListTask(this); pTask->ctx = qfl->ctx; pTask->fsmState = 2; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); return 0; } case USER_EVT_BIND_FWB: { pEvt->SetHandled(); BindFWBEvent* bf = dynamic_cast(pEvt); BindFWBTask* pTask = new BindFWBTask(this); pTask->ctx = bf->ctx; pTask->fsmState = 2; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); return 0; } default: break; } return 0; } //Reading void CCardSwiperFSM::s3_on_entry() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_READING); // 紧急注释,小心崩溃 -Josephus@20171116 9:28:28 //if(Error_Succeed != CheckPinPadStatus()) //{ // ReStartRelateEntity("PinPad"); // // 不提示密码键盘故障,因为会尝试恢复 --Josephus at 11:11:50 2017110 // //SendDevStatusMsg(6); //} } void CCardSwiperFSM::s3_on_exit() { } unsigned int CCardSwiperFSM::s3_on_event(FSMEvent* pEvt) { Dbg("s3 event(%d)",pEvt->iEvt); switch(pEvt->iEvt) { case USER_EVT_READFINISHED: { m_bReading = false; pEvt->SetHandled(); CardReadFinishedEvent *pCRFE = dynamic_cast(pEvt); int err = pCRFE->param1; Dbg("readfinish(%d)",err); if (err == 0) { pCRFE->ctx->Answer(Error_Succeed); m_resetTimes = 0; if(m_csAllInOneState.IsStartWith("F", true) || m_csAllInOneState.IsStartWith("R", true)) m_csAllInOneState = "N"; if(m_nReadFailCnt != 0) m_nReadFailCnt = 0; SendDevStatusMsg(1); return 0; }else if (err == 2) return 2; else if (err == 3) { Dbg("front cancel read"); pCRFE->ctx->Answer(Error_Cancel); return 0; }else if (err == 4) { Dbg("timeout"); pCRFE->ctx->Answer(Error_TimeOut); return 0; } else if (err == 5) { pCRFE->ctx->Answer(Error_Succeed); return 0; } else { pCRFE->ctx->Answer(Error_Unexpect, AlarmDECToBusiness()); if(err == 6) {//rebuild channel action. ProcessEnChannel(); if(pEvt->param2 == 1) {//need build before read. return 0; } } else if(err == -1) { return 1; } else if((m_csAllInOneState.IsStartWith("N", true)) && (++m_nReadFailCnt < FAILED_MAXTIMES_TO_RESET)) { Dbg("Read failed hold on %d/%d times", m_nReadFailCnt, FAILED_MAXTIMES_TO_RESET); return 0; } return 1; } } break; case USER_EVT_CANCELINSERT: { pEvt->SetHandled(); // --Josephus at 23:28:03 2016126 CancelReadTask* task = new CancelReadTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_EXIT: { //m_bReading = false; pEvt->SetHandled(); ExitTask* task = new ExitTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } break; case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } default: break; } return 0; } //Hold void CCardSwiperFSM::s4_on_entry() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_HOLD); } void CCardSwiperFSM::s4_on_exit() { LOG_FUNCTION(); } unsigned int CCardSwiperFSM::s4_on_event(FSMEvent* pEvt) { switch(pEvt->iEvt) { case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } default: break; } return 0; } //Failed void CCardSwiperFSM::s5_on_entry() { LOG_FUNCTION(); if(m_connStatus == 0) { PostEventFIFO(new FSMEvent(USER_EVT_DEV_DISCONNECTED)); return; } GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_FAILED); m_eDevState = DEVICE_STATUS_FAULT; //if (m_periodResetCount == 0) //{ // m_dwPeriodResetTime = GetTickCount(); //} //m_periodResetCount++; //DWORD dwNow = GetTickCount(); ////以10分钟为一个区间,区间内采取延缓重启策略 //if ((dwNow - m_dwPeriodResetTime) > 1000 * 60 * 10) //{ // m_periodResetCount = 1; // m_dwPeriodResetTime = dwNow; //} if(m_nLstSate == s3 && !m_csAllInOneState.IsStartWith("N", true)) { PostEventFIFO(new FSMEvent(USER_EVT_WAITREMOVE)); if(m_csAllInOneState.IsStartWith("R", true)) { } return; } SendDevStatusMsg(2); FSMEvent *e = new FSMEvent(USER_EVT_RESET); PostEventFIFO(e); } void CCardSwiperFSM::s5_on_exit() { m_testResult = Error_Succeed; } unsigned int CCardSwiperFSM::s5_on_event(FSMEvent* pEvt) { Dbg("s5(failed) evt(%d)",pEvt->iEvt); switch(pEvt->iEvt) { case USER_EVT_RESET: { pEvt->SetHandled(); if(m_nLstSate == s10) { Dbg("Commitcuicide failed."); m_testResult = Error_InvalidState; return 0; } m_resetTimes++; Dbg("Current Reset Times: %d.", m_resetTimes); if (m_resetTimes >= MAX_RESET_TIMES_PERIOD) { //TODO: Josephus@20161208 Dbg("restart tried %d/%d times, give up", m_resetTimes, MAX_RESET_TIMES_PERIOD); //Replace Error_InvalidState with Error_DevNotAvailable, //Don't remeber add shakehand settings in SelfCheck config file. //m_testResult = Error_DevNotAvailable; RecordRunCfg("F"); PostEventFIFO(new FSMEvent(USER_EVT_WAITTODIE)); return 0; } // addby oilyang, 10分钟的区间内,2s递增执行重置行为 --Josephus at 10:51:47 2016126 //Sleep(2000 * m_periodResetCount); 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("reset result %d",rfe->param1); if (rfe->param1 == 0) return 0; else { //if (m_periodResetCount == 0) //{ // m_dwPeriodResetTime = GetTickCount(); //} //m_periodResetCount++; //DWORD dwNow = GetTickCount(); ////以10分钟为一个区间,区间内采取延缓重启策略 //if ((dwNow - m_dwPeriodResetTime) > 1000 * 60 * 10) //{ // m_periodResetCount = 1; // m_dwPeriodResetTime = dwNow; //} FSMEvent *e = new FSMEvent(USER_EVT_RESET); PostEventFIFO(e); return 1; } } case USER_EVT_DEV_DISCONNECTED: { } pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); return 0; case USER_EVT_ACCEPT_CANCEL: m_bCancelAccept = true; pEvt->SetHandled(); break; case EVT_TIMER: { if(pEvt->param1 == TIMER_KILL) { Dbg("Unexpected, survived !!!"); pEvt->SetHandled(); ResetDeviceEvent* rde = dynamic_cast(pEvt); ResetTask* task = new ResetTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } } break; case USER_EVT_WAITTODIE: { pEvt->SetHandled(); } break; default: break; } return 0; } //Eject(WaitingFetch) void CCardSwiperFSM::s6_on_entry() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_WAITFETCHING); } void CCardSwiperFSM::s6_on_exit() { LOG_FUNCTION(); } unsigned int CCardSwiperFSM::s6_on_event(FSMEvent* pEvt) { Dbg("s6(eject.waitingfetch) event(%d)(%d)",pEvt->iEvt,pEvt->param1); switch(pEvt->iEvt) { case USER_EVT_EJECTFINISHED: { SetExitFlag(false); 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."); Dbg("客户取走卡片msg发送"); return 0; } else if (pEvt->param1 == 2) { FetchCard evt; evt.status = 2; SpSendBroadcast(m_pEntity->GetFunction(),SP_MSG_OF(FetchCard),SP_MSG_SIG_OF(FetchCard),evt); Dbg("客户未取卡超时msg发送"); LogWarn(Severity_Low,Error_NotInit, CardSwiper_UserErrorCode_Customer_Forget_Fectch_Card,"Customer forget fetch card."); return 2; }else { return 1; } } break;//no use,just for sonar case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } case USER_EVT_EXIT: pEvt->SetHandled(); SetExitFlag(); break; default: break; } return 0; } void CCardSwiperFSM::s7_on_entry() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_MAGDATA_TRANS_INIT); } void CCardSwiperFSM::s7_on_exit() { } unsigned int CCardSwiperFSM::s7_on_event(FSMEvent* pEvt) { Dbg("s7(mag data transfer init) event(%d)(%d)",pEvt->iEvt,pEvt->param1); switch(pEvt->iEvt) { case USER_EVT_MAGDATA_TRANSFER_INIT_FINISHED: { pEvt->SetHandled(); MagDataTransferInitFinishedEvent *pMDTIFE = dynamic_cast(pEvt); pMDTIFE->ctx->Ans.result = pEvt->param1; pMDTIFE->ctx->Answer(Error_Succeed); return 0; } case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_EXIT: pEvt->SetHandled(); SetExitFlag(); break; default: break; } return 0; } //DeviceOff void CCardSwiperFSM::s8_on_entry() { LOG_FUNCTION(); m_testResult = Error_Succeed; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_FAILED); m_eDevState = DEVICE_STATUS_NOCFG; //oilyang@20200519 only crypt machine need to show this message if (IsCryptMachinaType()) { ShowFatalrForConnect("多合一设备已断开连接!"); if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { if (m_bFWBOpenSucEver) LogWarn(Severity_High, Error_DevConnFailed, AlarmDEC(DEC_DEV_DISCONNECTED_BLUETOOTH), "cardswiper(fwb) device disconnecetd."); } else LogWarn(Severity_High, Error_DevConnFailed, AlarmDEC(DEC_DEV_DISCONNECTED), "cardswiper device disconnecetd."); } if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { Dbg("As fwb device don't have insert message like usb device,need Entity selfchecker to restart it."); if (m_pCardSwiper != NULL) { m_pCardSwiper->DevClose(); m_bFWBOpenSucEver = false; } m_testResult = Error_InvalidState; } } void CCardSwiperFSM::s8_on_exit() { //oilyang@20200402 //if it's fwb,BindFWB or QueryFWBList can reach here,but i doesn't mean The device is ok. //so,we should exclude the fwb if (!IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { m_eDevState = DEVICE_STATUS_NORMAL; if (IsCryptMachinaType())//oilyang@20200519 only crypt machine need to show this message { ShowFatalrForConnect("多合一设备已连接!", FALSE); LogEvent(Severity_High, AlarmDECToBusiness(DEC_DEV_ALREADY_CONNECTED), "cardswiper device is connected."); } } } unsigned int CCardSwiperFSM::s8_on_event(FSMEvent* pEvt) { unsigned int uRet = 0; Dbg("s8(DeviceOff) event(%d)(%d),currStateName:%s",pEvt->iEvt,pEvt->param1, GetCurrStateName()); switch(pEvt->iEvt) { case USER_EVT_DEV_CONNECTED: { //SendDevStatusMsg(1); pEvt->SetHandled(); if(CheckPinPadStatus() != Error_Succeed) { ReStartRelateEntity("PinPad"); } if(CheckDevCtrlStatus() != Error_Succeed) { ReStartRelateEntity("DeviceControl"); } if(CheckIDCerStatus() != Error_Succeed) { ReStartRelateEntity("IDCertificate"); } if(m_nLstSate == s9) //Last State is WaitingRemove { RecordRunCfg("R"); // --Josephus at 10:56:09 2017113 //if(m_csAllInOneState.IsStartWith("R", true)) { PostEventFIFO(new FSMEvent(USER_EVT_WAITTODIE)); uRet = 1; //stop from jumping to failed. } m_csAllInOneState = "R"; if(m_resetTimes + 1 >= MAX_RESET_TIMES_PERIOD) { m_resetTimes = MAX_RESET_TIMES_PERIOD - 2; } } else { m_resetTimes--; } } break; case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); if(pQCIE && pQCIE->ctx != NULL) { pQCIE->ctx->Ans.position = 0; pQCIE->ctx->Ans.reserved1 = 0; pQCIE->ctx->Ans.reserved2 = ""; Dbg("Abort to GetDevStatus, seems(set) no card status previously"); pQCIE->ctx->Answer(Error_Succeed); } //QueryCardInfoTask* task = new QueryCardInfoTask(this); //task->ctx = pQCIE->ctx; //GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_QUIT: { pEvt->SetHandled(); } break; case USER_EVT_EXIT: pEvt->SetHandled(); SetExitFlag(); break; case USER_EVT_WAITTODIE: pEvt->SetHandled(); break; case USER_EVT_QUERY_FWB_LIST: { pEvt->SetHandled(); QueryFWBListEvent* qfl = dynamic_cast(pEvt); QueryFWBListTask* pTask = new QueryFWBListTask(this); pTask->ctx = qfl->ctx; pTask->fsmState = 8; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); return 0; } case USER_EVT_BIND_FWB: { pEvt->SetHandled(); BindFWBEvent* bf = dynamic_cast(pEvt); BindFWBTask* pTask = new BindFWBTask(this); pTask->ctx = bf->ctx; pTask->fsmState = 8; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); return 0; } case USER_EVT_QUERY_FWB_LIST_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; case USER_EVT_BIND_FWB_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } default: break; } return uRet; } //WaitingRemove void CCardSwiperFSM::s9_on_entry() { LOG_FUNCTION(); SendDevStatusMsg(3, true); m_testResult = Error_Succeed; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_FAILED); //LogWarn(Severity_Middle, Error_DevNotAvailable, LOG_ERR_CARDREADER_FAILED,"CardSwiper is waiting to remove."); ScheduleTimer(TIMER_REMOVE, MAX_REMOVE_TIMEOUT); } void CCardSwiperFSM::s9_on_exit() { CancelTimer(TIMER_REMOVE); } unsigned int CCardSwiperFSM::s9_on_event(FSMEvent* pEvt) { Dbg("s9(WaitingRemove) event(%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(); SendDevStatusMsg(10); 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(); SendDevStatusMsg(10); 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(); SendDevStatusMsg(10); return 0; } case USER_EVT_QUERY_CARD_INFO: { pEvt->SetHandled(); QueryCardInfoEvent *pQCIE = dynamic_cast(pEvt); QueryCardInfoTask* task = new QueryCardInfoTask(this); task->ctx = pQCIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_QUIT: { pEvt->SetHandled(); SendDevStatusMsg(10); return 0; } case USER_EVT_EJECT: { pEvt->SetHandled(); EjectTask *pTask = new EjectTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); SendDevStatusMsg(10); return 0; } case USER_EVT_MAGDATA_TRANSFER_INIT: { pEvt->SetHandled(); MagDataTransferInitEvent *pMDTIE = dynamic_cast(pEvt); MagTransInitTask* task = new MagTransInitTask(this); task->ctx = pMDTIE->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_MAGDATA_TRANSFER_INIT_V2: { pEvt->SetHandled(); MagTransInitV2Task* task = new MagTransInitV2Task(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } case USER_EVT_DEV_DISCONNECTED: pEvt->SetHandled(); return 0; case EVT_TIMER: if(pEvt->param1 == TIMER_REMOVE) { pEvt->SetHandled(); SendDevStatusMsg(10); } break; default: break; } return 0; } //WaitingDie void CCardSwiperFSM::s10_on_entry() { LOG_FUNCTION(); SendDevStatusMsg(2); if(CommitSuicide() == Error_Succeed) { SendDevStatusMsg(7); //LogWarn(Severity_Middle, Error_DevNotAvailable, LOG_ERR_CARDREADER_FAILED,"CardSwiper is waiting to die."); ScheduleTimer(TIMER_DIE, MAX_DIE_TIMEOUT); } else { ScheduleTimer(TIMER_DIE, MAX_DIE_TIMEOUT / 1000); } m_testResult = Error_Succeed; GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_FAILED); } void CCardSwiperFSM::s10_on_exit() { } unsigned int CCardSwiperFSM::s10_on_event(FSMEvent* pEvt) { Dbg("s9(WaitingDie) event(%d)(%d)",pEvt->iEvt,pEvt->param1); switch(pEvt->iEvt){ case EVT_TIMER: if(pEvt->param1 == TIMER_DIE) { pEvt->SetHandled(); PostEventFIFO(new FSMEvent(USER_EVT_WAITTODIE_TIMEOUT)); } break; case USER_EVT_WAITTODIE_TIMEOUT: { Dbg("Waiting to die timeout."); pEvt->SetHandled(); } break; default: break; } return 0; } //FWB void CCardSwiperFSM::s11_on_entry() { } void CCardSwiperFSM::s11_on_exit() { } unsigned int CCardSwiperFSM::s11_on_event(FSMEvent* pEvt) { Dbg("s11(FWB) %d,%d", pEvt->iEvt, pEvt->param1); switch (pEvt->iEvt) { case USER_EVT_QUERY_FWB_LIST_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; case USER_EVT_BIND_FWB_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; default: break; } return 0; } ErrorCodeEnum CCardSwiperFSM::OnInit() { LOG_FUNCTION(); /*------2020-02-27------*/ //modify by LZM VendorLogControler(this, "CardSwiper"); /*---------------------*/ AddStateHooker(this); return Error_Succeed; } ErrorCodeEnum CCardSwiperFSM::OnExit() { LOG_FUNCTION(); ErrorCodeEnum eExit; if (m_pCardSwiper != NULL) { //eExit = m_pCardSwiper->GetDevStatus(devStatus); //if (eExit == Error_Succeed) //{ // if (devStatus.eMedia == CI_MEDIA_PRESENT){ // } //} eExit = m_pCardSwiper->DevClose(); m_bFWBOpenSucEver = false; if (eExit != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eExit, DevClose); Dbg("读卡器关闭失败(%d)",eExit); } eExit = ReleaseDevComponent((DeviceBaseClass *&)m_pCardSwiper); m_pCardSwiper = NULL; } if(m_connChecking) { m_bCancelQueryConn = true; DWORD dwStart = GetTickCount(); while(m_connChecking && GetTickCount() <= dwStart + 3000) { Sleep(50); } } RemoveStateHooker(this); DeleteCriticalSection(&g_csCntStatus); DeleteCriticalSection(&g_csChannelStatus); DeleteCriticalSection(&g_csAuthAccessStatus); FSMImpl::OnExit(); return Error_Succeed; } void TestShowRecvData(PBYTE hexBuf,DWORD len) { char* show = new char[512]; 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 CCardSwiperFSM::GetDevStatus() { //LOG_FUNCTION(); int getDevInfoCount = 0; ErrorCodeEnum err; do{ err = m_pCardSwiper->GetDevStatus(devStatus); if (Error_Succeed == err) return true; else { LOG_CARDSWIPER_ERROR_MSG_MACRO(err, GetDevStatus); getDevInfoCount++; Sleep(3000); } } while (getDevInfoCount < GET_DEV_STATUS_COUNT); Dbg("getdevstatus to reset"); err = m_pCardSwiper->Reset(); Sleep(MAX_RESET_TIMEROUT); if (err == Error_Succeed) { err = m_pCardSwiper->GetDevStatus(devStatus); } return false; } int CCardSwiperFSM::Reset() { LOG_FUNCTION(); //do { if (m_pCardSwiper->Reset() == Error_Succeed) { if (Error_Succeed == m_pCardSwiper->GetDevStatus(devStatus)) { return 0; } else return 1; } else return 1; //m_resetTries++; //}while(m_resetTries < RESET_TRY_NUM); 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; } ErrorCodeEnum CCardSwiperFSM::Load(CSimpleStringA csDevSN) { //MessageBoxA(0,0,0,0); LOG_FUNCTION(); HRESULT hr; int initTries = 0; bool bClosePort = false; m_csVendor = ""; ErrorCodeEnum eErrDev; CSimpleStringA dllName, csDepPath(""), csBackslash("\\"), csTmp(""),csVersion("8.1"); int baudRate,port,smflag,onlineOnly; CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfigRun; eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfigRun); if (eErrDev == Error_Succeed) { //FWB if (csDevSN.GetLength() > 1) { m_csVendor = TransferAboutVendorShortName(csDevSN.SubString(0, 2)); } else spConfigRun->ReadConfigValue("fwb", "vendor", m_csVendor); if (csDevSN.GetLength() > 1) m_csDevNo = csDevSN; else spConfigRun->ReadConfigValue("fwb", "devSN", m_csDevNo); HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, m_csVendor); spConfigRun->ReadConfigValue("fwb", "version", csTmp); if (csTmp.GetLength() > 1)//如果忘记配置,则直接使用默认值8.1 csVersion = csTmp; Dbg("vendor:%s,devSN:%s", (const char*)m_csVendor,(const char*)m_csDevNo); GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath); dllName = csDepPath + csBackslash + "CardSwiper." + m_csVendor + "." + csVersion + ".dll";//oiltmp Dbg("%s",(const char*)dllName); port = 0; baudRate = 0; } Dbg("after fwb"); if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { Dbg("This is fwb."); GetEntityBase()->GetFunction()->SetSysVar("FWBVendor", m_csVendor,true); GetEntityBase()->GetFunction()->SetSysVar("FWBDevSN", m_csDevNo,true); GetEntityBase()->GetFunction()->SetSysVar("FWBVersion", csVersion, true); HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, m_csVendor); } else//normal AllInOne device { GetEntityBase()->GetFunction()->SetSysVar("FWBVendor", "", true); GetEntityBase()->GetFunction()->SetSysVar("FWBDevSN", "", true); GetEntityBase()->GetFunction()->SetSysVar("FWBVersion", "", true); eErrDev = SpGetDevAdaptorPath(m_pEntity, GetEntityBase()->GetEntityName(), dllName); if (eErrDev != Error_Succeed) { Dbg("load vendor dll(%s) failed.", (LPCTSTR)dllName); return Error_DevLoadFileFailed; } Dbg("%s", (LPCTSTR)dllName); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; eErrDev = spEntityFunction->OpenConfig(Config_Root, spConfig); if (eErrDev != Error_Succeed) { Dbg("open cfg file failed!"); return eErrDev; } eErrDev = spConfig->ReadConfigValue("Device.CardSwiper", "Vendor", m_csVendor); if (eErrDev != Error_Succeed) { Dbg("read vendor failed(%d).", eErrDev); return eErrDev; } HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, m_csVendor); m_version = m_batch = 1; eErrDev = spConfig->ReadConfigValueInt("Device.CardSwiper", "Version", m_version); if (eErrDev != Error_Succeed) { Dbg("read Version failed(%d).", eErrDev); return eErrDev; } eErrDev = spConfig->ReadConfigValueInt("Device.CardSwiper", "Batch", m_batch); if (eErrDev != Error_Succeed) { Dbg("read Batch failed(%d).", eErrDev); return eErrDev; } spConfig->ReadConfigValueInt("Device.CardSwiper", "Baudrate", baudRate); spConfig->ReadConfigValueInt("Device.CardSwiper", "Port", port); spConfig->ReadConfigValueInt("Device.Utility","SMSupport",smflag); spConfig->ReadConfigValueInt("Device.Utility","OnlineOnly",onlineOnly); } CSystemStaticInfo sysInfo; eErrDev = GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo); if (eErrDev != Error_Succeed) { Dbg("Get System Static info failed(%d).",eErrDev); //return eErrDev; } m_csMachineType = sysInfo.strMachineType; m_csSite = sysInfo.strSite; m_majorVerion = sysInfo.MachineVersion.GetMajor(); m_minorVerion = sysInfo.MachineVersion.GetMinor(); Dbg("MachineType:%s,Site:%s,machineVersion:%d.%d", (const char*)m_csMachineType, (const char*)m_csSite , m_majorVerion, m_minorVerion); CSimpleStringA csBinPath; ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Bin", csBinPath); if (eErrPath != Error_Succeed) { Dbg("GetBasePath failed (%d).",eErrPath); return Error_Param; } Dbg("to load dll:%s",(const char*)dllName); m_hVerdorDll = LoadLibraryA(dllName); if (m_hVerdorDll == NULL) { Dbg("Load dll failed.%d",GetLastError()); LogErrMsg("Load:LoadLibraryA", Error_Unexpect, MEC_DLL_LOAD_FAILED, TRUE); 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; } CSimpleStringA csCMBPrint("CMBPrint.dll"); csCMBPrint = csBinPath + csBackslash + csCMBPrint; Dbg("cmbpath %s",(LPCTSTR)csCMBPrint); HMODULE cmbPrinthr = LoadLibraryA(csCMBPrint); if (cmbPrinthr== NULL) { Dbg("Load CMBPrint failed(%d).", GetLastError()); LogErrMsg("Load:LoadLibraryA", Error_Unexpect, MEC_DEV_LOAD_THIRD_PARTY_PLUGIN_FAILED, TRUE); return Error_DevLoadFileFailed; } if ((cmdDecodeMag2=(lpCMBdecodeMag2)GetProcAddress(cmbPrinthr, "CMBdecodeMag2")) == NULL) { Dbg("Get Mag2 address failed."); return Error_DevLoadFileFailed; } if ((cmdDecodeEx=(lpCMBdecodeEx)GetProcAddress(cmbPrinthr, "CMBdecodeEx")) == NULL) { Dbg("Get Mag23Ex address failed."); return Error_DevLoadFileFailed; } do{ if (m_pCardSwiper == NULL) { if (CreateDevComponent((DeviceBaseClass *&)m_pCardSwiper) != Error_Succeed) { LOG_TRACE("创建读卡器设备模块失败"); LogErrMsg("Load:CreateDevComponent",Error_Unexpect,MEC_DEV_OBJECT_CREATE_FAILED,TRUE); initTries++; continue; } } CardSwiperClass* pxx = (CardSwiperClass*)m_pCardSwiper; m_bSM = 1;//oiltmp //oiltmp 20160506 no offline business now //m_bOnlineOnly = onlineOnly; m_bOnlineOnly = true; //oiltest //port = 6; //baudRate = 115200; ErrorCodeEnum eErr = Error_Unexpect; //CSimpleStringA csPubKey = ""; //eErr = spConfig->ReadConfigValue("MagTransfer", "pubparam", csPubKey); Dbg("open card swiper [%d][%d],devNo:%s",port,baudRate,(const char*)m_csDevNo); BYTE btType = 0; if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { m_bDevOpenEx = true; Dbg("to call DevOpenEx"); eErr = m_pCardSwiper->DevOpenEx(port, baudRate, DEV_OPEN_TYPE_USB | DEV_OPEN_TYPE_BLUETOOTH, (const char*)m_csDevNo, btType); Dbg("after call DevOpenEx:eErr:%d,byType:%d",eErr,btType); if(eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, DevOpenEx); } m_bDevOpenEx = false; } else { eErr = m_pCardSwiper->DevOpen(port, baudRate); if(eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, DevOpen); } } m_nSplitRes = -1; if (eErr == Error_Succeed) { bClosePort = true; Dbg("读卡器打开成功"); if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { //oilyang@20200407 if csDevSN is null or invalid,no need to restart if (csDevSN.GetLength() < 2) { m_bFWBOpenSucEver = true; ReStartRelateEntity("PinPad"); ReStartRelateEntity("FingerPrint"); ReStartRelateEntity("DeviceControl"); ReStartRelateEntity("IDCertificate"); ReStartRelateEntity("Sensors"); } //LogEvent(Severity_High, LOG_EVT_CARDREADER_OPEN_SUC_FWB, "FWB open suc."); } eErr = m_pCardSwiper->GetDevCategory(m_devCat); if (eErr == 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); m_nSplitRes = SplitDevModelInfo(); Dbg("ret:%d", m_nSplitRes); } initTries = 0; break; } else { initTries++; } }while(initTries < INIT_TRY_NUM); Dbg("inittries[%d]",initTries); if (initTries != 0) { LogWarn(Severity_Middle, Error_DevNotAvailable, AlarmDEC(), (LPCTSTR)m_csAlarmMsg); //if (bClosePort) // m_pCardSwiper->DevClose(); //LOG_TRACE("读卡器打开失败"); return Error_Succeed; //return Error_DevCommFailed; } else { return Error_Succeed; } } const int MAX_KEY_SIZE = 256; unsigned char SM2_enc_mkey(unsigned char * sm2pubkey,unsigned char mkeylen,unsigned char * mkey,unsigned char * encmkey) { unsigned char pubkey_x[128]; unsigned char pubkey_y[128]; unsigned char random_k[128]; unsigned char tbuf[4096]; int encdatalen; int iloop; memset(pubkey_x,0,sizeof(pubkey_x)); memset(pubkey_y,0,sizeof(pubkey_y)); memcpy(pubkey_x,sm2pubkey,64); memcpy((char *)pubkey_y,sm2pubkey+64,64); srand((int)time(NULL)); for(iloop=0;iloop<32;iloop++) tbuf[iloop]=rand()%256; ConvAscii(tbuf,(char*)random_k,32); AsciiToHex((char *)mkey,tbuf,mkeylen); encdatalen=sm2_encrypt_new((char *)random_k,(char *)pubkey_x,(char *)pubkey_y,(char *)tbuf,mkeylen/2,(char *)encmkey); return 0; } void vSJLTransToGM(PBYTE pENCData, BYTE bENCDataLength) { BYTE bResponseData[512]; BYTE dwDataInLen = 0; //把C1C2C3调整为C1C3C2 dwDataInLen = bENCDataLength - 0x60; memcpy(bResponseData, pENCData, bENCDataLength); memcpy(pENCData, bResponseData, 64); memcpy(pENCData+64, bResponseData+64+dwDataInLen, 32); memcpy(pENCData+96, bResponseData+64, dwDataInLen); } ErrorCodeEnum CCardSwiperFSM::DataTransferInit() { LOG_FUNCTION(); //MessageBoxA(0,0,0,0); //MagTransInit(NULL);//oiltest CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErr = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErr != Error_Succeed) { Dbg("open run cfg file failed!"); return Error_IO; } CSimpleStringA csPubKey = ""; eErr = spConfig->ReadConfigValue("MagTransfer","pubparam",csPubKey); if (eErr != Error_Succeed) { Dbg("read pub key failed(%d).",csPubKey); return Error_IO; } m_pubKey = new char[MAX_KEY_SIZE+1]; ZeroMemory(m_pubKey,MAX_KEY_SIZE); memcpy(m_pubKey,csPubKey.GetData(),csPubKey.GetLength()); SwitchDataForSave(false,m_pubKey); if (strlen(m_pubKey)<8) { Dbg("pubkey wrong."); return Error_Param; } Dbg("m_pubKey [%s]",m_pubKey); //get public key-->send random number --> set working key int ret1,ret2,ret3,ret4; unsigned int ram[4]; ret1 = rand_s(&ram[0]); ret2 = rand_s(&ram[1]); ret3 = rand_s(&ram[2]); ret4 = rand_s(&ram[3]); Dbg("%d,%d,%d,%d",ret1,ret2,ret3,ret4); if ((ret1 != 0) || (ret2 != 0) || (ret3 != 0) || (ret4 != 0)) { return Error_Unexpect; } //BYTE btRam[16] = {0xA4,0x85,0x0D,0x9D,0xC3,0x0A,0x84,0x0C,0x35,0xD4,0xDE,0x93,0x9D,0x63,0x9D,0xED}; //BYTE btRam[16] = {0x9F,0x12,0x86,0xA4,0x6E,0x22,0x14,0x80,0xE6,0x80,0x86,0x0F,0x82,0xE4,0xBC,0x55}; BYTE btRam[16]; ZeroMemory(btRam,16); for (int i = 0,j = 0; j < 4; ++j) { btRam[i+0] = ((ram[j]&0xff000000)>>24); btRam[i+1] = ((ram[j]&0x00ff0000)>>16); btRam[i+2] = ((ram[j]&0x0000ff00)>>8); btRam[i+3] = (ram[j]&0x000000ff); i += 4; } char *pRamArr = new char[MAX_KEY_SIZE]; char *random_sm3hash = new char[MAX_KEY_SIZE]; char tbuf[MAX_KEY_SIZE],random_enc_bypbk[MAX_KEY_SIZE]; ZeroMemory(tbuf,MAX_KEY_SIZE); ZeroMemory(random_enc_bypbk,MAX_KEY_SIZE); ZeroMemory(random_sm3hash,MAX_KEY_SIZE); ZeroMemory(pRamArr,MAX_KEY_SIZE); HexBuf2StrBuf(btRam,&pRamArr,16); Dbg("to encrypt random ..."); //公钥加密随机数 SM2_enc_mkey((unsigned char *)m_pubKey,32,(unsigned char *)pRamArr,(unsigned char *)random_enc_bypbk); char *pData = new char[32]; ZeroMemory(pData,32); sm3((unsigned char *)btRam,16,(unsigned char *)tbuf); Dbg("oiltest random_enc_bypbk[%s]",random_enc_bypbk); if (_strnicmp(m_csVendor,"yotap",strlen("yotap")) == 0) { Dbg("To try skyui version..."); HexBuf2StrBuf((unsigned char *)tbuf,&random_sm3hash,32); BYTE *pTmpRnd = new BYTE[512]; ZeroMemory(pTmpRnd,512); //int tmpRnd = StrBuf2HexBuf(random_enc_bypbk,&pTmpRnd); //vSJLTransToGM(&pTmpRnd[1],tmpRnd -1); //char *pTmpStrRnd = new char[512]; //ZeroMemory(pTmpStrRnd,512); //HexBuf2StrBuf(&pTmpRnd[1],&pTmpStrRnd,tmpRnd-1); Dbg("oiltest %s,%s,%s.",pRamArr,random_enc_bypbk,random_sm3hash); //Dbg("oiltest %s",pTmpStrRnd); // eErr = m_pCardSwiper->SendRandomNum(random_enc_bypbk, random_sm3hash, pData);//oiltest 20150423 for skyui Dbg("pData:[%s]",pData); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, SendRandomNum); if (pTmpRnd != NULL) { delete []pTmpRnd; pTmpRnd = NULL; } //if (pTmpStrRnd != NULL) //{ // delete []pTmpStrRnd; // pTmpStrRnd = NULL; //} return Error_DevCommFailed; } } else //if (strnicmp(m_csVendor,"nantian",strlen("nantian")) == 0) { Dbg("To try [%s] version...",(LPCTSTR)m_csVendor); HexBuf2StrBuf((unsigned char *)tbuf,&random_sm3hash,16); Dbg("oiltest(nt) %s,%s,%s.",pRamArr,random_enc_bypbk,random_sm3hash); eErr = m_pCardSwiper->SendRandomNum(random_enc_bypbk,random_sm3hash,pData); Dbg("pData:[%s]", pData); } if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, SendRandomNum); return eErr; } char rBuf[32],tmpWkKey[MAX_KEY_SIZE]; ZeroMemory(rBuf,32); ZeroMemory(tmpWkKey,MAX_KEY_SIZE); memcpy(rBuf,btRam,16); if (_strnicmp(m_csVendor,"yotap",strlen("yotap")) == 0) { PBYTE pSKData = new BYTE[32]; ZeroMemory(pSKData,32); StrBuf2HexBuf(pData,&pSKData); memcpy(rBuf+16,pSKData,8); } else //if (strnicmp(m_csVendor,"nantian",strlen("nantian")) == 0) { memcpy(rBuf+16,pData,8); } sm3((unsigned char *)rBuf,24,(unsigned char *)tmpWkKey); char *pStrWkKey = new char[MAX_KEY_SIZE]; ZeroMemory(pStrWkKey,MAX_KEY_SIZE); HexBuf2StrBuf((unsigned char *)tmpWkKey,&pStrWkKey,16); //Dbg("oiltest wkkey[%s]",pStrWkKey); eErr = m_pCardSwiper->SendWorkingKey(pStrWkKey); //Dbg("oiltest wkkey[%s]",tmpWkKey); if (pData != NULL) { delete []pData; pData = NULL; } if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, SendWorkingKey); return Error_DevCommFailed; } Dbg("en channel ok."); m_bNeedInitCh = false; //oiltest 测试读卡 //MagTracks magTracks; //Dbg("mag card"); //magTracks.eRange = CI_TRACK_RANGE_2_3; //int iStatus = 0; //eErr = m_pCardSwiper->QueryCardStatus(7, iStatus, magTracks); //Dbg("%d,%d", eErr, iStatus); //if (iStatus == 1) //{ // Dbg("%s,%d", (char*)magTracks.track[0].data, magTracks.track[0].dwSize); // Dbg("%s,%d", (char*)magTracks.track[1].data, magTracks.track[1].dwSize); // Dbg("%s,%d", (char*)magTracks.track[2].data, magTracks.track[2].dwSize); // //Dbg("%s,%d", magTracks.track[2].data, magTracks.track[2].dwSize); //} return Error_Succeed; } int CCardSwiperFSM::Initial(CSimpleStringA csDevSN, bool bInitChannel) { LOG_FUNCTION(); InitializeCriticalSection(&g_csCntStatus); InitializeCriticalSection(&g_csChannelStatus); InitializeCriticalSection(&g_csAuthAccessStatus); InitializeCriticalSection(&g_csFwbRecord); m_pCardProcess = new CCardProcess(); if (m_pCardProcess == NULL)//almost no use... { Dbg("create card process failed."); return 5; } ErrorCodeEnum errCode = Load(csDevSN); if (errCode != Error_Succeed) { Dbg("Load failed(%d).", errCode); // --Josephus at 8:25:33 2016126 delete m_pCardProcess; m_pCardProcess = NULL; return 5; } CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfigRun; errCode = spEntityFunction->OpenConfig(Config_Run, spConfigRun); CSimpleStringA csTmpState; errCode = spConfigRun->ReadConfigValue("State", "AllInOneState", csTmpState); if (errCode != Error_Succeed || csTmpState.GetLength() <= 0) { Dbg("Get AllInOneState from RunCfg failed 0x%x [%s].", errCode, (LPCTSTR)csTmpState); m_csAllInOneState = "N"; } else { m_csAllInOneState = csTmpState; } errCode = spConfigRun->WriteConfigValue("State", "AllInOneState", "N"); Dbg("Set AllInOneState with 'N' to RunCfg returned 0x%x, current state: %s.", errCode, (LPCTSTR)m_csAllInOneState); devStatus.eMedia = CI_MEDIA_NOTPRESENT; int nRes = 0; m_periodResetCount = 0; if (IsCryptMachinaType()) { int online = 0; int nTemp = 0; ErrorCodeEnum eErr = Error_Unexpect; EnterCriticalSection(&g_csCntStatus); eErr = m_pCardSwiper->IfDevOnline(online); if (eErr == Error_Succeed && online == 1) { GetEntityBase()->GetFunction()->SetUserDefineState(USER_CARDSWIPER_IDLE); m_eDevState = DEVICE_STATUS_NORMAL; // --Josephus at 9:50:47 2016126 m_connStatus = 1; if (bInitChannel) nTemp = ProcessEnChannel(); if(nTemp != 0) {// --Josephus at 14:59:23 201754 nRes = 2; } } else { Dbg("The device is disconnected rc(%d), ol(%d).", eErr, online); //设备断开 --Josephus at 9:51:12 2016126 m_eDevState = DEVICE_STATUS_NOCFG; m_connStatus = 0; nRes = 1; } LeaveCriticalSection(&g_csCntStatus); if (!m_connChecking) { QueryConnectTask *pTask = new QueryConnectTask(this); if(nTemp != 0) pTask->nReserved = nTemp; GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } } return nRes; } 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 CCardSwiperFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData) { if (pTrack2.IsNullOrEmpty() || pTrack2.GetLength() == 0) return -1; int dataLen = strlen(pTrack2); 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 CCardSwiperFSM::ReadCard(SpReqAnsContext::Pointer ctx) { //BYTE btTest[32] = {0x5F,0x30,0x90,0xC8,0x57,0x83,0x4F,0xB2,0xC7,0x3F,0x9D,0x3A,0x60,0x59,0xD4,0xF9,0x29,0x68,0x24,0x43,0x31,0xFF,0xD5,0x05}; //char *pTmpWk = new char[256]; //ZeroMemory(pTmpWk,256); //sm3((unsigned char *)btTest,24,(unsigned char *)pTmpWk); //char *pStrWkKey = new char[MAX_KEY_SIZE]; //ZeroMemory(pStrWkKey,MAX_KEY_SIZE); //HexBuf2StrBuf((unsigned char *)pTmpWk,&pStrWkKey,16); //Dbg("oiltest wkkey[%s]",pStrWkKey); LOG_FUNCTION(); m_pCardProcess->DataInit(); bool bICSuc = false; m_bCancelRead = false; ErrorCodeEnum eErr; //if (!_strnicmp(ctx->Req.reserved1,"I",1)) //{ // GetBaseInfoNotInRecord(); // GetICDataFromCard("A000000333"); // ICData track2(false,0x57,0x00); // if (FindTagValue(m_vICData,track2,false,0,m_vICData.size()) == -1) // { // Dbg("[ic]no track2 data"); // bICSuc = false; // //eErr = m_pCardSwiper->ReleaseIC(); // //Dbg("ic failed,release it %d",eErr); // } // else // { // int pos = FindHexCharPosition(track2.value,0x0d,track2.lenth); // Dbg("ic.track2[%s]",track2.value); // int cardCat = DetectCardTypeInfoByAccount(track2.value,track2.lenth); // Dbg("card category %d",cardCat); // //ctx->Ans.data1 = "无效数据ic"; // char *dd = new char[128]; // char *ddd = new char[128]; // memset(dd,0,128); // memset(ddd,0,128); // HexBuf2StrBuf(track2.value,&dd,pos/2+1); // memcpy(ddd,dd,pos-1); // ctx->Ans.t2Account = (char*)ddd;//oiltest // Dbg("count : %s",ctx->Ans.t2Account); // Dbg("[%d,%d,%d,%d]",m_TVR[0],m_TVR[1],m_TVR[2],m_TVR[3]); // ctx->Ans.ICType = 1; // ctx->Ans.status = 0; // ctx->Answer(Error_Succeed); // return 0; // } //} ctx->Ans.ICType = 0; DWORD dwStart = GetTickCount(); //HRESULT hr = -1; MagTracks magTracks; // int readTries = 0; bool bReadCardInfo = false; Dbg("mag card"); //oiltest 20140507 //eErr = m_pCardSwiper->ContactIC(); //Dbg("%d",eErr); //SplitBusinessData("9f02060000000000009f03060000000000009f1a0201565f2a0201569c01709A031405069F21031607389f4e140000000000000000000000000000007715010002",130); //DetectAndReadICData(); //return 0; LightPosEnum ePos; //switch(ctx->Req.LightPos) //{ //case 1: // ePos = CI_LIGHT_MAG; // break; //case 2: // ePos = CI_LIGHT_IC; // break; //case 3: //default: // ePos = CI_LIGHT_MAG_IC; // break; //} Dbg("%d,%d",ctx->Req.LightPos,ctx->Req.reserved1); bool bPrinter = false; if (ctx->Req.reserved1 == 1) bPrinter = true; char chType; if (!bICSuc) { DoRead: magTracks.eRange = CI_TRACK_RANGE_2_3; do { m_bReading = true; //TrackInfo* pTracks = new TrackInfo; //eErr = m_pCardSwiper->MagRead(magTracks); int iStatus = 0; //oilyang@20200709 comment the following light ficker //add light flicker for RVC.Wall 2015-12-22 oilyang if ((ctx->Req.LightPos & CI_LIGHT_MAG) == CI_LIGHT_MAG) LogEvent(Severity_Middle, LOG_EVT_CARDREADER_GREEN_ON, "CardReader(MAG) warning on"); //if ((ctx->Req.LightPos & CI_LIGHT_IC) == CI_LIGHT_IC) // LogEvent(Severity_Middle, LOG_EVT_CARDREADER_RED_ON, "CardReader(IC) warning on"); //if ((ctx->Req.LightPos & CI_LIGHT_CONTACTLESS) == CI_LIGHT_CONTACTLESS && m_csMachineType.Compare("RVC.Desk2S") != 0) // LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_ON, "CardReader(Contactless IC) warning on"); eErr = m_pCardSwiper->QueryCardStatus(ctx->Req.LightPos,iStatus,magTracks); //oilyang@20200709 comment the following light ficker //add light flicker for RVC.Wall 2015-12-22 oilyang if ((ctx->Req.LightPos & CI_LIGHT_MAG) == CI_LIGHT_MAG) LogEvent(Severity_Middle, LOG_EVT_CARDREADER_GREEN_OFF, "CardReader(MAG) warning off"); //if ((ctx->Req.LightPos & CI_LIGHT_IC) == CI_LIGHT_IC) // LogEvent(Severity_Middle, LOG_EVT_CARDREADER_RED_OFF, "CardReader(IC) warning off"); //if ((ctx->Req.LightPos & CI_LIGHT_CONTACTLESS) == CI_LIGHT_CONTACTLESS && m_csMachineType.Compare("RVC.Desk2S") != 0) // LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_OFF, "CardReader(Contactless IC) warning off"); ctx->Ans.CardPos = iStatus; Dbg("iStatus %d, bCancelRead %d, bAcceptWaitMore %d.", iStatus, m_bCancelRead, m_bWaitAccepteMore); Dbg("t2.state:%d,t2.size:%d", magTracks.track[1].eStatus, magTracks.track[1].dwSize); if(m_bCancelRead) { return 3; } //oilyang@20180416 add for insert wait more if (iStatus == 0 && m_bWaitAccepteMore) goto DoRead; m_bReading = false; if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, QueryCardStatus); return -1; } FetchCard evt; evt.status = 3;//oilyang@20190507 用于通知ContactlessCard取消等待读卡 SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(FetchCard), SP_MSG_SIG_OF(FetchCard), evt); ctx->Ans.t2Account = ctx->Ans.ICData = ""; switch(iStatus) { case 0: if (bPrinter) break; // --Josephus at 15:05:40 2016/11/29 //if (m_bCancelRead) // return 3; //else return 4; break; case 1: bPrinter = false; ctx->Ans.ICType = 2; ctx->Ans.CardPos = 1;//swipe mag card Dbg("MAGread(%d,%d)...",eErr,iStatus);//oiltest Dbg("track1,2,3:%d,%d,%d",magTracks.track[0].eStatus,magTracks.track[1].eStatus,magTracks.track[2].eStatus); Dbg("track1,2,3:%d,%d,%d",magTracks.track[0].dwSize,magTracks.track[1].dwSize,magTracks.track[2].dwSize); //oilyang@20200423 to check if the track size is valid if ((magTracks.track[1].eStatus == CI_DATA_OK && magTracks.track[1].dwSize > 40) || (magTracks.track[2].eStatus == CI_DATA_OK && magTracks.track[2].dwSize > 107)) { Dbg("track data length is wrong!"); break; } for (int i = 0; i < 20; ++i) { if (magTracks.track[1].data[i] < 0x30 || (magTracks.track[1].data[i] > 0x39 && (magTracks.track[1].data[i] != 0x3d && magTracks.track[1].data[i] != 0x3e))) { //oilyang 20160523 //not '0'-'9' or '=' or '>' m_bNeedInitCh = true; break; } } if (IsCryptMachinaType() && m_bNeedInitCh) { Dbg("data invalid.to rebuild encrypted channel."); return 6; } if (Error_Succeed == eErr && magTracks.track[1].eStatus == CI_DATA_OK) { LogEvent(Severity_Middle,LOG_EVT_CARDISSUER_OP,"CardIssuer op."); ctx->Ans.track2 = (char*)magTracks.track[1].data; Track2Data track2Data; track2Data.status = 0; track2Data.t2Account = ""; char tmpMag2_3[512]; char *pTmpMag2 = new char[128]; ZeroMemory(pTmpMag2,128); ZeroMemory(tmpMag2_3,512); memcpy(tmpMag2_3,GetStrData(magTracks.track[1]).GetData(),magTracks.track[1].dwSize); char cardType[8] = {0}; 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,pTmpMag2); //Dbg("%s,%s,%s",tmpMag2_3,cardType,pTmpMag2);//oiltest 20141107 } if (magTracks.track[2].eStatus != CI_DATA_OK || strlen(cardType) < 4) { Dbg("no track 3"); ctx->Ans.track3 = ""; char *p37Buf = new char[37+1]; ZeroMemory(p37Buf,38); memcpy(p37Buf,tmpMag2_3,37); cmdDecodeMag2(p37Buf,pTmpMag2); delete []p37Buf; } //decode account from track 2 Dbg("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; break; //out } char *ddd = new char[40]; memset(ddd,0,40); memcpy(ddd,magTracks.track[1].data,pos); if ((magTracks.track[2].eStatus == CI_DATA_OK) && (SplitTrack2(pTmpMag2,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; delete []pTmpMag2; //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",(LPCTSTR)track2Data.t2Account); bReadCardInfo = true; delete []ddd; } Dbg("%s,%s", (LPCTSTR)ctx->Ans.t2Account.SubString(0, 6), (LPCTSTR)ctx->Ans.t2Account.SubString(pos - 4, 4)); break; } else { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, QueryCardStatus); Dbg("idc_read errmsg[%d][%d]",magTracks.track[1].eStatus,magTracks.track[2].eStatus); break; } break; case 2://ic bPrinter = false; { m_eReadType = CARD_MACHINE_SWIPER; Dbg("ic card."); ctx->Ans.CardPos = 2;//ic card deteced ctx->Ans.ICType = 3; ctx->Ans.status = 0; bReadCardInfo = true; ErrorCodeEnum eErr; eErr = m_pCardSwiper->ContactIC(); Dbg("contact ic %d",eErr); eErr = m_pCardSwiper->ActiveICCard(); Dbg("active ic %d",eErr); m_pCardProcess->GetICDataFromCard(m_eReadType,m_pCardSwiper,"A000000333"); ICData track2(false,0x57,0x00); eErr = Error_Unexpect; string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType; if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,track2,false,0) == -1) { Dbg("[ic]no track2 data"); eErr = m_pCardSwiper->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'; { char *ddd = new char[128]; memset(ddd,0,128); memcpy(ddd,pICTrack2,pos-1); t2ICTrack2 = pICTrack2; t2ICAccount = (char*)ddd;//oiltest Dbg("count : %s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length()-4,4).c_str()); ctx->Ans.ICData = ctx->Ans.t2Account = t2ICAccount.c_str(); delete []ddd; } delete []pICTrack2; } eErr = m_pCardSwiper->ReleaseIC(); Dbg("release ic %d",eErr); //following for ic test oiltest 20140506 //if (iStatus == 2) //{ // eErr = m_pCardSwiper->ContactIC(); // Dbg("%d",eErr); // SplitBusinessData("9f02060000000000009f03060000000000009f1a0201565f2a0201569c01709A031405069F21031607389f4e140000000000000000000000000000007715010002",130); // DetectAndReadICData(); //} break; } break; case 3: bPrinter = false; break; case 4://contactless card process bPrinter = false; { m_eReadType = CARD_MACHINE_SWIPER_RF; ctx->Ans.CardPos = 4; ctx->Ans.ICType = 4; ctx->Ans.status = 0; bReadCardInfo = true; eErr = m_pCardSwiper->ActiveContactlessICCard('A','B','M',chType); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, ActiveContactlessICCard); return 1; } ctx->Ans.reserved3 = chType; Dbg("active type %d",chType); m_pCardProcess->GetICDataFromCard(m_eReadType,m_pCardSwiper,"A000000333"); ICData track2(false,0x57,0x00); eErr = Error_Unexpect; string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType; if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,track2,false,0) == -1) { Dbg("no track2 data"); eErr = m_pCardSwiper->DeactContactlessICCard(); Dbg("deactive contactless card returned erroCode: %d",eErr); if(eErr != Error_Succeed) { //LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, DeactContactlessICCard); } LogErrMsg("ReadCard:Can't find track2 data in ic.",Error_Unexpect, AlarmDEC(MEC_DEVAPI_CARDSWIPER_ICCommand),TRUE); return 1; } 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;//oiltest Dbg("count : %s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str()); ctx->Ans.ICData = ctx->Ans.t2Account = t2ICAccount.c_str(); delete []ddd; } delete []pICTrack2; } break; } break; case 5: case 6: bPrinter = false; Dbg("unexpected card or id card detected."); ctx->Ans.CardPos = iStatus; ctx->Ans.ICType = iStatus; ctx->Ans.status = 1; return 5; break; default: bPrinter = false; break; } //}while(readTries < READ_TRY_NUM); }while(bPrinter); } // m_bWaitAccepteMore = false; Dbg("ictype %d",ctx->Ans.ICType); DWORD dwEnd = GetTickCount(); DWORD dwCollapse = dwEnd-dwStart; if ((dwCollapse < 8000) && (!bReadCardInfo)) { // duplicate!!! --Josephus at 7:04:41 2016127 //bReadCardInfo = true; ctx->Ans.status = 1; Dbg("cannot read mag."); } //oiltest temp, no chance return 2 josephus; bool bEjectSelf = false; if (!bReadCardInfo) { ctx->Ans.status = 1; } if (GetDevStatus()) { if (m_bCancelRead) { return 3; } else { if (bEjectSelf) return 2; else return 0; } }else return 1; } void CCardSwiperFSM::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("CMBCreditMag",tmp,bin.bin); bin.bDC = false; bin.bIC = true; m_vBin.push_back(bin); } } //0:unknown //1:本行借记磁卡;2 本行借记IC;3 本行贷记磁卡;4 本行贷记IC;5 他行卡 int CCardSwiperFSM::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 } int CCardSwiperFSM::PreOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_pCardProcess->DataInit(); Dbg("bus data[%s]",(LPCTSTR)ctx->Req.businessData); 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; if (!m_pCardProcess->DetectAndReadICData(m_eReadType, m_pCardSwiper, "A000000333", activeCardType))//oiltest 20140915 { ctx->Answer(Error_Unexpect, AlarmDECToBusiness(MEC_DEVAPI_CARDSWIPER_ICCommand)); return 0; } //if (m_cardType == CI_CARDTYPE_IC) //{ // ProcessRestrict(); // CardholderVerify(); m_pCardProcess->TermRiskManage(); CSimpleStringA taaResult; BYTE bt9f27 = 0; int retTAA = m_pCardProcess->TermActionAnalyze(m_eReadType,m_pCardSwiper,taaResult,m_bOnlineOnly,m_bCDA,bt9f27); Dbg("TermActionAnalyze %d",retTAA); switch(retTAA) {//to be added oiltest 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) { 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"); 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_pRFIC->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); char *ddd = new char[40]; ZeroMemory(ddd,40); memcpy(ddd,pICTrack2,pos-1); 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 (_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; 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; //Dbg("data to host[%s]",(LPCTSTR)ctx->Ans.result); Dbg("data to host(less)[%s],baseICData length:%d", txtresult.c_str(), baseICData.length()); delete []pExpireDate; if (m_pDataToARQC != NULL) { delete []m_pDataToARQC; m_pDataToARQC = NULL; } ctx->Answer(Error_Succeed); return 0; } int CCardSwiperFSM::PostOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); Dbg("post online data[%s]",(LPCTSTR)ctx->Req.data); m_pCardProcess->SplitOnlineReplyData(ctx->Req.data,strlen(ctx->Req.data)); int issBnkAuth = m_pCardProcess->IssueBankAuth(m_eReadType,m_pCardSwiper); CSimpleStringA csTransEnd; if (issBnkAuth == 0) { int transEnd = m_pCardProcess->TransEnd(m_eReadType,m_pCardSwiper,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; } int CCardSwiperFSM::QueryCardInfo(SpReqAnsContext::Pointer ctx) { CardSwiperStatus devStatus; ErrorCodeEnum eErr = m_pCardSwiper->GetDevStatus(devStatus); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, GetDevStatus); ctx->Answer(Error_Unexpect, AlarmDECToBusiness()); return 1; } int ret = 0; switch(devStatus.eMedia) { case CI_MEDIA_IC: ret = 2; break; case CI_MEDIA_NOT_IC: ret = 3; break; case CI_MEDIA_RF: ret = 4; break; case CI_MEDIA_IDCARD: ret = 6; break; case CI_MEDIA_NOTPRESENT: default: ret = 0; break; } ctx->Ans.position = ret; Dbg("query card eMedia:%d, position:%d", devStatus.eMedia, ctx->Ans.position); ctx->Answer(Error_Succeed); return ret; } void CCardSwiperFSM::SelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { //for simple pTransactionContext->SendAnswer(m_testResult); } //void CCardSwiperFSM::LogErrInfo(const char* msgHead) //{ // DevErrorInfo errInfo; // ErrorCodeEnum eErr = m_pCardSwiper->GetLastErr(errInfo); // if (eErr == Error_Succeed) // Dbg("%s,%s",msgHead,errInfo.szErrMsg); //} int CCardSwiperFSM::DoAbortRead() { if(m_bReading) { Dbg("do abort"); m_bCancelRead = true; ErrorCodeEnum eErr = m_pCardSwiper->AbortRead(); if(eErr == Error_Succeed) { return 0; } else { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, AbortRead); return 1; } } Dbg("Not reading situation, ignore it."); return -1; } int CCardSwiperFSM::Eject() { LOG_FUNCTION(); int ret = 0; DWORD dwStart = GetTickCount(); DWORD dwEnd = dwStart; ErrorCodeEnum eErr = Error_Unexpect; eErr = m_pCardSwiper->EjectCard(CI_MOVECARD_FRONT_GATE); if (eErr == Error_Succeed) { //for RVC.Desk2S //oilyang@20200426 add Desk1S if (_strnicmp(m_csMachineType, "RVC.Desk2S", strlen("RVC.Desk2S")) == 0 ||_strnicmp(m_csMachineType, "RVC.Desk1S", strlen("RVC.Desk1S")) == 0) LogEvent(Severity_Middle, LOG_EVT_CARDREADER_GREEN_ON, "CardReader(MAG) warning on"); while (1) { if (m_bExit) { Dbg("bExit == true."); ret = 2; break; } dwEnd = GetTickCount(); if ((dwEnd - dwStart) > 58 * 1000) { Dbg("TickCount timeout."); ret = 2; break; } ErrorCodeEnum eErr = m_pCardSwiper->GetDevStatus(devStatus); if (eErr == Error_Succeed) { Dbg("devStatus.eMedia %d", devStatus.eMedia); if (devStatus.eMedia != CI_MEDIA_IC && devStatus.eMedia != CI_MEDIA_NOT_IC && devStatus.eMedia != CI_MEDIA_RF && devStatus.eMedia != CI_MEDIA_IDCARD && devStatus.eMedia != CI_MEDIA_ENTERING) { ret = 0; break; } } Sleep(100); } //for RVC.Desk2S //oilyang@20200426 add Desk1S if (_strnicmp(m_csMachineType, "RVC.Desk2S", strlen("RVC.Desk2S")) == 0 || _strnicmp(m_csMachineType, "RVC.Desk1S", strlen("RVC.Desk1S")) == 0) LogEvent(Severity_Middle, LOG_EVT_CARDREADER_GREEN_OFF, "CardReader(MAG) warning off."); return ret; } else { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, EjectCard); return 2; } } int CCardSwiperFSM::MagTransInit(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); if (_strnicmp(m_csVendor,"yotap",strlen("yotap")) == 0 && m_version == 1 && m_batch == 1) { Dbg("SKYUI version 1.1,no need to init."); return 0; } Dbg("%d,%s,%d", m_csCM.GetLength(), (const char*)m_csCM, strlen("V2.0")); if (m_csCM.GetLength() > 3 && _strnicmp(m_csCM, "V2.0", strlen("V2.0")) == 0) { return TransInitEx(true); } CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErr = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErr != Error_Succeed) { Dbg("open run cfg file failed!"); return 1; } int ret = 0; int priKeyLen,pubKeyLen; char *pPriKey = new char[MAX_KEY_SIZE]; char *pPubKey = new char[MAX_KEY_SIZE]; ZeroMemory(pPriKey,MAX_KEY_SIZE); ZeroMemory(pPubKey,MAX_KEY_SIZE); eErr = m_pCardSwiper->GetKeyPair((char*&)pPriKey,priKeyLen,pPubKey,pubKeyLen); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, GetKeyPair); //ctx->Ans.result = 1; //ctx->Answer(Error_Succeed); return 1; } else Dbg("GetKeyPair suc."); eErr = m_pCardSwiper->LoadPrivateKey(pPriKey,priKeyLen); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, LoadPrivateKey); //ctx->Ans.result = 1; //ctx->Answer(Error_Succeed); return 1; } else Dbg("LoadPrivateKey suc."); //Dbg("oiltest [%s]",pPubKey); SwitchDataForSave(true,pPubKey); //Dbg("oiltest [%s]",pPubKey); eErr = spConfig->WriteConfigValue("MagTransfer","pubparam",pPubKey); if (eErr != Error_Succeed) { Dbg("write pub key failed(%d).",eErr); return 1; } eErr = DataTransferInit();//oiltest Dbg("device init.init data transfer(%d)",eErr); //if (eErr != Error_Succeed) // LogErrInfo("DTI"); //Dbg("oiltest pri[%s],pub[%s]",pPriKey,pPubKey); //ctx->Ans.result = 0; //ctx->Answer(Error_Succeed); //m_pubKey = new char[MAX_KEY_SIZE+1]; //ZeroMemory(m_pubKey,MAX_KEY_SIZE); //strncpy(m_pubKey,pPubKey,pubKeyLen); return 0; } void CCardSwiperFSM::SwitchDataForSave(bool bSet,char *&pData) { if (strlen(pData) < 16) { Dbg("wrong data lenth to switch."); return; } char tmpFst8Byte[8],tmpSnd8Byte[8]; ZeroMemory(tmpFst8Byte,8); ZeroMemory(tmpSnd8Byte,8); strncpy(tmpFst8Byte,pData,8); strncpy(tmpSnd8Byte,pData+8,8); strncpy(pData,tmpSnd8Byte,8); strncpy(pData+8,tmpFst8Byte,8); return; } int CCardSwiperFSM::QueryConnInfo(int nFlag /* = 0*/) { //if (m_bReading) { // return 1; } //return 1;//oiltest 20160421 m_connChecking = true; int OldFlag = nFlag; int online = 0; ErrorCodeEnum eErr = Error_Unexpect; int preConnStatus = -1, count = 0,getBatteryCount = 0; m_bCancelQueryConn = false; while (!m_bCancelQueryConn) { if(m_pCardSwiper == NULL) { break; } if (!m_bReading && m_bInMainPage) { EnterCriticalSection(&g_csCntStatus); eErr = m_pCardSwiper->IfDevOnline(online); if (eErr == Error_Succeed && online == 1) { //oilyang@20200618 add if (m_bFWBOpenSucEver) { if ((getBatteryCount % 150) == 0 && m_bFWBOpenSucEver)//2000(ms)*150 = 5 minutes { Dbg("to get battery status"); FWBStatus fwbStatus; eErr = m_pCardSwiper->GetBatteryStatus(fwbStatus); if (eErr == Error_Succeed) { if (fwbStatus.BatteryLeft > 0 && fwbStatus.BatteryLeft <= 100) { Dbg("fwb battery left:%d", fwbStatus.BatteryLeft); char buf[32] = { 0 }; sprintf_s(buf, "fwb battery left:%d", fwbStatus.BatteryLeft); LogWarn(Severity_Low, Error_Succeed, LOG_EVT_BATTERY_LEFT, buf); } } } getBatteryCount++; } else getBatteryCount = 0; if (preConnStatus != m_connStatus) { preConnStatus = 1; //if(m_nLstSate == s9) //{ // SendDevStatusMsg(2); //} //else //{ // SendDevStatusMsg(1); //} SendDevStatusMsg(1); Dbg("设备连接正常"); if (!m_bDoingBindFWB)//oilyang@20200407 being in BindFWB,no need to post event PostEventFIFO(new FSMEvent(USER_EVT_DEV_CONNECTED)); } m_connStatus = 1; } else { if (preConnStatus != m_connStatus) { preConnStatus = 0; SendDevStatusMsg(0); Dbg("设备连接断开"); PostEventFIFO(new FSMEvent(USER_EVT_DEV_DISCONNECTED)); } m_connStatus = 0; } LeaveCriticalSection(&g_csCntStatus); if(m_connStatus == 1) { if (m_bNeedInitCh) { count++; } else count = 0; int newFlag = GetAAState(); if(newFlag == 0) { if (count > 60)//60*2 = 120s,两分钟 { Dbg("两分钟内通道未建立,再次尝试建立"); OldFlag = ProcessEnChannel(); count = 0; } else if(count != 0 && OldFlag != 0) { Dbg("准入状态成功,再次尝试建立"); OldFlag = ProcessEnChannel(); count = 0; } } } } Sleep(2000); } m_connChecking = false; return 0; } //void CCardSwiperFSM::LogDevErrorInfo() //{ // if (m_pCardSwiper != NULL) // { // DevErrorInfo devErrInfo; // ErrorCodeEnum eErr; // eErr = m_pCardSwiper->GetLastErr(devErrInfo); // if (eErr == Error_Succeed) // { // Dbg("deverrinfo[%s]", devErrInfo.szErrMsg); // } // } //} //int CCardSwiperFSM::TransInitEx() // //{ // LOG_FUNCTION(); // //oilyang 20160507,to judge if the device support the encrypted channel v2 // //MessageBoxA(0, 0, 0, 0); // 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; // ErrorCodeEnum eErr = m_pCardSwiper->TransferEnInit(iStatus, Cr1, lenCr1, Cr3, lenCr3, dKey, lenDKey); // if (eErr != Error_Succeed) // { // Dbg("TransferEnInit failed:%d,%d", eErr, iStatus); // LogDevErrorInfo(); // return 1; // } // ZeroMemory(m_r1, ONE_K / 8); // char tmp[2048]; // ZeroMemory(tmp, ONE_K * 2); // ConvAscii(Cr1, tmp, lenCr1); // int rt = sm2_decrypt_new((const char*)tmp, (const char*)m_priKey, (char*)m_r1); // if (rt == 0) // { // Dbg("decrypte Cr1 failed,%s,%d.", tmp, lenCr1); // LogDevErrorInfo(); // bFirstFailed = true; // } // Dbg("Cr1 %s,%d.", tmp, lenCr1); // ZeroMemory(m_r3, ONE_K / 8); // ZeroMemory(tmp, ONE_K * 2); // ConvAscii(Cr3, tmp, lenCr3); // rt = sm2_decrypt_new((const char*)tmp, (const char*)m_priKey, (char*)m_r3); // if (rt == 0) // { // Dbg("decrypte Cr3 failed,%s,%d.", tmp, lenCr3); // LogDevErrorInfo(); // bFirstFailed = true; // } // Dbg("Cr3 %s,%d.", tmp, lenCr3); // ZeroMemory(m_devPubKey, ONE_K / 2); // ZeroMemory(tmp, ONE_K * 2); // ConvAscii(dKey, tmp, lenDKey); // // rt = sm2_decrypt_new((const char*)tmp, (const char*)m_priKey, (char*)m_devPubKey); // Dbg("dKey %s,%d.", tmp, lenDKey); // if (rt == 0) // { // Dbg("decrypte dKey failed,%s,%d.", tmp, lenDKey); // LogDevErrorInfo(); // bFirstFailed = true; // } // if (bFirstFailed) // { // Dbg("decrypte data failed."); // LogDevErrorInfo(); // return 2; // } // char pubkey_x[128]; // char pubkey_y[128]; // char random_key[128]; // unsigned char tbuf[4096]; // char encrnd[1024]; // int encdatalen; // int iloop; // memset(pubkey_x, 0, sizeof(pubkey_x)); // memset(pubkey_y, 0, sizeof(pubkey_y)); // //取随机因子 // srand((int)time(NULL)); // for (iloop = 0; iloop < 32; iloop++) // tbuf[iloop] = rand() % 256; // ConvAscii(tbuf, random_key, 32); // // //公钥X分量 // ConvAscii(m_devPubKey, pubkey_x, 32); // ConvAscii(m_devPubKey + 32, pubkey_y, 32); // // //随机数2 // // BYTE r2[16]; // ZeroMemory(r2, 16); // for (int i = 0; i < 15; ++i) // { // unsigned int ram; // int ret = rand_s(&ram); // 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); // Dbg("randomkey:%s,public_x[%s],public_y[%s],r2:[%s]", (char*)random_key, (char*)pubkey_x, (char*)pubkey_y, xxxR2); // // encdatalen = sm2_encrypt_new(random_key, pubkey_x, pubkey_y, (char *)r2, 16, encrnd); // Dbg("Cr2:%s", encrnd); // // unsigned char *xxxCR2 = new unsigned char[512]; // ZeroMemory(xxxCR2, 512); // AsciiToHex(encrnd, xxxCR2, strlen(encrnd)); // eErr = m_pCardSwiper->SetR2(iStatus, xxxCR2, strlen(encrnd) / 2); // if (eErr != Error_Succeed) // { // Dbg("SetR2 failed:%d,%d", eErr, iStatus); // LogDevErrorInfo(); // return 3; // } // // //oiltest // //char *x1 = "166001A67806649588436EAC17DC9509",*x2="46C3036973421444746B40C64AE0D16C",*x3="8474EE7382F493B3467F8ED1672C3B2D"; // //char *x1 = "022E51F72A2AF7906FFC8CA5F0A9DBD5", *x2 = "2EB281B004101BF0C2E339559E5B4A90", *x3 = "4D1144D471082AEC5FCE61BF48074330"; // // //AsciiToHex(x1, m_r1, 32); // //AsciiToHex(x2, m_r2, 32); // //AsciiToHex(x3, m_r3, 32); // // // //CR1 = 8F4C28DA23E9067AD611B70B2B18CFDA21B70EE0BF02D1EBD18C3D234C2A8C9ED37C59AF2DC58C87DFD3C57710B6DC4C5078B3061868C10CD8766FE8E363E1D9CD51D1487CBDDBFB96649F473451B187BC2393F8B7F4D013571DB42BDAFC9255A1FB0A4B30FC63D2C70FE3D5E4A201C3 // // random1 = C55F695E411FC8907CBB2D683051C68E // // CR3 = 5C356C52BAF5332914DD2D1A0BDACD3C31147645B15CF191DA66655799859A652D1A1C7D2ADD5BB902188E3D0BE7DB1FB5FBE09E5C2827CAD96E4170B07136E5F9DF2635CFC77A90CB2D8AFA910E79FCC6B472679D178E4F079D55081A610C66BDD410560C6502B2DD2995EB8CEACCD0 // // random3 = E2A31C0ADE2026F95B5C08FF32CC6A12 // // dkey = 9C9A27CFCF996862907FC7D4714C31120FEDD7FB34FB4068D7FF6004B68DD78A305703DAEFBEB7B238DF27DDAD1587C01C854B4E47C20D05A99B19011E7E5637E5BE19632AC5109E8FED45306311CCD00EBB683FED6176F0B16FBC1182EB017ECA01DD700A7D5456775BD048EDEA2772A537E62A87BB54316ADD365CB798B20008AF6C50873CAC9AFFE300DFB85B40D64809554DF1E80CB9B9965F3F9B057EED // // 设备公钥D0D0133CE6972F9CB7E8B1F1F32F02191FDF557C6D25BCA331A7756F31FCDD187692C265B0B4B3AFE357341769815202D92B8626860DE9554EFD1B25118A72BF // // 协商密钥请求成功 // // // 11223344556677881122334455667788 // // // // 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; // sm3((unsigned char *)tbuf, ilen, (unsigned char *)(databuf + 64)); // sm3((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_pCardSwiper->SendWorkingKey(sessionKey); // if (eErr != Error_Succeed) // { // Dbg("SendWorkingKey failed:%d,iStatus", eErr, iStatus); // LogDevErrorInfo(); // return 4; // } // //oiltest 测试读卡 // //MagTracks magTracks; // //Dbg("mag card"); // //magTracks.eRange = CI_TRACK_RANGE_2_3; // ////int iStatus = 0; // //eErr = m_pCardSwiper->QueryCardStatus(7, iStatus, magTracks); // //Dbg("%d,%d", eErr, iStatus); // //if (iStatus == 1) // //{ // // Dbg("%s,%d", (char*)magTracks.track[0].data, magTracks.track[0].dwSize); // // Dbg("%s,%d", (char*)magTracks.track[1].data, magTracks.track[1].dwSize); // // Dbg("%s,%d", (char*)magTracks.track[2].data, magTracks.track[2].dwSize); // // //Dbg("%s,%d", magTracks.track[2].data, magTracks.track[2].dwSize); // //} // return 0; //} int CCardSwiperFSM::TransInitEx(bool bPassvie/* = false*/) { 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) { LogWarn(Severity_Middle, eErr, AlarmDEC(MEC_CLIENT_CONNECT_FAILED), "TransInitEx:connect to Entity AccessAuth failed"); 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_pCardSwiper->TransferEnInit(iStatus, Cr1, lenCr1, Cr3, lenCr3, dKey, lenDKey); if (eErr != Error_Succeed) { Dbg("TransferEnInit failed:%d,%d", eErr, iStatus); LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, TransferEnInit); return 1; } Dbg("TransferEnInit ok."); 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) { unsigned int ram; int ret = rand_s(&ram); 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; //oiltmp@20200413 as the Vendor(grg) set the szVendor in wild disorder if (_strnicmp("GrgBanking", m_devCat.szVendor, strlen("GrgBanking")) == 0) req.Vendor = "grg"; else req.Vendor = m_devCat.szVendor; Dbg("to InitDev(%s).",(const char*)req.Vendor); eErr = pAccessAuthClient->InitDev(req, ans, 5000); if (eErr != Error_Succeed) { LogWarn(Severity_Middle, eErr, AlarmDEC(MEC_CLIENT_REQUEST_FAILED), "InitDev from AccessAuth returned failed."); 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()); Dbg("Start to SetR2..."); eErr = m_pCardSwiper->SetR2(iStatus, xxxCR2, ans.EncR2.GetLength() / 2); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, SetR2); 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; sm3((unsigned char *)tbuf, ilen, (unsigned char *)(databuf + 64)); sm3((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_pCardSwiper->SendWorkingKey(sessionKey); if (eErr != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(eErr, SendWorkingKey); return 4; } m_bNeedInitCh = false; return 0; } int CCardSwiperFSM::SplitDevModelInfo() { LOG_FUNCTION(); if (strlen(m_devCat.szModel) < 3) { Dbg("Wrong szModel:%s",m_devCat.szModel); return -1; } m_csCM = m_csPM = ""; 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); } if (_strnicmp(arrParam[i], "PM", 2) == 0) { m_csPM = arrParam[i].SubString(3, arrParam[i].GetLength() - 3); } } Dbg("CM=%s,PM=%s",(const char*)m_csCM,(const char*)m_csPM); return 0; } int CCardSwiperFSM::ProcessEnChannel(bool bIgnore/* = false*/) { int ret = 0; EnterCriticalSection(&g_csChannelStatus); if (IsCryptMachinaType() && m_bNeedInitCh) { if(m_nSplitRes == -1) { ErrorCodeEnum erroCode = m_pCardSwiper->GetDevCategory(m_devCat); if(erroCode != Error_Succeed) { LOG_CARDSWIPER_ERROR_MSG_MACRO(erroCode, GetDevCategory); } m_nSplitRes = SplitDevModelInfo(); } Dbg("%d,%s,%d", m_csCM.GetLength(), (const char*)m_csCM, strlen("V2.0")); if (m_csCM.GetLength() > 3 && _strnicmp(m_csCM, "V2.0", strlen("V2.0")) == 0) { Dbg("传输加密方案V2"); if(!bIgnore) { int nStatus = GetAAState(); if(nStatus != 0) { Dbg("准入状态无效:%d", nStatus); LeaveCriticalSection(&g_csChannelStatus); return nStatus; } } ret = TransInitEx(); if (ret != 0) { ShowFatalrForTransferChannel(2); } else { ShowFatalrForTransferChannel(2, FALSE); } } else { Dbg("传输加密方案V1"); //MagTransInit(NULL);//oiltest 20160509 //oiltest 20160509 if (_strnicmp(m_csVendor, "yotap", strlen("yotap")) == 0) { ret = MagTransInit(NULL); } else ret = DataTransferInit(); if (ret != 0) { ShowFatalrForTransferChannel(1); //GetEntityBase()->GetFunction()->ShowFatalError("CardSwiper加密传输通道V1建立失败!"); } else { ShowFatalrForTransferChannel(1, FALSE); } } } LeaveCriticalSection(&g_csChannelStatus); return 0; } void CCardSwiperFSM::LogErrMsg(const char *pMsgHead, ErrorCodeEnum eErrCode, DWORD defaultDevCode, BOOL bAlarm /*= FALSE*/, BOOL bError/*=FALSE*/) { Dbg("%s failed, EC = %d(0x%x)", pMsgHead, eErrCode, eErrCode); WORD wdErrCode = 0; CSimpleStringA csErrMsg(true); ErrorCodeEnum ec = DeviceBaseHelper::GetAndSplitDevErrInfo(m_pCardSwiper, csErrMsg, wdErrCode); if(ec == Error_Succeed && wdErrCode != 0) { //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly if ((defaultDevCode >> 20) == m_entCode.dwEntityId) UpdateDEC(defaultDevCode); else UpdateDEC(wdErrCode); } else if(defaultDevCode != 0) { UpdateDEC(defaultDevCode); } m_csAlarmMsg = CSimpleStringA::Format("%s failed EC= 0x%x : %s", pMsgHead, eErrCode, (LPCTSTR)csErrMsg); if(bAlarm) { if (bError) LogWarn(Severity_High, eErrCode, AlarmDECToBusiness(), (LPCTSTR)m_csAlarmMsg); else LogWarn(Severity_High, eErrCode, AlarmDEC(), (LPCTSTR)m_csAlarmMsg); } return; } ErrorCodeEnum CCardSwiperFSM::CommitSuicide() { ErrorCodeEnum erroCode = Error_Succeed; erroCode = ReStartRelateEntity("CardSwiper"); //if(m_pSelfcheckClient == NULL) //{ // m_pSelfcheckClient = new SelfChekerClient(this->GetEntityBase()); // if(m_pSelfcheckClient == NULL) // return Error_Unexpect; // erroCode = m_pSelfcheckClient->Connect(); // if(erroCode != Error_Succeed) // { // m_pSelfcheckClient->SafeDelete(); // m_pSelfcheckClient = NULL; // Dbg("Connect to SelfCheck entity failed, 0x%x.", erroCode); // return erroCode; // } // Dbg("Connect to SelfCheck entity suc."); //} //SelfCheckerService_RealCheck_Req req; //req.name = this->GetEntityBase()->GetEntityName(); //SelfCheckerService_RealCheck_Ans ans; //erroCode = m_pSelfcheckClient->RealCheck(req, ans, 5000); //if(erroCode != Error_Succeed) //{ // Dbg("RealCheck for %s failed 0x%x.", (LPCTSTR)req.name, erroCode); // m_pSelfcheckClient->SafeDelete(); // m_pSelfcheckClient = NULL; //} //else //{ // Dbg("RealCheck for %s suc.", (LPCTSTR)req.name); //} return erroCode; } ErrorCodeEnum CCardSwiperFSM::CheckPinPadStatus() { LOG_FUNCTION(); ErrorCodeEnum erroCode = Error_Unexpect; PinPadService_ClientBase* pPinPadClient = new PinPadService_ClientBase(this->GetEntityBase()); erroCode = pPinPadClient->Connect(); if (erroCode != Error_Succeed) { Dbg("connect PinPad fail 0x%x(%d).", erroCode, erroCode); } else { PinPadService_GetDevInfo_Req req = {}; PinPadService_GetDevInfo_Ans ans = {}; erroCode = pPinPadClient->GetDevInfo(req, ans, 3000); if (erroCode != Error_Succeed) Dbg("PinPad::GetDevInfo() fail: 0x%x", erroCode); else { Dbg("PinPad::GetDevInfo() return state: %d", ans.state); if(ans.state == DEVICE_STATUS_NOT_READY) { Sleep(2000); PinPadService_GetDevInfo_Req req2 = {}; PinPadService_GetDevInfo_Ans ans2 = {}; erroCode = pPinPadClient->GetDevInfo(req, ans, 3000); if (erroCode != Error_Succeed) Dbg("PinPad::GetDevInfo() again fail: 0x%x", erroCode); else { Dbg("PinPad::GetDevInfo() again return state: %d", ans.state); if(ans.state != DEVICE_STATUS_NORMAL) erroCode = Error_DevNotAvailable; } } else if(ans.state != DEVICE_STATUS_NORMAL) erroCode = Error_DevNotAvailable; } pPinPadClient->GetFunction()->CloseSession(); } pPinPadClient->SafeDelete(); pPinPadClient = NULL; return erroCode; } ErrorCodeEnum CCardSwiperFSM::ReStartRelateEntity(LPCTSTR szEntityName /*= ""*/) { LOG_TRACE("Enter CCardSwiperFSM::ReStartRelateEntity(%s).", szEntityName); static DWORD sTickInterval = 8000; if(strlen(szEntityName) <= 0) { //TODO: Restart all related entity?? return Error_Param; } if(strnicmp(szEntityName, "PinPad", strlen("PinPad")) == 0) { static int nRestartTick = 0; if(nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_PINPAD_RESTART, "To restart PinPad."); } else if(strnicmp(szEntityName, "CardSwiper", strlen("CardSwiper")) == 0) { static int nRestartTick = 0; if(nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_CARDSWIPER_RESTART, "To restart CardSwiper."); } else if(strnicmp(szEntityName, "IDCertificate", strlen("IDCertificate")) == 0) { static int nRestartTick = 0; if(nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_IDCERTIFICATE_RESTART, "To restart IDCer."); } else if(strnicmp(szEntityName, "DeviceControl", strlen("DeviceControl")) == 0) { static int nRestartTick = 0; if(nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_DEVICECONTROL_RESTART, "To restart DeviceCtrl."); } else if (strnicmp(szEntityName, "Sensors", strlen("Sensors")) == 0) { static int nRestartTick = 0; if (nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_SENSORS_RESTART, "To restart Sensors."); } else if (strnicmp(szEntityName, "FingerPrint", strlen("FingerPrint")) == 0) { static int nRestartTick = 0; if (nRestartTick != 0 && nRestartTick + sTickInterval > GetTickCount()) { Dbg("Restart %s too frequently, ignore it.", szEntityName); return Error_NoPrivilege; } nRestartTick = GetTickCount(); LogEvent(Severity_High, LOG_EVT_CARDSWIPER_FINGERPRINT_RESTART, "To restart FingerPrint."); } else { Dbg("Nothing to do with entity %s.", szEntityName); } return Error_Succeed; } ErrorCodeEnum CCardSwiperFSM::CheckDevCtrlStatus() { ErrorCodeEnum erroCode = Error_Unexpect; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CEntityRunInfo runInfo; erroCode = pFunc->GetEntityRunInfo("IDCertificate", runInfo); if(erroCode != Error_Succeed) { Dbg("GetEntityRunInfo about 'IDCertificate' failed 0x%x(%d).", erroCode); } if(erroCode == Error_Succeed && runInfo.eState == EntityState_Lost) { return Error_DevNotAvailable; } if(erroCode == Error_NoPrivilege) {// --Josephus at 15:16:23 2017110 erroCode = Error_Succeed; } return erroCode; } ErrorCodeEnum CCardSwiperFSM::CheckIDCerStatus() { ErrorCodeEnum erroCode = Error_Unexpect; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CEntityRunInfo runInfo; erroCode = pFunc->GetEntityRunInfo("DeviceControl", runInfo); if(erroCode != Error_Succeed) { Dbg("GetEntityRunInfo about 'DeviceControl' failed 0x%x(%d).", erroCode); } if(erroCode == Error_Succeed && runInfo.eState == EntityState_Lost) { return Error_DevNotAvailable; } if(erroCode == Error_NoPrivilege) {// --Josephus at 15:16:23 2017110 erroCode = Error_Succeed; } return erroCode; } void CCardSwiperFSM::RecordRunCfg(CSimpleStringA csState) { CSmartPointer spConfigRun; ErrorCodeEnum ecRet = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if(ecRet == Error_Succeed) { ecRet = spConfigRun->WriteConfigValue("State", "AllInOneState", (LPCTSTR)csState); Dbg("Set 'AllInOneState' with '%s' returned 0x%x.", (LPCTSTR)csState, ecRet); } else { Dbg("Open RunConfig failed when store '%s' returned 0x%x.", (LPCTSTR)csState, ecRet); } } int CCardSwiperFSM::GetAccessAuthState() { int nRes = -1; HealthMngClient* pClient = new HealthMngClient(this->GetEntityBase()); if(pClient != NULL) { ErrorCodeEnum ec = pClient->Connect(); if(ec != Error_Succeed) { pClient->SafeDelete(); pClient = NULL; LogWarn(Severity_Low, ec, AlarmDEC(MEC_CLIENT_CONNECT_FAILED), "Connect to HealthManager entity failed"); return nRes; } HealthManagerService_GetNetworkState_Req req; HealthManagerService_GetNetworkState_Ans ans; ans.reserved1 = 0; ec = pClient->GetNetworkState(req, ans, 5000); if(ec == Error_Succeed) { nRes = ans.reserved1; Dbg("AccessAuth state(reserved1): %d", nRes); } else { Dbg("GetNetworkState from HealthManager failed 0x%x.", ec); } pClient->GetFunction()->CloseSession(); pClient->SafeDelete(); pClient = NULL; } return nRes; } void CCardSwiperFSM::SetAAState(int val) { Dbg("Start to Set accessauth state: %d", val); EnterCriticalSection(&g_csAuthAccessStatus); m_nAAStatus = val; Dbg("Real Set accessauth state: %d", m_nAAStatus); LeaveCriticalSection(&g_csAuthAccessStatus); } void CCardSwiperFSM::SetAcceptWaitMore(bool bValue) { if (bValue) { if (m_bReading) { if (m_bWaitAccepteMore) m_bResetInsertMore = true; else { Dbg("to wait more..."); InsertWaitMoreTask *pTask = new InsertWaitMoreTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask); } m_bWaitAccepteMore = true; } } else m_bWaitAccepteMore = false; } void CCardSwiperFSM::InsertWaitMore() { LOG_FUNCTION(); INT64 iStart = GetTickCount64(); INT64 iEnd = GetTickCount64(); while ((iEnd - iStart) < 60 * 1000) { if (m_bCancelRead || !m_bReading) { Dbg("bCancelRead %d or m_bReading %d ", m_bCancelRead, m_bReading); SetAcceptWaitMore(false); return; } if (m_bResetInsertMore) { iStart = GetTickCount64(); m_bResetInsertMore = false; } Sleep(1000); iEnd = GetTickCount64(); } Dbg("InsertWaitMore timeout,to call AbortRead."); SetAcceptWaitMore(false); if (m_pCardSwiper) { ErrorCodeEnum eErr = m_pCardSwiper->AbortRead(); Dbg("AbortRead ret:%d",eErr); } } int CCardSwiperFSM::IsValidFWBName(const char* pName, int len) { //设备唯一标识:约定序列号以厂商简称的大写形式开头(两个字母,避免重复,需报备行方) //+“FWB” + “A” + 6 位顺序序号,如:SZ-FWB-A000001,其中“SZ”是厂家简称,“A”为迭代版 // 本,分隔符为“ - ”(短横杠),共 14 个字符 //厂商 xxx if (len != 14) return 0; if (_strnicmp(pName + 3, "FWB", 3) == 0) return 1; else return 0; } void CCardSwiperFSM::AddToFWBRecords(const char* name, const char* remoteMac, bool bFirst) { EnterCriticalSection(&g_csFwbRecord); if (bFirst) { m_vFWBRecords.clear(); } FWBRecord record; record.name = name; record.remoteMac = remoteMac; m_vFWBRecords.push_back(record); Dbg("the %dth sci,name is:%s", m_vFWBRecords.size(), name); LeaveCriticalSection(&g_csFwbRecord); } void CCardSwiperFSM::ClearFWBRecords() { EnterCriticalSection(&g_csFwbRecord); m_vFWBRecords.clear(); LeaveCriticalSection(&g_csFwbRecord); return; } int CCardSwiperFSM::nameToBthAddr(bool isSearchNearBy) { LOG_FUNCTION(); BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) }; BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp; HBLUETOOTH_DEVICE_FIND hbf; //find hRadio HANDLE hRadio = NULL; BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) }; HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio); int countHRadio = 0; if (NULL != hFind) { do { Dbg("BluetoothFindNextRadio"); if (hRadio) { Dbg("BluetoothGetRadioInfo"); BLUETOOTH_RADIO_INFO LocalRadioInfo = { sizeof(LocalRadioInfo) }; if (ERROR_SUCCESS == BluetoothGetRadioInfo(hRadio, &LocalRadioInfo)) { char output[256]; ZeroMemory(output, 256); sprintf(output, "%ws", LocalRadioInfo.szName); Dbg("LocalRadioInfo.szName: %s,deviceClass:%d", output, LocalRadioInfo.ulClassofDevice); countHRadio++; } } } while (BluetoothFindNextRadio(hFind, &hRadio)); //BluetoothFindRadioClose(hFind); } else Dbg("hFind is null."); Dbg("the end"); //bdsp.hRadio //A handle for the radio on which to perform the inquiry.Set to NULL to perform the inquiry on all local Bluetooth radios. if (countHRadio > 1) hRadio = NULL; ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)); if (isSearchNearBy) { bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS); bdsp.hRadio = hRadio; bdsp.fReturnAuthenticated = TRUE; bdsp.fReturnRemembered = FALSE; bdsp.fReturnUnknown = TRUE; bdsp.fReturnConnected = FALSE; bdsp.fIssueInquiry = TRUE; bdsp.cTimeoutMultiplier = 4;// 4 * 1.28 s 用于搜索蓝牙的时间,经验值 } else { bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS); bdsp.hRadio = hRadio;//设置执行搜索设备所在的句柄,应设为执行BluetoothFindFirstRadio函数所得到的句柄 bdsp.fReturnAuthenticated = true;//是否搜索已配对的设备 bdsp.fReturnRemembered = false;//是否搜索已记忆的设备 bdsp.fReturnUnknown = false;//是否搜索未知设备 bdsp.fReturnConnected = false;//是否搜索已连接的设备 bdsp.fIssueInquiry = false;//是否重新搜索,True的时候会执行新的搜索,时间较长,FALSE的时候会直接返回上次的搜索结果。 bdsp.cTimeoutMultiplier = 2;//指示查询超时的值,以1.28秒为增量。 例如,12.8秒的查询的cTimeoutMultiplier值为10.此成员的最大值为48.当使用大于48的值时,调用函数立即失败并返回 } Dbg("BluetoothFindFirstDevice"); hbf = BluetoothFindFirstDevice(&bdsp, &bdi); if (hbf == NULL) { Dbg("BluetoothFindFirstDevice failed,GetLastError:%d",GetLastError()); return 1; } char output[256]; bool bFirst = false; while (true) { ZeroMemory(output, 256); sprintf(output, "%ws", bdi.szName); Dbg("find %s",output); if (IsValidFWBName(output, strlen(output))) { Dbg("find fwb: %s", output); AddToFWBRecords(output, "xx", bFirst); bFirst = false; } if (!BluetoothFindNextDevice(hbf, &bdi)) break; } Dbg("BluetoothFindDeviceClose"); BluetoothFindDeviceClose(hbf); return 0; } int CCardSwiperFSM::ScanNearbyBTDevice() { LOG_FUNCTION(); //oiltest@20200325 ClearFWBRecords(); nameToBthAddr(true); return 0; ClearFWBRecords(); 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) {//oiltest@20200310 if (WSAGetLastError() == 10108) { WSASetLastError(10108); const int maxWaitTimes = 12; int currentWaitTimes = 0; //oiltest comment the following lines //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); } addressSize = sizeof(addressAsString); // Print the remote bluetooth device address... if (WSAAddressToString(pCSAddr->RemoteAddr.lpSockaddr, pCSAddr->RemoteAddr.iSockaddrLength, &protocolInfo, (LPSTR)addressAsString, &addressSize) == 0) { if (IsValidFWBName(pResults->lpszServiceInstanceName, strlen(pResults->lpszServiceInstanceName))) { Dbg("The remote device address: %s", addressAsString); AddToFWBRecords(pResults->lpszServiceInstanceName, addressAsString, bFirst); bFirst = false; } } 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; } int CCardSwiperFSM::QueryFWBList(SpReqAnsContext::Pointer ctx, int fsmState) { LOG_FUNCTION(); if (!m_bBTScan) { Dbg("to ScanNearbyBTDevice"); m_bBTScan = true; ScanNearbyBTDevice(); m_bBTScan = false; } EnterCriticalSection(&g_csFwbRecord); if (m_vFWBRecords.size() > 0) ctx->Ans.fwbNo.Init(m_vFWBRecords.size()); vector::iterator it; for (it = m_vFWBRecords.begin(); it != m_vFWBRecords.end(); it++) { ctx->Ans.fwbNo.Append(&(it->name),0,1); } LeaveCriticalSection(&g_csFwbRecord); ctx->Answer(Error_Succeed); return fsmState; } int CCardSwiperFSM::BindFWB(SpReqAnsContext::Pointer ctx, int fsmState) { LOG_FUNCTION(); m_bDoingBindFWB = true; Dbg("bindSCI type:%d, name:%s, previous fsm state: %d,current devSN:%s", ctx->Req.type , (const char*)ctx->Req.fwbNo, fsmState,(const char*)m_csDevNo); ErrorCodeEnum eErr = Error_Unexpect; int ret = fsmState;; switch (ctx->Req.type) {//绑定类型:0:查询绑定,如果绑定则返回绑定设备序列号;1:绑定; 2:解绑 case 0://查询绑定,如果绑定则返回绑定设备序列号 ctx->Ans.fwbNo = ""; if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { ctx->Ans.fwbNo = m_csDevNo; } ctx->Answer(Error_Succeed); break; case 1://绑定 if (IsValidFWBName((const char*)m_csDevNo, m_csDevNo.GetLength())) { Dbg("have already bind to %s",(const char*)m_csDevNo); ctx->Answer(Error_Duplication); } else { if (!IsValidFWBName((const char*)ctx->Req.fwbNo, ctx->Req.fwbNo.GetLength())) { ctx->Answer(Error_Param); } else { ClearHandleOjbects(); int retInit = Initial(ctx->Req.fwbNo,false); if (retInit == 0) { AfterBindUpdateFWBNameToRunCfg((const char*)ctx->Req.fwbNo, true); ReStartRelateEntity("PinPad"); ReStartRelateEntity("FingerPrint"); ReStartRelateEntity("DeviceControl"); ReStartRelateEntity("IDCertificate"); ReStartRelateEntity("Sensors"); ctx->Answer(Error_Succeed); Sleep(3000); m_bNeedInitCh = true; ProcessEnChannel(); ret = 2; } else { //ClearHandleOjbects(); m_csDevNo = ""; m_csVendor = ""; HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, m_csVendor); Dbg("bind failed. ret:%d", retInit); ctx->Answer(Error_Unexpect, CardSwiper_UserErrorCode_After_Bind_FWB_Initial_Failed); } } } break; case 2://解绑 if (m_csDevNo.GetLength() < 1) { Dbg("no bind relation in local."); ctx->Answer(Error_Succeed); } if (!IsValidFWBName((const char*)ctx->Req.fwbNo, ctx->Req.fwbNo.GetLength()) || m_csDevNo.Compare(ctx->Req.fwbNo,true) != 0) { ctx->Answer(Error_Param); } else { AfterBindUpdateFWBNameToRunCfg((const char*)ctx->Req.fwbNo,false); ClearHandleOjbects(); ReStartRelateEntity("PinPad"); ReStartRelateEntity("FingerPrint"); ReStartRelateEntity("DeviceControl"); ReStartRelateEntity("IDCertificate"); ReStartRelateEntity("Sensors"); ret = 0; ctx->Answer(Error_Succeed); } break; default: break; } m_bDoingBindFWB = false; return ret; } ErrorCodeEnum CCardSwiperFSM::AfterBindUpdateFWBNameToRunCfg(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("(AfterBindUpdateFWBNameToRunCfg)open cfg file failed!"); return eErrDev; } if (bBind) { CSimpleStringA csName(name); spConfig->WriteConfigValue("fwb", "devSN", name); CSimpleStringA csVendor = csName.SubString(0, 2); Dbg("fwb vendor: %s", (const char*)csVendor); spConfig->WriteConfigValue("fwb", "vendor", (const char*)TransferAboutVendorShortName(csVendor)); } else { spConfig->WriteConfigValue("fwb", "vendor", ""); spConfig->WriteConfigValue("fwb", "devSN", ""); GetEntityBase()->GetFunction()->SetSysVar("FWBVendor","",true); GetEntityBase()->GetFunction()->SetSysVar("FWBDevSN","", true); GetEntityBase()->GetFunction()->SetSysVar("FWBVersion","", true); m_csDevNo = ""; } return Error_Succeed; } //定期扫描,功能: //1.搜索附近符合FWB规范的蓝牙,在业务取列表式,直接返回;对性能的影响? //2.如果绑定过蓝牙多合一,而没有连接上,在搜索结果中发现对应序列号设备,定期尝试连接; //3.如果蓝牙多合一已经连接上或者旧版多合一打开成功,不做任何事情 int CCardSwiperFSM::FWBBluetoothScanTask() { while(1) { if (m_bDoingBindFWB) { Sleep(10 * 1000); } else if (m_bDevOpenEx) { Sleep(10 * 1000); } else { if (!m_bBTScan) { m_bBTScan = true; ScanNearbyBTDevice(); m_bBTScan = false; } else Sleep(10 * 1000); } } return 0; } void CCardSwiperFSM::ClearHandleOjbects() { LOG_FUNCTION(); m_csDevNo = ""; m_csVendor = ""; HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, m_csVendor); if (m_pCardSwiper != NULL) { Dbg("to clear m_pCardSwiper"); m_pCardSwiper->DevClose(); m_bFWBOpenSucEver = false; ReleaseDevComponent((DeviceBaseClass * &)m_pCardSwiper); m_pCardSwiper = NULL; } if (m_pCardProcess != NULL) { Dbg("to clear m_pCardProcess"); delete m_pCardProcess; } } CSimpleStringA CCardSwiperFSM::TransferAboutVendorShortName(CSimpleStringA name) { if (name.Compare("CT", true) == 0) return "Centerm"; else if (name.Compare("GW", true) == 0) return "GWI"; else if (name.Compare("NT", true) == 0) return "nantian"; else return CSimpleStringA(name); }