浏览代码

!10889 st2
Merge pull request !10889 from 80174847/ST2

杨诗友80174847 1 月之前
父节点
当前提交
78fae40e82

+ 11 - 4
DevAdapter/simulator/idcer.1.1/idcer_httpans.h

@@ -115,10 +115,11 @@ typedef struct IDCerDevAns
         int dwSize;
         JSONCONVERT2OBJECT_MEMEBER_REGISTER(data, dwSize)
     }reserved5;
+    int headPhotoFlag;
     
     JSONCONVERT2OBJECT_MEMEBER_REGISTER(name, sex, nation, birthday, address, idno, department, startDate, endDate,
         photoPath, newAddress, englishName, nationality, idVersion, idType, reserved, reserved, txzCode, issuedSN, reserved2,
-        reserved3, reserved4, reserved5)
+        reserved3, reserved4, reserved5, headPhotoFlag)
     
    /* std::string sex;
     std::string nation;
@@ -151,8 +152,14 @@ typedef struct IDCerDevAns
 
 
 typedef struct QueryCardPosAns {
-    int errNum;
     int pos;
 
-    JSONCONVERT2OBJECT_MEMEBER_REGISTER(errNum, pos)
-}QueryCardPosAns;
+    JSONCONVERT2OBJECT_MEMEBER_REGISTER(pos)
+}QueryCardPosAns;
+
+typedef struct ScanIDAndSaveImgAns {
+    int frontPhotoFlag;
+    int backPhotoFlag;
+
+    JSONCONVERT2OBJECT_MEMEBER_REGISTER(frontPhotoFlag, backPhotoFlag)
+}ScanIDAndSaveImgAns;

+ 13 - 11
DevAdapter/simulator/idcer.1.1/idcer_impl.cpp

@@ -173,6 +173,11 @@ ErrorCodeEnum IDCerClassImpl::ex2HttpFunction(IDCerInfoEx2& idCerInfoEx2)
             return Error_Unexpect;
         }
 
+        if (idCerRet.headPhotoFlag)
+        {
+            GenerateBmpFile("zp.bmp");
+        }
+
 #ifdef _MSC_VER
         ConvertGBKToUtf8(idCerRet.name.data);
         ConvertGBKToUtf8(idCerRet.sex.data);
@@ -372,19 +377,21 @@ ErrorCodeEnum IDCerClassImpl::ForceIDEject()
 ErrorCodeEnum IDCerClassImpl::ScanIDAndSaveImage()
 {
     ErrorCodeEnum err = Error_NotImpl;
-    err = SimulatorHttpFunction(EntityName, "ScanIDAndSaveImage");
+    ScanIDAndSaveImgAns ans;
+    err = SimulatorHttpFunction(EntityName, "ScanIDAndSaveImage", ans);
     LOG4VTM(INFO, "ScanIDAndSaveImage err = " << err);
 
     if (err == Error_Succeed)
     {
-        bool flag1 = GenerateBmpFile("idfront.bmp");
-        bool flag2 = GenerateBmpFile("idback.bmp");
-        if (!(flag1 & flag2))
+        if (ans.frontPhotoFlag)
+        {
+            GenerateBmpFile("idfront.bmp");
+        }
+        if (ans.backPhotoFlag)
         {
-            err = Error_Bug;
+            GenerateBmpFile("idback.bmp");
         }
     }
-
     return err;
 }
 
@@ -461,11 +468,6 @@ ErrorCodeEnum IDCerClassImpl::IDCerGetDataEx2(IDCerInfoEx2& idCerInfoEx2)
     ErrorCodeEnum err = Error_Succeed;
     memset(&idCerInfoEx2, 0, sizeof(IDCerInfoEx2));
     err = ex2HttpFunction(idCerInfoEx2);
-    bool flag = GenerateBmpFile("zp.bmp");
-    if (!flag)
-    {
-        err = Error_Bug;
-    }
 
     LOG4VTM(INFO, "IDCerGetDataEx2 err = " << err);
     return err;

+ 74 - 9
Module/mod_IDCertificate/IDCertFSM.cpp

@@ -515,6 +515,10 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 	m_bCancelRead = false;
 	m_bReading = true;
 	m_bExit = false;
+	m_bGetHeadPhotoFailed = false;
+	m_bHeadPhotoTimeError = false;
+	m_bFrontPhotoTimeError = false;
+	m_bBackPhotoTimeError = false;
 
 	LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on");
 	while (elapsed < IDCER_READ_TIMEOUT && (errReadEx2 != Error_Succeed) && !m_bCancelRead)
@@ -585,6 +589,10 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 
 					//转换数据并赋值至传出字段
 					CopyIDCerDataToCtx(idInfoEx2, ctx);
+					if (m_bGetHeadPhotoFailed)
+					{
+						break;
+					}
 					ctx->Ans.photodata = ctx->Ans.headphoto; //现接口继续保持复制图片,JS接口下掉photodata字段 - 2025.6.17
 
 					ctx->Ans.hasscan = 0;
@@ -635,7 +643,30 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 
 	if (errReadEx2 == Error_Succeed)
 	{
-		ctx->Answer(Error_Succeed);
+		if (m_bGetHeadPhotoFailed) //头像图片获取失败
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211B")("Get Headphoto failed!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_GetHeadPhotoFailed);
+		}
+		else if (m_bHeadPhotoTimeError) //头像图片修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211C")("Headphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_HeadPhotoTimeError);
+		}
+		else if (m_bFrontPhotoTimeError) //正面扫描件修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211D")("Frontphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_FrontPhotoTimeError);
+		}
+		else if (m_bBackPhotoTimeError) //背面扫描件修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211E")("Backphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_BackPhotoTimeError);
+		}
+		else
+		{
+			ctx->Answer(Error_Succeed);
+		}
 	}
 	else if (m_bCancelRead)
 	{
@@ -647,14 +678,14 @@ int CIDCertFSM::ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCe
 			if (errReadEx2 != Error_Succeed) {
 
 				SetErrorAndLog(errReadEx2, MEC_DEVAPI_IDCER_IDCerGetDataEx2, "DevAdapter::IDCerGetDataEx2", __FUNCTION__,
-					true, IDCerGetDataEx2Time, IDCertService_LogCode_IDCerGetDataEx2);
+					IsInBusiness(), IDCerGetDataEx2Time, IDCertService_LogCode_IDCerGetDataEx2);
 				ctx->Answer(Error_TimeOut, GetAlarmDEC()); //RTA2109
 			}
 		}
 		else if (errRfOpen != Error_Succeed)
 		{
 			SetErrorAndLog(errRfOpen, MEC_DEVAPI_IDCER_IDCerRFControl, "DevAdapter::IDCerRFControl", __FUNCTION__,
-				true, OpenRFControlTime, IDCertService_LogCode_OpenIDCerRFControl);
+				IsInBusiness(), OpenRFControlTime, IDCertService_LogCode_OpenIDCerRFControl);
 			ctx->Answer(Error_TimeOut, GetAlarmDEC());
 		}
 		else
@@ -727,6 +758,10 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 	m_bCancelRead = false;
 	m_bReading = true;
 	m_bExit = false;
+	m_bGetHeadPhotoFailed = false;
+	m_bHeadPhotoTimeError = false;
+	m_bFrontPhotoTimeError = false;
+	m_bBackPhotoTimeError = false;
 
 	LogEvent(Severity_Middle, LOG_EVT_IDCERTIFICATE_GREEN_ON, "IDCer warning on");
 	while (elapsed < IDCER_READ_TIMEOUT && (errReadEx2 != Error_Succeed) && !m_bCancelRead)
@@ -790,6 +825,10 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 
 				//转换数据并赋值至传出字段
 				CopyIDCerDataToCtx(idInfoEx2, ctx);
+				if (m_bGetHeadPhotoFailed)
+				{
+					break;
+				}
 
 				ctx->Ans.hasscan = 0;
 				if (igestionVer == TRUE) //吸入式设备才调用正反扫描功能
@@ -838,7 +877,30 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 
 	if (errReadEx2 == Error_Succeed)
 	{
-		ctx->Answer(Error_Succeed);
+		if (m_bGetHeadPhotoFailed) //头像图片获取失败
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211B")("Get Headphoto failed!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_GetHeadPhotoFailed);
+		}
+		else if (m_bHeadPhotoTimeError) //头像图片修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211C")("Headphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_HeadPhotoTimeError);
+		}
+		else if (m_bFrontPhotoTimeError) //正面扫描件修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211D")("Frontphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_FrontPhotoTimeError);
+		}
+		else if (m_bBackPhotoTimeError) //背面扫描件修改时间异常
+		{
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setResultCode("RTA211E")("Backphoto time error!");
+			ctx->Answer(Error_Unexpect, IDCertificate_UserErrorCode_ReadAndScan_BackPhotoTimeError);
+		}
+		else
+		{
+			ctx->Answer(Error_Succeed);
+		}
 	}
 	else if (m_bCancelRead)
 	{
@@ -850,14 +912,14 @@ int CIDCertFSM::ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req,
 			if (errReadEx2 != Error_Succeed) {
 
 				SetErrorAndLog(errReadEx2, MEC_DEVAPI_IDCER_IDCerGetDataEx2, "DevAdapter::IDCerGetDataEx2", __FUNCTION__,
-					true, IDCerGetDataEx2Time, IDCertService_LogCode_IDCerGetDataEx2);
+					IsInBusiness(), IDCerGetDataEx2Time, IDCertService_LogCode_IDCerGetDataEx2);
 				ctx->Answer(Error_Unexpect, GetAlarmDEC()); //RTA2109
 			}
 		}
 		else if (errRfOpen != Error_Succeed)
 		{
 			SetErrorAndLog(errRfOpen, MEC_DEVAPI_IDCER_IDCerRFControl, "DevAdapter::IDCerRFControl", __FUNCTION__,
-				true, OpenRFControlTime, IDCertService_LogCode_OpenIDCerRFControl);
+				IsInBusiness(), OpenRFControlTime, IDCertService_LogCode_OpenIDCerRFControl);
 			ctx->Answer(Error_Unexpect, GetAlarmDEC()); //RTA2106
 		}
 		else
@@ -972,6 +1034,7 @@ ErrorCodeEnum CIDCertFSM::GetPngBlobEx(CBlob &data, CSimpleStringA fileNamePrefi
 			errInfo["description"] = disecription.GetData();
 			tErrStr = generateJsonStr(errInfo).second.c_str();
 			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(imgRTACode).setAPI("DeleteFileIfExisted")(tErrStr.GetData());
+			m_bGetHeadPhotoFailed = true;
 		}
 
 		errMsg = CSimpleStringA::Format("read file %s.bmp failed.err:%d", (const char*)strPath, GetLastError());
@@ -1770,9 +1833,11 @@ void CIDCertFSM::WarnImgCreateTime()
 	CSimpleStringA fileTimeWarn = CSimpleStringA::Format("头像图片时间:[%s], 正面图片时间:[%s],背面图片时间:[%s]",
 		headPhotoTimeStr.GetData(), frontPhotoTimeStr.GetData(), backPhotoTimeStr.GetData());
 	SeverityLevelEnum ImgTimeWarnLevel = Severity_Low;
-	if ((headPhotoTime > 0 && headPhotoTime < currentSysTime) ||
-		(frontPhotoTime > 0 && frontPhotoTime < currentSysTime) ||
-		(backPhotoTime > 0 && backPhotoTime < currentSysTime))
+	m_bHeadPhotoTimeError = headPhotoTime > 0 && headPhotoTime < currentSysTime;
+	m_bFrontPhotoTimeError = frontPhotoTime > 0 && frontPhotoTime < currentSysTime;
+	m_bBackPhotoTimeError = backPhotoTime > 0 && backPhotoTime < currentSysTime;
+
+	if (m_bHeadPhotoTimeError || m_bFrontPhotoTimeError || m_bBackPhotoTimeError)
 	{
 		ImgTimeWarnLevel = Severity_Middle;			//若生成图片的时间早于本次交易时间,则告LEVEL2
 	}

+ 4 - 2
Module/mod_IDCertificate/IDCertFSM.h

@@ -97,6 +97,7 @@ enum BmpType
 
 #pragma region forsonar
 typedef IDCertificate::IDCertService_CancelRead_Info IDCert_CancelRead_Info;
+typedef IDCertificate::IDCertService_Exit_Info IDCert_Exit_Info;
 typedef IDCertificate::IDCertService_ReadAndScanUTF8_Req IDCert_ReadAndScanUTF8_Req; //ex2
 typedef IDCertificate::IDCertService_ReadAndScanUTF8_Ans IDCert_ReadAndScanUTF8_Ans;
 typedef IDCertificate::IDCertService_ReadAndScanUTF8JS_Req IDCert_ReadAndScanUTF8JS_Req; //js ReadAndScanUTF8
@@ -229,7 +230,8 @@ public:
 	END_FSM_RULE()
 
 		CIDCertFSM() :m_bCancelRead(false), m_bReading(false),
-		m_bExit(false), m_testResult(Error_Succeed), m_getDevCategory(Error_Unexpect),transImgMsg("")
+		m_bExit(false), m_bGetHeadPhotoFailed(false), m_bHeadPhotoTimeError(false), m_bFrontPhotoTimeError(false), m_bBackPhotoTimeError(false),
+		m_testResult(Error_Succeed), m_getDevCategory(Error_Unexpect), transImgMsg("")
 	{
 		ZeroMemory(&m_adapterInfo, sizeof(m_adapterInfo));
 		HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x201);
@@ -305,7 +307,7 @@ private:
 public:
 		std::string checkImgURL;
 private:
-	bool m_bCancelRead, m_bReading, m_bExit;
+	bool m_bCancelRead, m_bReading, m_bExit, m_bGetHeadPhotoFailed, m_bHeadPhotoTimeError, m_bFrontPhotoTimeError, m_bBackPhotoTimeError;
 	ErrorCodeEnum m_testResult;
 	ErrorCodeEnum m_getDevCategory;
 	DevCategoryInfo m_devCatInfo;

+ 2 - 0
Module/mod_IDCertificate/IDCertificate.xml

@@ -3,6 +3,8 @@
 	<class name="IDCertService" overlap="true" exclusive="false">
 		<oneway name="CancelRead" overlap="true" method_id="1">
 		</oneway>
+		<oneway name="Exit" overlap="true" method_id="3">
+		</oneway>
 		<!-- 1、设备未打开,errorCode为Error_DevNotAvailable(2050),rtaCode为RTA2105 -->
 		<twoway name="GetDevInfo" overlap="true" jsflag="true" method_id="65535">
 			<req>

+ 4 - 0
Module/mod_IDCertificate/IDCertificate_UserErrorCode.h

@@ -27,6 +27,10 @@
 #define IDCertificate_UserErrorCode_FindFile_in_DepBak			0x20100220 //旧dep目录下获取到厂商文件
 #define IDCertificate_UserErrorCode_Timeout_NoCard			0x20100221 //超时未插卡
 #define IDCertificate_UserErrorCode_Timeout_OtherCard		0x20100222 //插入其他卡片(非身份证)
+#define IDCertificate_UserErrorCode_ReadAndScan_GetHeadPhotoFailed	0x20100223 //获取芯片头像图片失败
+#define IDCertificate_UserErrorCode_ReadAndScan_HeadPhotoTimeError	0x20100224 //头像图片时间异常
+#define IDCertificate_UserErrorCode_ReadAndScan_FrontPhotoTimeError	0x20100225 //正面扫描件时间异常
+#define IDCertificate_UserErrorCode_ReadAndScan_BackPhotoTimeError	0x20100226 //背面扫描件时间异常
 
 #define IDCertificate_UserErrorCode_GetImgFileTime			0x20100230 //图片文件的最近修改时间
 

+ 14 - 0
Module/mod_IDCertificate/IDCertificate_client_g.h

@@ -72,6 +72,20 @@ public:
 		return ret;
 	}
 
+	ErrorCodeEnum Exit()
+	{
+		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(IDCertService_Method_Exit, IDCertService_MethodSignature_Exit, m_context);
+		m_context.clear();
+		return ret;
+	}
+
 	ErrorCodeEnum GetDevInfo(IDCertService_GetDevInfo_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
 	{
 		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();

+ 12 - 0
Module/mod_IDCertificate/IDCertificate_def_g.h

@@ -13,18 +13,21 @@ namespace IDCertificate {
 //
 
 #define IDCertService_Method_CancelRead 1
+#define IDCertService_Method_Exit 3
 #define IDCertService_Method_GetDevInfo 65535
 #define IDCertService_Method_ReadAndScanUTF8 9
 #define IDCertService_Method_ReadAndScanUTF8JS 10
 #define IDCertService_Method_CancelReadJS 11
 
 #define IDCertService_MethodSignature_CancelRead -342104338
+#define IDCertService_MethodSignature_Exit -1158854104
 #define IDCertService_MethodSignature_GetDevInfo 296205965
 #define IDCertService_MethodSignature_ReadAndScanUTF8 1171255469
 #define IDCertService_MethodSignature_ReadAndScanUTF8JS 1636770944
 #define IDCertService_MethodSignature_CancelReadJS -1728083983
 
 #define IDCertService_LogCode_CancelRead "QLR040220101"
+#define IDCertService_LogCode_Exit "QLR040220103"
 #define IDCertService_LogCode_GetDevInfo "QLR040220199"
 #define IDCertService_LogCode_ReadAndScanUTF8 "QLR040220109"
 #define IDCertService_LogCode_ReadAndScanUTF8JS "QLR040220110"
@@ -39,6 +42,15 @@ struct IDCertService_CancelRead_Info
 
 };
 
+struct IDCertService_Exit_Info
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
 struct IDCertService_GetDevInfo_Req
 {
 

+ 27 - 0
Module/mod_IDCertificate/IDCertificate_server_g.h

@@ -37,6 +37,13 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case IDCertService_Method_Exit:
+			if (dwSignature == IDCertService_MethodSignature_Exit) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		case IDCertService_Method_GetDevInfo:
 			if (dwSignature == IDCertService_MethodSignature_GetDevInfo) {
 				bOverlap = true;
@@ -81,6 +88,11 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case IDCertService_Method_Exit:
+			if (dwSignature != IDCertService_MethodSignature_Exit) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		case IDCertService_Method_GetDevInfo:
 			if (dwSignature != IDCertService_MethodSignature_GetDevInfo) {
 				Error = Error_MethodSignatureFailed;
@@ -113,6 +125,11 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_Exit(SpOnewayCallContext<IDCertService_Exit_Info>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void Handle_GetDevInfo(SpReqAnsContext<IDCertService_GetDevInfo_Req, IDCertService_GetDevInfo_Ans>::Pointer ctx)
 	{
 	/// override by user
@@ -159,6 +176,16 @@ public:
 						Handle_CancelRead(ctx);
 					}
 					break;
+				case IDCertService_Method_Exit:
+					{
+						SpOnewayCallContext<IDCertService_Exit_Info>::Pointer ctx;
+						ctx.Attach(new SpOnewayCallContext<IDCertService_Exit_Info>());
+						SpBuffer2Object(Buf, ctx->Info);
+						pTransactionContext->GetLinkContext(ctx->link);
+						EntityResource::setLink(ctx->link);
+						Handle_Exit(ctx);
+					}
+					break;
 				case IDCertService_Method_GetDevInfo:
 					{
 						SpReqAnsContext<IDCertService_GetDevInfo_Req,IDCertService_GetDevInfo_Ans>::Pointer ctx;

+ 8 - 0
Module/mod_IDCertificate/mod_IDCertificate.cpp

@@ -16,6 +16,14 @@ void IDCertServerSession::Handle_CancelReadJS(SpReqAnsContext<IDCert_CancelReadJ
 	m_pEntity->CancelReadJS(ctx);
 }
 
+
+void IDCertServerSession::Handle_Exit(SpOnewayCallContext<IDCert_Exit_Info>::Pointer ctx)
+{
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Handle_Exit");
+	m_pEntity->Exit(ctx);
+}
+
 void IDCertServerSession::Handle_GetDevInfo(SpReqAnsContext<IDCert_GetDevInfo_Req, IDCert_GetDevInfo_Ans>::Pointer ctx)
 {
 	DbgToBeidou(ctx->link, __FUNCTION__)();

+ 7 - 0
Module/mod_IDCertificate/mod_IDCertificate.h

@@ -19,6 +19,7 @@ public:
 	virtual ~IDCertServerSession(){}
 	virtual void Handle_CancelRead(SpOnewayCallContext<IDCert_CancelRead_Info>::Pointer ctx);
 	virtual void Handle_CancelReadJS(SpReqAnsContext<IDCert_CancelReadJS_Req, IDCert_CancelReadJS_Ans>::Pointer ctx);
+	virtual void Handle_Exit(SpOnewayCallContext<IDCert_Exit_Info>::Pointer ctx);
 	virtual void Handle_GetDevInfo(SpReqAnsContext<IDCert_GetDevInfo_Req, IDCert_GetDevInfo_Ans>::Pointer ctx);
 	virtual void Handle_ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCert_ReadAndScanUTF8_Ans>::Pointer ctx); //ex1
 	virtual void Handle_ReadAndScanUTF8JS(SpReqAnsContext<IDCert_ReadAndScanUTF8JS_Req, IDCert_ReadAndScanUTF8JS_Ans>::Pointer ctx);
@@ -92,6 +93,12 @@ public:
 		ctx->Answer(Error_Succeed);
 	}
 
+	void Exit(SpOnewayCallContext<IDCert_Exit_Info>::Pointer ctx)
+	{
+		FSMEvent* evt = new FSMEvent(USER_EVT_EXIT);
+		m_fsm.PostEventFIFO(evt);
+	}
+
 	void ReadAndScanUTF8(SpReqAnsContext<IDCert_ReadAndScanUTF8_Req, IDCert_ReadAndScanUTF8_Ans>::Pointer ctx) //ex2
 	{
 		if (!m_fsm.GetDevInitFlag())