فهرست منبع

!10686 非接js接口项目归并到st2
Merge pull request !10686 from 80174520/feature_T25CV091_js

杨诗友80174847 6 ماه پیش
والد
کامیت
7fa931269d

+ 15 - 4
DevAdapter/include/CardAssist.cpp

@@ -458,10 +458,10 @@ bool CCardProcess::DetectIfICCard(CardReadType eType, DeviceBaseClass *pCardX, i
 			return false;
 		}
 		else {
-			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard");
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard,Detect contactless card type %d", ch);
 		}
 		cardType = ch;
-		DbgInfo(CSimpleStringA::Format("Detect contactless card type %d",ch));
+		
 	}
 	else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF)
 	{
@@ -487,10 +487,10 @@ bool CCardProcess::DetectIfICCard(CardReadType eType, DeviceBaseClass *pCardX, i
 			return false; 
 		}
 		else {
-			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard");
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard,(CardIssuer)Detect contactless card type %d", ch);
 		}
 		cardType = ch;
-		DbgInfo(CSimpleStringA::Format("(CardIssuer)Detect contactless card type %d", ch));
+		
 	}
 	return true;
 }
@@ -2690,6 +2690,17 @@ int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass *pCard
 		DbgWarn("<DetectIfICCard>, not ic card.");
 		return -1;
 	}
+	else {
+		//兼容发卡非接上电有的厂商非IC卡也返回成功,直接返回上电失败
+		if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) {
+			if ( bIssue && cardType != 'A' && cardType != 'B' && cardType != 'M') {
+				CSimpleStringA errMsg = CSimpleStringA::Format("{\"ErrCode\":2147483646,\"Description\":\"<DetectIfICCard>, not ic card,cardType=%d\"}", cardType);
+				setCardAssistLastErr(Error_Exception, errMsg.GetData(), "DevAdapter::ActiveContactlessICCard");
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<DetectIfICCard>, not ic card.");
+				return -1;
+			}
+		}
+	}
 	int bGetICData = -3;
 
 	bGetICData = GetICDataFromCard(eType,pCardX,pAIDs);

+ 95 - 11
Module/mod_ContactlessCard/ContactlessCard.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="gb2312" ?>
 <entity name="ContactlessCard">
 	<class name="ContactlessCardService" overlap="true" exclusive="false">
-		<twoway name="Insert" overlap="true">
+		<twoway name="Insert" overlap="true" method_id="0">
 			<req>
 				<param name="aid" type="string"/>
 				<param name="order" type="string"/>
@@ -27,11 +27,11 @@
 				<param name="reserved4" type="string"/>
 			</res>		
 		</twoway>
-		<oneway name="CancelInsert" overlap="true">			
+		<oneway name="CancelInsert" overlap="true" method_id="1">			
 		</oneway>
-		<oneway name="InsertWaitMore" overlap="true">			
+		<oneway name="InsertWaitMore" overlap="true" method_id="2">			
 		</oneway>								
-		<twoway name="PreOnline" overlap="true">
+		<twoway name="PreOnline" overlap="true" method_id="3">
 			<req>
 				<param name="businessData" type="string"/>
 				<param name="reserved1" type="string"/>
@@ -41,7 +41,7 @@
 				<param name="result" type="string"/>
 			</res>			
 		</twoway>
-		<twoway name="PostOnline" overlap="true">
+		<twoway name="PostOnline" overlap="true" method_id="4">
 			<req>
 				<param name="data" type="string"/>
 			</req>
@@ -49,15 +49,15 @@
 				<param name="result" type="string"/>
 			</res>			
 		</twoway>
-		<twoway name="Eject" overlap="true">
+		<twoway name="Eject" overlap="true" method_id="5">
 			<req>
 			</req>
 			<res>
 			</res>			
 		</twoway>
-		<oneway name="Exit" overlap="true">			
+		<oneway name="Exit" overlap="true" method_id="6">			
 		</oneway>
-		<twoway name="QueryCardInfo" overlap="true">
+		<twoway name="QueryCardInfo" overlap="true" method_id="7">
 			<req>
 			</req>
 			<res>
@@ -65,17 +65,101 @@
 				<param name="reserved1" type="int"/>
 				<param name="reserved2" type="string"/>
 			</res>			
-		</twoway>										
-		<twoway name="GetDevInfo" overlap="true" method_id="65535">
+		</twoway>	
+		<!--查询卡机设备状态接口 -->
+		<!--1、非接打开失败, errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2J10-->
+		<!--2、非接正在打开中, errorCode为Error_NotInit(769),rtaCode为RTA2J10-->
+		<twoway name="GetDevInfo" overlap="true" method_id="65535" jsflag="true">
 			<req>
 			</req>
 			<res>
 				<param name="type" type="string" />
 				<param name="model" type="string" />
 				<param name="version" type="string" />
+				<!--卡机状态 0设备未打开 1 正常运行 3卡机异常不可工作-->
 				<param name="state" type="int" />
 			</res>			
-		</twoway>							
+		</twoway>	
+		
+		<!--非接读卡接口 -->
+		<!--1、非接打开失败, errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2J10-->
+		<!--2、非接处寻卡超时, errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J12-->
+		<!--3、卡检测失败,非IC卡 errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J13-->
+		<!--4、读卡失败,激活非接失败, errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J01-->
+		<!--5、读卡失败,读IC数据失败 errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J02-->
+		<!--6、读卡取消, errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J14-->
+		<twoway name="ReadJS" overlap="true" method_id="40" jsflag="true">
+			<req>
+				<!--Aid列表-->
+				<param name="aid" type="string"/>
+				<!--业务数据-->
+				<param name="businessData" type="string"/>
+				<param name="reserved1" type="int"/>
+				<param name="reserved2" type="string"/>
+			</req>
+			<res>
+				<!--读IC结果 0失败 1成功-->
+				<param name="icState" type="int"/>
+				<!--IC读取的数据<json格式>
+					ACTION:行为代码
+					ATC_CODE:交易计数器code
+					ARQC_CODE:授权请求code
+					MAC:安全报文鉴别码
+					ARQC_SIZE:授权请求长度
+					ARQC_DATA:授权请求数据
+					T2TRACK2_DATA:磁道2数据
+					EXPIRE_DATE:卡片失效日期
+					T2CARD_SERIAL:卡序号
+					CARD_CAT:卡类型
+					IC_TAGS:基础IC数据
+				-->
+				<param name="result" type="string"/>
+				<param name="reserved1" type="array_int"/>
+				<param name="reserved2" type="array_string"/>
+			</res>
+		</twoway>
+			
+		<!--联机后处理接口-->
+		<!--1、非接打开失败, errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J10-->
+		<twoway name="PostOnlineJS" overlap="true" method_id="41" jsflag="true">
+			<req>
+				<!--联机后处理数据-->
+				<param name="data" type="string"/>
+			</req>
+			<res>
+				<!--处理结果-->
+				<param name="result" type="string"/>
+			</res>			
+		</twoway>
+		
+		<!--吐卡接口-->
+		<!--1、非接打开失败, errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2J10-->
+		<!--2、超时未取卡 errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J16-->
+		<twoway name="EjectJS" overlap="true" method_id="42" jsflag="true">
+			<req>
+			</req>
+			<res>
+			</res>			
+		</twoway>
+
+		<!--查询非接卡片位置接口-->
+		<!--1、非接打开失败, errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2J10-->
+		<!--2、查询设备状态失败, errorCode为Error_Unexpect(2147483646),rtaCode为RTA2J04-->
+		<twoway name="QueryHasCardJS" overlap="true" method_id="43" jsflag="true">
+			<req>
+			</req>
+			<res>
+				<!--卡片位置情况 0:没有发现卡片 6:非接处有非接卡片 7:非接处有身份证-->
+				<param name="position" type="int"/>
+				<param name="reserved1" type="int"/>
+				<param name="reserved2" type="string"/>
+			</res>			
+		</twoway>
+		
+		<!--取消插卡接口-->
+		<oneway name="CancelReadJS" overlap="true" method_id="44" jsflag="true">			
+		</oneway>
+		
 	</class>
 	<message name="FetchCard">
 			<param name="status" type="int"/>

+ 16 - 0
Module/mod_ContactlessCard/ContactlessCard_UserErrorCode.h

@@ -28,9 +28,25 @@
 
 #define ContactlessCard_UserErrorCode_DevOpen_Success						(ContactlessCard_UserErrorCode_Start + 31)	//设备打开成功
 #define ContactlessCard_UserErrorCode_DevOpen_Failed						(ContactlessCard_UserErrorCode_Start + 32)	//设备打开失败
+#define ContactlessCard_UserErrorCode_Read_TimeOut							(ContactlessCard_UserErrorCode_Start + 33)	//读卡寻卡超时
+#define ContactlessCard_UserErrorCode_Read_Not_IC							(ContactlessCard_UserErrorCode_Start + 34)	//读卡检测,非IC卡
+#define ContactlessCard_UserErrorCode_Read_Cancel							(ContactlessCard_UserErrorCode_Start + 35)	//读卡取消
+#define ContactlessCard_UserErrorCode_Forget_Fectch_Card					(ContactlessCard_UserErrorCode_Start + 36)	//吐卡超时未取卡
 
 //实际root配置
 //#define ContactlessCard_UserErrorCode_Real_Root_Config						(ContactlessCard_UserErrorCode_Start + 36)	//实际root配置
 #define ContactlessCard_UserErrorCode_ReadAccount							(ContactlessCard_UserErrorCode_Start + 37)	//读到卡片信息
 
+#define ContactlessCard_UserErrorCode_EntityInStateCannotProcess			(CardIssuerStore_UserErrorCode_Start + 38) //卡机当前状态无法处理此请求
+
+//非接流程状态报错
+#define ContactlessCard_UserErrorCode_PROCESS_IDLE					0x21300402		//当前处于卡机无卡空闲状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_HOLD					0x21300404		//当前处于卡机有卡等待状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_READ					0x21300405		//当前处于正在读卡状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_EJECT					0x21300406		//当前处于正在吐卡状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_WAIT_FETCH			0x21300407		//当前处于正在取卡状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_CAPTURE				0x21300408		//当前处于正在吞卡状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_FAULT					0x21300409		//当前处于卡机故障异常状态,无法处理此请求
+#define ContactlessCard_UserErrorCode_PROCESS_READ_JS				0x2130040A		//当前处于正在读卡状态,无法处理此请求,请稍后再试
+#define ContactlessCard_UserErrorCode_PROCESS_EJECT_JS				0x2130040B		//当前处于正在取卡状态,无法处理此请求,请稍后再试
 #endif //_CONTACTLESSCARD_USER_ERRORCODE_H

+ 210 - 0
Module/mod_ContactlessCard/ContactlessCard_client_g.h

@@ -394,6 +394,216 @@ public:
 		return Error;
 	}
 
+	ErrorCodeEnum ReadJS(ContactlessCardService_ReadJS_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		if (m_context.checkEmpty())
+		{
+			m_context.AutoGenerate();
+			DbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : "")();
+			m_context = m_context.upgradeLink();
+		}
+		auto ret = pFunc->AsyncRequest(ContactlessCardService_Method_ReadJS, ContactlessCardService_MethodSignature_ReadJS, Buf, spAsyncWait, m_context, dwTimeout);
+		m_context.clear();
+		return ret;
+	}
+	ErrorCodeEnum ReadJS(ContactlessCardService_ReadJS_Req &Req, ContactlessCardService_ReadJS_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = ReadJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum ReadJS(ContactlessCardService_ReadJS_Req &Req, ContactlessCardService_ReadJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError, CSimpleString &str)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = ReadJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum ReadJS(ContactlessCardService_ReadJS_Req &Req, ContactlessCardService_ReadJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = ReadJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			CSimpleString str;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum PostOnlineJS(ContactlessCardService_PostOnlineJS_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		if (m_context.checkEmpty())
+		{
+			m_context.AutoGenerate();
+			DbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : "")();
+			m_context = m_context.upgradeLink();
+		}
+		auto ret = pFunc->AsyncRequest(ContactlessCardService_Method_PostOnlineJS, ContactlessCardService_MethodSignature_PostOnlineJS, Buf, spAsyncWait, m_context, dwTimeout);
+		m_context.clear();
+		return ret;
+	}
+	ErrorCodeEnum PostOnlineJS(ContactlessCardService_PostOnlineJS_Req &Req, ContactlessCardService_PostOnlineJS_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = PostOnlineJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum PostOnlineJS(ContactlessCardService_PostOnlineJS_Req &Req, ContactlessCardService_PostOnlineJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError, CSimpleString &str)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = PostOnlineJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum PostOnlineJS(ContactlessCardService_PostOnlineJS_Req &Req, ContactlessCardService_PostOnlineJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = PostOnlineJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			CSimpleString str;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum EjectJS(ContactlessCardService_EjectJS_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		if (m_context.checkEmpty())
+		{
+			m_context.AutoGenerate();
+			DbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : "")();
+			m_context = m_context.upgradeLink();
+		}
+		auto ret = pFunc->AsyncRequest(ContactlessCardService_Method_EjectJS, ContactlessCardService_MethodSignature_EjectJS, Buf, spAsyncWait, m_context, dwTimeout);
+		m_context.clear();
+		return ret;
+	}
+	ErrorCodeEnum EjectJS(ContactlessCardService_EjectJS_Req &Req, ContactlessCardService_EjectJS_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EjectJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum EjectJS(ContactlessCardService_EjectJS_Req &Req, ContactlessCardService_EjectJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError, CSimpleString &str)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EjectJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum EjectJS(ContactlessCardService_EjectJS_Req &Req, ContactlessCardService_EjectJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EjectJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			CSimpleString str;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum QueryHasCardJS(ContactlessCardService_QueryHasCardJS_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		if (m_context.checkEmpty())
+		{
+			m_context.AutoGenerate();
+			DbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : "")();
+			m_context = m_context.upgradeLink();
+		}
+		auto ret = pFunc->AsyncRequest(ContactlessCardService_Method_QueryHasCardJS, ContactlessCardService_MethodSignature_QueryHasCardJS, Buf, spAsyncWait, m_context, dwTimeout);
+		m_context.clear();
+		return ret;
+	}
+	ErrorCodeEnum QueryHasCardJS(ContactlessCardService_QueryHasCardJS_Req &Req, ContactlessCardService_QueryHasCardJS_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = QueryHasCardJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum QueryHasCardJS(ContactlessCardService_QueryHasCardJS_Req &Req, ContactlessCardService_QueryHasCardJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError, CSimpleString &str)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = QueryHasCardJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum QueryHasCardJS(ContactlessCardService_QueryHasCardJS_Req &Req, ContactlessCardService_QueryHasCardJS_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = QueryHasCardJS(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			CSimpleString str;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum CancelReadJS()
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		if (m_context.checkEmpty())
+		{
+			m_context.AutoGenerate();
+			DbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : "")();
+			m_context = m_context.upgradeLink();
+		}
+		auto ret = pFunc->OnewayCall(ContactlessCardService_Method_CancelReadJS, ContactlessCardService_MethodSignature_CancelReadJS, m_context);
+		m_context.clear();
+		return ret;
+	}
+
 
 	bool SafeDelete()
 	{

+ 114 - 0
Module/mod_ContactlessCard/ContactlessCard_def_g.h

@@ -21,6 +21,11 @@ namespace ContactlessCard {
 #define ContactlessCardService_Method_Exit 6
 #define ContactlessCardService_Method_QueryCardInfo 7
 #define ContactlessCardService_Method_GetDevInfo 65535
+#define ContactlessCardService_Method_ReadJS 40
+#define ContactlessCardService_Method_PostOnlineJS 41
+#define ContactlessCardService_Method_EjectJS 42
+#define ContactlessCardService_Method_QueryHasCardJS 43
+#define ContactlessCardService_Method_CancelReadJS 44
 
 #define ContactlessCardService_MethodSignature_Insert -1860890966
 #define ContactlessCardService_MethodSignature_CancelInsert -1202478828
@@ -31,6 +36,11 @@ namespace ContactlessCard {
 #define ContactlessCardService_MethodSignature_Exit -1158854104
 #define ContactlessCardService_MethodSignature_QueryCardInfo 154962579
 #define ContactlessCardService_MethodSignature_GetDevInfo 296205965
+#define ContactlessCardService_MethodSignature_ReadJS -1004160201
+#define ContactlessCardService_MethodSignature_PostOnlineJS -92324905
+#define ContactlessCardService_MethodSignature_EjectJS -687956608
+#define ContactlessCardService_MethodSignature_QueryHasCardJS -2034090823
+#define ContactlessCardService_MethodSignature_CancelReadJS -1728083983
 
 #define ContactlessCardService_LogCode_Insert "QLR040221300"
 #define ContactlessCardService_LogCode_CancelInsert "QLR040221301"
@@ -41,6 +51,11 @@ namespace ContactlessCard {
 #define ContactlessCardService_LogCode_Exit "QLR040221306"
 #define ContactlessCardService_LogCode_QueryCardInfo "QLR040221307"
 #define ContactlessCardService_LogCode_GetDevInfo "QLR040221399"
+#define ContactlessCardService_LogCode_ReadJS "QLR040221340"
+#define ContactlessCardService_LogCode_PostOnlineJS "QLR040221341"
+#define ContactlessCardService_LogCode_EjectJS "QLR040221342"
+#define ContactlessCardService_LogCode_QueryHasCardJS "QLR040221343"
+#define ContactlessCardService_LogCode_CancelReadJS "QLR040221344"
 
 struct ContactlessCardService_Insert_Req
 {
@@ -218,6 +233,105 @@ struct ContactlessCardService_GetDevInfo_Ans
 
 };
 
+struct ContactlessCardService_ReadJS_Req
+{
+	CSimpleStringA aid;
+	CSimpleStringA businessData;
+	int reserved1;
+	CSimpleStringA reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & aid & businessData & reserved1 & reserved2;
+	}
+
+};
+
+struct ContactlessCardService_ReadJS_Ans
+{
+	int icState;
+	CSimpleStringA result;
+	CAutoArray<int> reserved1;
+	CAutoArray<CSimpleStringA> reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & icState & result & reserved1 & reserved2;
+	}
+
+};
+
+struct ContactlessCardService_PostOnlineJS_Req
+{
+	CSimpleStringA data;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & data;
+	}
+
+};
+
+struct ContactlessCardService_PostOnlineJS_Ans
+{
+	CSimpleStringA result;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result;
+	}
+
+};
+
+struct ContactlessCardService_EjectJS_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct ContactlessCardService_EjectJS_Ans
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct ContactlessCardService_QueryHasCardJS_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct ContactlessCardService_QueryHasCardJS_Ans
+{
+	int position;
+	int reserved1;
+	CSimpleStringA reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & position & reserved1 & reserved2;
+	}
+
+};
+
+struct ContactlessCardService_CancelReadJS_Info
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
 
 ///////////////////////////
 

+ 135 - 0
Module/mod_ContactlessCard/ContactlessCard_server_g.h

@@ -93,6 +93,41 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case ContactlessCardService_Method_ReadJS:
+			if (dwSignature == ContactlessCardService_MethodSignature_ReadJS) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_PostOnlineJS:
+			if (dwSignature == ContactlessCardService_MethodSignature_PostOnlineJS) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_EjectJS:
+			if (dwSignature == ContactlessCardService_MethodSignature_EjectJS) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_QueryHasCardJS:
+			if (dwSignature == ContactlessCardService_MethodSignature_QueryHasCardJS) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_CancelReadJS:
+			if (dwSignature == ContactlessCardService_MethodSignature_CancelReadJS) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -149,6 +184,31 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case ContactlessCardService_Method_ReadJS:
+			if (dwSignature != ContactlessCardService_MethodSignature_ReadJS) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_PostOnlineJS:
+			if (dwSignature != ContactlessCardService_MethodSignature_PostOnlineJS) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_EjectJS:
+			if (dwSignature != ContactlessCardService_MethodSignature_EjectJS) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_QueryHasCardJS:
+			if (dwSignature != ContactlessCardService_MethodSignature_QueryHasCardJS) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case ContactlessCardService_Method_CancelReadJS:
+			if (dwSignature != ContactlessCardService_MethodSignature_CancelReadJS) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -201,6 +261,31 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_CancelReadJS(SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void OnRequest(CSmartPointer<ITransactionContext> pTransactionContext)
 	{
 		CAutoBuffer Buf;
@@ -307,6 +392,56 @@ public:
 						Handle_GetDevInfo(ctx);
 					}
 					break;
+				case ContactlessCardService_Method_ReadJS:
+					{
+						SpReqAnsContext<ContactlessCardService_ReadJS_Req,ContactlessCardService_ReadJS_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ContactlessCardService_ReadJS_Req,ContactlessCardService_ReadJS_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_ReadJS(ctx);
+					}
+					break;
+				case ContactlessCardService_Method_PostOnlineJS:
+					{
+						SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req,ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req,ContactlessCardService_PostOnlineJS_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_PostOnlineJS(ctx);
+					}
+					break;
+				case ContactlessCardService_Method_EjectJS:
+					{
+						SpReqAnsContext<ContactlessCardService_EjectJS_Req,ContactlessCardService_EjectJS_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ContactlessCardService_EjectJS_Req,ContactlessCardService_EjectJS_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_EjectJS(ctx);
+					}
+					break;
+				case ContactlessCardService_Method_QueryHasCardJS:
+					{
+						SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req,ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req,ContactlessCardService_QueryHasCardJS_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_QueryHasCardJS(ctx);
+					}
+					break;
+				case ContactlessCardService_Method_CancelReadJS:
+					{
+						SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>::Pointer ctx;
+						ctx.Attach(new SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>());
+						SpBuffer2Object(Buf, ctx->Info);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_CancelReadJS(ctx);
+					}
+					break;
 				default:
 					assert(0);
 					break;

+ 684 - 0
Module/mod_ContactlessCard/ContactlessFSM.cpp

@@ -29,6 +29,7 @@ class CContactlessCardEntity;
 void CContactlessCardFSM::s0_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 0;
 	SetDevState(DEVICE_STATUS_NOT_READY);
 	FSMEvent *e = new FSMEvent(USER_EVT_INIT);
 	PostEventFIFO(e);
@@ -57,6 +58,7 @@ unsigned int CContactlessCardFSM::s0_on_event(FSMEvent* e)
 void CContactlessCardFSM::s1_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 1;
 }
 void CContactlessCardFSM::s1_on_exit()
 {
@@ -83,6 +85,7 @@ unsigned int CContactlessCardFSM::s1_on_event(FSMEvent* event)
 void CContactlessCardFSM::s2_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 2;
 	SetDevState(DEVICE_STATUS_NORMAL);
 	m_resetTimes = 0;
 	m_testResult = Error_Succeed;
@@ -97,6 +100,44 @@ unsigned int CContactlessCardFSM::s2_on_event(FSMEvent* pEvt)
 	int ret = 0;
 	switch(pEvt->iEvt)
 	{
+	case USER_EVT_JS_READ:
+		{
+			ReadJSEvent* rje = dynamic_cast<ReadJSEvent*>(pEvt);
+			m_bCancelRead = false;
+			m_bPageExit = false;
+			ReadJSTask* task = new ReadJSTask(this);
+			task->ctx = rje->ctx;
+			GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
+			pEvt->SetHandled();
+		}
+		break;
+	case USER_EVT_JS_EJECT:
+		{
+			EjectJSEvent* eje = dynamic_cast<EjectJSEvent*>(pEvt);
+			m_bPageExit = false;
+			EjectJSTask* task = new EjectJSTask(this);
+			task->ctx = eje->ctx;
+			GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
+			pEvt->SetHandled();
+		}
+		break;
+	case USER_EVT_JS_POSTONLINE:
+		{
+			PostOnlineJSEvent* pje = dynamic_cast<PostOnlineJSEvent*>(pEvt);
+			m_bCancelRead = false;
+			m_bPageExit = false;
+			PostOnlineJSTask* task = new PostOnlineJSTask(this);
+			task->ctx = pje->ctx;
+			GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
+			pEvt->SetHandled();
+		}
+		break;
+	case USER_EVT_JS_READ_CANCEL:
+		{
+			m_bCancelRead = true;
+			pEvt->SetHandled();
+		}
+		break;
 	case USER_EVT_ACCEPT:
 		{
 			CardAcceptEvent *cae = dynamic_cast<CardAcceptEvent*>(pEvt);
@@ -146,6 +187,7 @@ unsigned int CContactlessCardFSM::s2_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s3_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 3;
 }
 void CContactlessCardFSM::s3_on_exit()
 {
@@ -205,6 +247,7 @@ unsigned int CContactlessCardFSM::s3_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s4_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 4;
 }
 void CContactlessCardFSM::s4_on_exit()
 {
@@ -292,6 +335,7 @@ unsigned int CContactlessCardFSM::s4_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s5_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 5;
 }
 void CContactlessCardFSM::s5_on_exit()
 {
@@ -326,6 +370,7 @@ unsigned int CContactlessCardFSM::s5_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s6_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 6;
 }
 void CContactlessCardFSM::s6_on_exit()
 {
@@ -353,6 +398,7 @@ unsigned int CContactlessCardFSM::s6_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s7_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 7;
 	WaitFetchingTask* task = new WaitFetchingTask(this);
 	GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
 }
@@ -413,6 +459,7 @@ unsigned int CContactlessCardFSM::s7_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s8_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 8;
 }
 void CContactlessCardFSM::s8_on_exit()
 {
@@ -437,6 +484,7 @@ unsigned int CContactlessCardFSM::s8_on_event(FSMEvent* pEvt)
 void CContactlessCardFSM::s9_on_entry()
 {
 	LOG_FUNCTION();
+	m_currentFSMState = 9;
 	SetDevState(DEVICE_STATUS_FAULT);
 	FSMEvent *e = new FSMEvent(USER_EVT_RESET);
 	PostEventFIFO(e);
@@ -496,6 +544,91 @@ unsigned int CContactlessCardFSM::s9_on_event(FSMEvent* pEvt)
 	return 0;
 }
 
+void CContactlessCardFSM::s10_on_entry()
+{
+	LOG_FUNCTION();
+	m_currentFSMState = 10;
+}
+
+void CContactlessCardFSM::s10_on_exit()
+{
+	LOG_FUNCTION();
+}
+
+unsigned int CContactlessCardFSM::s10_on_event(FSMEvent* pEvt)
+{
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s10 event(%d)", pEvt->iEvt);
+	int ret = 0;
+	switch (pEvt->iEvt)
+	{
+	case USER_EVT_JS_READ_FINISHED:
+		{
+			pEvt->SetHandled();
+			ret = 0;
+		}
+	break;
+	case USER_EVT_JS_POSTONLINEFINISHED:
+		{
+			pEvt->SetHandled();
+			ret = 0;
+		}
+	break;
+	case USER_EVT_JS_READ_CANCEL:
+		{
+			m_bCancelRead = true;
+			pEvt->SetHandled();
+			ret = 0;
+		}
+	break;
+	case USER_EVT_EXIT_MIAN_PAGE:
+		{
+			m_bPageExit = true;
+			pEvt->SetHandled();
+			ret = 0;
+		}
+	break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+void CContactlessCardFSM::s11_on_entry()
+{
+	LOG_FUNCTION();
+	m_currentFSMState = 11;
+}
+
+void CContactlessCardFSM::s11_on_exit()
+{
+	LOG_FUNCTION();
+}
+
+unsigned int CContactlessCardFSM::s11_on_event(FSMEvent* pEvt)
+{
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("s11 event(%d)", pEvt->iEvt);
+	int ret = 0;
+	switch (pEvt->iEvt)
+	{
+	case USER_EVT_JS_EJECTFINISHED:
+		{
+			pEvt->SetHandled();
+			ret = pEvt->param1;
+		}
+	break;
+	case USER_EVT_EXIT_MIAN_PAGE:
+	{
+		m_bPageExit = true;
+		pEvt->SetHandled();
+		ret = 0;
+	}
+	break;
+	default:
+		break;
+	}
+	return ret;
+}
+
 ErrorCodeEnum CContactlessCardFSM::OnInit()
 {
 	LOG_FUNCTION();
@@ -1510,3 +1643,554 @@ void CContactlessCardFSM::GetCardProcessLastErr(ErrorCodeEnum& eErrCode, CSimple
 	alarmMsg = alarmMsgStr.GetData();
 	csErrMsgWithReturnCode = csErrMsgWithReturnCodeStr.GetData();
 }
+
+DWORD CContactlessCardFSM::GetFsmStateErrCode()
+{
+	int state = GetFSMState();
+	switch (state)
+	{
+	case 2:
+		return ContactlessCard_UserErrorCode_PROCESS_IDLE;
+	case 4:
+		return ContactlessCard_UserErrorCode_PROCESS_HOLD;
+	case 5:
+		return ContactlessCard_UserErrorCode_PROCESS_READ;
+	case 6:
+		return ContactlessCard_UserErrorCode_PROCESS_EJECT;
+	case 7:
+		return ContactlessCard_UserErrorCode_PROCESS_WAIT_FETCH;
+	case 8:
+		return ContactlessCard_UserErrorCode_PROCESS_CAPTURE;
+	case 9:
+		return ContactlessCard_UserErrorCode_PROCESS_FAULT;
+	case 10:
+		return ContactlessCard_UserErrorCode_PROCESS_READ_JS;
+	case 11:
+		return ContactlessCard_UserErrorCode_PROCESS_EJECT_JS;
+	default:
+		return ContactlessCard_UserErrorCode_EntityInStateCannotProcess;
+	}
+}
+
+void CContactlessCardFSM::QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	int ret = 0;
+	if (m_hDevHelper == nullptr) {
+		ctx->Answer(Error_Unexpect, ContactlessCard_UserErrorCode_DevOpen_Failed);
+	}
+	else {
+		RFICReaderStatus devStatus;
+		long l_beginTime, l_endTime;
+		l_beginTime = SP::Module::Comm::RVCGetTickCount();
+		ErrorCodeEnum eErr = m_hDevHelper->GetDevStatus(devStatus);
+		l_endTime = SP::Module::Comm::RVCGetTickCount();
+
+		if (Error_Succeed == eErr)
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetDevStatus").setCostTime(l_endTime - l_beginTime)("QueryInternalHasCardJS::GetDevStatus, eMedia pos:%d", devStatus.eMediaPos);
+
+			//switch (devStatus.eMediaPos)
+			//{
+			//case CI_MEDIA_RF:
+			//	ret = 6;
+			//	break;
+			//case CI_MEDIA_NOTPRESENT:
+			//	ret = 0;
+			//	break;
+			//case CI_MEDIA_IDCARD:
+			//	ret = 7;
+			//	break;
+			//default:
+			//	ret = 0;
+			//	break;
+			//}
+
+			ctx->Ans.position = (int)devStatus.eMediaPos;
+			ctx->Answer(Error_Succeed);
+		}
+		else
+		{
+			DWORD dwTmpUserErrCode = SetErrorAndLog(eErr, MEC_DEVAPI_RF_GetDevStatus, "DevAdapter::GetDevStatus", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+			ctx->Answer(Error_Unexpect, dwTmpUserErrCode);
+		}
+
+	}
+}
+
+int CContactlessCardFSM::EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("吐卡开始");
+	m_pCardProcess->DataInit();
+	int ret = 0;
+	int getDevInfoCount = 0;
+	DWORD dwStart = SP::Module::Comm::RVCGetTickCount();
+	DWORD dwEnd = dwStart;
+	LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_ON, "ContactCard(fetch) warning on");
+	while (true)
+	{
+
+		dwEnd = SP::Module::Comm::RVCGetTickCount();
+		if ((dwEnd - dwStart) > 58 * 1000)
+		{
+			ret = 1;//超时
+			break;
+		}
+
+		if (m_bPageExit) {
+			ret = 2;
+			break;//退到首页
+		}
+
+		ErrorCodeEnum eErr = m_hDevHelper->GetDevStatus(devStatus);
+		if (eErr == Error_Succeed)
+		{
+			if (devStatus.eMediaPos == CI_MEDIA_RF || devStatus.eMediaPos == CI_MEDIA_NOTPRESENT)
+			{
+				if (devStatus.eMediaPos == CI_MEDIA_NOTPRESENT){
+					DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("EjectCard, devStatus.eMedia %d", devStatus.eMediaPos);
+					ret = 0;//取走
+					break;
+				}
+				else if (devStatus.eMediaPos == CI_MEDIA_RF) {
+				}
+			}
+		}
+		else {
+			getDevInfoCount++;
+			if (getDevInfoCount % 10 == 0) {
+				DevErrorInfo devErrInfo;
+				m_hDevHelper->GetLastErr(devErrInfo);
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetDevStatus, errMsg:%s", devErrInfo.szErrMsg);
+			}
+		}
+		Sleep(WAIT_INTERVAL);
+	}
+	LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_OFF, "ContactCard(fetch) warning off");
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("eject return.ret=%d",ret);
+	if (ctx != NULL) {
+		if (ret == 0) {
+			ctx->Answer(Error_Succeed);
+		}
+		else if(ret == 1 || ret == 2){
+			ctx->Answer(Error_Exception, ContactlessCard_UserErrorCode_Forget_Fectch_Card);
+		}
+	}
+	return ret;
+}
+
+int CContactlessCardFSM::ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("读卡开始");
+	int ret = InternalAcceptCardJS();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InternalAcceptCardJS ret:%d", ret);
+
+	if (ret == 0) {
+		//寻卡成功,开始联机读卡
+		ret = PreOnlineJS(ctx);
+	}
+	else if (ret == 1) {
+		//非IC卡
+		ctx->Answer(Error_Exception, ContactlessCard_UserErrorCode_Read_Not_IC);
+	}
+	else if (ret == 2) {
+		//寻卡超时
+		ctx->Answer(Error_Exception, ContactlessCard_UserErrorCode_Read_TimeOut);
+	}
+	else if (ret == 3 || ret == 4){
+		//读卡取消
+		ctx->Answer(Error_Exception, ContactlessCard_UserErrorCode_Read_Cancel);
+	}
+	return 0;
+}
+
+int CContactlessCardFSM::PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("(PostOnlineJS) 联机后IC接触处理");
+	m_pCardProcess->DataInit();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("postOnLine data[%s]", ctx->Req.data.GetData());
+	m_pCardProcess->SplitOnlineReplyData(ctx->Req.data, strlen(ctx->Req.data));
+	int issBnkAuth = m_pCardProcess->IssueBankAuth(CARD_MACHINE_RFIC, m_hDevHelper);
+	CSimpleStringA csTransEnd;
+	if (issBnkAuth == 0)
+	{
+		int transEnd = m_pCardProcess->TransEnd(CARD_MACHINE_RFIC, m_hDevHelper, m_bCDA);
+		if (transEnd == 0) {
+			csTransEnd = "TRANSEND,0";
+		}
+		else if (transEnd == 1) {
+			csTransEnd = "TRANSEND,1";
+		}
+	}
+	else {
+		csTransEnd = "TRANSEND,1";
+	}
+	ctx->Ans.result = csTransEnd;
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PostOnlineJS>, issBnkAuth:%d, csTransEnd:%s", issBnkAuth, csTransEnd.GetData());
+	ctx->Answer(Error_Succeed);
+	return 0;
+}
+
+int CContactlessCardFSM::InternalAcceptCardJS()
+{
+	LOG_FUNCTION();
+	int err = 0;
+	long l_beginTime, l_endTime;
+	DWORD64 dwStart = SP::Module::Comm::RVCGetTickCount();
+	DWORD64 dwEnd = dwStart;
+	ErrorCodeEnum eErr = Error_Succeed;
+	LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_ON, "ContactCard green on");
+
+	int timeOutResult = 0;
+	do {
+		if (m_bCancelRead) {
+			err = 3;//取消读卡
+			break;
+		}
+		if (m_bPageExit) {
+			err = 4;//退到首页,取消读卡
+			break;
+		}
+
+		l_beginTime = SP::Module::Comm::RVCGetTickCount();
+		eErr = m_hDevHelper->GetDevStatus(devStatus);
+		l_endTime = SP::Module::Comm::RVCGetTickCount();
+
+		if (eErr == Error_Succeed) {
+			if (devStatus.eMediaPos == CI_MEDIA_RF) {
+				LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_OP, "Contactless card op.");
+
+				int activeCardType;
+				l_beginTime = SP::Module::Comm::RVCGetTickCount();
+				bool bIC = m_pCardProcess->DetectIfICCard(CARD_MACHINE_RFIC, m_hDevHelper, activeCardType);
+				l_endTime = SP::Module::Comm::RVCGetTickCount();
+				if (bIC) {
+					DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("InternalAcceptCardJS::DetectIfICCard activeCardType=%d", activeCardType);
+					if (activeCardType == 'A' || activeCardType == 'B' || activeCardType == 'M') {
+						err = 0;//探测到IC卡
+					}
+					else {
+						err = 1;//非IC卡
+					}
+					break;
+				}
+				else {
+					//探测失败,继续循环
+					err = 2;
+					timeOutResult = 1;
+					Sleep(ACCEPT_TRY_INTERVAL);
+				}
+			}
+			else {
+				//无卡,继续循环
+				err = 2;
+				timeOutResult = 3;
+				Sleep(ACCEPT_TRY_INTERVAL);
+			}
+		}
+		else {
+			//查询卡机状态失败,继续循环
+			err = 2;
+			timeOutResult = 2;
+			Sleep(ACCEPT_TRY_INTERVAL);
+		}
+		dwEnd = SP::Module::Comm::RVCGetTickCount();
+	} while (dwEnd - dwStart <= 55 * 1000);
+
+	//超时报错
+	if (err == 2) {
+		if (timeOutResult == 1) {
+			SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_ActiveContactlessICCard, "DevAdapter::ActiveContactlessICCard", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+		}
+		else if (timeOutResult == 2) {
+			SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_GetDevStatus, "DevAdapter::GetDevStatus", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+		}
+		else {
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InternalAcceptCardJS No IC card found ");
+		}
+	}
+
+	LogEvent(Severity_Middle, LOG_EVT_CONTACTLESS_CARD_GREEN_OFF, CSimpleStringA::Format("ContactCard green off,err=%d", err).GetData());
+
+	return err;
+
+}
+
+int CContactlessCardFSM::PreOnlineJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	long l_beginTime, l_endTime;
+	m_pCardProcess->DataInit();
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS>, aid[%s], bus data[%s]", ctx->Req.aid.GetData(),ctx->Req.businessData.GetData());
+	m_pCardProcess->SplitBusinessData(ctx->Req.businessData, ctx->Req.businessData.GetLength());
+	m_pCardProcess->SplitBusinessData("DF690101", strlen("DF690101"));
+	int activeCardType;
+	//oilyang@20201014 add emv card support
+	int retDetectAndRead = -1;
+	ICData aidFromBus(false, 0x4f, 0x00);
+	if (m_pCardProcess->FindTagValue(TAG_VECTOR_BUS, aidFromBus, false, 0) == -1)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the front BusinessData han't provide aid data.");
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, m_aidList, activeCardType);
+
+	}
+	else {
+		char* pAIDTmp = new char[64];
+		memset(pAIDTmp, 0, 64);
+		HexBuf2StrBuf(aidFromBus.value, &pAIDTmp, aidFromBus.lenth);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnline>, the aid is[%s],len:%d .", pAIDTmp, strlen(pAIDTmp));
+		CAutoArray<CSimpleString> preAIDs;
+		preAIDs.Init(1);
+		preAIDs[0] = (CSimpleStringA)pAIDTmp;
+		l_beginTime = SP::Module::Comm::RVCGetTickCount();
+		retDetectAndRead = m_pCardProcess->DetectAndReadICData(CARD_MACHINE_RFIC, m_hDevHelper, preAIDs, activeCardType);
+		l_endTime = SP::Module::Comm::RVCGetTickCount();
+
+		if (pAIDTmp != NULL) {
+			delete[]pAIDTmp;
+		}
+	}
+
+	if (retDetectAndRead < 0)
+	{
+		ctx->Ans.icState = 0;//调用失败
+		if (retDetectAndRead == -1) {
+			DWORD dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_ActiveContactlessICCard, "DevAdapter::ActiveContactlessICCard", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+			ctx->Answer(Error_Exception, dwTmpUserErrCode);
+		}
+		else if (retDetectAndRead == -2) {
+			DWORD dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+			ctx->Answer(Error_Exception, dwTmpUserErrCode);
+		}
+		else if (retDetectAndRead == -3) {
+			DWORD dwTmpUserErrCode = SetErrorAndLog(Error_Unexpect, MEC_DEVAPI_RF_RFTypeABCommand, "DevAdapter::RFTypeABCommand", __FUNCTION__, false, l_endTime - l_beginTime, "", "");
+			ctx->Answer(Error_Exception, dwTmpUserErrCode);
+		}
+		return -1;
+	}
+
+	m_pCardProcess->TermRiskManage();
+	CSimpleStringA taaResult;
+	BYTE bt9f27 = 0;
+	int retTAA = m_pCardProcess->TermActionAnalyze(CARD_MACHINE_RFIC, m_hDevHelper, taaResult, true, m_bCDA, bt9f27);
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("<PreOnlineJS>,TermActionAnalyze retTAA:%d, taaResult:%s", retTAA, taaResult.GetData());
+	switch (retTAA)
+	{//to be added oiltest 20140929
+	case -1:	//some data may be wrong
+		break;
+	case 1:		//terminal trans
+		break;
+	case 2:		//to do trans end "TransEnd"
+		break;
+	default:
+		break;
+	}
+	ctx->Ans.result = taaResult;
+
+	if (ctx->Ans.result.GetLength() == 0)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("<PreOnlineJS>,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[1024];
+	ZeroMemory(pSomeICData, 1024);
+	int lenRet = m_pCardProcess->ConstructARQCData(tmpResult.substr(6, 4).c_str(), m_pDataToARQC, pSomeICData);
+	baseICData = pSomeICData;
+	if (pSomeICData != NULL) {
+		delete[]pSomeICData;
+	}
+	char arqcLen[8];
+	ZeroMemory(arqcLen, sizeof(arqcLen));
+#ifdef RVC_OS_WIN
+	itoa(lenRet, arqcLen, 10);
+#else
+	sprintf(arqcLen, "%d", lenRet);
+#endif // RVC_OS_WIN
+
+	
+
+	ICData 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)("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)("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)("no track2 data in ic");
+	}
+	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)("<PreOnline>, split pos:%d", pos);
+		char* ddd = new char[40];
+		ZeroMemory(ddd, 40);
+		memcpy(ddd, pICTrack2, pos - 1);
+
+		char icTrack2Data[128];
+		ZeroMemory(icTrack2Data, sizeof(icTrack2Data));
+
+		Track2Data track2Data;
+		track2Data.status = 0;
+		track2Data.t2Account = "";
+		cmdDecodeMag2(pICTrack2, icTrack2Data);
+		if (SplitTrack2(icTrack2Data, track2Data) == 0)
+		{
+			t2ICAccount = track2Data.t2Account;
+			//t2ICCardSerial = track2Data.t2CardSerial;
+			t2ICCVC = track2Data.t2CVC;
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("done(ic).");
+		}
+
+		if (strnicmp(track2Data.t2Account, ddd, strlen(ddd)))
+		{
+			t2ICCVC = "";
+			t2ICAccount = (char*)ddd;
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("contactless card countcount:%s,%s", t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str());
+		}
+		delete[]ddd;
+
+		LogWarn(Severity_Low, Error_Succeed, ContactlessCard_UserErrorCode_ReadAccount, CSimpleStringA::Format("split pos:%d, card acount:%s,%s"
+			, pos, t2ICAccount.substr(0, 6).c_str(), t2ICAccount.substr(t2ICAccount.length() - 4, 4).c_str()));//读到的卡号
+	}
+	delete[]pICTrack2;
+
+
+	//80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000
+	if (m_pCardProcess->GetP1() == 0x1)
+		actionType = "ARQC";
+	else
+		actionType = "";
+	//【55域】
+	//	基本域:
+	//	9F26	8b	应用密文AC
+	//	9F27	1b	密文信息数据
+	//	9F10	max.32b	发卡行应用数据IAD
+	//	9F37	4b	不可预知数
+	//	9F36	2b	应用交易计数器ATC
+	//	95	5b	终端验证结果TVR
+	//	9A	3cn	交易日期(6位有效数字,YYMMDD)
+	//	9C	1cn	交易类型(2位有效数字)
+	//	9F02	6cn	授权金额(12位有效数字)
+	//	5F2A	2cn	交易货币代码(3位有效数字)
+	//	82	2b	应用交互特征AIP
+	//	9F1A	2cn	终端国家代码(3位有效数字)
+	//	9F03	6cn	其他金额(12位有效数字)
+	//	9F33	3b	终端性能 "E0C900"
+
+	//	可选域:
+	//添加9F26,9F27,9F10,9F33的数据
+	char* pCID = new char[4];
+	ZeroMemory(pCID, 4);
+	HexBuf2StrBuf(&bt9f27, &pCID, 1);
+	char* pIssueBankLen = new char[4];
+	ZeroMemory(pIssueBankLen, 4);
+	int len9f10 = tmpResult.length() - 26 - 4;
+	int lenHigh, lenLow;
+	len9f10 = len9f10 / 2;
+	lenHigh = len9f10 / 16;
+	lenLow = len9f10 % 16;
+	BYTE bt9f10;
+	bt9f10 = (lenHigh << 4) + lenLow;
+	HexBuf2StrBuf(&bt9f10, &pIssueBankLen, 1);
+	baseICData += "9F2608" + tmpResult.substr(10, 16) + "9F2701" + pCID + "9F10" + pIssueBankLen + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "9F3303" + "E0C900";
+
+	
+	//result = "ACTION," + actionType + "|" + "ATCCODE," + tmpResult.substr(6, 4) + "|" + "ARQCCODE," + tmpResult.substr(10, 16) + "|"
+	//	+ "MAC," + tmpResult.substr(26, tmpResult.length() - 26 - 4) + "|" + "ARQCSIZE," + string(arqcLen) + "|"
+	//	+ "ARQCDATA," + m_pDataToARQC + "|EXPIREDATE," + pExpireDate + "|T2ACCOUNT," + t2ICAccount + "|T2CARDSERIAL," + t2ICCardSerial
+	//	+ "|T2CVC," + t2ICCVC + "|T2TRACK2," + t2ICTrack2 + "|CARDCAT," + cardType + "|ICTAGS," + baseICData;
+	//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();
+
+	ctx->Ans.result = result.c_str();
+	ctx->Ans.icState = 1;
+	//DbgWithLink(LOG_LEVEL_INFO, 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_DEBUG, LOG_TYPE_SYSTEM)("data to host(less)[%s]", txtresult.c_str());
+
+
+	if (pCID != NULL)
+		delete[]pCID;
+	if (pIssueBankLen != NULL)
+		delete[]pIssueBankLen;
+
+	if (m_pDataToARQC != NULL)
+	{
+		delete[]m_pDataToARQC;
+		m_pDataToARQC = NULL;
+	}
+	ctx->Answer(Error_Succeed);
+	return 0;
+
+}
+
+int CContactlessCardFSM::ExitToMainPage()
+{
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("exit to main page, send event");
+	FSMEvent* evt = new FSMEvent(USER_EVT_EXIT_MIAN_PAGE);
+	PostEventFIFO(evt);
+	return 0;
+}

+ 155 - 24
Module/mod_ContactlessCard/ContactlessFSM.h

@@ -38,7 +38,15 @@ enum EvtType
 	USER_EVT_READ_FINISHED,
 	USER_EVT_QUERY_CARD_INFO,
 	USER_EVT_QUERY_CARD_INFO_FINISHED,
-
+	//new 
+	USER_EVT_JS_READ,
+	USER_EVT_JS_READ_FINISHED,
+	USER_EVT_JS_EJECT,
+	USER_EVT_JS_EJECTFINISHED,
+	USER_EVT_JS_POSTONLINE,
+	USER_EVT_JS_POSTONLINEFINISHED,
+	USER_EVT_JS_READ_CANCEL,
+	USER_EVT_EXIT_MIAN_PAGE
 };
 
 using namespace ContactlessCard;
@@ -156,21 +164,75 @@ public:
 protected:
 private:
 };
+//new
+class EjectJSEvent : public FSMEvent
+{
+public:
+	EjectJSEvent() : FSMEvent(USER_EVT_JS_EJECT) {}
+	~EjectJSEvent() {}
+	SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx;
+	virtual void OnUnhandled()
+	{
+		if (ctx != NULL) {
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("EjectJS unhandled");
+			//ctx->Answer(Error_InvalidState);
+		}
+	}
+protected:
+private:
+};
+
+class PostOnlineJSEvent : public FSMEvent
+{
+public:
+	PostOnlineJSEvent() : FSMEvent(USER_EVT_JS_POSTONLINE) {}
+	~PostOnlineJSEvent() {}
+	SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx;
+	virtual void OnUnhandled()
+	{
+		if (ctx != NULL) {
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("PostOnlineJS unhandled");
+			//ctx->Answer(Error_InvalidState);
+		}
+	}
+protected:
+private:
+};
+
+class ReadJSEvent : public FSMEvent
+{
+public:
+	ReadJSEvent() : FSMEvent(USER_EVT_JS_READ) {}
+	~ReadJSEvent() {}
+	SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx;
+	virtual void OnUnhandled()
+	{
+		if (ctx != NULL) {
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ReadJS unhandled");
+			//ctx->Answer(Error_InvalidState);
+		}
+	}
+protected:
+private:
+};
+
 class CContactlessCardFSM : public CCommDevFSM<CContactlessCardFSM, RFICClass>
 {
 public:
-	enum {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9};
+	enum {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11};
 	BEGIN_FSM_STATE(CContactlessCardFSM)
-		FSM_STATE_ENTRY(s0,"Init",s0_on_entry,s0_on_exit,s0_on_event)
-		FSM_STATE_ENTRY(s1,"Initializing",s1_on_entry,s1_on_exit,s1_on_event)
-		FSM_STATE_ENTRY(s2,"Idle",s2_on_entry,s2_on_exit,s2_on_event)
-		FSM_STATE_ENTRY(s3,"Accepting",s3_on_entry,s3_on_exit,s3_on_event)
-		FSM_STATE_ENTRY(s4,"Hold",s4_on_entry,s4_on_exit,s4_on_event)
-		FSM_STATE_ENTRY(s5,"Reading",s5_on_entry,s5_on_exit,s5_on_event)
-		FSM_STATE_ENTRY(s6,"Ejecting",s6_on_entry,s6_on_exit,s6_on_event)
-		FSM_STATE_ENTRY(s7,"WaitFetching",s7_on_entry,s7_on_exit,s7_on_event)
-		FSM_STATE_ENTRY(s8,"Capturing",s8_on_entry,s8_on_exit,s8_on_event)
-		FSM_STATE_ENTRY(s9,"Failed",s9_on_entry,s9_on_exit,s9_on_event)
+		FSM_STATE_ENTRY(s0, "Init", s0_on_entry, s0_on_exit, s0_on_event)
+		FSM_STATE_ENTRY(s1, "Initializing", s1_on_entry, s1_on_exit, s1_on_event)
+		FSM_STATE_ENTRY(s2, "Idle", s2_on_entry, s2_on_exit, s2_on_event)
+		FSM_STATE_ENTRY(s3, "Accepting", s3_on_entry, s3_on_exit, s3_on_event)
+		FSM_STATE_ENTRY(s4, "Hold", s4_on_entry, s4_on_exit, s4_on_event)
+		FSM_STATE_ENTRY(s5, "Reading", s5_on_entry, s5_on_exit, s5_on_event)
+		FSM_STATE_ENTRY(s6, "Ejecting", s6_on_entry, s6_on_exit, s6_on_event)
+		FSM_STATE_ENTRY(s7, "WaitFetching", s7_on_entry, s7_on_exit, s7_on_event)
+		FSM_STATE_ENTRY(s8, "Capturing", s8_on_entry, s8_on_exit, s8_on_event)
+		FSM_STATE_ENTRY(s9, "Failed", s9_on_entry, s9_on_exit, s9_on_event)
+		FSM_STATE_ENTRY(s10, "ReadJs", s10_on_entry, s10_on_exit, s10_on_event)
+		FSM_STATE_ENTRY(s11, "EjectJs", s11_on_entry, s11_on_exit, s11_on_event)
 		END_FSM_STATE()
 
 		BEGIN_FSM_RULE(CContactlessCardFSM,s0)
@@ -180,7 +242,6 @@ public:
 		FSM_RULE_ENTRY(s1,s9,USER_EVT_INITFINISHED,1)
 		FSM_RULE_ENTRY(s1, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
 		FSM_RULE_ENTRY(s2,s3,USER_EVT_ACCEPT,0)
-		//		FSM_RULE_ENTRY(s2,s9,USER_EVT_ACCEPT,1)
 		FSM_RULE_ENTRY(s2, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
 		FSM_RULE_ENTRY(s2, s6, USER_EVT_EJECT, 0)
 		FSM_RULE_ENTRY(s3,s4,USER_EVT_ACCEPTFINISHED,0)
@@ -189,11 +250,8 @@ public:
 		FSM_RULE_ENTRY(s3,s2,USER_EVT_ACCEPTFINISHED,3)
 		FSM_RULE_ENTRY(s3,s7,USER_EVT_ACCEPTFINISHED,4)
 		FSM_RULE_ENTRY(s3, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
-		//FSM_RULE_ENTRY(s4,s5,USER_EVT_READ,0)
-		//FSM_RULE_ENTRY(s4,s5,USER_EVT_READ,0)
 		FSM_RULE_ENTRY(s4,s6,USER_EVT_EJECT,0)
 		FSM_RULE_ENTRY(s4,s6,USER_EVT_EXIT,0)
-		//FSM_RULE_ENTRY(s4,s2,USER_EVT_ACCEPT,0)
 		FSM_RULE_ENTRY(s4,s2,USER_EVT_QUERY_CARD_INFO_FINISHED,0)
 		FSM_RULE_ENTRY(s4, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
 		FSM_RULE_ENTRY(s5,s4,USER_EVT_READ_FINISHED,0)
@@ -208,21 +266,22 @@ public:
 		FSM_RULE_ENTRY(s6, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
 		FSM_RULE_ENTRY(s7,s2,USER_EVT_WAITFINISHED,0)
 		FSM_RULE_ENTRY(s7,s2,USER_EVT_WAITFINISHED,2)
-		//FSM_RULE_ENTRY(s7,s9,USER_EVT_WAITFINISHED,1)
-		//FSM_RULE_ENTRY(s7,s8,USER_EVT_WAITFINISHED,2)
 		FSM_RULE_ENTRY(s7, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
-		//FSM_RULE_ENTRY(s8,s2,USER_EVT_CAPTUREFINISHED,0)
-		//FSM_RULE_ENTRY(s8,s9,USER_EVT_CAPTUREFINISHED,1)
 		FSM_RULE_ENTRY(s8, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
-		//FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 0)
 		FSM_RULE_ENTRY(s9, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
 		FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 0)
 		FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 1)
+		FSM_RULE_ENTRY(s10, s2, USER_EVT_JS_READ_FINISHED, 0)
+		FSM_RULE_ENTRY(s10, s2, USER_EVT_JS_POSTONLINEFINISHED, 0)
+		FSM_RULE_ENTRY(s11, s2, USER_EVT_JS_EJECTFINISHED, 0)
+		FSM_RULE_ENTRY(s11, s2, USER_EVT_JS_EJECTFINISHED, 1)
+		FSM_RULE_ENTRY(s11, s2, USER_EVT_JS_EJECTFINISHED, 2)
 		END_FSM_RULE()
 
-		CContactlessCardFSM() : m_bCancelAccept(false),m_bWaitingAccept(false),
-		m_bWaitAccepteMore(false),m_bExit(false),m_resetTimes(0),m_testResult(Error_Succeed)
-		,m_bCDA(false),m_pDataToARQC(NULL), m_csMachineType(true), m_csDevNo(""),m_devInit(false), m_repeatErrTimes(0)
+		CContactlessCardFSM() : m_bCancelAccept(false), m_bWaitingAccept(false),
+		m_bWaitAccepteMore(false), m_bExit(false), m_resetTimes(0), m_testResult(Error_Succeed)
+		, m_bCDA(false), m_pDataToARQC(NULL), m_csMachineType(true), m_csDevNo(""), m_devInit(false), m_repeatErrTimes(0),
+		m_bCancelRead(false),m_bPageExit(false)
 		{
 			HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x213); 
 			cmdDecodeMag2 = NULL;
@@ -267,6 +326,13 @@ public:
 	void s9_on_exit();
 	unsigned int s9_on_event(FSMEvent* event);
 
+	void s10_on_entry();
+	void s10_on_exit();
+	unsigned int s10_on_event(FSMEvent* event);
+	void s11_on_entry();
+	void s11_on_exit();
+	unsigned int s11_on_event(FSMEvent* event);
+
 	int Initial();
 	ErrorCodeEnum Load();
 	bool GetDevStatus(bool bPrint=true);
@@ -289,6 +355,26 @@ public:
 	{
 		pTransactionContext->SendAnswer(m_testResult);
 	}
+	//new interface
+	int GetFSMState()
+	{
+		//DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_currentFSMState:%d", m_currentFSMState);
+		return m_currentFSMState;
+	}
+	DWORD GetFsmStateErrCode();
+	void QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx);
+
+	int EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx);
+
+	int ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx);
+
+	int PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx);
+
+	int InternalAcceptCardJS();
+
+	int PreOnlineJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx);
+
+	int ExitToMainPage();
 
 protected:
 	int m_iInsertTries;
@@ -318,6 +404,11 @@ private:
 	int SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData);
 
 	int m_repeatErrTimes;
+
+	int m_currentFSMState;
+	//new
+	bool m_bCancelRead;
+	bool m_bPageExit;
 };
 struct InitTask : public ITaskSp
 {
@@ -416,4 +507,44 @@ struct QueryCardInfoTask : public ITaskSp
 		fsm->PostEventFIFO(e);
 	}
 };
+
+
+struct EjectJSTask : public ITaskSp
+{
+	SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx;
+	CContactlessCardFSM* fsm;
+	EjectJSTask(CContactlessCardFSM* f) : fsm(f) {}
+	void Process()
+	{
+		FSMEvent* e = new FSMEvent(USER_EVT_JS_EJECTFINISHED);
+		e->param1 = fsm->EjectJS(ctx);
+		fsm->PostEventFIFO(e);
+	}
+};
+
+struct ReadJSTask : public ITaskSp
+{
+	SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx;
+	CContactlessCardFSM* fsm;
+	ReadJSTask(CContactlessCardFSM* f) : fsm(f) {}
+	void Process()
+	{
+		FSMEvent* e = new FSMEvent(USER_EVT_JS_READ_FINISHED);
+		e->param1 = fsm->ReadJS(ctx);
+		fsm->PostEventFIFO(e);
+	}
+};
+
+struct PostOnlineJSTask : public ITaskSp
+{
+	SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx;
+	CContactlessCardFSM* fsm;
+	PostOnlineJSTask(CContactlessCardFSM* f) : fsm(f) {}
+	void Process()
+	{
+		FSMEvent* e = new FSMEvent(USER_EVT_JS_POSTONLINEFINISHED);
+		e->param1 = fsm->PostOnlineJS(ctx);
+		fsm->PostEventFIFO(e);
+	}
+};
 #endif //_CONTACTLESS_FSM_H

+ 50 - 0
Module/mod_ContactlessCard/mod_ContactlessCard.cpp

@@ -73,6 +73,56 @@ void ContactlessCardServerSession::Handle_GetDevInfo(SpReqAnsContext<Contactless
 	m_pEntity->GetDevInfo(ctx);
 }
 
+
+//new interface
+
+void ContactlessCardServerSession::Handle_CancelReadJS(SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Invoke CancelReadJS");
+	m_pEntity->CancelReadJS(ctx);
+}
+void ContactlessCardServerSession::Handle_ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Invoke ReadJS");
+	m_pEntity->ReadJS(ctx);
+}
+void ContactlessCardServerSession::Handle_PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Invoke PostOnlineJS");
+	m_pEntity->PostOnlineJS(ctx);
+}
+void ContactlessCardServerSession::Handle_EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Invoke EjectJS");
+	m_pEntity->EjectJS(ctx);
+}
+void ContactlessCardServerSession::Handle_QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx)
+{
+	LOG_FUNCTION();
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Invoke QueryHasCardJS");
+	m_pEntity->QueryHasCardJS(ctx);
+}
+
+void CContactlessCardEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName)
+{
+	if ((_strnicmp(pszKey, "UIState", strlen("UIState")) == 0))
+	{
+		m_fsm.OnUIState4SetWhatPage(pszValue);
+		if (_strnicmp(pszValue, "M", strlen("M")) == 0) {
+			m_fsm.ExitToMainPage();
+		}
+	}
+}
+
 SP_BEGIN_ENTITY_MAP()
 	SP_ENTITY(CContactlessCardEntity)
 SP_END_ENTITY_MAP()

+ 93 - 1
Module/mod_ContactlessCard/mod_ContactlessCard.h

@@ -22,11 +22,19 @@ public:
 	virtual void Handle_Exit(SpOnewayCallContext<ContactlessCardService_Exit_Info>::Pointer ctx);
 	virtual void Handle_QueryCardInfo(SpReqAnsContext<ContactlessCardService_QueryCardInfo_Req, ContactlessCardService_QueryCardInfo_Ans>::Pointer ctx);
 	virtual void Handle_GetDevInfo(SpReqAnsContext<ContactlessCardService_GetDevInfo_Req, ContactlessCardService_GetDevInfo_Ans>::Pointer ctx);
+
+	//new interface
+	virtual void Handle_CancelReadJS(SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>::Pointer ctx);
+	virtual void Handle_ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx);
+	virtual void Handle_PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx);
+	virtual void Handle_EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx);
+	virtual void Handle_QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx);
+
 private:
 	CContactlessCardEntity* m_pEntity;
 };
 
-class CContactlessCardEntity : public CDevAdptEntityBase
+class CContactlessCardEntity : public CDevAdptEntityBase, public ISysVarListener
 {
 public:
 	CContactlessCardEntity()
@@ -39,6 +47,7 @@ public:
 		LOG_FUNCTION();
 
 		ErrorCodeEnum eStart = m_fsm.Init(this);
+		GetFunction()->RegistSysVarEvent("UIState", this);
 		pTransactionContext->SendAnswer(Error_Succeed);
 	}
 
@@ -161,6 +170,88 @@ public:
 		}
 	}
 
+	//new interface
+
+	void CancelReadJS(SpOnewayCallContext<ContactlessCardService_CancelReadJS_Info>::Pointer ctx)
+	{
+		LOG_FUNCTION();
+		if (!m_fsm.GetDevInitFlag()) {
+			LogWarn(Severity_Middle, Error_DevNotAvailable, ContactlessCard_UserErrorCode_DevOpen_Failed, "CancelInsert but DevOpen failed.");
+		}
+		else {
+			FSMEvent* evt = new FSMEvent(USER_EVT_JS_READ_CANCEL);
+			m_fsm.PostEventFIFO(evt);
+		}
+	}
+
+	void ReadJS(SpReqAnsContext<ContactlessCardService_ReadJS_Req, ContactlessCardService_ReadJS_Ans>::Pointer ctx)
+	{
+		LOG_FUNCTION();
+		if (!m_fsm.GetDevInitFlag()) {
+			ctx->Answer(Error_DevNotAvailable, ContactlessCard_UserErrorCode_DevOpen_Failed);
+		}
+		else if (_stricmp(m_fsm.GetCurrStateName(), "Idle") != 0) {
+			DWORD errCode = m_fsm.GetFsmStateErrCode();
+			int state = m_fsm.GetFSMState();
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ReadJS req is unhandled ,CurrState=%d", state);
+			ctx->Answer(Error_Unexpect, errCode);
+		}
+		else {
+			ReadJSEvent* pEvt = new ReadJSEvent();
+			pEvt->ctx = ctx;
+			m_fsm.PostEventFIFO(pEvt);
+		}
+	}
+
+	void PostOnlineJS(SpReqAnsContext<ContactlessCardService_PostOnlineJS_Req, ContactlessCardService_PostOnlineJS_Ans>::Pointer ctx)
+	{
+		LOG_FUNCTION();
+		if (!m_fsm.GetDevInitFlag()) {
+			ctx->Answer(Error_DevNotAvailable, ContactlessCard_UserErrorCode_DevOpen_Failed);
+		}
+		else if (_stricmp(m_fsm.GetCurrStateName(), "Idle") != 0) {
+			DWORD errCode = m_fsm.GetFsmStateErrCode();
+			int state = m_fsm.GetFSMState();
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("PostOnlineJS req is unhandled ,CurrState=%d", state);
+			ctx->Answer(Error_Unexpect, errCode);
+		}
+		else {
+			PostOnlineJSEvent* pEvt = new PostOnlineJSEvent();
+			pEvt->ctx = ctx;
+			m_fsm.PostEventFIFO(pEvt);
+		}
+	}
+
+	void EjectJS(SpReqAnsContext<ContactlessCardService_EjectJS_Req, ContactlessCardService_EjectJS_Ans>::Pointer ctx)
+	{
+		LOG_FUNCTION();
+		if (!m_fsm.GetDevInitFlag()) {
+			ctx->Answer(Error_DevNotAvailable, ContactlessCard_UserErrorCode_DevOpen_Failed);
+		}
+		else if (_stricmp(m_fsm.GetCurrStateName(), "Idle") != 0) {
+			DWORD errCode = m_fsm.GetFsmStateErrCode();
+			int state = m_fsm.GetFSMState();
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("EjectJS req is unhandled ,CurrState=%d", state);
+			ctx->Answer(Error_Unexpect, errCode);
+		}
+		else {
+			EjectJSEvent* e = new EjectJSEvent();
+			e->ctx = ctx;
+			m_fsm.PostEventFIFO(e);
+		}
+	}
+
+	void QueryHasCardJS(SpReqAnsContext<ContactlessCardService_QueryHasCardJS_Req, ContactlessCardService_QueryHasCardJS_Ans>::Pointer ctx)
+	{
+		LOG_FUNCTION();
+		if (!m_fsm.GetDevInitFlag()) {
+			ctx->Answer(Error_DevNotAvailable, ContactlessCard_UserErrorCode_DevOpen_Failed);
+		}
+		else {
+			m_fsm.QueryHasCardJS(ctx);
+		}
+	}
+
 	virtual void OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
 	{
 		m_fsm.SelfTest(eTestType,pTransactionContext);
@@ -169,6 +260,7 @@ public:
 	{
 		return new ContactlessCardServerSession(this);
 	}
+	virtual void OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName);
 	virtual bool IsService()const{return true;}
 	virtual bool IsMultiThread()const{return true;}
 protected:

+ 6 - 2
Module/mod_cardissuerstore/CardIssuerFSM.cpp

@@ -8546,6 +8546,8 @@ int CCardIssuerFSM::IssueFromBoxJS(SpReqAnsContext<CardIssuerStoreService_IssueF
 	if (ctx->Req.hopper < 1 || ctx->Req.hopper > 6) {
 		errMsg = CSimpleStringA::Format("Issuer Card, the hopperNo(%d) is wrong!!!", ctx->Req.hopper);
 		LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_Invalid_Hopper, errMsg.GetData());
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR040222045").setResultCode("RTA2WCX")(errMsg.GetData());
+		ctx->Answer(Error_Param, CardIssuerStore_UserErrorCode_Invalid_Hopper);
 		return 1;
 	}
 	m_currentHopper = ctx->Req.hopper;//设置发送的卡箱号
@@ -8759,6 +8761,8 @@ int CCardIssuerFSM::ReadJS(SpReqAnsContext<CardIssuerStoreService_ReadJS_Req, Ca
 		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) {
@@ -10614,11 +10618,11 @@ int CCardIssuerFSM::PreOnlineCrossJS_RF(SpReqAnsContext<CardIssuerStoreService_P
 			GetCardProcessLastErr(eErrCode, ApiName, alarmMsg, csErrMsgWithReturnCode);
 
 			if (IsInBusiness()) {
-				DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040222052").setResultCode("RTA2W0V")(csErrMsgWithReturnCode.GetData());
+				DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040222052").setResultCode("RTA2W26")(csErrMsgWithReturnCode.GetData());
 				LogError(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_ActiveContactlessICCard_Failed, alarmMsg.GetData());
 			}
 			else {
-				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040222052").setResultCode("RTA2W0V")(csErrMsgWithReturnCode.GetData());
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setAPI(ApiName.GetData()).setCostTime(l_endTime - l_beginTime).setLogCode("QLR040222052").setResultCode("RTA2W26")(csErrMsgWithReturnCode.GetData());
 				LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_ActiveContactlessICCard_Failed, alarmMsg.GetData());
 			}
 			ctx->Answer(Error_Unexpect, CardIssuerStore_UserErrorCode_ActiveContactlessICCard_Failed);