#include "stdafx.h" #include "ContactlessFSM.h" #include "EventCode.h" #include "ContactlessCard_msg_g.h" #include "ModuleMix.h" #include "ContactlessCard_UserErrorCode.h" #include "CommDevEntityErrorCode.h" #include #include "publicFunExport.h" #ifdef RVC_OS_WIN #else #include #endif //RVC_OS_WIN const int GET_DEV_STATUS_COUNT = 3; const int MAX_RESET_TIMES_PERIOD = 1000;//oiltest configure to ini file? const int MAX_RESET_TIMEROUT = 5000; const int WAIT_TRY_NUM = 120; const int WAIT_INTERVAL = 500; const int ACCEPT_TRY_INTERVAL = 500; const int ACCEPT_TRY_NUM = 110; // 500*110=55 seconds const int READ_TRY_NUM = 1;//oiltest const int INIT_TRY_NUM = 3; class CContactlessCardEntity; void CContactlessCardFSM::s0_on_entry() { LOG_FUNCTION(); m_eDevState = DEVICE_STATUS_NOT_READY; FSMEvent *e = new FSMEvent(USER_EVT_INIT); PostEventFIFO(e); } void CContactlessCardFSM::s0_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::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 CContactlessCardFSM::s1_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s1_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s1_on_event(FSMEvent* event) { LOG_FUNCTION(); if (event->iEvt == USER_EVT_INITFINISHED) { event->SetHandled(); int err = event->param1; if (err == 0) { return 0; } else { return 1; } }else if (event->iEvt == USER_EVT_QUIT) { event->SetHandled(); return 0; } return 0; } //Idle void CContactlessCardFSM::s2_on_entry() { LOG_FUNCTION(); m_eDevState = DEVICE_STATUS_NORMAL; m_resetTimes = 0; m_testResult = Error_Succeed; ToLogWarnInfoAboutTermCustom(); } void CContactlessCardFSM::s2_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s2_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s2 evt(%d)",pEvt->iEvt); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_ACCEPT: { CardAcceptEvent *cae = dynamic_cast(pEvt); m_bCancelAccept = false; AcceptTask* task = new AcceptTask(this); task->ctx = cae->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_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_EJECT: { CardEjectEvent *cee; if (pEvt->iEvt == USER_EVT_EJECT) cee = dynamic_cast(pEvt); EjectTask *task= new EjectTask(this); if (pEvt->iEvt == USER_EVT_EJECT) task->ctx = cee->ctx; else task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } case USER_EVT_EXIT: m_bExit = true; pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; default: break; } return ret; } //accepting void CContactlessCardFSM::s3_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s3_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s3_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s3 evt (%d)(%d)",pEvt->iEvt,pEvt->param1); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_ACCEPTFINISHED: { pEvt->SetHandled(); switch(pEvt->param1) { case 0: case 1: case 2: case 3: case 4: ret = pEvt->param1; break; default: ret = 1; break; } } break; case USER_EVT_ACCEPT_CANCEL: m_bCancelAccept = true; pEvt->SetHandled(); ret = 3; 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_EXIT: m_bExit = true; pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; default: break; } return ret; } //Hold void CContactlessCardFSM::s4_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s4_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s4_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s4 evt(%d,%d)",pEvt->iEvt,pEvt->param1); switch(pEvt->iEvt){ case USER_EVT_ACCEPT: { CardAcceptEvent *cae = dynamic_cast(pEvt); m_bCancelAccept = false; AcceptTask* task = new AcceptTask(this); task->ctx = cae->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); } break; case USER_EVT_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_EXIT: case USER_EVT_EJECT: { pEvt->SetHandled(); CardEjectEvent *cee; if (pEvt->iEvt == USER_EVT_EJECT) cee = dynamic_cast(pEvt); EjectTask *task= new EjectTask(this); if (pEvt->iEvt == USER_EVT_EJECT) task->ctx = cee->ctx; else task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); 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_QUERY_CARD_INFO_FINISHED: { pEvt->SetHandled(); if (pEvt->param1 == 0) return 0; else return 1; } case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } case USER_EVT_ACCEPT_CANCEL: m_bCancelAccept = true; pEvt->SetHandled(); default: break; } return 0; } //Reading void CContactlessCardFSM::s5_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s5_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s5_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s5 event(%d)",pEvt->iEvt); switch(pEvt->iEvt) { case USER_EVT_EXIT: { EjectTask *task= new EjectTask(this); task->ctx = NULL; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); pEvt->SetHandled(); return 0; } break; case USER_EVT_QUIT: { pEvt->SetHandled(); return 0; } default: break; } return 0; } //Ejecting void CContactlessCardFSM::s6_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s6_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s6_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s6 evt(%d,%d)",pEvt->iEvt,pEvt->param1); int ret = 0; switch(pEvt->iEvt) { case USER_EVT_EJECTFINISHED: pEvt->SetHandled(); ret = pEvt->param1; break; case USER_EVT_QUIT: case USER_EVT_EXIT: pEvt->SetHandled(); break; default: break; } return ret; } void CContactlessCardFSM::s7_on_entry() { LOG_FUNCTION(); WaitFetchingTask* task = new WaitFetchingTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CContactlessCardFSM::s7_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s7_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s7 evt(%d)",pEvt->iEvt); switch(pEvt->iEvt) { case USER_EVT_WAITFINISHED: { pEvt->SetHandled(); if (pEvt->param1 == 0) { FetchCard evt; evt.status = 0; SpSendBroadcast(m_pEntity->GetFunction(),SP_MSG_OF(FetchCard),SP_MSG_SIG_OF(FetchCard),evt); LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_OP,"CardIssuer op."); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("客户取走卡片msg发送"); return 0; } else if (pEvt->param1 == 1) { //FetchCard evt; //evt.status = 1; //SpSendBroadcast(m_pEntity->GetFunction(),SP_MSG_OF(FetchCard),SP_MSG_SIG_OF(FetchCard),evt); //Dbg("取卡时设备故障"); //return 1; } else { FetchCard evt; evt.status = 2; SpSendBroadcast(m_pEntity->GetFunction(),SP_MSG_OF(FetchCard),SP_MSG_SIG_OF(FetchCard),evt); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("客户未取卡超时msg发送"); LogWarn(Severity_Middle, Error_NotInit, ContactlessCard_UserErrorCode_FORGET_FETCH, "Customer forget fetch card."); return 2; } } 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; } //capture void CContactlessCardFSM::s8_on_entry() { LOG_FUNCTION(); } void CContactlessCardFSM::s8_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s8_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s8 evt(%d)",pEvt->iEvt); if (pEvt->iEvt == USER_EVT_CAPTUREFINISHED){ pEvt->SetHandled(); int err = pEvt->param1; if (err == 0) return 0; else return 1; }else if (pEvt->iEvt == USER_EVT_QUIT) { pEvt->SetHandled(); return 0; } return 0; } void CContactlessCardFSM::s9_on_entry() { LOG_FUNCTION(); m_eDevState = DEVICE_STATUS_FAULT; FSMEvent *e = new FSMEvent(USER_EVT_RESET); PostEventFIFO(e); } void CContactlessCardFSM::s9_on_exit() { LOG_FUNCTION(); } unsigned int CContactlessCardFSM::s9_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s9 evt(%d)(%d)",pEvt->iEvt, pEvt->param1); switch(pEvt->iEvt) { case USER_EVT_RESET: { pEvt->SetHandled(); m_resetTimes++; if (m_resetTimes > MAX_RESET_TIMES_PERIOD) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("restart tried %d times,give up",m_resetTimes); m_testResult = Error_InvalidState; LogWarn(Severity_Middle,Error_Unexpect, ContactlessCard_UserErrorCode_Reset_Failed,"reset failed more times"); return 0; } ResetDeviceEvent* rde = dynamic_cast(pEvt); ResetTask* task = new ResetTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); return 0; } break; case USER_EVT_RESETFINISHED: { ResetFinishedEvent *rfe = dynamic_cast(pEvt); return rfe->param1; } 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_ACCEPT_CANCEL: m_bCancelAccept = true; pEvt->SetHandled(); break; default: break; } return 0; } ErrorCodeEnum CContactlessCardFSM::OnInit() { LOG_FUNCTION(); auto pEntity = GET_DEV_ENTITY_BASE_POINTER(); pEntity->InitializeVendorLogSwitch(); FulfillAdapterInfoFrom(pEntity->vendorLibInfo); m_pCardProcess = new CCardProcess(); if (m_pCardProcess == NULL)//almost no use... { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create card process failed."); return Error_Resource; } CSystemStaticInfo sysInfo; m_csMachineType = ""; GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo); m_csMachineType = sysInfo.strMachineType; m_bOpening = true; ErrorCodeEnum errCode = Load(); if (errCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load failed(%d).",errCode); m_bOpening = false; return errCode; } devStatus.eMediaPos = CI_MEDIA_NOTPRESENT; m_bOpening = false; return Error_Succeed; } ErrorCodeEnum CContactlessCardFSM::OnExit() { LOG_FUNCTION(); ErrorCodeEnum eExit; long l_beginTime, l_endTime; if (m_hDevHelper != nullptr) { l_beginTime = SP::Module::Comm::RVCGetTickCount(); eExit = m_hDevHelper->GetDevStatus(devStatus); l_endTime = SP::Module::Comm::RVCGetTickCount(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnExit::GetDevStatus eMedia:%d, eErr:%d", devStatus.eMediaPos, eExit); if (eExit == Error_Succeed) { if (devStatus.eMediaPos == CI_MEDIA_PRESENT){ } } l_beginTime = SP::Module::Comm::RVCGetTickCount(); eExit = m_hDevHelper->DevClose(); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (eExit == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::DevClose").setCostTime(l_endTime - l_beginTime)("读卡器关闭成功"); } else{ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("读卡器关闭失败"); SetErrorAndLog(eExit, MEC_DEVAPI_RF_DevClose, "DevAdapter::DevClose", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } } FSMImpl::OnExit(); return Error_Succeed; } ErrorCodeEnum CContactlessCardFSM::Load() { LOG_FUNCTION(); ErrorCodeEnum hr; long l_beginTime, l_endTime; int initTries = 0; ErrorCodeEnum eErrDev = Error_Unexpect; CSimpleString errMsg(true); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; CSimpleStringA csBinPath,csBackslash("\\"); ErrorCodeEnum eErrPath = GetEntityBase()->GetFunction()->GetPath("Bin", csBinPath); if (eErrPath != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load, GetBasePath failed (%d).",eErrPath); return Error_Param; } LogWarn(Severity_Low, Error_Unexpect, ContactlessCard_UserErrorCode_RootInfo, m_adapterInfo.adapterFilePath.GetData()); if (Error_Succeed != LoadUpAdapterLibrary()) { errMsg = "非接读卡器加载厂商适配器失败!请检查root.ini配置是否正确。"; LogWarn(Severity_Middle, Error_Unexpect, ContactlessCard_UserErrorCode_DllLoadFailed, errMsg.GetData()); return Error_DevLoadFileFailed; } do{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("open card issuer, port:%d, baudRate:%d", m_adapterInfo.GetPortInt(), m_adapterInfo.GetBaudrateInt()); l_beginTime = SP::Module::Comm::RVCGetTickCount(); hr = m_hDevHelper->DevOpen(m_adapterInfo.GetPortInt(), m_adapterInfo.GetBaudrateInt()); l_endTime = SP::Module::Comm::RVCGetTickCount(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("port:%d, baudRate:%d, hr:%d",m_adapterInfo.GetPortInt(), m_adapterInfo.GetBaudrateInt(), hr); if (hr == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::DevOpen").setCostTime(l_endTime - l_beginTime)("ContactlessCard DevOpen succ , dwPort:%d, dwBaudRate:%d", m_adapterInfo.GetPortInt(), m_adapterInfo.GetBaudrateInt()); ToLogRootINIInfo(); m_bOpened = true; ZeroMemory(m_devCatInfo.szModel, sizeof(m_devCatInfo.szModel)); ZeroMemory(m_devCatInfo.szType, sizeof(m_devCatInfo.szType)); ZeroMemory(m_devCatInfo.szVendor, sizeof(m_devCatInfo.szVendor)); l_beginTime = SP::Module::Comm::RVCGetTickCount(); eErrDev = m_hDevHelper->GetDevCategory(m_devCatInfo); l_endTime = SP::Module::Comm::RVCGetTickCount(); if(eErrDev == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetDevCategory").setCostTime(l_endTime - l_beginTime)("OpenDevice, szVendor:%s, szType:%s, szModel:%s",m_devCatInfo.szVendor, m_devCatInfo.szType, m_devCatInfo.szModel); m_adapterInfo.FulfillCategoryInfo(m_devCatInfo); } else { SetErrorAndLog(eErrDev, MEC_DEVAPI_RF_GetDevCategory, "DevAdapter::GetDevCategory", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); return Error_DevCommFailed; } //#ifdef RVC_OS_WIN // CSimpleStringA csCMBPrint("CMBPrint.dll"); // csCMBPrint = csBinPath + csBackslash + csCMBPrint; // DbgInfo(CSimpleStringA::Format("cmbpath %s", (LPCTSTR)csCMBPrint)); // HMODULE hr = LoadLibraryA(csCMBPrint); // if (hr == NULL) // { // DbgWarn(CSimpleStringA::Format("Load CMBPrint failed(%d).", hr)); // return Error_DevLoadFileFailed; // } // if ((cmdDecodeMag2 = (lpCMBdecodeMag2)GetProcAddress(hr, "CMBdecodeMag2")) == NULL) // { // DbgWarn("Get Mag2 address failed."); // return Error_DevLoadFileFailed; // } // if ((cmdDecodeEx = (lpCMBdecodeEx)GetProcAddress(hr, "CMBdecodeEx")) == NULL) // { // DbgWarn("Get Mag23Ex address failed."); // return Error_DevLoadFileFailed; // } // initTries = 0; // break; //#else // CSimpleStringA csCMBPrint("libCMBPrint.so"); // csCMBPrint = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", // csBinPath.GetData(), csCMBPrint.GetData()); // DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("cmbpath %s", csCMBPrint.GetData()); // // toolkit_lib_t dlOpen; // int res = toolkit_dlopen(csCMBPrint, &dlOpen); // if (res != 0) { // DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Load CMBPrint failed with error %s.", toolkit_dlerror(&dlOpen)); // return Error_DevLoadFileFailed; // } // // if ((res = toolkit_dlsym(&dlOpen, "CMBdecodeMag2", (void**)&cmdDecodeMag2)) != 0) { // DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get Mag2 address failed."); // return Error_DevLoadFileFailed; // } // // if ((res = toolkit_dlsym(&dlOpen, "CMBdecodeEx", (void**)&cmdDecodeEx)) != 0) { // DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get Mag23Ex address failed."); // return Error_DevLoadFileFailed; // } // // initTries = 0; // break; //#endif // RVC_OS_WIN if (!LoadCMBPrint(csBinPath)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Contactless 启动失败:Load CMBPrint failed."); //LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_LoadLibraryA_CMBPrint_Failed, errMsg.GetData()); return Error_DevLoadFileFailed; } initTries = 0; break; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ContactlessCard DevOpen failed , dwPort:%d, dwBaudRate:%d", m_adapterInfo.GetPortInt(), m_adapterInfo.GetBaudrateInt()); SetErrorAndLog(hr, MEC_DEVAPI_RF_DevOpen, "DevAdapter::DevOpen", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ContactlessCard 启动失败:DevOpen failed.重试:%d", initTries); initTries++; } } while (initTries < INIT_TRY_NUM); if (initTries != 0) { if (m_bOpened) { m_hDevHelper->DevClose(); m_bOpened = false; } errMsg = CSimpleStringA::Format("非接读卡器启动失败,have tried %d times!!!", initTries); LogWarn(Severity_Middle, Error_Unexpect, ContactlessCard_UserErrorCode_DevOpen_Failed, errMsg.GetData()); return Error_DevCommFailed; } else { eErrDev = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErrDev != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load, open run cfg file failed!"); return eErrDev; } int ret = 0,isIssue = 0; if ((spConfig->ReadConfigValueInt("RunInfo","CardRemains",m_CardRemains) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","CardIssued",m_CardIssued) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","CardCaptured",m_CardCaptured) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","IsIssue",isIssue) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","CardMixed",m_CardMixed) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","CardInit",m_CardInit) == Error_Succeed) && (spConfig->ReadConfigValueInt("RunInfo","CardPercent",m_CardPercent) == Error_Succeed)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("CardRemains:%d, m_CardIssued:%d, CardCaptured:%d, isIssue:%d, CardMixed:%d, CardInit:%d", m_CardRemains, m_CardIssued, m_CardCaptured, isIssue, m_CardMixed, m_CardInit); m_bIssued = !!(isIssue); //ret = UnAcceptCard(); } else return Error_IO; if (ret == 0) { m_devInit = true; LogWarn(Severity_Low, Error_Unexpect, ContactlessCard_UserErrorCode_DevOpen_Success, "非接读卡器打开成功"); return Error_Succeed; } else{ LogWarn(Severity_Middle, Error_Unexpect, ContactlessCard_UserErrorCode_DevOpen_Failed, "非接读卡器打开失败1"); return Error_Unexpect; } } } int CContactlessCardFSM::Initial() { return 0; } bool CContactlessCardFSM::GetDevStatus(bool bPrint) { int getDevInfoCount = 0; long l_beginTime, l_endTime; ErrorCodeEnum eErr; do{ l_beginTime = SP::Module::Comm::RVCGetTickCount(); eErr = m_hDevHelper->GetDevStatus(devStatus); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (bPrint) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("GetDevStatus eMedia:%d, eErr:%d", devStatus.eMediaPos, eErr); if (Error_Succeed == eErr) { return true; } else { DevErrorInfo devErrInfo; m_hDevHelper->GetLastErr(devErrInfo); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetDevStatus, errMsg:%s",devErrInfo.szErrMsg); getDevInfoCount++; Sleep(3000); } } while (getDevInfoCount < GET_DEV_STATUS_COUNT); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("getdevstatus to reset"); eErr = m_hDevHelper->Reset(); Sleep(MAX_RESET_TIMEROUT); if (eErr == Error_Succeed) { eErr = m_hDevHelper->GetDevStatus(devStatus); if (eErr == Error_Succeed && devStatus.eMediaPos == CI_MEDIA_PRESENT) { } } return false; } int CContactlessCardFSM::Reset() { LOG_FUNCTION(); ErrorCodeEnum eErr; long l_beginTime, l_endTime; l_beginTime = SP::Module::Comm::RVCGetTickCount(); eErr = m_hDevHelper->Reset(); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (eErr == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::Reset").setCostTime(l_endTime - l_beginTime)("Reset succ"); l_beginTime = SP::Module::Comm::RVCGetTickCount(); eErr = m_hDevHelper->GetDevStatus(devStatus); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (Error_Succeed == eErr) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetDevStatus").setCostTime(l_endTime - l_beginTime)("Reset::GetDevStatus,eMedia:%d", devStatus.eMediaPos); return 0; } else{ SetErrorAndLog(eErr, MEC_DEVAPI_RF_GetDevStatus, "DevAdapter::GetDevStatus", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); return 2; } } else { SetErrorAndLog(eErr, MEC_DEVAPI_RF_Reset, "DevAdapter::Reset", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); return 1; } } int CContactlessCardFSM::InternalAcceptCard() { LOG_FUNCTION(); int acceptTries = 0, err = 0; m_bWaitingAccept = true; DWORD64 dwStart = SP::Module::Comm::RVCGetTickCount(); DWORD64 dwEnd = dwStart; do { if (m_bExit) { m_bCancelAccept = true; break; } if (m_bCancelAccept) { err = 3; goto Err; } if (m_bWaitAccepteMore) { acceptTries = 0; m_bWaitAccepteMore = false; dwEnd = dwStart = SP::Module::Comm::RVCGetTickCount(); } if (GetDevStatus(false)) { if (devStatus.eMediaPos == CI_MEDIA_RF) { LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_OP, "Contactless card op."); acceptTries = 0; goto Err; } else { acceptTries++; Sleep(ACCEPT_TRY_INTERVAL); } } else { err = 1; goto Err; } dwEnd = SP::Module::Comm::RVCGetTickCount(); } while (dwEnd - dwStart <= 55 * 1000); err = 2; Err: m_bExit = false; m_bWaitingAccept = false; if (m_bCancelAccept && err != 1) { if (GetDevStatus()) { if (devStatus.eMediaPos == CI_MEDIA_PRESENT) { err = 4; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cancel eject......"); } } else err = 2; } return err; } 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; } int CContactlessCardFSM::AcceptCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); long l_beginTime, l_endTime; ctx->Ans.ICType = 0; m_pCardProcess->DataInit(); LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_ON,"ContactCard green on"); m_bWaitAccepteMore = false; int rc = InternalAcceptCard(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InternalAcceptCard ret:%d", rc); LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_OFF,"ContactCard green off"); if (rc == 0) { //FSMSetIssueFlag(false); if (ctx != NULL) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("insert error_succeed"); //FetchCard evt; //evt.status = 3;//oilyang@20181210 用于通知CardIssuer取消插卡 //SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(FetchCard), SP_MSG_SIG_OF(FetchCard), evt); ctx->Ans.ICData = ""; int activeCardType; //int retICData = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, "A000000333", activeCardType); //oilyang@20201014 add emv card support int retDetectAndRead = -1; if (!ctx->Req.aid.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("front business provide aid:[%s]",(const char*)ctx->Req.aid); CAutoArray aidReq; aidReq.Init(1); aidReq[0] = ctx->Req.aid; l_beginTime = SP::Module::Comm::RVCGetTickCount(); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, aidReq, activeCardType); l_endTime = SP::Module::Comm::RVCGetTickCount(); } else { l_beginTime = SP::Module::Comm::RVCGetTickCount(); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, m_aidList, activeCardType); l_endTime = SP::Module::Comm::RVCGetTickCount(); } if (retDetectAndRead < 0) { // -1和-2是上电或APDU交互失败,功能集循环调用 if (retDetectAndRead == -1){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_ActiveContactlessICCard, "DevAdapter::ActiveContactlessICCard", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); } else if (retDetectAndRead == -2){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); }else if (retDetectAndRead == -3){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); } return 2; } ctx->Ans.t2Account = ctx->Ans.ICData = ""; ICData track2(false,0x57,0x00); ErrorCodeEnum eErr = Error_Unexpect; string t2ICAccount(""),t2ICCardSerial(""),t2ICCVC(""),t2ICTrack2(""),cardType; if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,track2,false,0) == -1) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("no track2 data in ic"); l_beginTime = SP::Module::Comm::RVCGetTickCount(); eErr = m_hDevHelper->HaltCard(); l_endTime = SP::Module::Comm::RVCGetTickCount(); if(Error_Succeed != eErr){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(eErr, MEC_DEVAPI_RF_HaltCard, "DevAdapter::HaltCard", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } } ctx->Answer(Error_Interact);//can't find track2,retry 20150128 } 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 LogWarn(Severity_Low, Error_Succeed, ContactlessCard_UserErrorCode_ReadAccount, CSimpleStringA::Format("split pos:%d, card acount:%s,%s" , pos, t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str())); ctx->Ans.ICData = ctx->Ans.t2Account = t2ICAccount.c_str(); ctx->Ans.ICType = 4; ctx->Ans.status = 0; delete[]ddd; delete[]pICTrack2; //m_hDevHelper->DeactContactlessICCard(); } ctx->Answer(Error_Succeed); } } else if(rc == 2) { if (ctx != NULL) ctx->Answer(Error_TimeOut); } else if(rc == 3 || rc == 4) { if (ctx != NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("insert cancel (%d)",rc); ctx->Answer(Error_Cancel); } }else { //oilyang@20221212 //actully,we reach here only when calling GetDevStatus failed //we have ContactlessCard AND CardIssuer,no need to throw Error_Unexpect here if (ctx != NULL) ctx->Answer(Error_DevNotAvailable); } return rc; } static CSimpleStringA GetStrData(TrackInfo trackInfo) { //LOG_FUNCTION(); CSimpleStringA strRet; switch (trackInfo.eStatus) { case CI_DATA_OK: strRet = (char*)trackInfo.data; break; case CI_DATA_INVALID: strRet = "无效数据"; break; //case CI_DATA_MISSING: default: strRet = "数据丢失"; } return strRet; } int CContactlessCardFSM::SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData) { if (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 25://AE Card decodeData.t2Account = CSimpleString(pTrack2, 15); decodeData.t2CardSerial = pTrack2.SubString(15, 1); decodeData.t2CVC = pTrack2.SubString(16, 5); decodeData.t2ExpireDate = pTrack2.SubString(21, 4); decodeData.t2Region = ""; break; case 38: break; default: return -1; } decodeData.status = 0; return 0; } int CContactlessCardFSM::PreOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); long l_beginTime, l_endTime; m_pCardProcess->DataInit(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(", bus data[%s]", ctx->Req.businessData.GetData()); m_pCardProcess->SplitBusinessData(ctx->Req.businessData,ctx->Req.businessData.GetLength()); m_pCardProcess->SplitBusinessData("DF690101",strlen("DF690101")); int activeCardType; //oilyang@20201014 add emv card support int retDetectAndRead = -1; ICData aidFromBus(false, 0x4f, 0x00); if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the front BusinessData han't provide aid data."); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, m_aidList, activeCardType); } else { char* pAIDTmp = new char[64]; memset(pAIDTmp, 0, 64); HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(", the aid is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp)); CAutoArray preAIDs; preAIDs.Init(1); preAIDs[0] = (CSimpleStringA)pAIDTmp; l_beginTime = SP::Module::Comm::RVCGetTickCount(); retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, preAIDs, activeCardType); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (pAIDTmp != NULL) delete[]pAIDTmp; } if (retDetectAndRead < 0) { // -1和-2是上电或APDU交互失败,功能集循环调用 if (retDetectAndRead == -1){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_ActiveContactlessICCard, "DevAdapter::ActiveContactlessICCard", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); } else if (retDetectAndRead == -2){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); }else if (retDetectAndRead == -3){ if (!ctx->Req.reserved1.IsNullOrEmpty() && ctx->Req.reserved1.Compare("P") == 0) { SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); } ctx->Answer(Error_Interact, GetAlarmDEC()); } return 0; } //if (m_cardType == CI_CARDTYPE_IC) //{ // ProcessRestrict(); // CardholderVerify(); m_pCardProcess->TermRiskManage(); CSimpleStringA taaResult; BYTE bt9f27 = 0; int retTAA = m_pCardProcess->TermActionAnalyze(CARD_MACHINE_RFIC,m_hDevHelper,taaResult,true,m_bCDA,bt9f27); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("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; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(", 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[1024]; ZeroMemory(pSomeICData, 1024); 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)); #ifdef RVC_OS_WIN itoa(lenRet, arqcLen, 10); #else sprintf(arqcLen, "%d", lenRet); #endif // RVC_OS_WIN ICData appExpiryDate(false,0x5f,0x24); if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,appExpiryDate,false,0) == -1) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("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) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("can't find card serial."); } else { HexBuf2StrBuf(ICCardSerial.value,&pICCardSerial,ICCardSerial.lenth); } if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC,track2,false,0) == -1) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("no track2 data in ic"); } 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'; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(", split 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; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("done(ic)."); } //} if (strnicmp(track2Data.t2Account,ddd,strlen(ddd))) { t2ICCVC = ""; t2ICTrack2 = pICTrack2; t2ICAccount = (char*)ddd; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("contactless card countcount:%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; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("data to host(less)[%s],baseICData length:%d", txtresult.c_str(), baseICData.length()); if (m_pDataToARQC != NULL) { delete []m_pDataToARQC; m_pDataToARQC = NULL; } ctx->Answer(Error_Succeed); return 0; } int CContactlessCardFSM::PostOnline(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("post online data[%s]",(LPCTSTR)ctx->Req.data); m_pCardProcess->SplitOnlineReplyData(ctx->Req.data,strlen(ctx->Req.data)); int issBnkAuth = m_pCardProcess->IssueBankAuth(CARD_MACHINE_RFIC,m_hDevHelper); CSimpleStringA csTransEnd; if (issBnkAuth == 0) { int transEnd = m_pCardProcess->TransEnd(CARD_MACHINE_RFIC,m_hDevHelper,m_bCDA); if (transEnd == 0) csTransEnd = "TRANSEND,0"; else if (transEnd == 1) csTransEnd = "TRANSEND,1"; } else csTransEnd = "TRANSEND,1"; ctx->Ans.result = csTransEnd; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("PostOnline, issBnkAuth:%d, csTransEnd:%s", issBnkAuth, csTransEnd.GetData()); ctx->Answer(Error_Succeed); return 0; } int CContactlessCardFSM::EjectCard(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_pCardProcess->DataInit(); int ret = 0; DWORD dwStart = SP::Module::Comm::RVCGetTickCount(); DWORD dwEnd = dwStart; while(1) { if (m_bExit) { ret = 2; break; } dwEnd = SP::Module::Comm::RVCGetTickCount(); if ((dwEnd-dwStart) > 58*1000) { ret = 2; break; } ErrorCodeEnum eErr = m_hDevHelper->GetDevStatus(devStatus); if (eErr == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("EjectCard, devStatus.eMedia %d",devStatus.eMediaPos); if (devStatus.eMediaPos == CI_MEDIA_RF || devStatus.eMediaPos == CI_MEDIA_NOTPRESENT) { if (devStatus.eMediaPos == CI_MEDIA_NOTPRESENT) ret = 0; else if (devStatus.eMediaPos == CI_MEDIA_RF) ret = 1; break; } } Sleep(100); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("eject return."); if (ctx != NULL) ctx->Answer(Error_Succeed); return ret; } int CContactlessCardFSM::WaitFetchingCard() { LOG_FUNCTION(); int waitTries = 0; LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_ON,"ContactCard(fetch) warning on"); do { if (GetDevStatus(false)){ if (devStatus.eMediaPos == CI_MEDIA_RF){ Sleep(WAIT_INTERVAL); waitTries++; } else if (devStatus.eMediaPos == CI_MEDIA_NOTPRESENT){ waitTries = 0; LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_OFF,"ContactCard(fetch) warning off"); return 0; } }else { LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_OFF,"ContactCard(fetch) warning off"); return 1; } }while (waitTries < WAIT_TRY_NUM); LogEvent(Severity_Middle,LOG_EVT_CONTACTLESS_CARD_GREEN_OFF,"ContactCard(fetch) warning off"); return 2; } int CContactlessCardFSM::QueryCardInfo(SpReqAnsContext::Pointer ctx) { RFICReaderStatus devStatus; long l_beginTime, l_endTime; l_beginTime = SP::Module::Comm::RVCGetTickCount(); ErrorCodeEnum eErr = m_hDevHelper->GetDevStatus(devStatus); l_endTime = SP::Module::Comm::RVCGetTickCount(); if (eErr != Error_Succeed) { SetErrorAndLog(eErr, MEC_DEVAPI_RF_GetDevStatus, "DevAdapter::GetDevStatus", __FUNCTION__, false, l_endTime - l_beginTime, "", ""); ctx->Answer(TransECWithRepeat(Error_Unexpect)); return 1; } int ret = 0; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetDevStatus").setCostTime(l_endTime - l_beginTime)("QueryCardInfo, eMedia pos:%d",devStatus.eMediaPos); switch(devStatus.eMediaPos) { //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_NOTPRESENT: default: ret = 0; break; } ctx->Ans.position = ret; ctx->Answer(Error_Succeed); return ret; } void CContactlessCardFSM::ToLogWarnInfoAboutTermCustom() { LOG_FUNCTION(); ToLogWarnInfoAboutTerm(); } bool CContactlessCardFSM::LoadCMBPrint(CSimpleStringA csBinPath) { if (cmdDecodeEx == NULL) { CSimpleStringA csCMBPrint(""); #ifdef RVC_OS_WIN csCMBPrint = "CMBPrint.dll"; csCMBPrint = csBinPath + SPLIT_SLASH_STR + csCMBPrint; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("cmbpath %s", (const char*)csCMBPrint); HMODULE hr = LoadLibraryA(csCMBPrint); if (hr == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load CMBPrint failed(%d).", hr); return false; } if ((cmdDecodeMag2 = (lpCMBdecodeMag2)GetProcAddress(hr, "CMBdecodeMag2")) == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get Mag2 address failed."); return false; } if ((cmdDecodeEx = (lpCMBdecodeEx)GetProcAddress(hr, "CMBdecodeEx")) == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get Mag23Ex address failed."); cmdDecodeMag2 = NULL; return false; } #else csCMBPrint = "libCMBPrint.so"; csCMBPrint = csBinPath + "/" + csCMBPrint; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("cmbpath %s", (const char*)csCMBPrint); void* hr = NULL; hr = dlopen(csCMBPrint, RTLD_LAZY); if (hr == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load CMBPrint failed(%s).", dlerror()); return false; } //pfunc_unpack = (PF_unpack)dlsym(hLib, "_Z6unpackPcS_i"); if ((cmdDecodeMag2 = (lpCMBdecodeMag2)dlsym(hr, "CMBdecodeMag2")) == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get Mag2 address failed."); return false; } if ((cmdDecodeEx = (lpCMBdecodeEx)dlsym(hr, "CMBdecodeEx")) == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get Mag23Ex address failed."); cmdDecodeMag2 = NULL; return false; } #endif DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Load %s succ.", (const char*)csCMBPrint); } return true; } void CContactlessCardFSM::GetCardProcessLastErr(ErrorCodeEnum& eErrCode, CSimpleStringA& ApiName, CSimpleStringA& alarmMsg, CSimpleStringA& csErrMsgWithReturnCode) { if (m_pCardProcess == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetCardProcessLastErr m_pCardProcess is null"); eErrCode = Error_Null; ApiName = ""; alarmMsg = ""; csErrMsgWithReturnCode = ""; return; } ErrorCodeEnum lastErrCode = Error_Succeed; CSimpleStringA lastErrMsg = ""; CSimpleStringA lastApiName = ""; m_pCardProcess->getCardAssistLastErr(lastErrCode, lastErrMsg, lastApiName); const CSimpleStringA alarmMsgStr = CSimpleStringA::Format("{\"Function\":\"%s\", \"DevApi\":\"%s\", \"ReturnCode\":\"%s\", \"Msg\":\"%s\", \"Context\":\"%s\"}" , __FUNCTION__, lastApiName.GetData(), SpStrError(lastErrCode), lastErrMsg.GetData(), ""); std::map msgInfo; msgInfo["ReturnCode"] = SpStrError(lastErrCode); msgInfo["ErrMsg"] = lastErrMsg.GetData(); msgInfo["Context"] = ""; std::pair strResult; strResult = generateJsonStr(msgInfo); CSimpleStringA csErrMsgWithReturnCodeStr = strResult.second.c_str(); eErrCode = lastErrCode; ApiName = lastApiName; alarmMsg = alarmMsgStr.GetData(); csErrMsgWithReturnCode = csErrMsgWithReturnCodeStr.GetData(); }