#include "stdafx.h" #include "IDCertFSM.h" #include "GetDevInfoHelper.h" #include "EventCode.h" #include "libimageproc.h" #include "ModuleMix.h" #include "IDCertificate_UserErrorCode.h" #include #include #include #include #ifdef RVC_OS_LINUX #include "CommDevEntityErrorCode.h" #include #include #include "fileutil.h" #include #include using namespace SP::Module::Comm; #else #include "RVCComm.h" #include "ModuleHelper.h" #include "../Other/libpublicFun/publicFunExport.h" #include "json.h" #include #include #pragma comment(lib,"user32.lib") #endif // RVC_OS_LINUX #define IDCER_INIT_COUNT 3 #define IDCER_READ_TIMEOUT 60000 #define IDCER_AUTH_INTERVAL 300 //oiltmp need to move together? int StrBuf2HexBuf(LPCTSTR strBuf, PBYTE* hexBuf) { int len = strlen(strBuf); if (len == 0 || len % 2 != 0) return 0; BYTE* buf = new BYTE[len / 2]; if (buf == NULL) return 0; int j = 0; for (int i = 0; i < len;) { int tmpVal; sscanf(strBuf + i, "%2X", &tmpVal); buf[j] = tmpVal; i += 2; j++; } *hexBuf = buf; return j; } int HexBuf2StrBuf(PBYTE hexBuf, char** strBuf, DWORD len) { char* tmpStr = *strBuf; int count = 0; for (int i = 0; i < len; ++i) { sprintf(tmpStr + count, "%0.2X", hexBuf[i]); count += 2; } return 0; } //Normal/Idle void CIDCertFSM::s0_on_entry() { LOG_FUNCTION(); #ifdef RVC_OS_LINUX m_devState = DEVICE_STATUS_NORMAL; GetEntityBase()->GetFunction()->SetUserDefineState(USER_IDCERTIFICATE_IDLE); if (m_FirstStart) { m_FirstStart = FALSE; ToLogRootINIInfoOnce(); ToLogWarnInfoAboutTerm(); } #else //oilyang@20220413 except RVC.PAD without FWB CSimpleStringA tmpFWBDevSN(""); GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpFWBDevSN); if (!m_logBefore && !(m_csMachineType.Compare("RVC.PAD", true) == 0 && tmpFWBDevSN.IsNullOrEmpty())) { ToLogWarnInfoAboutTerm(); m_logBefore = true; } m_devState = DEVICE_STATUS_NORMAL; GetEntityBase()->GetFunction()->SetUserDefineState(USER_IDCERTIFICATE_IDLE); #endif } void CIDCertFSM::s0_on_exit() { LOG_FUNCTION(); } unsigned int CIDCertFSM::s0_on_event(FSMEvent* pEvt) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("s0 evt %d",pEvt->iEvt); switch (pEvt->iEvt) { case USER_EVT_ERROR: pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; case USER_EVT_READ_AND_SCAN: { pEvt->SetHandled(); ReadAndScanEvent* ide = dynamic_cast(pEvt); ReadAndScanTask* task = new ReadAndScanTask(this); task->ctx = ide->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_READ_AND_SCAN_UTF8: //ex1 { pEvt->SetHandled(); ReadAndScanUTF8Event* ide = dynamic_cast(pEvt); ReadAndScanUTF8Task* task = new ReadAndScanUTF8Task(this); task->ctx = ide->ctx; GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; #ifndef RVC_OS_LINUX case USER_EVT_TODO_INIT: { pEvt->SetHandled(); ProcFWBReConnTask* task = new ProcFWBReConnTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_TODO_INIT_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; #endif // RVC_OS_LINUX default: break; } return 0; } //Reading void CIDCertFSM::s1_on_entry() { LOG_FUNCTION(); GetEntityBase()->GetFunction()->SetUserDefineState(USER_IDCERTIFICATE_READING); } void CIDCertFSM::s1_on_exit() { LOG_FUNCTION(); } unsigned int CIDCertFSM::s1_on_event(FSMEvent *pEvt) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("s1_on_event")("s1 evt %d", pEvt->iEvt); int ret = 0; switch(pEvt->iEvt) { #ifndef RVC_OS_LINUX case USER_EVT_TODO_INIT: { pEvt->SetHandled(); ProcFWBReConnTask* task = new ProcFWBReConnTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_TODO_INIT_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; #endif // RVC_OS_LINUX case USER_EVT_CANCEL_READ: pEvt->SetHandled(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("s1_on_event")("Set cancel read flag"); m_bCancelRead = true; break; case USER_EVT_EXIT: pEvt->SetHandled(); SetExitFlag(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; case USER_EVT_READ_AND_SCAN_FINISHED: #ifndef RVC_OS_LINUX if (pEvt->param1 == -1) { invalidBreak = true; return 5; } #endif // !RVC_OS_LINUX pEvt->SetHandled(); ret = pEvt->param1; break; case USER_EVT_READ_AND_SCAN_UTF8_FINISHED: #ifndef RVC_OS_LINUX if (pEvt->param1 == -1) { invalidBreak = true; return 5; } #endif // !RVC_OS_LINUX pEvt->SetHandled(); ret = pEvt->param1; break; default: break; } return ret; } //failed void CIDCertFSM::s2_on_entry() { LOG_FUNCTION(); m_devState = DEVICE_STATUS_FAULT; GetEntityBase()->GetFunction()->SetUserDefineState(USER_IDCERTIFICATE_FAILED); m_testResult = Error_InvalidState; } void CIDCertFSM::s2_on_exit() { LOG_FUNCTION(); } unsigned int CIDCertFSM::s2_on_event(FSMEvent* e) { LOG_FUNCTION(); if (e->iEvt == USER_EVT_QUIT) { e->SetHandled(); return 0; } return 0; } //Eject void CIDCertFSM::s3_on_entry() { } void CIDCertFSM::s3_on_exit() { } unsigned int CIDCertFSM::s3_on_event(FSMEvent* e) { return 0; } //WaitingFetch void CIDCertFSM::s4_on_entry() { LOG_FUNCTION(); WaitFetchIDCardTask* task = new WaitFetchIDCardTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CIDCertFSM::s4_on_exit() { } unsigned int CIDCertFSM::s4_on_event(FSMEvent* pEvt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("s4_on_event") ("wait fetch id card.event %d,%d", pEvt->iEvt, pEvt->param1); switch (pEvt->iEvt) { case USER_EVT_WAIT_FETCH_IDCARD_FINISHED: pEvt->SetHandled(); break; default: break; } return 0; } //Init void CIDCertFSM::s5_on_entry() { LOG_FUNCTION(); m_devState = DEVICE_STATUS_NOT_READY; InitTask* task = new InitTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CIDCertFSM::s5_on_exit() { LOG_FUNCTION(); } unsigned int CIDCertFSM::s5_on_event(FSMEvent* pEvt) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("s5_on_event")("s5 evt %d", pEvt->iEvt); int ret = 0; switch (pEvt->iEvt) { case USER_EVT_ERROR: pEvt->SetHandled(); break; case USER_EVT_QUIT: pEvt->SetHandled(); break; case USER_EVT_INIT_FINISHED: { pEvt->SetHandled(); ret = pEvt->param1; } break; #ifdef RVC_OS_LINUX #else case USER_EVT_TODO_INIT: { pEvt->SetHandled(); ProcFWBReConnTask* task = new ProcFWBReConnTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } break; case USER_EVT_TODO_INIT_FINISHED: { pEvt->SetHandled(); return pEvt->param1; } break; #endif default: break; } return ret; } ErrorCodeEnum CIDCertFSM::GetVendorDllPath(CSimpleStringA &strPath) { strPath = "termb.dll"; return Error_Succeed;//oiltest CSimpleStringA strDepPath; ErrorCodeEnum Error = m_pEntity->GetFunction()->GetPath("Dep", strDepPath); if (Error == Error_Succeed) { strPath = "termb.dll";//CSimpleStringA::Format("%s\\mod_IDCertificate\\termb.dll", (LPCSTR)strDepPath); } return Error; } 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 CIDCertFSM::OnInit() { ZeroMemory(m_devCatInfo.szModel, MAX_DEV_MODEL_LEN); ZeroMemory(m_devCatInfo.szType, MAX_DEV_TYPE_LEN); ZeroMemory(m_devCatInfo.szVendor, MAX_DEV_VENDOR_LEN); #ifdef RVC_OS_LINUX m_devCatInfo.eState = DEVICE_STATUS_NOT_READY; m_devCatInfo.version = { 0, 0, 0, 0 }; #endif // RVC_OS_LINUX nationalCode[1] = "汉"; nationalCode[2] = "蒙古"; nationalCode[3] = "回"; nationalCode[4] = "藏"; nationalCode[5] = "维吾尔"; nationalCode[6] = "苗"; nationalCode[7] = "彝"; nationalCode[8] = "壮"; nationalCode[9] = "布依"; nationalCode[10] = "朝鲜"; nationalCode[11] = "满"; nationalCode[12] = "侗"; nationalCode[13] = "瑶"; nationalCode[14] = "白"; nationalCode[15] = "土家"; nationalCode[16] = "哈尼"; nationalCode[17] = "哈萨克"; nationalCode[18] = "傣"; nationalCode[19] = "黎"; nationalCode[20] = "傈僳"; nationalCode[21] = "佤"; nationalCode[22] = "畲"; nationalCode[23] = "高山"; nationalCode[24] = "拉祜"; nationalCode[25] = "水"; nationalCode[26] = "东乡"; nationalCode[27] = "纳西"; nationalCode[28] = "景颇"; nationalCode[29] = "阿尔克孜"; nationalCode[30] = "土"; nationalCode[31] = "达斡尔"; nationalCode[32] = "仫佬"; nationalCode[33] = "羌"; nationalCode[34] = "布朗"; nationalCode[35] = "撒拉"; nationalCode[36] = "毛南"; nationalCode[37] = "仡佬"; nationalCode[38] = "锡伯"; nationalCode[39] = "阿昌"; nationalCode[40] = "普米"; nationalCode[41] = "塔吉克"; nationalCode[42] = "怒"; nationalCode[43] = "乌孜别克"; nationalCode[44] = "俄罗斯"; nationalCode[45] = "鄂温克"; nationalCode[46] = "德昂"; nationalCode[47] = "保安"; nationalCode[48] = "裕固"; nationalCode[49] = "京"; nationalCode[50] = "塔塔尔"; nationalCode[51] = "独龙"; nationalCode[52] = "鄂伦春"; nationalCode[53] = "赫哲"; nationalCode[54] = "门巴"; nationalCode[55] = "珞巴"; nationalCode[56] = "基诺"; supportUCS2 = FALSE; return Error_Succeed; } ErrorCodeEnum CIDCertFSM::OnExit() { #ifdef RVC_OS_LINUX if (m_hDevHelper) { ErrorCodeEnum err = Error_Succeed; m_hDevHelper.TearDown(); return err; } return Error_Succeed; #else if (m_pIDCert != NULL) { ErrorCodeEnum err; err = m_pIDCert->DevClose(); if (err != Error_Succeed) { SetErrPackage(m_errPkg, "OnExit::DevClose", m_devSN, err, MEC_DEVAPI_IDCER_DevClose); AlarmDEC(m_entCode, m_pIDCert, m_errPkg); } } if (m_pIDCert) { ReleaseDevComponent((DeviceBaseClass*&)m_pIDCert); m_pIDCert = NULL; } return Error_Succeed; #endif // RVC_OS_LINUX } ErrorCodeEnum CIDCertFSM::CheckDate(const char* date) { string strDate = date; if (strDate.find("长期") != string::npos) { return Error_Succeed; } else { regex pattern("^(([0-9]{4})(\.|-|年)(0[1-9]|1[0-2])(\.|-|月)(0[1-9]|[12][0-9]|3[01])(日)*)$"); smatch sm; if (regex_match(strDate, sm, pattern)) { int month = atoi(sm[4].str().c_str()); int day = atoi(sm[6].str().c_str()); if (month > 0 && month <= 12 && day > 0 && day <= 31) { return Error_Succeed; } } } return Error_Unexpect; } ErrorCodeEnum CIDCertFSM::CheckDate(const char* startDate, const char* endDate) { string strStartDate = startDate, strEndDate = endDate; regex pattern("^(([0-9]{4})(\.|-))"); smatch smStart, smEnd; if (regex_search(strStartDate, smStart, pattern) && regex_search(strEndDate, smEnd, pattern)) { strStartDate = smStart.suffix().str(); strEndDate = smEnd.suffix().str(); if (strStartDate == strEndDate) return Error_Succeed; } else if (strEndDate == "长期") return Error_Succeed; return Error_Unexpect; } void CIDCertFSM::LogDate(IDCerInfo idInfo) { ErrorCodeEnum eErrCode = CheckDate(idInfo.startDate.data); CSimpleStringA errMsg; if (Error_Succeed != eErrCode) { errMsg = CSimpleStringA::Format("Invalid startDate: %s", idInfo.startDate.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_InvalidStartDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDate")(errMsg); } eErrCode = CheckDate(idInfo.endDate.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("Invalid endDate: %s", idInfo.endDate.data); LogWarn(Severity_Middle, eErrCode, IDCertificate_UserErrorCode_InvalidEndDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDate")(errMsg); } eErrCode = CheckDate(idInfo.startDate.data, idInfo.endDate.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("起止日期不匹配:start=%s, end=%s", idInfo.startDate.data, idInfo.endDate.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_NotMatch, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDate")(errMsg); } eErrCode = CheckDate(idInfo.birthday.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("Invalid birthDate: %s", idInfo.birthday.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_InvalidBirthDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDate")(errMsg); } } void CIDCertFSM::LogDateEx(IDCerInfoEx idInfo) { ErrorCodeEnum eErrCode = CheckDate(idInfo.startDate.data); CSimpleStringA errMsg; if (Error_Succeed != eErrCode) { errMsg = CSimpleStringA::Format("Invalid startDate: %s", idInfo.startDate.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_InvalidStartDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDateEx")(errMsg); } eErrCode = CheckDate(idInfo.endDate.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("Invalid endDate: %s", idInfo.endDate.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_InvalidEndDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDateEx")(errMsg); } eErrCode = CheckDate(idInfo.startDate.data, idInfo.endDate.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("起止日期不匹配:start=%s, end=%s", idInfo.startDate.data, idInfo.endDate.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_NotMatch, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDateEx")(errMsg); } eErrCode = CheckDate(idInfo.birthday.data); if (Error_Succeed != eErrCode) { CSimpleStringA errMsg = CSimpleStringA::Format("Invalid birthDate: %s", idInfo.birthday.data); LogWarn(Severity_Low, eErrCode, IDCertificate_UserErrorCode_InvalidBirthDate, (const char*)errMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LogDateEx")(errMsg); } } int CIDCertFSM::ReadAndScan(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); DWORD elapsed = 0; DWORD dwStart = RVCGetTickCount(); DWORD dwEnd = RVCGetTickCount(); ErrorCodeEnum eErr; LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on"); DeleteZP(Bmp_ZP|Bmp_SCAN); bool bOpenRF = false, bGetIDCert = false; IDCerInfoEx idInfo; IDCerInfo idInfoOld; memset(&idInfo, 0, sizeof(idInfo)); memset(&idInfoOld, 0, sizeof(idInfoOld)); m_bCancelRead = false; m_bWaitReadMore = false; m_bReading = true; m_bExit = false; ErrorCodeEnum ecForIDCerRFControl(Error_Succeed); ErrorCodeEnum ecForIDCerAuthenticate(Error_Succeed); while (elapsed < IDCER_READ_TIMEOUT && !bGetIDCert && !m_bCancelRead) { if (m_bExit) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("exit"); break; } if (m_bWaitReadMore) { dwStart = RVCGetTickCount(); m_bWaitReadMore = false; } if (!bOpenRF) { eErr = m_hDevHelper->IDCerRFControl(true); ecForIDCerRFControl = eErr; if (Error_Succeed == eErr) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("open rf succeed."); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("open rf failed."); dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; Sleep(IDCER_AUTH_INTERVAL); continue; } } bOpenRF = true; Sleep(IDCER_AUTH_INTERVAL); eErr = m_hDevHelper->IDCerAuthenticate(); ecForIDCerAuthenticate = eErr; if (Error_Succeed != eErr) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("IDCerAuthenticate failed: %s", SpStrError(ecForIDCerAuthenticate)); dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; continue; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("auth succeed."); eErr = m_hDevHelper->IDCerGetDataEx(idInfo); if (eErr == Error_NotImpl) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("to call old interface"); eErr = m_hDevHelper->IDCerGetData(idInfoOld); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("Invoke IDCerGetData failed: %s", SpStrError(eErr)); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_USER)("read succeed."); LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_OP, "IDCertifacate op."); ctx->Ans.name = idInfoOld.name.data; ctx->Ans.sex = idInfoOld.sex.data; ctx->Ans.nation = idInfoOld.nation.data; ctx->Ans.birthday = idInfoOld.birthday.data; ctx->Ans.address = idInfoOld.address.data; //oiltest ctx->Ans.idcode = idInfoOld.idno.data; //oilyang@20180309 根据俞根伟,生产上存在身份证异常为'x'的问题,统一进行转换 if (ctx->Ans.idcode[ctx->Ans.idcode.GetLength() - 1] == 'x') { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("x to X"); ctx->Ans.idcode[ctx->Ans.idcode.GetLength() - 1] = 'X'; } //ctx->Ans.idcode = "370285198804025014"; ctx->Ans.department = idInfoOld.department.data; ctx->Ans.startdate = idInfoOld.startDate.data; ctx->Ans.enddate = idInfoOld.endDate.data; //hyc@2021.3.24 LogDate(idInfoOld); CSimpleStringA csIDLogInfo = CSimpleStringA::Format("Sex:%s,Nation:%s,EndDate:%s,IDNo:%s****%s," ,idInfoOld.sex.data ,idInfoOld.nation.data ,idInfoOld.endDate.data ,(const char*)ctx->Ans.idcode.SubString(0, 4), (const char*)ctx->Ans.idcode.SubString(ctx->Ans.idcode.GetLength() - 1, 1)); LogWarn(Severity_Low, Error_Succeed, IDCertificate_UserErrorCode_ReadAndScan_GetIDInfo, csIDLogInfo.GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get photo"); GetPngBlobEx(ctx->Ans.headphoto, "zp", true); eErr = GetPngBlob(ctx->Ans.photodata, true); if (eErr != Error_Succeed) { bGetIDCert = false; LOG_TRACE("get photo failed."); break; } bGetIDCert = true; break; } } else { if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Invoke IDCerGetDataEx failed: %s", SpStrError(eErr)); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("read succeed."); LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_OP, "IDCertifacate op."); ctx->Ans.name = idInfo.name.data; ctx->Ans.sex = idInfo.sex.data; ctx->Ans.nation = idInfo.nation.data; ctx->Ans.birthday = idInfo.birthday.data; ctx->Ans.address = idInfo.address.data; ctx->Ans.idcode = idInfo.idno.data; //oilyang@20180309 根据俞根伟,生产上存在身份证异常为'x'的问题,统一进行转换 if (ctx->Ans.idcode[ctx->Ans.idcode.GetLength() - 1] == 'x') { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("x to X"); ctx->Ans.idcode[ctx->Ans.idcode.GetLength() - 1] = 'X'; } ctx->Ans.department = idInfo.department.data; ctx->Ans.startdate = idInfo.startDate.data; ctx->Ans.enddate = idInfo.endDate.data; ctx->Ans.englishname = idInfo.englishName.data; ctx->Ans.nationality = idInfo.nationality.data; ctx->Ans.idversion = idInfo.idVersion.data; ctx->Ans.idtype = idInfo.idType.data; ctx->Ans.reserved = idInfo.reserved.data; ctx->Ans.startdate = idInfo.startDate.data; eErr = m_hDevHelper->ScanIDAndSaveImage(); ctx->Ans.hasscan = 0; if (eErr == Error_Succeed) { //idfront.bmp" and "idback.bmp ErrorCodeEnum eErrFront, eErrBack; eErrFront = GetPngBlobEx(ctx->Ans.frontphoto, "idfront", false); eErrBack = GetPngBlobEx(ctx->Ans.backphoto, "idback", false); if (eErrFront == Error_Succeed && eErrBack == Error_Succeed) ctx->Ans.hasscan = 1; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Invoke ScanIDAndSaveImage Failed: %s", SpStrError(eErr)); } GetPngBlobEx(ctx->Ans.headphoto, "zp", true); CSimpleStringA csIDLogInfo = CSimpleStringA::Format("Sex:%s,Nation:%s,EndDate:%s,IDNo:%s****%s,IDType:%s" , (const char*)ctx->Ans.sex, (const char*)ctx->Ans.nation , (const char*)ctx->Ans.enddate , (const char*)ctx->Ans.idcode.SubString(0, 4), (const char*)ctx->Ans.idcode.SubString(ctx->Ans.idcode.GetLength() - 1, 1) , (const char*)ctx->Ans.idtype); LogWarn(Severity_Low, Error_Succeed, IDCertificate_UserErrorCode_ReadAndScan_GetIDInfo, csIDLogInfo.GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get photo"); eErr = GetPngBlob(ctx->Ans.photodata, true); if (eErr != Error_Succeed) { bGetIDCert = false; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get photo failed."); break; } bGetIDCert = true; break; } } } dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; } m_bExit = false; m_bReading = false; LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_OFF, "IDCer warning off"); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("after close light"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("ans size:%d",sizeof(ctx->Ans)); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%d",FIELD_OFFSET(IDCertificate::IDCertService_ReadAndScan_Ans, reserved)); int pos = 99; ErrorCodeEnum eErr1 = m_hDevHelper->QueryCardPos(pos); if (eErr1 == Error_NotImpl) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("old version.no need position."); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pos before eject:%d", pos); switch (pos) { case 1: case 2: eErr1 = m_hDevHelper->IDCerRFControl(false); if (eErr1 != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("exec IDCerRFControl(false) failed, force eject..."); m_hDevHelper->ForceIDEject(); } else DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("exec IDCerRFControl(false) succ."); break; case 0: default: break; } //查询卡片位置以决定跳转 eErr1 = m_hDevHelper->QueryCardPos(pos); if (eErr1 == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pos after eject:%d", pos); } } if ( ! (eErr1 == Error_Succeed && pos == 2) ) { //oilyang@20180531 add for close enter card m_hDevHelper->IDCerRFControl(false); //这里基本不耗时,凯欣达新大机耗时较长(先改我们流程解决,后续需要厂商优化这里) } //zjw@20191219 处理完相关操作再返回给前端,防止状态还未跳转又发起流程 if (bGetIDCert) { ctx->Answer(Error_Succeed); } else if (m_bCancelRead) { ctx->Answer(Error_Cancel); LogWarn(Severity_Low, Error_Debug, IDCertificate_UserErrorCode_CancelOperation, "User cancel read IDCard from front."); } else if (elapsed >= IDCER_READ_TIMEOUT) { ctx->Answer(Error_TimeOut); if (ecForIDCerRFControl != Error_Succeed) { SetErrPackage("ReadAndScan::IDCerRFControl(Timeout)", m_devSN, ecForIDCerRFControl, MEC_DEVAPI_IDCER_IDCerRFControl); AlarmDEC(); } if (ecForIDCerAuthenticate != Error_Succeed) { SetErrPackage("ReadAndScan::IDCerAuthenticate(Timeout)", m_devSN, ecForIDCerAuthenticate, MEC_DEVAPI_IDCER_IDCerAuthenticate); AlarmDEC(); } } else { ctx->Answer(Error_Unexpect); if (ecForIDCerRFControl != Error_Succeed) { SetErrPackage("ReadAndScan::IDCerRFControl", m_devSN, ecForIDCerRFControl, MEC_DEVAPI_IDCER_IDCerRFControl); AlarmDEC(); } if (ecForIDCerAuthenticate != Error_Succeed) { SetErrPackage("ReadAndScan::IDCerAuthenticate", m_devSN, ecForIDCerAuthenticate, MEC_DEVAPI_IDCER_IDCerAuthenticate); AlarmDEC(); } LogError(Severity_High, Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_Failed, "ReadAndScan some thing wrong."); } if (eErr1 == Error_Succeed && pos == 2) { return 4; } return 0; } int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); if (supportUCS2 == FALSE) { ctx->Ans.msgtype = 0; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScanUTF8")("supportUCS2 = %d, 厂商不支持新接口,请调用旧接口。", supportUCS2); ctx->Answer(Error_Succeed); return 0; } DWORD elapsed = 0; DWORD dwStart = RVCGetTickCount(); DWORD dwEnd = RVCGetTickCount(); ErrorCodeEnum eErr; LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on"); DeleteZP(Bmp_ZP | Bmp_SCAN); bool bOpenRF = false, bGetIDCert = false; IDCerInfoEx2 idInfoEx2; IDCerInfoEx idInfo; IDCerInfo idInfoOld; memset(&idInfo, 0, sizeof(idInfo)); memset(&idInfoOld, 0, sizeof(idInfoOld)); m_bCancelRead = false; m_bWaitReadMore = false; m_bReading = true; m_bExit = false; ErrorCodeEnum ecForIDCerRFControl(Error_Succeed); ErrorCodeEnum ecForIDCerAuthenticate(Error_Succeed); memset(&idInfoEx2, 0, sizeof(idInfoEx2)); memset(&idInfo, 0, sizeof(idInfo)); memset(&idInfoOld, 0, sizeof(idInfoOld)); while (elapsed < IDCER_READ_TIMEOUT && !bGetIDCert && !m_bCancelRead) { if (m_bExit) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("exit"); break; } if (m_bWaitReadMore) { dwStart = RVCGetTickCount(); m_bWaitReadMore = false; } if (!bOpenRF) { eErr = m_hDevHelper->IDCerRFControl(true); ecForIDCerRFControl = eErr; if (Error_Succeed == eErr) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("open rf succeed."); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("open rf failed."); dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; Sleep(IDCER_AUTH_INTERVAL); continue; } } bOpenRF = true; Sleep(IDCER_AUTH_INTERVAL); eErr = m_hDevHelper->IDCerAuthenticate(); ecForIDCerAuthenticate = eErr; if (Error_Succeed != eErr) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("IDCerAuthenticate failed: %s", SpStrError(ecForIDCerAuthenticate)); dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; continue; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("auth succeed."); eErr = m_hDevHelper->IDCerGetDataEx2(idInfoEx2); if (eErr == Error_NotImpl) { ctx->Ans.msgtype = 0; //旧字段传递,GBK、字符串传递文字信息 DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScanUTF8")("厂商不支持新接口,请调用旧接口。"); } else { ctx->Ans.msgtype = 1; //新字段传递,UTF8、二进制传递文字信息 //ex2数据读取功能代码、UCS2转UTF8代码 DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScanUTF8")("使用新字段。"); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Invoke IDCerGetDataEx failed: %s", SpStrError(eErr)); } else { unsigned char name[1024]; memset(name, 0, 1024); unsigned char sex[1024]; memset(sex, 0, 1024); unsigned char nation[1024]; memset(nation, 0, 1024); unsigned char birthday[1024]; memset(birthday, 0, 1024); unsigned char address[1024]; memset(address, 0, 1024); unsigned char idno[1024]; memset(idno, 0, 1024); unsigned char department[1024]; memset(department, 0, 1024); unsigned char startDate[1024]; memset(startDate, 0, 1024); unsigned char endDate[1024]; memset(endDate, 0, 1024); unsigned char englishName[1024]; memset(englishName, 0, 1024); unsigned char nationality[1024]; memset(nationality, 0, 1024); unsigned char idVersion[1024]; memset(idVersion, 0, 1024); unsigned char idType[1024]; memset(idType, 0, 1024); unsigned char reserved[1024]; memset(reserved, 0, 1024); DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setLogCode("QLR040220106")("read succeed(sp2 scan)."); //bReadSuccess = true; LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_OP, "IDCertifacate op."); //oilyang@20210106 /*BYTE fileHash[32]; int fileSize = 0; GetFileSizeAndCalcHashValue(m_csVendorDllName, fileSize, fileHash);*/ /*BYTE fileHash[128]; memset(fileHash, 0, 128); memcpy(fileHash, idInfoEx2.name.data, 128);*/ /*char* strFileHash = new char[256]; memset(strFileHash, 0, 256); HexBuf2StrBuf(fileHash, &strFileHash, 128); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("Initial") ("身份证name数据:%s", strFileHash);*/ RemoveUCS2Blank((UINT16*)idInfoEx2.name.data); CheckHanZi((UINT16*)idInfoEx2.name.data); //测试汉字编码 RemoveUCS2Blank((UINT16*)idInfoEx2.sex.data); RemoveUCS2Blank((UINT16*)idInfoEx2.nation.data); RemoveUCS2Blank((UINT16*)idInfoEx2.birthday.data); RemoveUCS2Blank((UINT16*)idInfoEx2.address.data); RemoveUCS2Blank((UINT16*)idInfoEx2.idno.data); RemoveUCS2Blank((UINT16*)idInfoEx2.department.data); RemoveUCS2Blank((UINT16*)idInfoEx2.startDate.data); RemoveUCS2Blank((UINT16*)idInfoEx2.endDate.data); RemoveUCS2Blank((UINT16*)idInfoEx2.englishName.data); RemoveUCS2Blank((UINT16*)idInfoEx2.nationality.data); RemoveUCS2Blank((UINT16*)idInfoEx2.idVersion.data); RemoveUCS2Blank((UINT16*)idInfoEx2.idType.data); RemoveUCS2Blank((UINT16*)idInfoEx2.reserved.data); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScan")("已去除空格"); //转换成GBK用于debug上传 /*char* tSex = new char[32]; char* tNation = new char[32]; char* tEndDate = new char[32]; char* tIDcode = new char[1024]; char* tIDtype = new char[8]; memcpy(tSex, idInfoEx2.sex.data, 32); memcpy(tNation, idInfoEx2.nation.data, 32); memcpy(tEndDate, idInfoEx2.endDate.data, 32); memcpy(tIDcode, idInfoEx2.idno.data, 1024); memcpy(tIDtype, idInfoEx2.idType.data, 8);*/ //char* gbkSex, * gbkNation, * gbkEndDate, * gbkIDcode, * gbkIDtype; //int iSize; ////sex //iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tSex, -1, NULL, 0, NULL, NULL); //gbkSex = (char*)malloc((iSize + 1)); //WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tSex, -1, gbkSex, iSize, NULL, NULL); ////nation //iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tNation, -1, NULL, 0, NULL, NULL); //gbkNation = (char*)malloc((iSize + 1)); //WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tNation, -1, gbkNation, iSize, NULL, NULL); ////endate //iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tEndDate, -1, NULL, 0, NULL, NULL); //gbkEndDate = (char*)malloc((iSize + 1)); //WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tEndDate, -1, gbkEndDate, iSize, NULL, NULL); ////idcode //iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tIDcode, -1, NULL, 0, NULL, NULL); //gbkIDcode = (char*)malloc((iSize + 1)); //WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tIDcode, -1, gbkIDcode, iSize, NULL, NULL); ////idtype //iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tIDtype, -1, NULL, 0, NULL, NULL); //gbkIDtype = (char*)malloc((iSize + 1)); //WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tIDtype, -1, gbkIDtype, iSize, NULL, NULL); ////gbk转换结束 UCS2_to_UTF8((UINT16*)idInfoEx2.name.data, name); //UCS2_to_UTF8((UINT16*)idInfoEx2.sex.data, sex); GetSexUTF8String((UINT16*)idInfoEx2.sex.data, sex); //UCS2_to_UTF8((UINT16*)idInfoEx2.nation.data, nation); GetNationalUTF8String((UINT16*)idInfoEx2.nation.data, nation); //UCS2_to_UTF8((UINT16*)idInfoEx2.birthday.data, birthday); GetDateStandardFormatUTF8((UINT16*)idInfoEx2.birthday.data, birthday); UCS2_to_UTF8((UINT16*)idInfoEx2.address.data, address); UCS2_to_UTF8((UINT16*)idInfoEx2.idno.data, idno); UCS2_to_UTF8((UINT16*)idInfoEx2.department.data, department); //UCS2_to_UTF8((UINT16*)idInfoEx2.startDate.data, startDate); GetDateStandardFormatUTF8((UINT16*)idInfoEx2.startDate.data, startDate); //UCS2_to_UTF8((UINT16*)idInfoEx2.endDate.data, endDate); GetDateStandardFormatUTF8((UINT16*)idInfoEx2.endDate.data, endDate); UCS2_to_UTF8((UINT16*)idInfoEx2.englishName.data, englishName); UCS2_to_UTF8((UINT16*)idInfoEx2.nationality.data, nationality); UCS2_to_UTF8((UINT16*)idInfoEx2.idVersion.data, idVersion); UCS2_to_UTF8((UINT16*)idInfoEx2.idType.data, idType); UCS2_to_UTF8((UINT16*)idInfoEx2.reserved.data, reserved); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScan")("已转换成utf8"); ctx->Ans.name_utf8.Alloc(strlen((char*)name)); ctx->Ans.sex_utf8.Alloc(strlen((char*)sex)); ctx->Ans.nation_utf8.Alloc(strlen((char*)nation)); ctx->Ans.birthday_utf8.Alloc(strlen((char*)birthday)); ctx->Ans.address_utf8.Alloc(strlen((char*)address)); ctx->Ans.idcode_utf8.Alloc(strlen((char*)idno)); ctx->Ans.department_utf8.Alloc(strlen((char*)department)); ctx->Ans.startdate_utf8.Alloc(strlen((char*)startDate)); ctx->Ans.enddate_utf8.Alloc(strlen((char*)endDate)); ctx->Ans.englishname_utf8.Alloc(strlen((char*)englishName)); ctx->Ans.nationality_utf8.Alloc(strlen((char*)nationality)); ctx->Ans.idversion_utf8.Alloc(strlen((char*)idVersion)); ctx->Ans.idtype_utf8.Alloc(strlen((char*)idType)); ctx->Ans.reserved_utf8.Alloc(strlen((char*)reserved)); memcpy(ctx->Ans.name_utf8.m_pData, name, strlen((char*)name)); memcpy(ctx->Ans.sex_utf8.m_pData, sex, strlen((char*)sex)); memcpy(ctx->Ans.nation_utf8.m_pData, nation, strlen((char*)nation)); memcpy(ctx->Ans.birthday_utf8.m_pData, birthday, strlen((char*)birthday)); memcpy(ctx->Ans.address_utf8.m_pData, address, strlen((char*)address)); memcpy(ctx->Ans.idcode_utf8.m_pData, idno, strlen((char*)idno)); memcpy(ctx->Ans.department_utf8.m_pData, department, strlen((char*)department)); memcpy(ctx->Ans.startdate_utf8.m_pData, startDate, strlen((char*)startDate)); memcpy(ctx->Ans.enddate_utf8.m_pData, endDate, strlen((char*)endDate)); memcpy(ctx->Ans.englishname_utf8.m_pData, englishName, strlen((char*)englishName)); memcpy(ctx->Ans.nationality_utf8.m_pData, nationality, strlen((char*)nationality)); memcpy(ctx->Ans.idversion_utf8.m_pData, idVersion, strlen((char*)idVersion)); memcpy(ctx->Ans.idtype_utf8.m_pData, idType, strlen((char*)idType)); memcpy(ctx->Ans.reserved_utf8.m_pData, reserved, strlen((char*)reserved)); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("ReadAndScan")("已传递接口字段。"); eErr = m_hDevHelper->ScanIDAndSaveImage(); ctx->Ans.hasscan = 0; if (eErr == Error_Succeed) { //idfront.bmp" and "idback.bmp ErrorCodeEnum eErrFront, eErrBack; eErrFront = GetPngBlobEx(ctx->Ans.frontphoto, "idfront", false); eErrBack = GetPngBlobEx(ctx->Ans.backphoto, "idback", false); if (eErrFront == Error_Succeed && eErrBack == Error_Succeed) ctx->Ans.hasscan = 1; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Invoke ScanIDAndSaveImage Failed: %s", SpStrError(eErr)); } GetPngBlobEx(ctx->Ans.headphoto, "zp", true); /*DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("Sex:%s,Nation:%s,EndDate:%s,IDNo:%s****%s,IDType:%s" , (const char*)ctx->Ans.sex, (const char*)ctx->Ans.nation , (const char*)ctx->Ans.enddate , (const char*)ctx->Ans.idcode.SubString(0, 4), (const char*)ctx->Ans.idcode.SubString(ctx->Ans.idcode.GetLength() - 1, 1) , (const char*)ctx->Ans.idtype);*/ CSimpleStringA tIdcode = (char*)idno; CSimpleStringA csIDLogInfo = CSimpleStringA::Format("Sex:%s,Nation:%s,EndDate:%s,IDNo:%s****%s,IDType:%s" , (const char*)sex, (const char*)nation , (const char*)endDate , (const char*)tIdcode.SubString(0, 4), (const char*)tIdcode.SubString(tIdcode.GetLength() - 1, 1) , (const char*)idType); LogWarn(Severity_Low, Error_Succeed, IDCertificate_UserErrorCode_ReadAndScan_GetIDInfo, csIDLogInfo.GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get photo"); eErr = GetPngBlob(ctx->Ans.photodata, true); if (eErr != Error_Succeed) { bGetIDCert = false; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get photo failed."); break; } bGetIDCert = true; break; } } } dwEnd = RVCGetTickCount(); elapsed = dwEnd - dwStart; } m_bExit = false; m_bReading = false; LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_OFF, "IDCer warning off"); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("after close light"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("ans size:%d", sizeof(ctx->Ans)); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%d", FIELD_OFFSET(IDCertificate::IDCertService_ReadAndScan_Ans, reserved)); int pos = 99; ErrorCodeEnum eErr1 = m_hDevHelper->QueryCardPos(pos); if (eErr1 == Error_NotImpl) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("old version.no need position."); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pos before eject:%d", pos); switch (pos) { case 1: case 2: eErr1 = m_hDevHelper->IDCerRFControl(false); if (eErr1 != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("exec IDCerRFControl(false) failed, force eject..."); m_hDevHelper->ForceIDEject(); } else DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("exec IDCerRFControl(false) succ."); break; case 0: default: break; } //查询卡片位置以决定跳转 eErr1 = m_hDevHelper->QueryCardPos(pos); if (eErr1 == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pos after eject:%d", pos); } } if (!(eErr1 == Error_Succeed && pos == 2)) { //oilyang@20180531 add for close enter card m_hDevHelper->IDCerRFControl(false); //这里基本不耗时,凯欣达新大机耗时较长(先改我们流程解决,后续需要厂商优化这里) } //zjw@20191219 处理完相关操作再返回给前端,防止状态还未跳转又发起流程 if (bGetIDCert) { ctx->Answer(Error_Succeed); } else if (m_bCancelRead) { ctx->Answer(Error_Cancel); LogWarn(Severity_Low, Error_Debug, IDCertificate_UserErrorCode_CancelOperation, "User cancel read IDCard from front."); } else if (elapsed >= IDCER_READ_TIMEOUT) { ctx->Answer(Error_TimeOut); if (ecForIDCerRFControl != Error_Succeed) { SetErrPackage("ReadAndScanUTF8::IDCerRFControl(Timeout)", m_devSN, ecForIDCerRFControl, MEC_DEVAPI_IDCER_IDCerRFControl); AlarmDEC(); } if (ecForIDCerAuthenticate != Error_Succeed) { SetErrPackage("ReadAndScanUTF8::IDCerAuthenticate(Timeout)", m_devSN, ecForIDCerAuthenticate, MEC_DEVAPI_IDCER_IDCerAuthenticate); AlarmDEC(); } } else { ctx->Answer(Error_Unexpect); if (ecForIDCerRFControl != Error_Succeed) { SetErrPackage("ReadAndScanUTF8::IDCerRFControl", m_devSN, ecForIDCerRFControl, MEC_DEVAPI_IDCER_IDCerRFControl); AlarmDEC(); } if (ecForIDCerAuthenticate != Error_Succeed) { SetErrPackage("ReadAndScanUTF8::IDCerAuthenticate", m_devSN, ecForIDCerAuthenticate, MEC_DEVAPI_IDCER_IDCerAuthenticate); AlarmDEC(); } LogError(Severity_High, Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_Failed, "ReadAndScanUTF8 some thing wrong."); } if (eErr1 == Error_Succeed && pos == 2) { return 4; } return 0; } ErrorCodeEnum CIDCertFSM::GetPngBlob(CBlob &data, bool bClear) { CSimpleStringA strPath,strBkPath,strBmpPath,strPngPath,strTxtPath,strWltPath; ErrorCodeEnum err; err = m_pEntity->GetFunction()->GetPath("Dep", strPath); if (err != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get path failed."); return Error_Param; } strBkPath = strPath + SPLIT_SLASH_STR + "bk.bmp"; strBmpPath = strPath + SPLIT_SLASH_STR + "zp.bmp"; strPngPath = strPath + SPLIT_SLASH_STR + "zp.JPEG"; strTxtPath = strPath + SPLIT_SLASH_STR + "wz.txt"; strWltPath = strPath + SPLIT_SLASH_STR + "xp.wlt"; bool bResult = imageprocess((char*)strBkPath.GetData(), (char*)strBmpPath.GetData(), (char*)strPngPath.GetData()); if (!bResult) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetPngBlob")("photo changed failed."); return Error_Unexpect; } FILE *fp = fopen(strPngPath, "rb"); if (fp) { fseek(fp, 0, SEEK_END); long flen = ftell(fp); fseek(fp, 0, SEEK_SET); data.Alloc(flen); fread(data.m_pData, 1, flen, fp); fclose(fp); } else { LOG_TRACE("fopen %s failed!", (LPCSTR)strPngPath); err = Error_IO; } if (bClear) DeleteZP(Bmp_ZP); return err; } ErrorCodeEnum CIDCertFSM::GetPngBlobEx(CBlob &data, CSimpleStringA fileNamePrefix, bool bClear) { CSimpleStringA strPath; ErrorCodeEnum eErr; eErr = m_pEntity->GetFunction()->GetPath("Dep", strPath); if (eErr != Error_Succeed) { if (bClear) DeleteZP(Bmp_SCAN); return Error_Param; } strPath = strPath + SPLIT_SLASH_STR + fileNamePrefix; IplImage *src = cvLoadImage(strPath + ".bmp"); if (!src) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetPngBlobEx")("read file %s.bmp failed.err:%d", (const char*)strPath, GetLastError()); if (bClear) DeleteZP(Bmp_SCAN); return Error_Unexpect; } cvSaveImage(strPath + ".jpg", src); FILE *fp = fopen(strPath + ".jpg", "rb"); if (fp) { fseek(fp, 0, SEEK_END); long flen = ftell(fp); fseek(fp, 0, SEEK_SET); data.Alloc(flen); fread(data.m_pData, 1, flen, fp); fclose(fp); if (bClear) DeleteZP(Bmp_SCAN); return Error_Succeed; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("fopen %s failed!", (const char*)strPath); if (bClear) DeleteZP(Bmp_SCAN); return Error_IO; } } void CIDCertFSM::SelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { //for simple pTransactionContext->SendAnswer(m_testResult); } ErrorCodeEnum CIDCertFSM::DeleteFileIfExisted(LPCTSTR fileName) { if(strlen(fileName) == 0 || strchr(fileName, (int)'*') != NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DeleteFileIfExisted")("Invalid or empty fileName(%s)", fileName); return Error_Param; } CSimpleStringA strPath, strAimPath; ErrorCodeEnum erroCode = m_pEntity->GetFunction()->GetPath("Dep", strPath); strAimPath = strPath + SPLIT_SLASH_STR + fileName; #ifdef RVC_OS_LINUX if (ExistsFileA((LPCTSTR)strAimPath)) { if (RemoveFileA((LPCTSTR)strAimPath)) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RemoveFileA(%s) suc.", (LPCTSTR)strAimPath); return Error_Succeed; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("DeleteFile(%s) failed LastError(%d).", (LPCTSTR)strAimPath, GetLastError()); return Error_Unexpect; } } #else WIN32_FIND_DATA findData; if (FindFirstFileA((LPCTSTR)strAimPath, &findData) != INVALID_HANDLE_VALUE) { if (DeleteFileA((LPCTSTR)strAimPath) != 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DeleteFileIfExisted") ("DeleteFile(%s) suc.", (LPCTSTR)strAimPath); return Error_Succeed; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DeleteFileIfExisted") ("DeleteFile(%s) failed LastError(%d).", (LPCTSTR)strAimPath, GetLastError()); return Error_Unexpect; } } #endif // RVC_OS_LINUX if(GetLastError() == ERROR_FILE_NOT_FOUND) { return Error_Succeed; } DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DeleteFileIfExisted")("DeleteFile(%s) Unexpect GetLastError(%d).", (LPCTSTR)strAimPath, GetLastError()); return Error_Unexpect; } ErrorCodeEnum CIDCertFSM::GetDevCatInfo(DevCategoryInfo &devInfo, CSimpleStringA& devType) { #ifdef RVC_OS_LINUX LOG_FUNCTION(); if (m_bRVCIL) { memset(m_devCatInfo.szModel, 0, MAX_DEV_MODEL_LEN); memset(m_devCatInfo.szType, 0, MAX_DEV_TYPE_LEN); memset(m_devCatInfo.szVendor, 0, MAX_DEV_VENDOR_LEN); return Error_Succeed; } strncpy(devInfo.szModel, m_devCatInfo.szModel, (MAX_DEV_MODEL_LEN > strlen(m_devCatInfo.szModel)) ? strlen(m_devCatInfo.szModel) + 1 : MAX_DEV_MODEL_LEN); strncpy(devInfo.szType, m_devCatInfo.szType, (MAX_DEV_TYPE_LEN > strlen(m_devCatInfo.szType)) ? strlen(m_devCatInfo.szType) + 1 : MAX_DEV_TYPE_LEN); strncpy(devInfo.szVendor, m_devCatInfo.szVendor, (MAX_DEV_VENDOR_LEN > strlen(m_devCatInfo.szVendor)) ? strlen(m_devCatInfo.szVendor) + 1 : MAX_DEV_VENDOR_LEN); devType = m_devVer;//适配器版本号 devInfo.eState = DEVICE_STATUS_NORMAL; memcpy(&devInfo.version, &m_devCatInfo.version, sizeof(DevSoftVersion)); return Error_Succeed; #else LOG_FUNCTION(); strncpy_s(devInfo.szModel, m_devCatInfo.szModel, (MAX_DEV_MODEL_LEN > strlen(m_devCatInfo.szModel)) ? strlen(m_devCatInfo.szModel) : MAX_DEV_MODEL_LEN); strncpy_s(devInfo.szType, m_devCatInfo.szType, (MAX_DEV_TYPE_LEN > strlen(m_devCatInfo.szType)) ? strlen(m_devCatInfo.szType) : MAX_DEV_TYPE_LEN); strncpy_s(devInfo.szVendor, m_devCatInfo.szVendor, (MAX_DEV_VENDOR_LEN > strlen(m_devCatInfo.szVendor)) ? strlen(m_devCatInfo.szVendor) : MAX_DEV_VENDOR_LEN); devType = m_devVer;//适配器版本号 return Error_Succeed; #endif // RVC_OS_LINUX } int CIDCertFSM::WaitFetchIDCard() { LOG_FUNCTION(); ErrorCodeEnum eErr = Error_Unexpect; int pos = 99; DWORD64 dwStart = RVCGetTickCount(); DWORD64 dwEnd = 0; while ((dwEnd - dwStart)< 120 * 1000)//wait for 120 seconds { eErr = m_hDevHelper->QueryCardPos(pos); if (eErr == Error_Succeed && pos == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("WaitFetchIDCard")("身份证被取回"); return 0; } Sleep(1000); } // BugFix [4/16/2020 14:27 @Gifur] return -1; } void CIDCertFSM::DeleteZP(int type) { if ((type&Bmp_ZP) == Bmp_ZP) { DeleteFileIfExisted("zp.JPEG"); DeleteFileIfExisted("zp.jpg"); DeleteFileIfExisted("zp.bmp"); //All DeleteFileIfExisted("wz.txt"); //Sankyo DeleteFileIfExisted("xp.wlt"); DeleteFileIfExisted("ImgTemp.bmp"); //Nantian DeleteFileIfExisted("BP8913_ID.bmp"); //Nantian } if ((type&Bmp_SCAN) == Bmp_SCAN) { DeleteFileIfExisted("idfront.bmp"); DeleteFileIfExisted("idback.bmp"); DeleteFileIfExisted("idfront.jpg"); DeleteFileIfExisted("idback.jpg"); } } #ifdef RVC_OS_LINUX void CIDCertFSM::CrossTermCall(SpReqAnsContext::Pointer cctx) { ErrorCodeEnum eErr = Error_Unexpect; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CrossTermCall,type:%x", cctx->Req.type); switch (cctx->Req.type) { case IDCertService_Method_ReadAndScan: { DEFINE_PUPPET_CONTEXT_WITH_TYPE(IDCert_ReadAndScan_Req, IDCert_ReadAndScan_Ans); if ((eErr = SpBlob2Object(cctx->Req.paramX, ctx->Req)) == Error_Succeed) { if (this->ReadAndScan(ctx) != 0) { eErr = Error_Unexpect; } else { eErr = SpObject2Blob(ctx->Ans, cctx->Ans.retParamX); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("after ReadAndScan,eErr:%d,paramX.len:%d", eErr, cctx->Ans.retParamX.m_iLength); } } cctx->Answer(eErr); } break; case IDCertService_Method_CancelRead: m_bCancelRead = true; break; case IDCertService_Method_ReadWaitMore: if (GetReadFlag()) SetReadMore(); break; case IDCertService_Method_Exit: SetExitFlag(); break; default: break; } } void CIDCertFSM::CrossTermInvokeInfo(SpOnewayCallContext::Pointer ctx) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("entity sn:%x,type:%d,errcode:%x", ctx->Info.nEntityID, ctx->Info.type,ctx->Info.result); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("mxx 001[%d]", m_readAndScanCtx->Req.type); if (ctx->Info.paramX.m_iLength <= 1) { } ErrorCodeEnum eErr = Error_Unexpect; CSmartPointer pTransactionContext; switch (ctx->Info.type) { case IDCertService_Method_ReadAndScan: { auto pt = static_cast*>(m_mapCtx[ctx->Info.type].pCtx); SpReqAnsContext::Pointer tmpctx; tmpctx.Attach(pt); eErr = SpBlob2Object(ctx->Info.paramX, tmpctx->Ans); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("eErr:%d,Y len:%d", eErr, ctx->Info.paramX.m_iLength); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("name:%s",(const char*)tmpctx->Ans.name); tmpctx->Answer(eErr); tmpctx.SubRef(); m_mapCtx.erase(ctx->Info.type); } break; default: break; } } int CIDCertFSM::LocalCallHeartBeat(int method, CBlob &bbSend, bool bTwoWay) { ErrorCodeEnum eErr = Error_Unexpect; if (m_pHBClient == NULL) { m_pHBClient = new HeartBeatService_ClientBase(GetEntityBase()); if (m_pHBClient == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create HeartBeat client failed.GetLastError:%d", GetLastError()); return -1; } eErr = m_pHBClient->Connect(); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("client connect to HeartBeat failed:%x", eErr); m_pHBClient->SafeDelete(); m_pHBClient = NULL; return -1; } } HeartBeatService_CrossTermCall_Req req; HeartBeatService_CrossTermCall_Ans ans; req.nEntityID = 0x201; req.isTwoWay = bTwoWay; req.fromTerminalNo = m_terminalNo; GetAttachedTerminal(req.toTerminalNo); //req.toTerminalNo = "7717715004"; req.param1 = ""; req.param2 = ""; req.paramX = bbSend; req.type = method; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("call to heartbeat,from %s to %s,entity id:%x,type:%d",(const char*)req.fromTerminalNo,(const char*)req.toTerminalNo,req.nEntityID,req.type); eErr = m_pHBClient->CrossTermCall(req, ans, 20000); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CrossTermCall to HeartBeat result:%x", eErr); m_pHBClient->GetFunction()->CloseSession(); m_pHBClient = NULL;//resource cost? return 0; } bool CIDCertFSM::GetAttachedTerminal(CSimpleStringA &csTerm) { return (Error_Succeed == GetEntityBase()->GetFunction()->GetSysVar("AttachedTerminal", csTerm)); } #else //windows void CIDCertFSM::ToLogWarnInfoAboutTerm() { LOG_FUNCTION(); CSmartPointer spConfigRoot; GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfigRoot); CSimpleStringA csEnvCamera(""), csOptCamera, csOSVerion, csWarnMsg(""), strVendor(true); spConfigRoot->ReadConfigValue("Device.PinPad", "Vendor", strVendor); std::map termInfo; //oilyang@20210106 BYTE fileHash[32]; int fileSize = 0; GetFileSizeAndCalcHashValue(m_csVendorDllName, fileSize, fileHash); char* strFileHash = new char[128]; memset(strFileHash, 0, 128); HexBuf2StrBuf(fileHash, &strFileHash, 32); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("Initial") ("vendor dll %s,fileSize:%d,fileHash:%s", (const char*)m_csVendorDllName, fileSize, strFileHash); termInfo["VendorDllName"] = m_csVendorDllName; termInfo["VendorDllFileHash"] = strFileHash; memset(strFileHash, 0, 128); termInfo["VendorDllFileSize"] = _itoa(fileSize, strFileHash, 10); if (strlen(m_devCatInfo.szModel) > 1 && strlen(m_devCatInfo.szModel) < 255) termInfo["szModel"] = m_devCatInfo.szModel; if (strlen(m_devCatInfo.szType) > 1 && strlen(m_devCatInfo.szType) < 255) termInfo["szType"] = m_devCatInfo.szType; termInfo["Port"] = m_port; termInfo["Baudrate"] = m_Baudrate; std::pair strResult; strResult = generateJsonStr(termInfo); strResult.second.c_str(); CSmartPointer spConfigRun; GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); spConfigRun->ReadConfigValue("Run", "WarnMsg", csWarnMsg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("Initial") ("[%s]", strResult.second.c_str()); SYSTEMTIME localTime; GetLocalTime(&localTime); //oilyang@20201201 log warn every time if content of msg has changed if (csWarnMsg.Compare(strResult.second.c_str())) { spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay); spConfigRun->WriteConfigValue("Run", "WarnMsg", strResult.second.c_str()); LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_LogInfoAboutTerm, strResult.second.c_str()); } else { //oilyang@20201201 if day has changed,log 1 time,else no need to log int wDay = 99; spConfigRun->ReadConfigValueInt("Run", "WarnDay", wDay); if (wDay != localTime.wDay) { spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay); LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_LogInfoAboutTerm, strResult.second.c_str()); } } if (strFileHash != NULL) delete[] strFileHash; if (!m_csMachineType.Compare("RVC.Stand2S", true) && !strVendor.Compare("kxd", true)) { //先读取系统变量是否有该值? CSimpleStringA deviceInfo(true); GetEntityBase()->GetFunction()->GetSysVar("kxdInfo", deviceInfo); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("Initial") ("deviceInfo = %s", deviceInfo.GetData()); if (!deviceInfo.Compare("KXD", true)) { //读取运行时信息,如果有值,不再写,如果没有值,读取告警的信息 //这中间会存在这里还在写,但其他模块已经要去读取该运行时的信息了,可能有先后顺序? CSimpleStringA strWarnMsg(true); CSimpleStringA szTypeInfo(true); CSimpleStringA deviceType(true); spConfigRun->ReadConfigValue("Run", "WarnMsg", strWarnMsg); if (!strWarnMsg.IsNullOrEmpty()) { Json::Value root; Json::Reader reader; if (reader.parse((const char*)strWarnMsg, root)) { szTypeInfo = root.isMember("szType") ? CSimpleStringA(root["szType"].asCString()) : ""; if (!szTypeInfo.IsNullOrEmpty()) { if (!szTypeInfo.Compare("KXD.IDCertificate.SNBC-ID8101", true) || !szTypeInfo.Compare("KXD.IDCertificate.SNBC-ID81", true)) { deviceType = "KS218"; } else { deviceType = "KL286"; } GetEntityBase()->GetFunction()->SetSysVar("kxdInfo", deviceType, true); //加个告警? LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_KxdDeviceInfo, deviceType.GetData()); } } } } } } int CIDCertFSM::ProcFWBReConn() { if (m_pIDCert != NULL) { if (GetDevInitFlag()) { m_devInit = false; m_pIDCert->DevClose(); } ErrorCodeEnum eErr = ReleaseDevComponent((DeviceBaseClass*&)m_pIDCert); if (eErr != Error_Succeed) { LogWarn(Severity_Middle, Error_Unexpect, IDCertificate_UserErrorCode_Release_Object_Failed , CSimpleStringA::Format("ProcFWBReConn:ReleaseDevComponent failed:%d", eErr)); m_pIDCert = NULL; return 1; } m_pIDCert = NULL; } return 0; } #endif int CIDCertFSM::Initial() { LOG_FUNCTION(); auto pEntity = GET_DEV_ENTITY_BASE_POINTER(); pEntity->InitializeVendorLogSwitch(); FulfillAdapterInfoFrom(pEntity->vendorLibInfo); if (_strnicmp((const char*)m_csMachineType, "RVC.IL", strlen("RVC.IL")) == 0) { m_bRVCIL = true; return 0; } m_devState = DEVICE_STATUS_NOT_READY; CSimpleStringA csLibFullName; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To extra vendor lib file path..."); ErrorCodeEnum err = pEntity->ExtractVendorLibFullPath(csLibFullName); if (err != Error_Succeed) { LogWarn(Severity_Middle, err, IDCertificate_UserErrorCode_Open_RootCfg_Failed, "get dllname failed"); return Error_DevLoadFileFailed; } LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_RootInfo, csLibFullName.GetData()); m_adapterInfo.adapterFilePath = csLibFullName; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To load up vendor lib..."); err = m_hDevHelper.LoadUp(csLibFullName); if (err != Error_Succeed) { LogErrMsg("LoadUp", err, DEC_DEV_OBJECT_CREATE_FAILED, TRUE); return 2; } CSimpleStringA dllName, tmpVendor(""), tmpDevSN(""), tmpDLLVersion, csDepPath(""); GetEntityBase()->GetFunction()->GetSysVar("FWBVendor", tmpVendor); GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpDevSN); GetEntityBase()->GetFunction()->GetSysVar("FWBVersion", tmpDLLVersion); if (tmpDLLVersion.GetLength() < 2)//如果忘记配置,则直接使用默认值8.1 tmpDLLVersion = "8.1"; if (tmpDevSN.GetLength() > 12 && tmpDevSN.IndexOf("FWB") > 2) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("This is fwb device."); m_devSN = tmpDevSN; GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath); dllName = csDepPath + SPLIT_SLASH_STR + "IDCertificate." + tmpVendor + "." + tmpDLLVersion + ".dll";//oiltmp DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s", (const char*)dllName); HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, tmpVendor); } else { dllName = pEntity->GetVendorLibName(); CSmartPointer pConfig; ErrorCodeEnum rc = GetEntityBase()->GetFunction()->OpenConfig(Config_Root, pConfig); CSimpleStringA strSection = CSimpleStringA("Device.") + GetEntityBase()->GetEntityName(); CSimpleStringA str; pConfig->ReadConfigValue(strSection, "Vendor", str); HARDWARE_ENTITY_SET_VENDOR_NAME(m_entCode, str); } bool bOpenFlag = false; do { int tmpPort = 0; CSmartPointer spConfig; CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); err = spEntityFunction->OpenConfig(Config_Root, spConfig); if (err != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open cfg file failed!"); LogWarn(Severity_Middle, err, IDCertificate_UserErrorCode_Open_RootCfg_Failed, "open root cfg failed."); return 2; } spConfig->ReadConfigValueInt("Device.IDCertificate", "Port", tmpPort); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("IDCer open with port %d", tmpPort); err = m_hDevHelper->DevOpen(tmpPort); if (err != Error_Succeed) { SetErrPackage("Initial::DevOpen", m_devSN, err, MEC_DEVAPI_IDCER_DevOpen); AlarmDEC(); return 2; } } while (!m_hDevHelper && bOpenFlag == false); if (m_hDevHelper) { err = m_hDevHelper->IDCerRFControl(false); if (err != Error_Succeed) { SetErrPackage("Initial::IDCerRFControl", m_devSN, err, MEC_DEVAPI_IDCER_IDCerRFControl); AlarmDEC(false, false); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("close rf ok."); } } memset(m_devCatInfo.szModel, 0, MAX_DEV_MODEL_LEN); memset(m_devCatInfo.szType, 0, MAX_DEV_TYPE_LEN); memset(m_devCatInfo.szVendor, 0, MAX_DEV_VENDOR_LEN); err = m_hDevHelper->GetDevCategory(m_devCatInfo); if (err == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("szModel:%s, szType:%s, szVendor:%s", m_devCatInfo.szModel, m_devCatInfo.szType, m_devCatInfo.szVendor); m_adapterInfo.FulfillCategoryInfo(m_devCatInfo); CSimpleStringA szMod(m_devCatInfo.szModel); if (strstr(m_devCatInfo.szModel, "CODE=UCS2") != NULL) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("测试为UCS2新库。"); supportUCS2 = TRUE; } } else { SetErrPackage("Initial::GetDevCategory", m_devSN, err, MEC_DEVAPI_IDCER_GetDevCategory); AlarmDEC(); } if (m_hDevHelper) { m_devInit = true; return 0; } else { return 2; } } BOOL CIDCertFSM::UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code) { UINT8* out = utf8_code; if (!utf8_code) { return FALSE; } while (*ucs2_code != 0) { if (0x0080 > *ucs2_code) { /* 1 byte UTF-8 Character.*/ *out = (UINT8)*ucs2_code; ++out; } else if (0x0800 > *ucs2_code) { /*2 bytes UTF-8 Character.*/ *out = ((UINT8)(*ucs2_code >> 6)) | 0xc0; *(out + 1) = ((UINT8)(*ucs2_code & 0x003F)) | 0x80; out += 2; } else { /* 3 bytes UTF-8 Character .*/ *out = ((UINT8)(*ucs2_code >> 12)) | 0xE0; *(out + 1) = ((UINT8)((*ucs2_code & 0x0FC0) >> 6)) | 0x80; *(out + 2) = ((UINT8)(*ucs2_code & 0x003F)) | 0x80; out += 3; } //挪动两个字节 ++ucs2_code; } return TRUE; } BOOL CIDCertFSM::GetSexUTF8String(UINT16* in, UINT8* out) { if (!out) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("性别转换out字段为空!"); return false; } //linux默认编码就是utf8,直接拷贝 char* man = "男"; char* woman = "女"; char* unknow = "未说明"; unsigned char sexIn[1024]; memset(sexIn, 0, 1024); UCS2_to_UTF8(in, sexIn); //linux默认编码就是utf8,转成utf8格式后直接就是linux下的char类型 long sexCode = atoi((char*)sexIn); //直接转成数字 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("性别转换成数字, 成功。结果为%ld.", sexCode); switch (sexCode) { case 1: memcpy(out, man, strlen(man)); break; case 2: memcpy(out, woman, strlen(woman)); break; case 9: memcpy(out, unknow, strlen(unknow)); break; default: UCS2_to_UTF8(in, out); break; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("性别代码映射成功"); return true; } BOOL CIDCertFSM::GetNationalUTF8String(UINT16* in, UINT8* out) { if (!out) { return false; } unsigned char nationIn[1024]; memset(nationIn, 0, 1024); UCS2_to_UTF8(in, nationIn); //linux默认编码就是utf8,转成utf8格式后直接就是linux下的char类型 int nCode = atoi((char*)nationIn); //直接转成数字 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("民族编码转换成数字atoi成功。结果为%ld.", nCode); if (nCode >= 1 && nCode <= 56) { //linux默认编码就是utf8,直接拷贝 memcpy(out, nationalCode[nCode].c_str(), strlen(nationalCode[nCode].c_str())); } else { UCS2_to_UTF8(in, out); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("民族代码映射成功"); return true; } BOOL CIDCertFSM::GetDateStandardFormatUTF8(UINT16* in, UINT8* out) { if (!out) { return false; } char* ltimeCheck = "长期"; //linux默认编码就是utf8 unsigned char ltimeIn[1024]; memset(ltimeIn, 0, 1024); UCS2_to_UTF8(in, ltimeIn); int cmp = strcmp(ltimeCheck, (char*)ltimeIn); //判断长期证件 if (cmp == 0) { char tEndtime[1024] = "9999/12/31"; //linux默认编码就是utf8,不转换,直接传出去就好 memcpy(out, tEndtime, strlen(tEndtime)); return true; } UINT16 trans[1024]; memset(trans, 0, 1024); int cnt = 0; UINT16* p1 = in; UINT16* p2 = trans; while (*p1 != '\0') { if (cnt == 4 || cnt == 7) //在对年份和月份后增加斜杠 { *p2 = '/'; p2++; } else { *p2 = *p1; p1++; p2++; } cnt++; } //*p2 = '\0'; UCS2_to_UTF8(trans, out); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("日期格式转换成功!"); return true; } BOOL CIDCertFSM::RemoveUCS2Blank(UINT16* ucs2_code) { if (!ucs2_code) return false; bool findContent = false; UINT16* tmp = ucs2_code; //unsigned char tmpBuffer[1024]; memset(tmpBuffer, 0, 1024); // //while (*tmp == ' ') //{ // tmp++; // memset(tmpBuffer, 0, 1024); // memcpy(tmpBuffer, tmp, strlen((char*)tmp)); //} // while (*tmp != '\0') { if (*tmp != ' ' && findContent == false) { findContent = true; } else { if (findContent) //去除结尾空格 { if (*tmp == ' ') { *tmp = '\0'; break; } } } tmp++; } return true; } void CIDCertFSM::CheckHanZi(UINT16* ucs2_code) { if (!ucs2_code) return; UINT16* tmp = ucs2_code; int count = 1; while (*tmp != '\0') { if (*tmp >= 0x4e00 && *tmp <= 0x9fa5) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("是汉字。"); } else { BYTE fileHash[2]; memset(fileHash, 0, 2); memcpy(fileHash, tmp, 2); char* strFileHash = new char[4]; memset(strFileHash, 0, 4); HexBuf2StrBuf(fileHash, &strFileHash, 2); CSimpleStringA warn = CSimpleStringA::Format("姓名第%d个字非汉字编码, 数据为:%s", count, strFileHash); LogWarn(Severity_Low, Error_Debug, IDCertificate_UserErrorCode_ReadAndScan_NotHanZi, warn.GetData()); } tmp++; count++; } }