Prechádzať zdrojové kódy

Z991239-6087 #comment feat: 实现联机上电读卡接口

Signed-Off-By: commit-hook
刘文涛80174520 6 mesiacov pred
rodič
commit
069af8d42f

+ 818 - 1
Module/mod_CardIssuerStand/CardIssuerFSM.cpp

@@ -6106,6 +6106,745 @@ int CCardIssuerFSM::CheckCardType(CSimpleStringA cardNo, bool bReadMag, int& ICt
 	return 0;
 }
 
+int CCardIssuerFSM::PreOnlineJS_Contact(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx, bool& bICOK, bool& bContinue)
+{
+	LOG_FUNCTION();
+	long l_beginTime, l_endTime;
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("(PreOnlineJS_Contact) IC接触读卡");
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("PreOnlineJS_Contact, aid[%s], business data[%s]", ctx->Req.aid.GetData(), ctx->Req.businessData.GetData());
+
+	m_pCardProcess->DataInit();
+	//数据已读出,开始pmoc流程
+	m_pCardProcess->SplitBusinessData(ctx->Req.businessData, ctx->Req.businessData.GetLength());
+	m_pCardProcess->SplitBusinessData("DF690101", strlen("DF690101"));
+	int activeCardType;
+	//oilyang@20201014 add emv card support
+	int retDetectAndRead = -1;
+	ICData aidFromBus(false, 0x4f, 0x00);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, the front BusinessData have not provide aid data.");
+		int icRetryTimes = 0;
+		while (1)
+		{
+			l_beginTime = GetTickCountRVC();
+			retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_hDevHelper, m_aidList, activeCardType, m_issueStatus);
+			l_endTime = GetTickCountRVC();
+			if (retDetectAndRead == -1)//only retry for active ic card failed!
+				icRetryTimes++;
+			else
+				break;
+			Sleep(500);
+			if (icRetryTimes >= m_ICRetryTimes)
+				break;
+		}
+	}
+	else {
+		char* pAIDTmp = new char[64];
+		memset(pAIDTmp, 0, 64);
+		HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, the aid from business is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp));
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		int icRetryTimes = 0;
+		while (1)
+		{
+			l_beginTime = GetTickCountRVC();
+			retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER, m_hDevHelper, preAIDs, activeCardType, m_issueStatus);
+			l_endTime = GetTickCountRVC();
+			if (retDetectAndRead == -1)//only retry for active ic card failed!
+				icRetryTimes++;
+			else
+				break;
+			Sleep(500);
+			if (icRetryTimes >= m_ICRetryTimes)
+				break;
+		}
+		if (pAIDTmp != NULL)
+			delete[]pAIDTmp;
+	}
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, After invoke DetectAndReadICData, retDetectAndRead:%d, activeCardType:%d", retDetectAndRead, activeCardType);
+
+	if (retDetectAndRead < 0)
+	{
+		ErrorCodeEnum eErrCode = Error_Unexpect;
+		CSimpleStringA ApiName = "";
+		CSimpleStringA alarmMsg = "";
+		CSimpleStringA csErrMsgWithReturnCode = "";
+
+		if (IfUseRf()) {
+			bContinue = true; //继续后面的非接流程
+			if (retDetectAndRead == -1) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("检测卡片类型时上电失败");
+				GetCardProcessLastErr(eErrCode, ApiName, alarmMsg, csErrMsgWithReturnCode);
+
+				if (m_issueStatus) {
+					DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220320").setResultCode("RTA230V")(csErrMsgWithReturnCode.GetData());
+				}
+				else {
+					DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220303").setResultCode("RTA230M")(csErrMsgWithReturnCode.GetData());
+				}
+			}
+			else if (retDetectAndRead == -2) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("读取IC数据失败");
+				if (m_issueStatus) {
+					SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, false, l_endTime - l_beginTime, "QLR040220320", "");
+				}
+				else {
+					SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, false, l_endTime - l_beginTime, "QLR040220303", "");
+				}
+			}
+			else if (retDetectAndRead == -3) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("IC卡建立应用列表失败");
+				if (m_issueStatus) {
+					SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, false, l_endTime - l_beginTime, "QLR040220320", "");
+				}
+				else {
+					SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, false, l_endTime - l_beginTime, "QLR040220303", "");
+				}
+			}
+		}
+		else {
+			if (retDetectAndRead == -1) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("检测卡片类型时上电失败");
+				GetCardProcessLastErr(eErrCode, ApiName, alarmMsg, csErrMsgWithReturnCode);
+
+				if (m_issueStatus) {
+					if (IsInBusiness()) {
+						DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220320").setResultCode("RTA230V")(csErrMsgWithReturnCode.GetData());
+						LogError(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveICCard_Failed, alarmMsg.GetData());
+					}
+					else {
+						DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220320").setResultCode("RTA230V")(csErrMsgWithReturnCode.GetData());
+						LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveICCard_Failed, alarmMsg.GetData());
+					}
+					ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveICCard_Failed);
+				}
+				else {
+					if (IsInBusiness()) {
+						DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220303").setResultCode("RTA230M")(csErrMsgWithReturnCode.GetData());
+						LogError(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveICCard_Failed, alarmMsg.GetData());
+					}
+					else {
+						DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220303").setResultCode("RTA230M")(csErrMsgWithReturnCode.GetData());
+						LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveICCard_Failed, alarmMsg.GetData());
+					}
+					ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_ActiveICCard_Failed);
+				}
+			}
+			else if (retDetectAndRead == -2) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("读取IC数据失败");
+				DWORD dwTmpUserErrCode = 0;
+				if (m_issueStatus) {
+					dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220320", "");
+				}
+				else {
+					dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220303", "");
+				}
+				ctx->Answer(Error_Unexpect, dwTmpUserErrCode);
+			}
+			else if (retDetectAndRead == -3) {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("IC卡建立应用列表失败");
+				DWORD dwTmpUserErrCode = 0;
+				if (m_issueStatus) {
+					dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220320", "");
+				}
+				else {
+					dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ICCommand, "DevAdapter::ICCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220303", "");
+				}
+				ctx->Answer(Error_Unexpect, dwTmpUserErrCode);
+			}
+		}
+		bICOK = false;
+		return 0;//上电读卡失败
+	}
+
+	m_pCardProcess->TermRiskManage();
+	CSimpleStringA taaResult;
+	BYTE bt9f27 = 0;
+	int retTAA = m_pCardProcess->TermActionAnalyze(CARD_MACHINE_ISSUER, m_hDevHelper, taaResult, true, m_bCDA, bt9f27);
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, TermActionAnalyze, retTAA:%d, taaResult:%s", retTAA, taaResult.GetData());
+	switch (retTAA)
+	{//to be added oiltmp 20140929
+	case -1:	//some data may be wrong
+		break;
+	case 1:		//terminal trans
+		break;
+	case 2:		//to do trans end "TransEnd"
+		break;
+	default:
+		break;
+	}
+	ctx->Ans.result = taaResult;
+
+	if (ctx->Ans.result.GetLength() == 0)
+	{
+		if (IfUseRf()) {
+			bContinue = true; //继续后面的非接流程
+		}
+		else {
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>,TermActionAnalyze result len = 0");
+			ctx->Ans.icState = 0;
+			ctx->Answer(Error_Succeed);
+		}
+		return 0;
+	}
+
+	string tmpResult, actionType, result = "", baseICData = "";
+	tmpResult = ctx->Ans.result;
+	char* pSomeICData = new char[ONE_K];
+	ZeroMemory(pSomeICData, ONE_K);
+	int lenRet = m_pCardProcess->ConstructARQCData(tmpResult.substr(6, 4).c_str(), m_pDataToARQC, pSomeICData);
+	baseICData = pSomeICData;
+	if (pSomeICData != NULL) {
+		delete[]pSomeICData;
+	}
+	char arqcLen[8];
+	ZeroMemory(arqcLen, sizeof(arqcLen));
+	_itoa(lenRet, arqcLen, 10);
+
+	ICData track2(false, 0x57, 0x00), ICCardSerial(false, 0x5f, 0x34), appExpiryDate(false, 0x5f, 0x24);
+	ErrorCodeEnum eErr = Error_Unexpect;
+	string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType("0"), t2ICExpireDate("");
+
+	char* pExpireDate = new char[12];//获取ic有效期
+	ZeroMemory(pExpireDate, 12);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, appExpiryDate, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, can't find expire date");
+		if (IfUseRf()) {
+			bContinue = true; //继续后面的非接流程
+			delete[] pExpireDate;
+			return 0;
+		}
+	}
+	else {
+		HexBuf2StrBuf(appExpiryDate.value, &pExpireDate, appExpiryDate.lenth);
+		t2ICExpireDate = pExpireDate;
+	}
+	delete[] pExpireDate;
+
+
+	char* pICCardSerial = new char[4];//获取ic序号
+	ZeroMemory(pICCardSerial, 4);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, ICCardSerial, false) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, can't find card serial.");
+	}
+	else
+	{
+		HexBuf2StrBuf(ICCardSerial.value, &pICCardSerial, ICCardSerial.lenth);
+		t2ICCardSerial = pICCardSerial;
+	}
+	delete[] pICCardSerial;
+
+
+	char* pICTrack2 = new char[128];//获取等效磁条2
+	ZeroMemory(pICTrack2, 128);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineCrossJS_Contact>, ic no track2 data");
+		l_beginTime = GetTickCountRVC();
+		eErr = m_hDevHelper->ReleaseIC();
+		l_endTime = GetTickCountRVC();
+		if (eErr != Error_Succeed) {
+			SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_ReleaseIC, "DevAdapter::ReleaseIC", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+		}
+		else {
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ReleaseIC").setCostTime(l_endTime - l_beginTime)("PreOnlineJS_Contact::ReleaseIC");
+		}
+	}
+	else
+	{
+		HexBuf2StrBuf(track2.value, &pICTrack2, track2.lenth);
+		t2ICTrack2 = pICTrack2;
+
+		int pos = FindHexCharPosition(track2.value, 0x0d, track2.lenth);
+		pICTrack2[37] = '\0';
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, ic.track2, split pos:%d", pos);
+		char* ddd = new char[40];
+		memset(ddd, 0, 40);
+		memcpy(ddd, pICTrack2, pos - 1);
+
+		char icTrack2Data[128];
+		ZeroMemory(icTrack2Data, sizeof(icTrack2Data));
+
+		Track2Data track2Data;
+		track2Data.status = 0;
+		track2Data.t2Account = "";
+		cmdDecodeMag2(pICTrack2, icTrack2Data);
+		if (SplitTrack2(icTrack2Data, track2Data) == 0)
+		{
+			t2ICAccount = track2Data.t2Account;
+		}
+		else {
+			LogWarn(Severity_Low, Error_Succeed, CardIssuer_UserErrorCode_Split_ICTrack2_Failed, CSimpleStringA::Format("<PreOnlineJS_Contact> SplitTrack2 fail,ic pTrack2.len:%d", strlen(icTrack2Data)));
+		}
+		if (_strnicmp(track2Data.t2Account, ddd, strlen(ddd)))
+		{
+			t2ICAccount = (char*)ddd;
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("count:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str());
+		}
+		delete[]ddd;
+	}
+	delete[]pICTrack2;
+
+	//80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000
+	if (m_pCardProcess->GetP1() == 0x1) {
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, actionType:%s", actionType.c_str());
+		actionType = "ARQC";
+	}
+	else
+		actionType = "";
+	//【55域】
+	//	基本域:
+	//	9F26	8b	应用密文AC
+	//	9F27	1b	密文信息数据
+	//	9F10	max.32b	发卡行应用数据IAD
+	//	9F37	4b	不可预知数
+	//	9F36	2b	应用交易计数器ATC
+	//	95	5b	终端验证结果TVR
+	//	9A	3cn	交易日期(6位有效数字,YYMMDD)
+	//	9C	1cn	交易类型(2位有效数字)
+	//	9F02	6cn	授权金额(12位有效数字)
+	//	5F2A	2cn	交易货币代码(3位有效数字)
+	//	82	2b	应用交互特征AIP
+	//	9F1A	2cn	终端国家代码(3位有效数字)
+	//	9F03	6cn	其他金额(12位有效数字)
+	//	9F33	3b	终端性能 "E0C900"
+
+	//	可选域:
+	//添加9F26,9F27,9F10,9F33的数据
+	char* pCID = new char[4];
+	ZeroMemory(pCID, 4);
+	HexBuf2StrBuf(&bt9f27, &pCID, 1);
+	char* pIssueBankLen = new char[4];
+	ZeroMemory(pIssueBankLen, 4);
+	int len9f10 = tmpResult.length() - 26 - 4;
+	int lenHigh, lenLow;
+	len9f10 = len9f10 / 2;
+	lenHigh = len9f10 / 16;
+	lenLow = len9f10 % 16;
+	BYTE bt9f10;
+	bt9f10 = (lenHigh << 4) + lenLow;
+	HexBuf2StrBuf(&bt9f10, &pIssueBankLen, 1);
+	baseICData += "9F2608" + tmpResult.substr(10, 16) + "9F2701" + pCID + "9F10" + pIssueBankLen + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "9F3303" + "E0C900";
+
+
+	//result = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6, 4) + "|" + "ARQCCODE," + tmpResult.substr(10, 16) + "|"
+	//	+ "MAC," + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "|" + "ARQCSIZE," + string(arqcLen) + "|"
+	//	+ "ARQCDATA," + m_pDataToARQC + "|EXPIREDATE," + pExpireDate + "|T2ACCOUNT," + t2ICAccount + "|T2CARDSERIAL," + t2ICCardSerial
+	//	+ "|T2CVC," + t2ICCVC + "|T2TRACK2," + t2ICTrack2 + "|CARDCAT," + cardType + "|ICTAGS," + baseICData + "|MAGT2," + (const char*)csMagT2Track
+	//	+ "|MAGT3," + (const char*)csMagT3Track + "|MAGACCOUNT," + (const char*)csMagAccout + "|MAGREGION," + (const char*)csMagRegion
+	//	+ "|MAGCARDSERIAL," + (const char*)csMagCardSerial + "|MAGCVC," + (const char*)csMagCVC + "|MAGEXPIREDATAE," + (const char*)csMagExpireDate;
+
+	//json格式返回
+	std::map<std::string, std::string> msgInfo;
+	msgInfo["ACTION"] = actionType.c_str();
+	msgInfo["ATC_CODE"] = tmpResult.substr(6, 4).c_str();
+	msgInfo["ARQC_CODE"] = tmpResult.substr(10, 16).c_str();
+	msgInfo["MAC"] = tmpResult.substr(26, tmpResult.length() - 26 - 4).c_str();
+	CSimpleStringA arqcLenStr = arqcLen;
+	msgInfo["ARQC_SIZE"] = arqcLenStr.GetData();
+	CSimpleStringA arqcData = m_pDataToARQC;
+	msgInfo["ARQC_DATA"] = arqcData.GetData();
+	msgInfo["T2TRACK2_DATA"] = t2ICTrack2.c_str();
+	msgInfo["EXPIRE_DATE"] = t2ICExpireDate.c_str();
+	msgInfo["T2CARD_SERIAL"] = t2ICCardSerial.c_str();
+	msgInfo["CARD_CAT"] = cardType.c_str();
+	msgInfo["IC_TAGS"] = baseICData.c_str();
+
+	std::pair<bool, std::string> strResult;
+	strResult = generateJsonStr(msgInfo);
+	result = strResult.second.c_str();
+
+	//DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("data to host result=%s,len=%d", result.c_str(), result.length());
+
+	string txtresult = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6, 4) + "|" + "ARQCCODE," + tmpResult.substr(10, 16) + "|"
+		+ "MAC," + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "|" + "ARQCSIZE," + string(arqcLen) + "|ARQCDATA, " + m_pDataToARQC + "|"
+		+ "T2TRACK2(len)," + CSimpleStringA::Format("%d", t2ICTrack2.length()).GetData() + "|"
+		+ "EXPIREDATE(len)," + CSimpleStringA::Format("%d", t2ICExpireDate.length()).GetData() + "|"
+		+ "T2CARDSERIAL(len), " + CSimpleStringA::Format("%d", t2ICCardSerial.length()).GetData() + "|"
+		+ "CARDCAT, " + cardType + "|"
+		+ "ICTAGS, " + CSimpleStringA::Format("%d", baseICData.length()).GetData();
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, data to host(less)[%s]", txtresult.c_str());
+
+	m_currCardNo = t2ICAccount.c_str();
+	//LogWarn(Severity_Low, Error_Unexpect, CardIssuerStore_UserErrorCode_CardBin, cardInfo.GetData());
+
+	if (pCID != NULL)
+		delete[]pCID;
+	if (pIssueBankLen != NULL)
+		delete[]pIssueBankLen;
+
+	if (m_pDataToARQC != NULL)
+	{
+		delete[]m_pDataToARQC;
+		m_pDataToARQC = NULL;
+	}
+
+	ctx->Ans.result = result.c_str();
+	ctx->Ans.icState = 1;//成功
+	bICOK = true;
+	bContinue = false;
+	ctx->Answer(Error_Succeed);
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040220306")();
+	return 0;//不再继续后面的非接流程
+}
+
+int CCardIssuerFSM::PreOnlineJS_RF(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	long l_beginTime, l_endTime;
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("(PreOnlineJS_RF) IC非接读卡");
+	l_beginTime = GetTickCountRVC();
+	ErrorCodeEnum eErr = m_hDevHelper->MoveCard(CI_MOVECARD_RF_POSITION);
+	l_endTime = GetTickCountRVC();
+	if (eErr == Error_Succeed) {
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::MoveCard").setCostTime(l_endTime - l_beginTime)("PreOnlineJS_RF::MoveCard, (CI_MOVECARD_RF_POSITION)");
+	}
+	else {
+		SetErrorAndLog(eErr, MEC_DEVAPI_CARDISSUER_MoveCard, "DevAdapter::MoveCard", __FUNCTION__, false, l_endTime - l_beginTime, "QLR040220340", "");
+	}
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("PreOnlineJS_RF, aid[%s], business data[%s]", ctx->Req.aid.GetData(), ctx->Req.businessData.GetData());
+
+	m_pCardProcess->DataInit();
+	//数据已读出,开始pmoc流程
+	m_pCardProcess->SplitBusinessData(ctx->Req.businessData, ctx->Req.businessData.GetLength());
+	m_pCardProcess->SplitBusinessData("DF690101", strlen("DF690101"));
+
+	int activeCardType;
+	//oilyang@20201014 add emv card support
+	int retDetectAndRead = -1;
+	ICData aidFromBus(false, 0x4f, 0x00);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, the front BusinessData have not provide aid data.");
+		int icRetryTimes = 0;
+		while (1)
+		{
+			l_beginTime = GetTickCountRVC();
+			retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER_RF, m_hDevHelper, m_aidList, activeCardType, m_issueStatus);
+			l_endTime = GetTickCountRVC();
+			if (retDetectAndRead == -1)//only retry for active ic card failed!
+				icRetryTimes++;
+			else
+				break;
+			Sleep(500);
+			if (icRetryTimes >= m_ICRetryTimes)
+				break;
+		}
+	}
+	else {
+		char* pAIDTmp = new char[64];
+		memset(pAIDTmp, 0, 64);
+		HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, the aid from business is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp));
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		int icRetryTimes = 0;
+		while (1)
+		{
+			l_beginTime = GetTickCountRVC();
+			retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_ISSUER_RF, m_hDevHelper, preAIDs, activeCardType, m_issueStatus);
+			l_endTime = GetTickCountRVC();
+			if (retDetectAndRead == -1)//only retry for active ic card failed!
+				icRetryTimes++;
+			else
+				break;
+			Sleep(500);
+			if (icRetryTimes >= m_ICRetryTimes)
+				break;
+		}
+		if (pAIDTmp != NULL)
+			delete[]pAIDTmp;
+	}
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, After invoke DetectAndReadICData, retDetectAndRead:%d, activeCardType:%d", retDetectAndRead, activeCardType);
+
+	if (retDetectAndRead < 0)
+	{
+		ErrorCodeEnum eErrCode = Error_Unexpect;
+		CSimpleStringA ApiName = "";
+		CSimpleStringA alarmMsg = "";
+		CSimpleStringA csErrMsgWithReturnCode = "";
+
+		if (retDetectAndRead == -1) {
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("检测卡片类型时上电失败(非接)");
+			GetCardProcessLastErr(eErrCode, ApiName, alarmMsg, csErrMsgWithReturnCode);
+
+			if (m_issueStatus) {
+				if (IsInBusiness())
+				{
+					DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220320").setResultCode("RTA2327")(csErrMsgWithReturnCode.GetData());
+					LogError(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveRF_Failed, alarmMsg.GetData());
+				}
+				else {
+					DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220320").setResultCode("RTA2327")(csErrMsgWithReturnCode.GetData());
+					LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveRF_Failed, alarmMsg.GetData());
+				}
+
+				ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveRF_Failed);
+			}
+			else {
+				if (IsInBusiness())
+				{
+					DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220303").setResultCode("RTA2326")(csErrMsgWithReturnCode.GetData());
+					LogError(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveContactlessICCard_Failed, alarmMsg.GetData());
+				}
+				else
+				{
+					DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040220303").setResultCode("RTA2326")(csErrMsgWithReturnCode.GetData());
+					LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveContactlessICCard_Failed, alarmMsg.GetData());
+				}
+
+				ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_ActiveContactlessICCard_Failed);
+			}
+		}
+		else if (retDetectAndRead == -2) {
+
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("读取IC数据失败");
+			DWORD dwTmpUserErrCode = 0;
+			if (m_issueStatus) {
+				dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220320", "");
+			}
+			else {
+				dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220303", "");
+			}
+			ctx->Answer(Error_Unexpect, dwTmpUserErrCode);
+		}
+		else if (retDetectAndRead == -3) {
+
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("IC卡建立应用列表失败");
+			DWORD dwTmpUserErrCode = 0;
+			if (m_issueStatus) {
+				dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220320", "");
+			}
+			else {
+				dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_CARDISSUER_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, IsInBusiness(), l_endTime - l_beginTime, "QLR040220303", "");
+			}
+			ctx->Answer(Error_Unexpect, dwTmpUserErrCode);
+		}
+		return 0;//上电读卡失败
+	}
+
+	m_pCardProcess->TermRiskManage();
+	CSimpleStringA taaResult;
+	BYTE bt9f27 = 0;
+	int retTAA = m_pCardProcess->TermActionAnalyze(CARD_MACHINE_ISSUER_RF, m_hDevHelper, taaResult, true, m_bCDA, bt9f27);
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, TermActionAnalyze, retTAA:%d, taaResult:%s", retTAA, taaResult.GetData());
+	switch (retTAA)
+	{//to be added oiltmp 20140929
+	case -1:	//some data may be wrong
+		break;
+	case 1:		//terminal trans
+		break;
+	case 2:		//to do trans end "TransEnd"
+		break;
+	default:
+		break;
+	}
+	ctx->Ans.result = taaResult;
+
+	if (ctx->Ans.result.GetLength() == 0)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>,TermActionAnalyze result len = 0");
+		ctx->Ans.icState = 0;
+		ctx->Answer(Error_Succeed);
+		return 0;
+	}
+
+	string tmpResult, actionType, result = "", baseICData = "";
+	tmpResult = ctx->Ans.result;
+	char* pSomeICData = new char[ONE_K];
+	ZeroMemory(pSomeICData, ONE_K);
+	int lenRet = m_pCardProcess->ConstructARQCData(tmpResult.substr(6, 4).c_str(), m_pDataToARQC, pSomeICData);
+	baseICData = pSomeICData;
+	if (pSomeICData != NULL)
+		delete[]pSomeICData;
+	char arqcLen[8];
+	ZeroMemory(arqcLen, sizeof(arqcLen));
+	_itoa(lenRet, arqcLen, 10);
+
+
+	ICData track2(false, 0x57, 0x00), ICCardSerial(false, 0x5f, 0x34), appExpiryDate(false, 0x5f, 0x24);
+	string t2ICAccount(""), t2ICCardSerial(""), t2ICCVC(""), t2ICTrack2(""), cardType("0"), t2ICExpireDate("");
+
+	char* pExpireDate = new char[12];//获取ic有效期
+	ZeroMemory(pExpireDate, 12);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, appExpiryDate, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, can't find expire date");
+	}
+	else {
+		HexBuf2StrBuf(appExpiryDate.value, &pExpireDate, appExpiryDate.lenth);
+		t2ICExpireDate = pExpireDate;
+	}
+	delete[] pExpireDate;
+
+
+	char* pICCardSerial = new char[4];//获取ic序号
+	ZeroMemory(pICCardSerial, 4);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, ICCardSerial, false) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, can't find card serial.");
+	}
+	else
+	{
+		HexBuf2StrBuf(ICCardSerial.value, &pICCardSerial, ICCardSerial.lenth);
+		t2ICCardSerial = pICCardSerial;
+	}
+	delete[] pICCardSerial;
+
+
+
+	char* pICTrack2 = new char[128];//获取等效磁条2
+	ZeroMemory(pICTrack2, 128);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_IC, track2, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, ic no track2 data");
+	}
+	else
+	{
+		HexBuf2StrBuf(track2.value, &pICTrack2, track2.lenth);
+		t2ICTrack2 = pICTrack2;
+
+		int pos = FindHexCharPosition(track2.value, 0x0d, track2.lenth);
+		pICTrack2[37] = '\0';
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(CSimpleStringA::Format("<PreOnlineJS_RF>, ic.track2, split pos:%d", pos));
+		char* ddd = new char[40];
+		memset(ddd, 0, 40);
+		memcpy(ddd, pICTrack2, pos - 1);
+
+		char icTrack2Data[128];
+		ZeroMemory(icTrack2Data, sizeof(icTrack2Data));
+
+		Track2Data track2Data;
+		track2Data.status = 0;
+		track2Data.t2Account = "";
+		cmdDecodeMag2(pICTrack2, icTrack2Data);
+		if (SplitTrack2(icTrack2Data, track2Data) == 0)
+		{
+			t2ICAccount = track2Data.t2Account;
+		}
+		else {
+			LogWarn(Severity_Low, Error_Succeed, CardIssuer_UserErrorCode_Split_ICTrack2_Failed, CSimpleStringA::Format("<PreOnlineJS_RF> SplitTrack2 fail,ic pTrack2.len:%d", strlen(icTrack2Data)));
+		}
+		if (_strnicmp(track2Data.t2Account, ddd, strlen(ddd)))
+		{
+			t2ICAccount = (char*)ddd;
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("count:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str());
+		}
+		delete[]ddd;
+	}
+	delete[]pICTrack2;
+
+	//80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000
+	if (m_pCardProcess->GetP1() == 0x1) {
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_RF>, actionType:%s", actionType.c_str());
+		actionType = "ARQC";
+	}
+	else
+		actionType = "";
+	//【55域】
+	//	基本域:
+	//	9F26	8b	应用密文AC
+	//	9F27	1b	密文信息数据
+	//	9F10	max.32b	发卡行应用数据IAD
+	//	9F37	4b	不可预知数
+	//	9F36	2b	应用交易计数器ATC
+	//	95	5b	终端验证结果TVR
+	//	9A	3cn	交易日期(6位有效数字,YYMMDD)
+	//	9C	1cn	交易类型(2位有效数字)
+	//	9F02	6cn	授权金额(12位有效数字)
+	//	5F2A	2cn	交易货币代码(3位有效数字)
+	//	82	2b	应用交互特征AIP
+	//	9F1A	2cn	终端国家代码(3位有效数字)
+	//	9F03	6cn	其他金额(12位有效数字)
+	//	9F33	3b	终端性能 "E0C900"
+
+	//	可选域:
+	//添加9F26,9F27,9F10,9F33的数据
+	char* pCID = new char[4];
+	ZeroMemory(pCID, 4);
+	HexBuf2StrBuf(&bt9f27, &pCID, 1);
+	char* pIssueBankLen = new char[4];
+	ZeroMemory(pIssueBankLen, 4);
+	int len9f10 = tmpResult.length() - 26 - 4;
+	int lenHigh, lenLow;
+	len9f10 = len9f10 / 2;
+	lenHigh = len9f10 / 16;
+	lenLow = len9f10 % 16;
+	BYTE bt9f10;
+	bt9f10 = (lenHigh << 4) + lenLow;
+	HexBuf2StrBuf(&bt9f10, &pIssueBankLen, 1);
+	baseICData += "9F2608" + tmpResult.substr(10, 16) + "9F2701" + pCID + "9F10" + pIssueBankLen + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "9F3303" + "E0C900";
+
+	//result = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6, 4) + "|" + "ARQCCODE," + tmpResult.substr(10, 16) + "|"
+	//	+ "MAC," + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "|" + "ARQCSIZE," + string(arqcLen) + "|"
+	//	+ "ARQCDATA," + m_pDataToARQC + "|EXPIREDATE," + pExpireDate + "|T2ACCOUNT," + t2ICAccount + "|T2CARDSERIAL," + t2ICCardSerial
+	//	+ "|T2CVC," + t2ICCVC + "|T2TRACK2," + t2ICTrack2 + "|CARDCAT," + cardType + "|ICTAGS," + baseICData + "|MAGT2," + (const char*)csMagT2Track
+	//	+ "|MAGT3," + (const char*)csMagT3Track + "|MAGACCOUNT," + (const char*)csMagAccout + "|MAGREGION," + (const char*)csMagRegion
+	//	+ "|MAGCARDSERIAL," + (const char*)csMagCardSerial + "|MAGCVC," + (const char*)csMagCVC + "|MAGEXPIREDATAE," + (const char*)csMagExpireDate;
+
+	//json格式返回
+	std::map<std::string, std::string> msgInfo;
+	msgInfo["ACTION"] = actionType.c_str();
+	msgInfo["ATC_CODE"] = tmpResult.substr(6, 4).c_str();
+	msgInfo["ARQC_CODE"] = tmpResult.substr(10, 16).c_str();
+	msgInfo["MAC"] = tmpResult.substr(26, tmpResult.length() - 26 - 4).c_str();
+	CSimpleStringA arqcLenStr = arqcLen;
+	msgInfo["ARQC_SIZE"] = arqcLenStr.GetData();
+	CSimpleStringA arqcData = m_pDataToARQC;
+	msgInfo["ARQC_DATA"] = arqcData.GetData();
+	msgInfo["T2TRACK2_DATA"] = t2ICTrack2.c_str();
+	msgInfo["EXPIRE_DATE"] = t2ICExpireDate.c_str();
+	msgInfo["T2CARD_SERIAL"] = t2ICCardSerial.c_str();
+	msgInfo["CARD_CAT"] = cardType.c_str();
+	msgInfo["IC_TAGS"] = baseICData.c_str();
+
+	std::pair<bool, std::string> strResult;
+	strResult = generateJsonStr(msgInfo);
+	result = strResult.second.c_str();
+
+	//DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("data to host result=%s,len=%d", result.c_str(), result.length());
+
+	string txtresult = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6, 4) + "|" + "ARQCCODE," + tmpResult.substr(10, 16) + "|"
+		+ "MAC," + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "|" + "ARQCSIZE," + string(arqcLen) + "|ARQCDATA, " + m_pDataToARQC + "|"
+		+ "T2TRACK2(len)," + CSimpleStringA::Format("%d", t2ICTrack2.length()).GetData() + "|"
+		+ "EXPIREDATE(len)," + CSimpleStringA::Format("%d", t2ICExpireDate.length()).GetData() + "|"
+		+ "T2CARDSERIAL(len), " + CSimpleStringA::Format("%d", t2ICCardSerial.length()).GetData() + "|"
+		+ "CARDCAT, " + cardType + "|"
+		+ "ICTAGS, " + CSimpleStringA::Format("%d", baseICData.length()).GetData();
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS_Contact>, data to host(less)[%s]", txtresult.c_str());
+
+	m_currCardNo = t2ICAccount.c_str();
+
+	if (pCID != NULL)
+		delete[]pCID;
+	if (pIssueBankLen != NULL)
+		delete[]pIssueBankLen;
+
+	if (m_pDataToARQC != NULL)
+	{
+		delete[]m_pDataToARQC;
+		m_pDataToARQC = NULL;
+	}
+
+	ctx->Ans.result = result.c_str();
+	ctx->Ans.icState = 1;//成功
+	ctx->Answer(Error_Succeed);
+	LogWarn(Severity_Low, Error_Succeed, CardIssuer_UserErrorCode_ReadByRF, CSimpleStringA::Format("PreOnline_RF ok.iIssue:%d ", m_issueStatus));
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040220306")();
+	return 0;
+}
+
 int CCardIssuerFSM::ReadJS(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx)
 {
 	//判断是否有卡,无卡则报错
@@ -6143,7 +6882,52 @@ int CCardIssuerFSM::ReadJS(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, Ca
 	m_bUseRFTillNext = false;//默认初始值
 	int ret = CheckCardType(t2Account, bReadMag, ICtype);
 
-	return 0;
+	if (ret == 0) {
+		if (ICtype == 3) {
+			ctx->Ans.magStatus = 0;//单IC设置磁条为空,后续进行ic上电
+		}
+
+		if (ICtype == 0) {
+			ctx->Ans.magStatus = 0;
+			ctx->Ans.icState = 0;
+			ctx->Ans.icMode = -1;
+			ctx->Ans.result = "";
+			ctx->Answer(Error_Succeed);//无磁无IC直接返回
+		}
+		else if (ICtype == 2) {
+			ctx->Ans.magStatus = 1;
+			ctx->Ans.icState = 0;
+			ctx->Ans.icMode = -1;
+			ctx->Ans.result = "";
+			ctx->Answer(Error_Succeed);//单磁条直接返回
+		}
+		else if (ICtype == 1 || ICtype == 3) {
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("to PreOnline");//联机上电
+			ctx->Ans.icState = 0;//默认值
+			ctx->Ans.icMode = -1;//默认值
+			if (m_bUseRFTillNext) {
+				ctx->Ans.icMode = 1;
+				PreOnlineJS_RF(ctx);
+			}
+			else {
+				//先接触上电,有条件进行非接上电
+				bool bCtOK = false;
+				bool bContinue = false;//是否继续非接流程
+				ctx->Ans.icMode = 0;
+				PreOnlineJS_Contact(ctx, bCtOK, bContinue);
+				if (bContinue) {
+					DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("PreOnlineJS_Contact 用非接兜底");
+					ctx->Ans.icMode = 1;
+					PreOnlineJS_RF(ctx);
+				}
+			}
+		}
+		return 0;
+	}
+	else {
+		ctx->Answer(Error_Unexpect, CardIssuer_UserErrorCode_Account_EAC_Mismatch);//账户和户口系统的最新账户不匹配
+		return 0;
+	}
 }
 
 int CCardIssuerFSM::InsertJS(SpReqAnsContext<CardIssuerStandService_InsertJS_Req, CardIssuerStandService_InsertJS_Ans>::Pointer ctx)
@@ -6207,4 +6991,37 @@ CSimpleStringA CCardIssuerFSM::MaskCardno(const char* cardno)
 	}
 
 	return maskCardno;
+}
+
+void CCardIssuerFSM::GetCardProcessLastErr(ErrorCodeEnum& eErrCode, CSimpleStringA& ApiName, CSimpleStringA& alarmMsg, CSimpleStringA& csErrMsgWithReturnCode)
+{
+	if (m_pCardProcess == NULL) {
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetCardProcessLastErr m_pCardProcess is null");
+		eErrCode = Error_Null;
+		ApiName = "";
+		alarmMsg = "";
+		csErrMsgWithReturnCode = "";
+		return;
+	}
+
+	ErrorCodeEnum lastErrCode = Error_Succeed;
+	CSimpleStringA lastErrMsg = "";
+	CSimpleStringA lastApiName = "";
+	m_pCardProcess->getCardAssistLastErr(lastErrCode, lastErrMsg, lastApiName);
+
+	const CSimpleStringA alarmMsgStr = CSimpleStringA::Format("{\"Function\":\"%s\", \"DevApi\":\"%s\", \"ReturnCode\":\"%s\", \"Msg\":\"%s\", \"Context\":\"%s\"}"
+		, __FUNCTION__, lastApiName.GetData(), SpStrError(lastErrCode), lastErrMsg.GetData(), "");
+
+	std::map<std::string, std::string> msgInfo;
+	msgInfo["ReturnCode"] = SpStrError(lastErrCode);
+	msgInfo["ErrMsg"] = lastErrMsg.GetData();
+	msgInfo["Context"] = "";
+	std::pair<bool, std::string> strResult;
+	strResult = generateJsonStr(msgInfo);
+	CSimpleStringA csErrMsgWithReturnCodeStr = strResult.second.c_str();
+
+	eErrCode = lastErrCode;
+	ApiName = lastApiName;
+	alarmMsg = alarmMsgStr.GetData();
+	csErrMsgWithReturnCode = csErrMsgWithReturnCodeStr.GetData();
 }

+ 3 - 0
Module/mod_CardIssuerStand/CardIssuerFSM.h

@@ -1117,9 +1117,12 @@ public:
 
 	int ReadMag(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx, bool& bReadCardInfo, bool& bReadMag, CSimpleStringA& t2Account);
 	int CheckCardType(CSimpleStringA cardNo, bool bReadMag, int& ICtype);
+	int PreOnlineJS_Contact(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx, bool& bICOK, bool& bContinue);
+	int PreOnlineJS_RF(SpReqAnsContext<CardIssuerStandService_ReadJS_Req, CardIssuerStandService_ReadJS_Ans>::Pointer ctx);
 
 	DWORD GetFsmStateErrCode();
 	CSimpleStringA MaskCardno(const char* cardno);
+	void GetCardProcessLastErr(ErrorCodeEnum& eErrCode, CSimpleStringA& lastApiName, CSimpleStringA& alarmMsg, CSimpleStringA& csErrMsgWithReturnCode);
 };
 struct InitTask : public ITaskSp
 {

+ 1 - 0
Module/mod_CardIssuerStand/CardIssuer_UserErrorCode.h

@@ -223,6 +223,7 @@
 #define CardIssuer_UserErrorCode_Capture_NoCard_Failed							0x20300306 //吞卡时发现读卡器无卡
 #define CardIssuer_UserErrorCode_Forget_Fetch_Card_Capture_Succ					0x20300307 //超时未取卡,已吞卡,请从吞卡箱中取卡
 #define CardIssuer_UserErrorCode_Forget_Fetch_Card_Capture_Fail					0x20300308 //超时未取卡,吞卡失败,请从发卡器取卡
+#define CardIssuer_UserErrorCode_Split_ICTrack2_Failed							0x20300309 //IC磁道2解析失败
 
 
 //卡机流程状态报错