Prechádzať zdrojové kódy

Z991239-6279 #comment feat: 简化UTF8读证接口,拆分文字数据转换、获取正反扫描件功能

陈纪林80310970 3 mesiacov pred
rodič
commit
be2028a838

+ 263 - 381
Module/mod_IDCertificate/IDCertFSM.cpp

@@ -497,61 +497,31 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 {
 	LOG_FUNCTION();
 
-	ULLINT OpenRFControlTime = 0;
-	ULLINT CloseRFControlTime = 0;
-	ULLINT IDCerAuthenticateTime = 0;
-	ULLINT IDCerGetDataEx2Time = 0;
-	ULLINT ScanIDAndSaveImageTime = 0;
+	DeleteZP(Bmp_ZP | Bmp_SCAN, 1); //清理图片文件
 
+	bool bExitWhenReading = false;
+	int curDeleteType = Bmp_ZP;
 	DWORD elapsed = 0;
 	DWORD dwStart = SP::Module::Comm::RVCGetTickCount();
 	DWORD dwEnd = SP::Module::Comm::RVCGetTickCount();
-	ErrorCodeEnum eErr = Error_Unexpect;
 	ErrorCodeEnum errRfOpen = Error_Unexpect;
 	ErrorCodeEnum errAuth = Error_Unexpect;
-	ErrorCodeEnum errRead = Error_Unexpect;
-	ErrorCodeEnum errReadEx = Error_Unexpect;
 	ErrorCodeEnum errReadEx2 = Error_Unexpect;
-	LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on");
-
-	DeleteZP(Bmp_ZP | Bmp_SCAN, 1);
-
-	bool bOpenRF = false, bGetIDCert = false;
-	IDCerInfoEx2 idInfoEx2;
-	IDCerInfoEx idInfo;
-	IDCerInfo idInfoOld;
-
-	memset(&idInfoEx2, 0, sizeof(idInfoEx2));
-	memset(&idInfo, 0, sizeof(idInfo));
-	memset(&idInfoOld, 0, sizeof(idInfoOld));
-
+	ErrorCodeEnum errRfClose = Error_Unexpect;
+	
 	m_bCancelRead = false;
-	m_bWaitReadMore = false;
 	m_bReading = true;
 	m_bExit = false;
-	bool bReadSuccess = false;
-	bool bInvokeReadEx = false;
-	bool bInvokeReadEx2 = false;
-	bool bExitWhenReading = false;
-	bool bIDCerAuthenticate = false;
-	int curDeleteType = Bmp_ZP;
 
-	while (elapsed < IDCER_READ_TIMEOUT && !bGetIDCert && !m_bCancelRead)
+	LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on");
+	while (elapsed < IDCER_READ_TIMEOUT && (errReadEx2 != Error_Succeed) && !m_bCancelRead)
 	{
 		if (m_bExit)
 		{
 			DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("exit");
 			break;
 		}
-		bReadSuccess = false;
-		bInvokeReadEx = false;
-		bInvokeReadEx2 = false;
-		if (m_bWaitReadMore)
-		{
-			dwStart = SP::Module::Comm::RVCGetTickCount();
-			m_bWaitReadMore = false;
-		}
-		if (!bOpenRF)
+		if (errRfOpen != Error_Succeed)
 		{
 			m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
 			errRfOpen = m_hDevHelper->IDCerRFControl(true);
@@ -571,10 +541,8 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 				continue;
 			}
 		}
-
-		bOpenRF = true;
 		Sleep(IDCER_AUTH_INTERVAL);
-		bIDCerAuthenticate = false;
+
 		m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
 		errAuth = m_hDevHelper->IDCerAuthenticate();
 		m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
@@ -589,7 +557,9 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 		{
 			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)
 				.setAPI("DevAdapter::IDCerAuthenticate").setLogCode(IDCertService_LogCode_IDCerAuthenticate).setCostTime(IDCerAuthenticateTime)();
-			bIDCerAuthenticate = true;
+
+			IDCerInfoEx2 idInfoEx2;
+			memset(&idInfoEx2, 0, sizeof(idInfoEx2));
 
 			m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
 			errReadEx2 = m_hDevHelper->IDCerGetDataEx2(idInfoEx2);
@@ -604,263 +574,38 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 			{
 				ctx->Ans.msgtype = 1; //新字段传递,UTF8、二进制传递文字信息
 				//ex2数据读取功能代码、UCS2转UTF8代码
-				bInvokeReadEx2 = true;
-				if (errReadEx2 != Error_Succeed)
+				if (errReadEx2 == Error_Succeed)
 				{
-					bReadSuccess = false;
-				}
-				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);//外国人永居证旧证件关联字段
-					unsigned char englishNameEx[1024]; memset(englishNameEx, 0, 1024); //英文名备用字段
-					unsigned char IssuedSN[1024]; memset(IssuedSN, 0, 1024); //换证次数
-
 					DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER)
 						.setAPI("DevAdapter::IDCerGetDataEx2").setLogCode(IDCertService_LogCode_IDCerGetDataEx2).setCostTime(IDCerGetDataEx2Time)();
-					bReadSuccess = true;
 					LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_OP, "IDCertifacate op.");
 
-					DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("各字段长度-姓名:%d; 性别:%d; 民族:%d; 身份证:%d;",
-						GetUCS2ByteLength((UINT16*)idInfoEx2.name.data), GetUCS2ByteLength((UINT16*)idInfoEx2.sex.data),
-						GetUCS2ByteLength((UINT16*)idInfoEx2.nation.data), GetUCS2ByteLength((UINT16*)idInfoEx2.idno.data));
-					//去除首尾空格
-					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); //外国人永居证旧证件关联字段
-					RemoveUCS2Blank((UINT16*)idInfoEx2.reserved2.data); //英文名备用字段
-					RemoveUCS2Blank((UINT16*)idInfoEx2.issuedSN.data); //换证次数
-#ifdef RVC_OS_WIN
-					//转换成GBK用于debug上传
-					char* tSex = new char[32];
-					char* tNation = new char[32];
-					char* tBirthday = new char[32];
-					char* tStartDate = new char[32];
-					char* tEndDate = new char[32];
-					char* tIDcode = new char[1024];
-					char* tIDtype = new char[8];
-					char* tName = new char[128];
-					char* tNationality = new char[8];
-					char* tChecKNum = new char[8];
-					memcpy(tSex, idInfoEx2.sex.data, 32);
-					memcpy(tNation, idInfoEx2.nation.data, 32);
-					memcpy(tBirthday, idInfoEx2.birthday.data, 32);
-					memcpy(tStartDate, idInfoEx2.startDate.data, 32);
-					memcpy(tEndDate, idInfoEx2.endDate.data, 32);
-					memcpy(tIDcode, idInfoEx2.idno.data, 1024);
-					memcpy(tIDtype, idInfoEx2.idType.data, 8);
-					memcpy(tName, idInfoEx2.name.data, 128);
-					memcpy(tNationality, idInfoEx2.nationality.data, 8);
-					memcpy(tChecKNum, idInfoEx2.issuedSN.data, 8);
-					char *gbkSex, *gbkNation, *gbkBirthday, *gbkStartDate, *gbkEndDate, *gbkIDcode, *gbkIDtype, *gbkName, *gbkNationality, *gbktCheckNum;
-					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);
-					//birthday
-					iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tBirthday, -1, NULL, 0, NULL, NULL);
-					gbkBirthday = (char*)malloc((iSize + 1));
-					WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tBirthday, -1, gbkBirthday, iSize, NULL, NULL);
-					//startdate
-					iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tStartDate, -1, NULL, 0, NULL, NULL);
-					gbkStartDate = (char*)malloc((iSize + 1));
-					WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tStartDate, -1, gbkStartDate, 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);
-					//name
-					iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tName, -1, NULL, 0, NULL, NULL);
-					gbkName = (char*)malloc((iSize + 1));
-					WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tName, -1, gbkName, iSize, NULL, NULL);
-					//natinality
-					iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tNationality, -1, NULL, 0, NULL, NULL);
-					gbkNationality = (char*)malloc((iSize + 1));
-					WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tNationality, -1, gbkNationality, iSize, NULL, NULL);
-					//issuedSN
-					iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tChecKNum, -1, NULL, 0, NULL, NULL);
-					gbktCheckNum = (char*)malloc((iSize + 1));
-					WideCharToMultiByte(CP_ACP, 0, (wchar_t*)tChecKNum, -1, gbktCheckNum, iSize, NULL, NULL);
-					//gbk转换结束
-#endif
-					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);
-					UCS2_to_UTF8((UINT16*)idInfoEx2.reserved2.data, englishNameEx);
-					UCS2_to_UTF8((UINT16*)idInfoEx2.issuedSN.data, IssuedSN);
-
-					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)); //新外国人永居证关联字段
-					ctx->Ans.othercode_utf8.Alloc(strlen((char*)englishNameEx)); //英文名备用字段
-
-					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)); //新外国人永居证关联字段
-					memcpy(ctx->Ans.othercode_utf8.m_pData, englishNameEx, strlen((char*)englishNameEx)); //英文名备用字段
-
-					GetPngBlobEx(ctx->Ans.headphoto, "zp"); //转换头像图片
-
+					//转换数据并赋值至传出字段
+					CopyTextIDCerDataToCtx(idInfoEx2, ctx);
+					//转换头像图片
+					GetPngBlobEx(ctx->Ans.headphoto, "zp"); 
+					ctx->Ans.photodata = ctx->Ans.headphoto;
 					ctx->Ans.hasscan = 0;
 					if (igestionVer == TRUE) //吸入式设备才调用正反扫描功能
 					{
-						m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
-						eErr = m_hDevHelper->ScanIDAndSaveImage();
-						m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
-						ScanIDAndSaveImageTime = m_ullEndTime - m_ullBeginTime;
-
-						if (eErr == Error_Succeed)
+						if (GetAndCheckScanImg(idInfoEx2, ctx->Ans.frontphoto, ctx->Ans.backphoto))
 						{
 							curDeleteType = Bmp_ZP | Bmp_SCAN;
-							DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI("DevAdapter::ScanIDAndSaveImage")
-								.setLogCode(IDCertService_LogCode_ScanIDAndSaveImage)
-								.setCostTime(ScanIDAndSaveImageTime)();
-
-							transImgMsg.Clear();
-							//idfront.bmp" and "idback.bmp
-							ErrorCodeEnum eErrFront, eErrBack;
-							eErrFront = GetPngBlobEx(ctx->Ans.frontphoto, "idfront");
-							eErrBack = GetPngBlobEx(ctx->Ans.backphoto, "idback");
-							if (eErrFront == Error_Succeed && eErrBack == Error_Succeed)
-							{
-								ctx->Ans.hasscan = 1;
-#ifdef RVC_OS_WIN
-								if (!closeImgCheck)
-								{
-									ImgChekTask* frontImgCheck = new ImgChekTask(this);
-									frontImgCheck->idNum =/* ctx->Ans.idcode_utf8.m_pData*/gbkIDcode;
-									frontImgCheck->inName = /*ctx->Ans.name_utf8.m_pData*/gbkName;
-									frontImgCheck->inNationality = /*ctx->Ans.nationality_utf8.m_pData*/gbkNationality;
-									frontImgCheck->inIdType = /*ctx->Ans.idtype_utf8.m_pData*/gbkIDtype;
-									frontImgCheck->imgInput = ctx->Ans.frontphoto;
-									frontImgCheck->imgType = "正面";
-									GetEntityBase()->GetFunction()->PostThreadPoolTask(frontImgCheck);
-
-									ImgChekTask* backImgCheck = new ImgChekTask(this);
-									backImgCheck->idNum = /*ctx->Ans.idcode_utf8.m_pData*/gbkIDcode;
-									backImgCheck->inName = /*ctx->Ans.name_utf8.m_pData*/gbkName;
-									backImgCheck->inNationality = /*ctx->Ans.nationality_utf8.m_pData*/gbkNationality;
-									backImgCheck->inIdType = /*ctx->Ans.idtype_utf8.m_pData*/gbkIDtype;
-									backImgCheck->imgInput = ctx->Ans.backphoto;
-									frontImgCheck->imgType = "背面";
-									GetEntityBase()->GetFunction()->PostThreadPoolTask(backImgCheck);
-								}
-#endif
-							}
-							else
-							{
-								CSimpleStringA warnMsg = "ScanIDAndSaveImage() suc. But GetPngBlobEx() failed.";
-								if (transImgMsg.GetLength() != 0)
-								{
-									warnMsg = warnMsg + transImgMsg;
-								}
-								LogWarn(Severity_Middle, Error_Succeed,
-									IDCertificate_UserErrorCode_ReadAndScan_TransImgFaild, warnMsg.GetData());
-							}
-						}
-						else
-						{
-							if (eErr != Error_NotImpl)
-								SetErrorAndLog(eErr, MEC_DEVAPI_IDCER_ScanIDAndSaveImage, "DevAdapter::ScanIDAndSaveImage", __FUNCTION__,
-									false, ScanIDAndSaveImageTime, IDCertService_LogCode_ScanIDAndSaveImage);
+							ctx->Ans.hasscan = 1;
 						}
 					}
 
 #ifdef RVC_OS_WIN
 					CSimpleStringA csIDLogInfo = CSimpleStringA::Format("IDNo:%s****%s"
-						, (const char*)CSimpleStringA(gbkIDcode).SubString(0, 4)
-						, (const char*)CSimpleStringA(gbkIDcode).SubString(CSimpleStringA(gbkIDcode).GetLength() - 1, 1));
+						, (const char*)CSimpleStringA(GetGBKString((UINT16*)idInfoEx2.idno.data)).SubString(0, 4)
+						, (const char*)CSimpleStringA(GetGBKString((UINT16*)idInfoEx2.idno.data)).SubString(CSimpleStringA(GetGBKString((UINT16*)idInfoEx2.idno.data)).GetLength() - 1, 1));
 #else
 					CSimpleStringA tIdcode = (char*)idno;
 					CSimpleStringA csIDLogInfo = CSimpleStringA::Format("IDNo:%s****%s"
 						, (const char*)tIdcode.SubString(0, 4), (const char*)tIdcode.SubString(tIdcode.GetLength() - 1, 1));
 #endif
-
 					LogWarn(Severity_Low, Error_Succeed, IDCertificate_UserErrorCode_ReadAndScan_GetIDInfo, csIDLogInfo.GetData());
-
-					ctx->Ans.photodata = ctx->Ans.headphoto;
 					DeleteZP(curDeleteType, 2);
-
-					bGetIDCert = true;
 					break;
 				}
 			}
@@ -868,24 +613,25 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 		dwEnd = SP::Module::Comm::RVCGetTickCount();
 		elapsed = dwEnd - dwStart;
 	}
-
 	DeleteZP(curDeleteType);
 
 	if (m_bExit)
+	{
 		bExitWhenReading = true;
+	}
 
 	m_bExit = false;
 	m_bReading = false;
 	LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_OFF, "IDCer warning off");
 
 	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
-	ErrorCodeEnum eErr1 = m_hDevHelper->IDCerRFControl(false);
+	errRfClose = m_hDevHelper->IDCerRFControl(false);
 	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
 	CloseRFControlTime = m_ullEndTime - m_ullBeginTime;
 
-	if (eErr1 != Error_Succeed)
+	if (errRfClose != Error_Succeed)
 	{
-		SetErrorAndLog(eErr1, MEC_DEVAPI_IDCER_IDCerRFControl, "DevAdapter::IDCerRFControl", __FUNCTION__,
+		SetErrorAndLog(errRfClose, MEC_DEVAPI_IDCER_IDCerRFControl, "DevAdapter::IDCerRFControl", __FUNCTION__,
 			false, CloseRFControlTime, IDCertService_LogCode_CloseIDCerRFControl);
 	}
 	else
@@ -895,7 +641,7 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 			.setCostTime(CloseRFControlTime)();
 	}
 
-	if (bGetIDCert)
+	if (errReadEx2 == Error_Succeed)
 	{
 		ctx->Answer(Error_Succeed);
 	}
@@ -903,17 +649,17 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 	{
 		ctx->Answer(Error_Cancel);
 	}
-	else if (elapsed >= IDCER_READ_TIMEOUT) 
+	else if (elapsed >= IDCER_READ_TIMEOUT)
 	{
-		if (bIDCerAuthenticate) {
-			if (bInvokeReadEx2 && !bReadSuccess) {
+		if (errAuth == Error_Succeed) {
+			if (errReadEx2 != Error_Succeed) {
 
 				SetErrorAndLog(errReadEx2, MEC_DEVAPI_IDCER_IDCerGetDataEx2, "DevAdapter::IDCerGetDataEx2", __FUNCTION__,
 					true, IDCerGetDataEx2Time, IDCertService_LogCode_IDCerGetDataEx2);
 				ctx->Answer(Error_TimeOut, GetAlarmDEC()); //RTA2109
 			}
 		}
-		else if (!bOpenRF)
+		else if (errRfOpen != Error_Succeed)
 		{
 			SetErrorAndLog(errRfOpen, MEC_DEVAPI_IDCER_IDCerRFControl, "DevAdapter::IDCerRFControl", __FUNCTION__,
 				true, OpenRFControlTime, IDCertService_LogCode_OpenIDCerRFControl);
@@ -926,26 +672,26 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 				LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_Timeout_OtherCard, "读证超时,插入的卡片非身份.");
 				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode(IDCertService_LogCode_IDCerAuthenticate)
 					.setAPI("DevAdapter::IDCerAuthenticate").setCostTime(IDCerAuthenticateTime)();
-				ctx->Answer(Error_TimeOut);
+				ctx->Answer(Error_TimeOut, GetAlarmDEC());
 			}
-			else if(errAuth == Error_Dev_IDCardNotFound)
+			else if (errAuth == Error_Dev_IDCardNotFound)
 			{
 				LogWarn(Severity_Low, Error_Unexpect, IDCertificate_UserErrorCode_Timeout_NoCard, "读证超时,未检测到有卡片插入.");
 				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode(IDCertService_LogCode_IDCerAuthenticate)
 					.setAPI("DevAdapter::IDCerAuthenticate").setCostTime(IDCerAuthenticateTime)();
-				ctx->Answer(Error_TimeOut);
+				ctx->Answer(Error_TimeOut, GetAlarmDEC());
 			}
 			else
 			{
 				SetErrorAndLog(errAuth, MEC_DEVAPI_IDCER_IDCerAuthenticate, "DevAdapter::IDCerAuthenticate", __FUNCTION__,
 					false, IDCerAuthenticateTime, IDCertService_LogCode_IDCerAuthenticate); //RTA2107
-				ctx->Answer(Error_Unexpect, GetAlarmDEC());
+				ctx->Answer(Error_TimeOut, GetAlarmDEC());
 			}
 		}
 	}
-	else 
+	else
 	{
-		DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setResultCode("RTA2104")("ReadAndScanUTF8JS some thing wrong.");
+		DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setResultCode("RTA2104")("ReadAndScanUTF8 some thing wrong.");
 		ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_Failed);
 		LogError(Severity_High, Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_Failed, "ReadAndScanUTF8 some thing wrong.");
 	}
@@ -963,7 +709,6 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 
 		return 2;
 	}
-
 	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("return 0");
 	return 0;
 }
@@ -1001,7 +746,6 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 	memset(&idInfoOld, 0, sizeof(idInfoOld));
 
 	m_bCancelRead = false;
-	m_bWaitReadMore = false;
 	m_bReading = true;
 	m_bExit = false;
 	bool bReadSuccess = false;
@@ -1021,11 +765,6 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 		bReadSuccess = false;
 		bInvokeReadEx = false;
 		bInvokeReadEx2 = false;
-		if (m_bWaitReadMore)
-		{
-			dwStart = SP::Module::Comm::RVCGetTickCount();
-			m_bWaitReadMore = false;
-		}
 		if (!bOpenRF)
 		{
 			m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
@@ -1611,42 +1350,6 @@ ErrorCodeEnum CIDCertFSM::GetDevCatInfo(DevCategoryInfo &devInfo, CSimpleStringA
 	return Error_Succeed;
 }
 
-int CIDCertFSM::WaitFetchIDCard()
-{
-	LOG_FUNCTION();
-	ErrorCodeEnum eErr = Error_Unexpect;
-	int pos = 99;
-	DWORD64 dwStart = SP::Module::Comm::RVCGetTickCount();
-	DWORD64 dwEnd = 0;
-	while ((dwEnd - dwStart) < 120 * 1000)//wait for 120 seconds
-	{
-		m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
-		eErr = m_hDevHelper->QueryCardPos(pos);
-		m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
-		if (eErr == Error_Succeed)
-		{
-			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::QueryCardPos")
-				.setCostTime(m_ullEndTime - m_ullBeginTime)
-				("QueryCardPos succeed");
-		}
-		else
-		{
-			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::QueryCardPos")
-				.setCostTime(m_ullEndTime - m_ullBeginTime)
-				.setResultCode("RTA210A")
-				("QueryCardPos failed.");
-		}
-		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, int deleteTiming)
 {
 	if ((type&Bmp_ZP) == Bmp_ZP)
@@ -1772,13 +1475,15 @@ int CIDCertFSM::Initial()
 	return 0;
 }
 
-BOOL CIDCertFSM::UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code)
+void CIDCertFSM::UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code)
 {
 	UINT8* out = utf8_code;
 
-	if (!utf8_code)
+	if (!utf8_code || !ucs2_code)
 	{
-		return FALSE;
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)
+			("UCS2转换异常:UCS2[%d], UTF8[%d]", (ucs2_code == NULL), (utf8_code == NULL));
+		return;
 	}
 
 	while (*ucs2_code != 0)
@@ -1809,15 +1514,16 @@ BOOL CIDCertFSM::UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code)
 		++ucs2_code;
 	}
 
-	return TRUE;
+	return;
 }
 
-BOOL CIDCertFSM::GetSexUTF8String(UINT16* in, UINT8* out)
+void CIDCertFSM::GetSexUTF8String(UINT16* in, UINT8* out)
 {
-	if (!out)
+	if (!in || !out)
 	{
-		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("性别转换out字段为空!");
-		return false;
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)
+			("性别转换参数异常:in_UCS2[%d], out_UTF8[%d]", (in == NULL), (out == NULL));
+		return;
 	}
 
 #ifdef RVC_OS_WIN
@@ -1872,21 +1578,23 @@ BOOL CIDCertFSM::GetSexUTF8String(UINT16* in, UINT8* out)
 		break;
 	}
 #endif
-	return true;
+	return;
 }
 
-BOOL CIDCertFSM::GetNationalUTF8String(UINT16* in, UINT8* out)
+void CIDCertFSM::GetNationalUTF8String(UINT16* in, UINT8* out)
 {
-	if (!out)
+	if (!in || !out)
 	{
-		return false;
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)
+			("民族转换参数异常:in_UCS2[%d], out_UTF8[%d]", (in == NULL), (out == NULL));
+		return;
 	}
 
 #ifdef RVC_OS_WIN
-	int sexCode = _wtoi((wchar_t*)in);
-	if (sexCode >= 1 && sexCode <= 56)
+	int nCode = _wtoi((wchar_t*)in);
+	if (nCode >= 1 && nCode <= 56)
 	{
-		UCS2_to_UTF8((UINT16*)nationalCode[sexCode].c_str(), out);
+		UCS2_to_UTF8((UINT16*)nationalCode[nCode].c_str(), out);
 	}
 	else
 	{
@@ -1908,15 +1616,17 @@ BOOL CIDCertFSM::GetNationalUTF8String(UINT16* in, UINT8* out)
 		UCS2_to_UTF8(in, out);
 	}
 #endif
-	return true;
+	return;
 }
 
 
-BOOL CIDCertFSM::GetDateStandardFormatUTF8(UINT16* in, UINT8* out)
+void CIDCertFSM::GetDateStandardFormatUTF8(UINT16* in, UINT8* out)
 {
-	if (!out)
+	if (!in || !out)
 	{
-		return false;
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)
+			("日期转换参数异常:in_UCS2[%d], out_UTF8[%d]", (in == NULL), (out == NULL));
+		return;
 	}
 
 #ifdef RVC_OS_WIN
@@ -1942,41 +1652,44 @@ BOOL CIDCertFSM::GetDateStandardFormatUTF8(UINT16* in, UINT8* out)
 		char tEndtime[1024] = "9999/12/31"; //linux默认编码就是utf8,不转换,直接传出去就好
 		memcpy(out, tEndtime, strlen(tEndtime));
 #endif
-		return true;
 	}
-
-	UINT16 trans[1024];
-	memset(trans, 0, 1024);
-
-	int cnt = 0;
-	UINT16* p1 = in;
-	UINT16* p2 = trans;
-	while (*p1 != '\0')
+	else //其他日期
 	{
-		if (cnt == 4 || cnt == 7) //在对年份和月份后增加斜杠
-		{
-			*p2 = '/';
-			p2++;
-		}
-		else
+		UINT16 trans[1024];
+		memset(trans, 0, 1024);
+
+		int cnt = 0;
+		UINT16* p1 = in;
+		UINT16* p2 = trans;
+		while (*p1 != '\0')
 		{
-			*p2 = *p1;
-			p1++;
-			p2++;
+			if (cnt == 4 || cnt == 7) //在对年份和月份后增加斜杠
+			{
+				*p2 = '/';
+				p2++;
+			}
+			else
+			{
+				*p2 = *p1;
+				p1++;
+				p2++;
+			}
+			cnt++;
 		}
-		cnt++;
-	}
-
-	//*p2 = '\0';
 
-	UCS2_to_UTF8(trans, out);
-	return true;
+		UCS2_to_UTF8(trans, out);
+	}
+	return;
 }
 
 
-BOOL CIDCertFSM::RemoveUCS2Blank(UINT16* ucs2_code)
+void CIDCertFSM::RemoveUCS2Blank(UINT16* ucs2_code)
 {
-	if (!ucs2_code) return false;
+	if (!ucs2_code)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("去除UCS2空格异常, UCS2数据地址为空!");
+		return;
+	}
 
 	bool findContent = false;
 	UINT16* tmp = ucs2_code;
@@ -2020,7 +1733,7 @@ BOOL CIDCertFSM::RemoveUCS2Blank(UINT16* ucs2_code)
 
 	ucs2_code = start;
 
-	return true;
+	return;
 }
 
 int CIDCertFSM::GetUCS2ByteLength(UINT16* ucs2_code)
@@ -2133,6 +1846,175 @@ CSimpleStringA CIDCertFSM::GetFileLastModifyTime(CSimpleStringA filePath)
 #endif
 }
 
+template <typename T>
+void CIDCertFSM::CopyTextIDCerDataToCtx(IDCerInfoEx2 idInfoEx2, T& ctx)
+{
+	IDCerTextData *utf8Data = new IDCerTextData();
+	memset(utf8Data, 0, sizeof(utf8Data));
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("各字段长度-姓名:%d; 性别:%d; 民族:%d; 身份证:%d;",
+		GetUCS2ByteLength((UINT16*)idInfoEx2.name.data), GetUCS2ByteLength((UINT16*)idInfoEx2.sex.data),
+		GetUCS2ByteLength((UINT16*)idInfoEx2.nation.data), GetUCS2ByteLength((UINT16*)idInfoEx2.idno.data));
+	//去除首尾空格
+	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); //外国人永居证旧证件关联字段
+	RemoveUCS2Blank((UINT16*)idInfoEx2.reserved2.data); //英文名备用字段
+	RemoveUCS2Blank((UINT16*)idInfoEx2.issuedSN.data); //换证次数
+	//转换各字段数据至UTF8格式
+	UCS2_to_UTF8((UINT16*)idInfoEx2.name.data, utf8Data->name);
+	GetSexUTF8String((UINT16*)idInfoEx2.sex.data, utf8Data->sex);
+	GetNationalUTF8String((UINT16*)idInfoEx2.nation.data, utf8Data->nation);
+	GetDateStandardFormatUTF8((UINT16*)idInfoEx2.birthday.data, utf8Data->birthday);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.address.data, utf8Data->address);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.idno.data, utf8Data->idno);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.department.data, utf8Data->department);
+	GetDateStandardFormatUTF8((UINT16*)idInfoEx2.startDate.data, utf8Data->startDate);
+	GetDateStandardFormatUTF8((UINT16*)idInfoEx2.endDate.data, utf8Data->endDate);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.englishName.data, utf8Data->englishName);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.nationality.data, utf8Data->nationality);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.idVersion.data, utf8Data->idVersion);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.idType.data, utf8Data->idType);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.reserved.data, utf8Data->reserved);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.reserved2.data, utf8Data->englishNameEx);
+	UCS2_to_UTF8((UINT16*)idInfoEx2.issuedSN.data, utf8Data->IssuedSN);
+	
+	//将数据拷贝至实体接口上下文
+	ctx->Ans.name_utf8.Alloc(strlen((char*)utf8Data->name));
+	ctx->Ans.sex_utf8.Alloc(strlen((char*)utf8Data->sex));
+	ctx->Ans.nation_utf8.Alloc(strlen((char*)utf8Data->nation));
+	ctx->Ans.birthday_utf8.Alloc(strlen((char*)utf8Data->birthday));
+	ctx->Ans.address_utf8.Alloc(strlen((char*)utf8Data->address));
+	ctx->Ans.idcode_utf8.Alloc(strlen((char*)utf8Data->idno));
+	ctx->Ans.department_utf8.Alloc(strlen((char*)utf8Data->department));
+	ctx->Ans.startdate_utf8.Alloc(strlen((char*)utf8Data->startDate));
+	ctx->Ans.enddate_utf8.Alloc(strlen((char*)utf8Data->endDate));
+	ctx->Ans.englishname_utf8.Alloc(strlen((char*)utf8Data->englishName));
+	ctx->Ans.nationality_utf8.Alloc(strlen((char*)utf8Data->nationality));
+	ctx->Ans.idversion_utf8.Alloc(strlen((char*)utf8Data->idVersion));
+	ctx->Ans.idtype_utf8.Alloc(strlen((char*)utf8Data->idType));
+	ctx->Ans.reserved_utf8.Alloc(strlen((char*)utf8Data->reserved)); //新外国人永居证关联字段
+	ctx->Ans.othercode_utf8.Alloc(strlen((char*)utf8Data->englishNameEx)); //英文名备用字段
+
+	memcpy(ctx->Ans.name_utf8.m_pData, utf8Data->name, strlen((char*)utf8Data->name));
+	memcpy(ctx->Ans.sex_utf8.m_pData, utf8Data->sex, strlen((char*)utf8Data->sex));
+	memcpy(ctx->Ans.nation_utf8.m_pData, utf8Data->nation, strlen((char*)utf8Data->nation));
+	memcpy(ctx->Ans.birthday_utf8.m_pData, utf8Data->birthday, strlen((char*)utf8Data->birthday));
+	memcpy(ctx->Ans.address_utf8.m_pData, utf8Data->address, strlen((char*)utf8Data->address));
+	memcpy(ctx->Ans.idcode_utf8.m_pData, utf8Data->idno, strlen((char*)utf8Data->idno));
+	memcpy(ctx->Ans.department_utf8.m_pData, utf8Data->department, strlen((char*)utf8Data->department));
+	memcpy(ctx->Ans.startdate_utf8.m_pData, utf8Data->startDate, strlen((char*)utf8Data->startDate));
+	memcpy(ctx->Ans.enddate_utf8.m_pData, utf8Data->endDate, strlen((char*)utf8Data->endDate));
+	memcpy(ctx->Ans.englishname_utf8.m_pData, utf8Data->englishName, strlen((char*)utf8Data->englishName));
+	memcpy(ctx->Ans.nationality_utf8.m_pData, utf8Data->nationality, strlen((char*)utf8Data->nationality));
+	memcpy(ctx->Ans.idversion_utf8.m_pData, utf8Data->idVersion, strlen((char*)utf8Data->idVersion));
+	memcpy(ctx->Ans.idtype_utf8.m_pData, utf8Data->idType, strlen((char*)utf8Data->idType));
+	memcpy(ctx->Ans.reserved_utf8.m_pData, utf8Data->reserved, strlen((char*)utf8Data->reserved)); //新外国人永居证关联字段
+	memcpy(ctx->Ans.othercode_utf8.m_pData, utf8Data->englishNameEx, strlen((char*)utf8Data->englishNameEx)); //英文名备用字段
+
+	if (utf8Data != nullptr)
+	{
+		delete utf8Data;
+		utf8Data = nullptr;
+	}
+
+	return;
+}
+
+BOOL CIDCertFSM::GetAndCheckScanImg(IDCerInfoEx2 idInfoEx2, CBlob& frontImg, CBlob& backImg)
+{
+	BOOL resFlag = FALSE;
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	ErrorCodeEnum eErr = m_hDevHelper->ScanIDAndSaveImage();
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+	ScanIDAndSaveImageTime = m_ullEndTime - m_ullBeginTime;
+
+	if (eErr == Error_Succeed)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI("DevAdapter::ScanIDAndSaveImage")
+			.setLogCode(IDCertService_LogCode_ScanIDAndSaveImage)
+			.setCostTime(ScanIDAndSaveImageTime)();
+
+		transImgMsg.Clear();
+		//idfront.bmp" and "idback.bmp
+		ErrorCodeEnum eErrFront, eErrBack;
+		eErrFront = GetPngBlobEx(frontImg, "idfront");
+		eErrBack = GetPngBlobEx(backImg, "idback");
+		if (eErrFront == Error_Succeed && eErrBack == Error_Succeed)
+		{
+			resFlag = TRUE;
+#ifdef RVC_OS_WIN
+			if (!closeImgCheck)
+			{
+				ImgChekTask* frontImgCheck = new ImgChekTask(this);
+				frontImgCheck->idNum = GetGBKString((UINT16*)idInfoEx2.idno.data);
+				frontImgCheck->inName = GetGBKString((UINT16*)idInfoEx2.name.data);
+				frontImgCheck->inNationality = GetGBKString((UINT16*)idInfoEx2.nationality.data);
+				frontImgCheck->inIdType = GetGBKString((UINT16*)idInfoEx2.idType.data);
+				frontImgCheck->imgInput = frontImg;
+				frontImgCheck->imgType = "正面";
+				GetEntityBase()->GetFunction()->PostThreadPoolTask(frontImgCheck);
+
+				ImgChekTask* backImgCheck = new ImgChekTask(this);
+				backImgCheck->idNum = GetGBKString((UINT16*)idInfoEx2.idno.data);
+				backImgCheck->inName = GetGBKString((UINT16*)idInfoEx2.name.data);
+				backImgCheck->inNationality = GetGBKString((UINT16*)idInfoEx2.nationality.data);
+				backImgCheck->inIdType = GetGBKString((UINT16*)idInfoEx2.idType.data);
+				backImgCheck->imgInput = backImg;
+				frontImgCheck->imgType = "背面";
+				GetEntityBase()->GetFunction()->PostThreadPoolTask(backImgCheck);
+			}
+#endif
+		}
+		else
+		{
+			CSimpleStringA warnMsg = "ScanIDAndSaveImage() suc. But GetPngBlobEx() failed.";
+			if (transImgMsg.GetLength() != 0)
+			{
+				warnMsg = warnMsg + transImgMsg;
+			}
+			LogWarn(Severity_Middle, Error_Succeed,
+				IDCertificate_UserErrorCode_ReadAndScan_TransImgFaild, warnMsg.GetData());
+		}
+	}
+	else
+	{
+		if (eErr != Error_NotImpl)
+			SetErrorAndLog(eErr, MEC_DEVAPI_IDCER_ScanIDAndSaveImage, "DevAdapter::ScanIDAndSaveImage", __FUNCTION__,
+				false, ScanIDAndSaveImageTime, IDCertService_LogCode_ScanIDAndSaveImage);
+	}
+
+	return resFlag;
+}
+
+#ifdef RVC_OS_WIN
+char* CIDCertFSM::GetGBKString(UINT16* ucs2_code) //将UCS2字段转换为GBK,用于WIN打印日志或者其他中文使用
+{
+	char* tData = new char[128];
+	memcpy(tData, ucs2_code, 128);
+	char* gbkData = NULL;
+
+	int iSize = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)ucs2_code, -1, NULL, 0, NULL, NULL);
+	gbkData = (char*)malloc((iSize + 1));
+	WideCharToMultiByte(CP_ACP, 0, (wchar_t*)ucs2_code, -1, gbkData, iSize, NULL, NULL);
+
+	return gbkData;
+}
+#endif // RVC_OS_WIN
+
+
 #ifdef RVC_OS_WIN
 void CIDCertFSM::HttpsLogCallBack(const char* logtxt)
 {

+ 41 - 10
Module/mod_IDCertificate/IDCertFSM.h

@@ -114,6 +114,26 @@ struct CtxInfo
 	LPVOID pCtx;
 };
 
+struct IDCerTextData
+{
+	unsigned char name[1024];
+	unsigned char sex[1024]; 
+	unsigned char nation[1024]; 
+	unsigned char birthday[1024];
+	unsigned char address[1024]; 
+	unsigned char idno[1024];
+	unsigned char department[1024];
+	unsigned char startDate[1024]; 
+	unsigned char endDate[1024]; 
+	unsigned char englishName[1024];
+	unsigned char nationality[1024];
+	unsigned char idVersion[1024];
+	unsigned char idType[1024];
+	unsigned char reserved[1024];
+	unsigned char englishNameEx[1024]; //英文名备用字段
+	unsigned char IssuedSN[1024]; //换证次数
+};
+
 class CancelReadEvent : public FSMEvent
 {
 public:
@@ -196,7 +216,7 @@ public:
 		FSM_RULE_ENTRY(s3, s2, USER_EVT_INIT_FINISHED, 2)
 	END_FSM_RULE()
 
-		CIDCertFSM() :m_bCancelRead(false), m_bReading(false), m_bWaitReadMore(false),
+		CIDCertFSM() :m_bCancelRead(false), m_bReading(false),
 		m_bExit(false), m_testResult(Error_Succeed), m_getDevCategory(Error_Unexpect), m_csMachineType(""), m_terminalNo(""), transImgMsg("")
 	{
 		ZeroMemory(&m_adapterInfo, sizeof(m_adapterInfo));
@@ -226,8 +246,6 @@ public:
 	int ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCert_ReadAndScanUTF8_Ans>::Pointer ctx); 
 	int ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req, IDCert_ReadAndScanUTF8JS_Ans>::Pointer ctx);
 
-	int WaitFetchIDCard();
-	void SetReadMore(){m_bWaitReadMore = true;}
 	void SetExitFlag(){m_bExit = true;}
 	bool GetReadFlag(){return m_bReading;}
 	ErrorCodeEnum GetDevCatInfo(DevCategoryInfo &devInfo, CSimpleStringA& devType);
@@ -250,21 +268,28 @@ private:
 	//Delete bmp file in dep directory, you should just convey fileName only without paths -Joseph
 	//deleteTiming:0, defalut; deleteTiming:1, delete before Read IDCard; deleteTiming:2, delete after Read IDCard
 	ErrorCodeEnum DeleteFileIfExisted(LPCTSTR fileName, int deleteTiming = 0);
-	BOOL UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code);
-	BOOL GetSexUTF8String(UINT16* in, UINT8* out);
-	BOOL GetNationalUTF8String(UINT16* in, UINT8* out);
-	BOOL GetDateStandardFormatUTF8(UINT16* in, UINT8* out);
-	BOOL RemoveUCS2Blank(UINT16* ucs2_code);
+	void UCS2_to_UTF8(UINT16* ucs2_code, UINT8* utf8_code);
+	void GetSexUTF8String(UINT16* in, UINT8* out);
+	void GetNationalUTF8String(UINT16* in, UINT8* out);
+	void GetDateStandardFormatUTF8(UINT16* in, UINT8* out);
+	void RemoveUCS2Blank(UINT16* ucs2_code);
 	int GetUCS2ByteLength(UINT16* ucs2_code);
 	void CheckHanZi(UINT16* ucs2_code);
 
 	CSimpleStringA GetFileHashStr(CSimpleStringA filePath);
 	CSimpleStringA GetFileLastModifyTime(CSimpleStringA filePath);
 
+	template <typename T>
+	void CopyTextIDCerDataToCtx(IDCerInfoEx2 idInfoEx2, T& ctx); //兼容JS接口
+	BOOL GetAndCheckScanImg(IDCerInfoEx2 idInfoEx2, CBlob& frontImg, CBlob& backImg);
+#ifdef RVC_OS_WIN
+	char* GetGBKString(UINT16* ucs2_code); //WIN打印源数据日志或其他中文用途
+#endif
+
 public:
 		std::string checkImgURL;
 private:
-	bool m_bCancelRead, m_bReading, m_bWaitReadMore, m_bExit;
+	bool m_bCancelRead, m_bReading, m_bExit;
 	ErrorCodeEnum m_testResult;
 	ErrorCodeEnum m_getDevCategory;
 	DevCategoryInfo m_devCatInfo;
@@ -278,10 +303,14 @@ private:
 	BOOL supportUCS2; //支持生僻字
 	BOOL igestionVer; //吸入式设备
 	BOOL supportNewForeigner; //支持新版外国人永居证 2023.11.10
-	CSimpleStringA bkPicPath; //合成背景的图片路径
 
 	BOOL closeImgCheck;
 	ULLINT m_ullBeginTime, m_ullEndTime;
+	ULLINT OpenRFControlTime;
+	ULLINT CloseRFControlTime;
+	ULLINT IDCerAuthenticateTime;
+	ULLINT IDCerGetDataEx2Time;
+	ULLINT ScanIDAndSaveImageTime;
 };
 
 struct ReadAndScanUTF8Task : public ITaskSp  //ex8
@@ -326,4 +355,6 @@ struct InitTask : public ITaskSp
 		fsm->PostEventFIFO(e);
 	}
 };
+
+
 #endif //IDCERTFSM_H

+ 37 - 11
Module/mod_IDCertificate/IDCertificate.xml

@@ -1,18 +1,22 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <entity name="IDCertificate">
-	<class name="IDCertService" overlap="true" exclusive="false">			
-		<oneway name="CancelRead" overlap="true" method_id="1">		
-		</oneway>		
-		<!-- 1、设备未打开,errorCodeΪError_DevNotAvailable(2050),rtaCodeΪRTA2105 -->
-		<twoway name="GetDevInfo" overlap="true" method_id="65535">
+	<class name="IDCertService" overlap="true" exclusive="false">
+		<oneway name="CancelRead" overlap="true" method_id="1">
+		</oneway>
+		<!-- 1、设备未打开,errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2105 -->
+		<twoway name="GetDevInfo" overlap="true" jsflag="true" method_id="65535">
 			<req>
 			</req>
 			<res>
+				<!--设备适配器DevCategoryInfo的szType-->
 				<param name="type" type="string" />
+				<!--设备适配器DevCategoryInfo的szModel-->
 				<param name="model" type="string" />
+				<!--设备适配器DevCategoryInfo的version-->
 				<param name="version" type="string" />
+				<!--硬件实体内置的状态,目前暂无使用场景,有需要再讨论如何定义-->
 				<param name="state" type="int" />
-			</res>			
+			</res>
 		</twoway>
 		<twoway name="ReadAndScanUTF8" overlap="true" method_id="9">
 			<req>
@@ -64,33 +68,55 @@
 				<param name="reserved2" type="array_string"/>
 			</req>
 			<res>
-				<!--msgtype用于区分传递方式的新旧-->
-				<param name="msgtype" type="int" />
+				<!--是否扫描成功-->
 				<param name="hasscan" type="int" />
-				<param name="photodata" type="blob" />
+				<!--正面扫描件-->
 				<param name="frontphoto" type="blob" />
+				<!--背面扫描件-->
 				<param name="backphoto" type="blob" />
+				<!--头像图片-->
 				<param name="headphoto" type="blob" />
+				<!--指纹数据1-->
 				<param name="finger1" type="blob" />
+				<!--指纹数据2-->
 				<param name="finger2" type="blob" />
+				<!--图片预留字段1-->
 				<param name="imgreserved1" type="blob" />
+				<!--图片预留字段2-->
 				<param name="imgreserved2" type="blob" />
+				<!--预留字段1-->
 				<param name="reserved1" type="array_int"/>
+				<!--预留字段2-->
 				<param name="reserved2" type="array_string"/>
+				<!--姓名-->
 				<param name="name_utf8" type="blob" />
+				<!--性别-->
 				<param name="sex_utf8" type="blob" />
+				<!--民族-->
 				<param name="nation_utf8" type="blob" />
+				<!--生日-->
 				<param name="birthday_utf8" type="blob" />
+				<!--地址-->
 				<param name="address_utf8" type="blob" />
+				<!--证件号码-->
 				<param name="idcode_utf8" type="blob" />
+				<!--签发机关-->
 				<param name="department_utf8" type="blob" />
+				<!--发证日期-->
 				<param name="startdate_utf8" type="blob" />
+				<!--证件有效期截止日期-->
 				<param name="enddate_utf8" type="blob" />
+				<!--英文名-->
 				<param name="englishname_utf8" type="blob" />
+				<!--国家-->
 				<param name="nationality_utf8" type="blob" />
+				<!--证件版本-->
 				<param name="idversion_utf8" type="blob" />
+				<!--证件类型-->
 				<param name="idtype_utf8" type="blob" />
+				<!--备用字段-->
 				<param name="othercode_utf8" type="blob" />
+				<!--备用字段-->
 				<param name="reserved_utf8" type="blob" />
 			</res>
 		</twoway>
@@ -105,6 +131,6 @@
 		</twoway>
 	</class>
 	<message name="FetchIDCard">
-			<param name="status" type="int"/>
-	</message>	
+		<param name="status" type="int"/>
+	</message>
 </entity>