浏览代码

Z991239-5384 #comment 新增JS接口实现

oilyang 1 年之前
父节点
当前提交
8004f78ae3
共有 4 个文件被更改,包括 483 次插入31 次删除
  1. 387 0
      Module/mod_pinpad/PinPadFSM.cpp
  2. 35 28
      Module/mod_pinpad/PinPadFSM.h
  3. 36 2
      Module/mod_pinpad/mod_PinPad.h
  4. 25 1
      Module/mod_pinpad/mod_pinpad.cpp

+ 387 - 0
Module/mod_pinpad/PinPadFSM.cpp

@@ -20,6 +20,7 @@ const int PINPAD_INIT_TRIES = 3;
 const int PINPAD_ANY_INPUT_TIMEOUT = 100;
 const int MAX_PINPAD_INPUT_TIMEOUT = 60000;
 const int MAX_INPUT_TIMER_TIMEOUT = 600000;
+const int CurrentPasswordLen = 6;//according to guodan, we only use 6
 
 void CPinPadFSM::ToLogWarnInfoAboutTermCustom()
 {
@@ -147,6 +148,12 @@ unsigned int CPinPadFSM::s2_on_event(FSMEvent* pEvt)
 			pEvt->SetHandled();
 			return 0;
 		}
+	case USER_EVT_GETINPUT_JS:
+	{
+		m_hInputConVar.Broadcast();
+		pEvt->SetHandled();
+		return 0;
+	}
 	case USER_EVT_LOADKEY_SM:
 		{
 			pEvt->SetHandled();
@@ -204,6 +211,9 @@ unsigned int CPinPadFSM::s3_on_event(FSMEvent* evt)
 	case USER_EVT_GETINPUT_SM_FINISHED:
 		evt->SetHandled();
 		break;
+	case USER_EVT_GETINPUT_JS_FINISHED:
+		evt->SetHandled();
+		break;
 	case USER_EVT_INPUTCANCEL:
 		evt->SetHandled();
 		m_bFrontCancel = true;
@@ -471,6 +481,18 @@ unsigned int __stdcall DoWork(void *pData)
 			ret = pFsm->Initial();
 			evt = new FSMEvent(USER_EVT_INITFINISHED);
 		}
+		else if (pFsm->IsInGetInputJS())
+		{
+			SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS;
+			bool bRet = pFsm->GetJSCtx(ctxJS);
+			if (!bRet)
+			{
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get ctx(JS) failed.doing nothing");
+				continue;
+			}
+			ret = pFsm->GetInputJS(ctxJS);
+			evt = new FSMEvent(USER_EVT_GETINPUT_JS_FINISHED);
+		}
 		else
 		{
 			SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctxSM;
@@ -1400,3 +1422,368 @@ void CPinPadFSM::SelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionCon
 	else
 		pTransactionContext->SendAnswer(Error_InvalidState);
 }
+ErrorCodeEnum CPinPadFSM::GetEncryptTextJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS)
+{
+	LOG_FUNCTION();
+	ErrorCodeEnum errCode;
+	CSmartPointer<IEntityFunction> spEntityFunction = GetEntityBase()->GetFunction();
+	int timeout = ctxJS->Req.timeout;
+
+	AccountInfo accInfo;
+	memset(accInfo.account, 0, MAX_ACCOUNT_LEN);
+	CSimpleStringA errMsg(true);
+
+	if (Get12Account(const_cast<char*>(ctxJS->Req.account.GetData())))
+		memcpy(accInfo.account, m_szAccount + 4, 12);
+	else
+	{
+		errMsg = CSimpleStringA::Format("Get12Account err(%s).", (const char*)ctxJS->Req.account);
+		if (m_iInWhatPage == PageType_Other)
+		{
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setResultCode("RTA2607")(errMsg.GetData());
+			LogError(Severity_High, Error_Unexpect, PinPad_UserErrorCode_PinPad_GetEncryptText_Get12Account_Error, errMsg.GetData());
+		}
+		else
+			LogWarn(Severity_High, Error_Unexpect, PinPad_UserErrorCode_PinPad_GetEncryptText_Get12Account_Error, errMsg.GetData());
+		ctxJS->Answer(Error_DevCommFailed, PinPad_UserErrorCode_PinPad_GetEncryptText_Get12Account_Error);
+		return Error_DevCommFailed;
+	}
+
+	//memcpy(accInfo.account,"588571006555",12);
+	accInfo.dwAccLen = 12;
+	DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("acc(%s)", accInfo.account);
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	errCode = m_hDevHelper->SetAccNo(accInfo);
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+	if (errCode != Error_Succeed)
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("[sm]set accout(%s)(%s) failed(%d).", (const char*)ctxJS->Req.account, accInfo.account, errCode);
+
+		SetErrPackage("GetEncryptText::SetAccNo", m_devSN, errCode, MEC_DEVAPI_EPP_SetAccNo);
+		if (IsInBusiness())
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetAccNo")
+				.setCostTime(m_ullEndTime - m_ullBeginTime).setResultCode("RTA2608")("设置账号失败:%s", SpStrError(errCode));
+		}
+		else
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetAccNo")
+				.setCostTime(m_ullEndTime - m_ullBeginTime).setResultCode("RTA2608")("设置账号失败:%s", SpStrError(errCode));
+		}
+
+		return Error_DevCommFailed;
+	}
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::SetAccNo").setCostTime(m_ullEndTime - m_ullBeginTime)();
+
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	errCode = m_hDevHelper->ActiveWorkingKey(1, 0);
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+	if (errCode != Error_Succeed)
+	{
+		SetErrPackage("GetEncryptText::ActiveWorkingKey", m_devSN, errCode, MEC_DEVAPI_EPP_ActiveWorkingKey);
+		if (IsInBusiness())
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::ActiveWorkingKey")
+				.setResultCode("RTA260C").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时激活工作密钥失败");
+		}
+		else
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::ActiveWorkingKey")
+				.setResultCode("RTA260C").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时激活工作密钥失败");
+		}
+		return Error_DevCommFailed;
+	}
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI("DevAdapter::ActiveWorkingKey").setCostTime(m_ullEndTime - m_ullBeginTime)();
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	errCode = m_hDevHelper->SetParam(EPP_PT_SET_PIN_ALGORITH, EPP_PIN_ALGO_SM4);
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+	if (errCode != Error_Succeed)
+	{
+		SetErrPackage("GetEncryptText::SetParam", m_devSN, errCode, MEC_DEVAPI_EPP_SetParam);
+		if (IsInBusiness())
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetParam")
+				.setResultCode("RTA260B")("计算密文时设置参数失败:%s", SpStrError(errCode));
+		}
+		else
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetParam")
+				.setResultCode("RTA260B")("计算密文时设置参数失败:%s", SpStrError(errCode));
+		}
+		return Error_DevCommFailed;
+	}
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::SetParam").setCostTime(m_ullEndTime - m_ullBeginTime)();
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	errCode = m_hDevHelper->StartPinInput(CurrentPasswordLen);
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+	if (errCode != Error_Succeed)
+	{
+		SetErrPackage("GetEncryptText::StartPinInput", m_devSN, errCode, MEC_DEVAPI_EPP_StartPinInput);
+		if (IsInBusiness())
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::StartPinInput")
+				.setResultCode("RTA2609").setCostTime(m_ullEndTime - m_ullBeginTime)("%s", SpStrError(errCode));
+		}
+		else
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::StartPinInput")
+				.setResultCode("RTA2609").setCostTime(m_ullEndTime - m_ullBeginTime)("%s", SpStrError(errCode));
+		}
+		return Error_DevCommFailed;
+	}
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::StartPinInput").setCostTime(m_ullEndTime - m_ullBeginTime)();
+	char* buf = new char[CurrentPasswordLen + 1];
+	memset(buf, 0, CurrentPasswordLen + 1);
+	int readed = 0;
+	DWORD elapsed = 0;
+	DWORD dwStart = SP::Module::Comm::RVCGetTickCount();
+	DWORD dwEnd = SP::Module::Comm::RVCGetTickCount();
+	bool bCancelInput = false;
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("req(pin),timeout:[%d]", timeout);
+	while (elapsed < MAX_PINPAD_INPUT_TIMEOUT) {
+		if (readed >= CurrentPasswordLen)
+			break;
+		if (m_bFrontCancel)
+		{
+			bCancelInput = true;
+			goto Err;
+		}
+		BYTE btCh;
+		Sleep(100);
+		errCode = m_hDevHelper->KeyRead(btCh);//循环调用,无需计算耗时
+		if (errCode == Error_Succeed) {
+			LogEvent(Severity_Middle, LOG_EVT_PINPAD_OP, "PinPad op.", ctxJS->link);
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("PinPad op: %d", readed);
+			if (btCh == 0x0d) {
+				dwEnd = SP::Module::Comm::RVCGetTickCount();
+				elapsed = dwEnd - dwStart;
+				continue;
+			}
+			else if (btCh == 0x08) { // back
+				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER)("clear input");
+				pop_char(buf, &readed, true);
+			}
+			else if (btCh == 0x1b) { // quit
+				bCancelInput = true;
+				goto Err;
+			}
+			else if (btCh == 0x3f) {
+				push_char(buf, &readed, '*');
+			}
+			else {
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("else[%d]", btCh);
+			}
+
+		}
+		else {
+		}
+		dwEnd = SP::Module::Comm::RVCGetTickCount();
+		elapsed = dwEnd - dwStart;
+	}
+	buf[readed] = 0;
+
+Err:
+
+	if (buf != NULL)
+		delete[]buf;
+	if (bCancelInput)
+	{
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040220602")("input cancel(pin)");
+		ctxJS->Answer(Error_Cancel);
+		return Error_Cancel;
+	}
+	if (readed < CurrentPasswordLen) {
+		if (elapsed >= MAX_PINPAD_INPUT_TIMEOUT) {
+			ctxJS->Answer(Error_TimeOut);
+			return Error_TimeOut;
+		}
+	}
+	PinBlock pinBlk;
+	DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to getpinblk");
+	Sleep(500);//nantian
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	errCode = m_hDevHelper->GetPinBlock(pinBlk);
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+
+	LogWarn(Severity_Low, Error_Succeed, PinPad_UserErrorCode_PinPad_GetPinBlock_Call
+		, CSimpleStringA::Format("{\"cost\":%d}", m_ullEndTime - m_ullBeginTime));
+	if (errCode == Error_Succeed)
+	{
+		char* tmpPinData = new char[MAX_PIN_BLOCK_SIZE];
+		if (tmpPinData == NULL)
+			return Error_Resource;
+		memset(tmpPinData, 0, MAX_PIN_BLOCK_SIZE);
+		memcpy(tmpPinData, pinBlk.data, pinBlk.dwSize);
+
+		ctxJS->Ans.data = tmpPinData;
+		//Dbg("pinblk(%s)",tmpPinData);
+		if (tmpPinData != NULL)
+		{
+			delete[]tmpPinData;
+			tmpPinData = NULL;
+		}
+		EnDecryptInfo srcInfo, dstInfo;
+		memset(srcInfo.data, 0, MAX_EN_DECRYPT_DATA_SIZE);
+		memcpy(srcInfo.data, m_devCheckData, m_devCheckData.GetLength());
+		srcInfo.dwSize = m_devCheckData.GetLength();
+		memset(dstInfo.data, 0, MAX_EN_DECRYPT_DATA_SIZE);
+		//set param
+		m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+		errCode = m_hDevHelper->SetParam(EPP_PT_SET_ENCRYPT_METHOD, EPP_ALGO_METHOD_SM4);
+		if (errCode == Error_Succeed)
+			errCode = m_hDevHelper->SetParam(EPP_PT_SET_ECB_CBC_MODE, EPP_ALGO_MODE_CBC);
+		m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+		if (errCode != Error_Succeed)
+		{
+			SetErrPackage("GetEncryptText::SetParam", m_devSN, errCode, MEC_DEVAPI_EPP_SetParam);
+			if (IsInBusiness())
+			{
+				ctxJS->Answer(Error_Param, AlarmDEC(true));
+				DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetParam")
+					.setResultCode("RTA260B").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时设置参数失败:%s", SpStrError(errCode));
+			}
+			else
+			{
+				ctxJS->Answer(Error_Param, AlarmDEC());
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::SetParam")
+					.setResultCode("RTA260B").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时设置参数失败:%s", SpStrError(errCode));
+			}
+			return Error_Param;
+		}
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::SetParam").setCostTime(m_ullEndTime - m_ullBeginTime)();
+		m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+		errCode = m_hDevHelper->EncryptData(srcInfo, dstInfo);
+		m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+
+		if (errCode != Error_Succeed)
+		{
+			SetErrPackage("GetEncryptText::EncryptData", m_devSN, errCode, MEC_DEVAPI_EPP_EncryptData);
+			if (IsInBusiness())
+			{
+				ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+				DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::EncryptData")
+					.setResultCode("RTA260D").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时数据加密失败", SpStrError(errCode));
+			}
+			else
+			{
+				ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+				DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::EncryptData")
+					.setResultCode("RTA260D").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文时数据加密失败", SpStrError(errCode));
+			}
+			return Error_DevCommFailed;
+		}
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::EncryptData").setCostTime(m_ullEndTime - m_ullBeginTime)();
+
+		char* tmpCheckCode = new char[MAX_PIN_BLOCK_SIZE];
+		if (tmpCheckCode == NULL)
+			return Error_Resource;
+		memset(tmpCheckCode, 0, MAX_PIN_BLOCK_SIZE);
+		//HexBuf2StrBuf(dstInfo.data,&tmpCheckCode,dstInfo.dwSize);
+		memcpy(tmpCheckCode, dstInfo.data, dstInfo.dwSize);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("ckckck[%s], m_keySNSM:%s", tmpCheckCode, m_keySNSM.GetData());
+
+
+		if (strnicmp(tmpCheckCode, "9F1F7BFF6F5511384D9430531E538FD3",
+			strlen("9F1F7BFF6F5511384D9430531E538FD3")) == 0)
+		{
+			SetErrPackage("GetEncryptText::EncryptData(SM)", m_devSN, Error_Unexpect, PinPad_UserErrorCode_KEY_LOST_SM);
+			AlarmDEC();
+		}
+		ctxJS->Ans.checkcode = tmpCheckCode;
+		ctxJS->Ans.deviceno = m_deviceNo;
+		ctxJS->Ans.keyseq = m_keySNSM;
+
+		CSimpleStringA tmpLastCkCode = m_lastCheckCode;
+		if (m_lastCheckCode.IsNullOrEmpty() || strnicmp(tmpCheckCode, m_lastCheckCode, m_lastCheckCode.GetLength()) != 0)
+		{
+			ErrorCodeEnum eErr;
+			CSmartPointer<IConfigInfo> spConfigRun;
+			eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun);
+			if (eErr == Error_Succeed)
+			{
+				spConfigRun->WriteConfigValue("Load", "ckckck", tmpCheckCode);
+				m_lastCheckCode = tmpCheckCode;
+			}
+			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("write ckckck:%s", tmpCheckCode);
+		}
+		if (!tmpLastCkCode.IsNullOrEmpty() && strnicmp(tmpCheckCode, tmpLastCkCode, tmpLastCkCode.GetLength()) != 0)
+		{
+			CSimpleStringA xCkChangeMsg = CSimpleStringA::Format("last ck:%s,current ck:%s,m_keySNSM:%s", tmpLastCkCode.GetData()
+				, tmpCheckCode, m_keySNSM.GetData());
+			LogWarn(Severity_Low, Error_Unexpect, PinPad_UserErrorCode_PinPad_CheckCode_Changed, xCkChangeMsg.GetData());
+		}
+	}
+	else
+	{
+		SetErrPackage("GetEncryptText::GetPinBlock", m_devSN, errCode, MEC_DEVAPI_EPP_GetPinBlock);
+		if (IsInBusiness())
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC(true));
+			DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::GetPinBlock")
+				.setResultCode("RTA260A").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文失败:%s", SpStrError(errCode));
+		}
+		else
+		{
+			ctxJS->Answer(Error_DevCommFailed, AlarmDEC());
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM).setAPI("DevAdapter::GetPinBlock")
+				.setResultCode("RTA260A").setCostTime(m_ullEndTime - m_ullBeginTime)("计算密文失败:%s", SpStrError(errCode));
+		}
+
+		return Error_DevCommFailed;
+	}
+	DbgWithLink(LOG_LEVEL_INFO, ctxJS->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setLogCode(PinPadService_LogCode_GetInputSM)
+		.setAPI("DevAdapter::GetPinBlock").setCostTime(m_ullEndTime - m_ullBeginTime)("获取密文成功");
+	//oilyang@20240410 move to out space,after stopinput & turn off the light
+	//Sleep(100);
+	//ctxSM->Answer(Error_Succeed);
+	return Error_Succeed;
+}
+int CPinPadFSM::GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS)
+{
+	DWORD dwCurrThId = GetCurrentThreadId();
+	DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetInput thread id:%d", dwCurrThId);
+	m_bFrontCancel = false;
+	LogEvent(Severity_Middle, LOG_EVT_PINPAD_GREEN_ON, "PinPad light on.");
+	if (!m_hDevHelper)
+	{
+		SetErrPackage("GetInput(JS)", m_devSN, Error_Unexpect, PinPad_UserErrorCode_PinPad_Instance_Is_Null);
+		m_inputJSCtx->Answer(Error_Unexpect, AlarmDEC());//TODO oiltmp ,to define RTAxxxx
+		LogEvent(Severity_Middle, LOG_EVT_PINPAD_GREEN_OFF, "PinPad light off.");
+		m_bPinInputJS = false;
+		return 1;
+	}
+
+	ErrorCodeEnum eErrCode = GetEncryptTextJS(m_inputJSCtx);
+
+	m_ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	ErrorCodeEnum errClosePinPad = m_hDevHelper->StopInput();
+	m_ullEndTime = SP::Module::Comm::RVCGetTickCount();
+	if (errClosePinPad != Error_Succeed)
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::StopInput").setResultCode("RTA2614").setCostTime(m_ullEndTime - m_ullBeginTime)("close pinpad(%s).", SpStrError(errClosePinPad));
+	else
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::StopInput").setCostTime(m_ullEndTime - m_ullBeginTime)("StopInput cost(%d)ms", m_ullEndTime - m_ullBeginTime);
+
+	DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)
+		("req acc.len:%d,ans.ck.len:%d", m_inputJSCtx->Req.account.GetLength(), m_inputJSCtx->Ans.checkcode.IsNullOrEmpty() ? 0 : m_inputJSCtx->Ans.checkcode.GetLength());
+	DbgToBeidou(m_inputJSCtx->link, "GetInput")();
+	m_bPinInput = false;
+	LogEvent(Severity_Middle, LOG_EVT_PINPAD_GREEN_OFF, "PinPad light off.");
+
+	if (eErrCode == Error_Succeed)
+		m_inputJSCtx->Answer(Error_Succeed);
+
+	return 0;
+}

+ 35 - 28
Module/mod_pinpad/PinPadFSM.h

@@ -32,6 +32,8 @@ enum EvtType
 	USER_EVT_GET_CHECKCODE_FINISHED,
 	USER_EVT_TODO_INIT,
 	USER_EVT_TODO_INIT_FINISHED,
+	USER_EVT_GETINPUT_JS,
+	USER_EVT_GETINPUT_JS_FINISHED,
 };
 #include "PinPad_server_g.h"
 #include "PinPad_msg_g.h"
@@ -39,23 +41,8 @@ enum EvtType
 #include "PinPadClass.h"
 #include "DeviceBaseHelper.h"
 
-//using namespace PinPad;
-using PinPad::PinPadService_InputWaitMore_Info;
-using PinPad::PinPadService_InputCancel_Info;
-using PinPad::PinPadService_Exit_Info;
-using PinPad::PinPadService_GetInputSM_Req;
-using PinPad::PinPadService_GetInputSM_Ans;
-using PinPad::PinPadService_LoadKeysSM_Req;
-using PinPad::PinPadService_LoadKeysSM_Ans;
-using PinPad::PinPadService_EncryptDataSM_Req;
-using PinPad::PinPadService_EncryptDataSM_Ans;
-using PinPad::PinPadService_QueryFunc_Req;
-using PinPad::PinPadService_QueryFunc_Ans;
-using PinPad::PinPadService_GetCheckCode_Req;
-using PinPad::PinPadService_GetCheckCode_Ans;
-using PinPad::PinPadService_GetDevInfo_Req;
-using PinPad::PinPadService_GetDevInfo_Ans;
-using PinPad::InputContent;
+using namespace PinPad;
+
 
 #include <map>
 using namespace std;
@@ -106,6 +93,17 @@ public:
 		}
 	}
 };
+class GetInputJSEvent : public FSMEvent
+{
+public:
+	GetInputJSEvent() : FSMEvent(USER_EVT_GETINPUT_JS) {}
+	~GetInputJSEvent() {}
+	SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctx;
+	virtual void OnUnhandled()
+	{
+		DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("InvalidState");
+	}
+};
 class LoadKeySMEvent : public FSMEvent
 {
 public:
@@ -168,10 +166,12 @@ public:
 		FSM_RULE_ENTRY(s1, s2, USER_EVT_INITFINISHED, 0)
 		FSM_RULE_ENTRY(s1, s6, USER_EVT_INITFINISHED, 1)
 		FSM_RULE_ENTRY(s2, s3, USER_EVT_GETINPUT_SM, 0)
+		FSM_RULE_ENTRY(s2, s3, USER_EVT_GETINPUT_JS, 0)
 		FSM_RULE_ENTRY(s2, s4, USER_EVT_LOADKEY_SM, 2)
 		FSM_RULE_ENTRY(s2, s4, USER_EVT_ENCRYPT_SM, 2)
 		FSM_RULE_ENTRY(s2, s0, USER_EVT_TODO_INIT_FINISHED, 0)
 		FSM_RULE_ENTRY(s3, s2, USER_EVT_GETINPUT_SM_FINISHED, 0)
+		FSM_RULE_ENTRY(s3, s2, USER_EVT_GETINPUT_JS_FINISHED, 0)
 		FSM_RULE_ENTRY(s3, s2, USER_EVT_EXIT, 0)
 		FSM_RULE_ENTRY(s4, s2, USER_EVT_LOADKEY_SM_FINISHED, 0)
 		FSM_RULE_ENTRY(s4, s2, USER_EVT_ENCRYPT_SM_FINISHED, 0)
@@ -185,7 +185,7 @@ public:
 		, m_dwDevCommFailCount(0), m_dwPinPadRunCount(0), m_eDevState(DEVICE_STATUS_NOT_READY), m_encryptkey(1)
 		, m_bSM(false), m_bSMLoaded(false), m_iInWhatPage(PageType_Other), m_szModel(""), m_szType("")
 		, m_szVendor(""),m_csMachineType(true), m_csSite(true), m_terminalNo(true), m_port(true), m_Baudrate(true)
-		, m_devSN(""){
+		, m_devSN(""), m_bPinInputJS(false){
 			HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x206);
 			ZeroMemory(&m_adapterInfo, sizeof(m_adapterInfo));
 	}
@@ -247,18 +247,24 @@ public:
 		ctxSM = m_inputSMCtx;
 		return true;
 	}
-	template <class TReq, class TAns>
-	void SaveCtx(int methodID, CSmartPointer<SpReqAnsContext<TReq, TAns> > ctx)
+	void SetJSCtx(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS)
 	{
-		m_mapCtx[methodID].pCtx = static_cast<void*>(ctx.GetRawPointer());
+		m_inputJSCtx = ctxJS;
+		m_bPinInputJS = true;
 	}
-	LPVOID  GetCtx(int methodID)
+	bool GetJSCtx(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer& ctxJS)
 	{
-		if (m_mapCtx.find(methodID) != m_mapCtx.end())
-			return m_mapCtx[methodID].pCtx;
-		else
-			return NULL;
+		if (m_inputJSCtx == NULL)
+		{
+			DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ctxJS is null");
+			return false;
+		}
+		ctxJS = m_inputJSCtx;
+		return true;
 	}
+	int GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS);
+	ErrorCodeEnum GetEncryptTextJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS);
+
 	bool GetDevInfo(DevCategoryInfo &devInfo);
 	int LoadKeySM(SpReqAnsContext<PinPadService_LoadKeysSM_Req, PinPadService_LoadKeysSM_Ans>::Pointer ctx);
 	int EncryptSM(SpReqAnsContext<PinPadService_EncryptDataSM_Req, PinPadService_EncryptDataSM_Ans>::Pointer ctx);
@@ -283,15 +289,17 @@ public:
 	void SetInWhatPage(int iPageType);
 	void SelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext);
 	void ToLogWarnInfoAboutTermCustom();
+	bool IsInGetInputJS() { return m_bPinInputJS; }
 public:
 	SP::Toolkit::CConditionVarPlus m_hInputConVar;
 	SP::Toolkit::CConditionVarPlus m_hInitConVar;
 private:
 
 	SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer m_inputSMCtx;
+	SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer m_inputJSCtx;
 	char m_szAccount[MAX_ACCOUNT_LEN];
 	bool m_bFrontCancel,m_bWaitingMore,m_bExit,m_bPlainPin,m_bEntityExit
-		,m_bPinInput,m_bLoadKey,m_bEncrypt,m_bSM,m_bSMLoaded;
+		,m_bPinInput,m_bLoadKey,m_bEncrypt,m_bSM,m_bSMLoaded, m_bPinInputJS;
 	ULLINT m_ullBeginTime, m_ullEndTime,m_ullConnectCost;
 	CSimpleStringA m_deviceNo, m_port, m_Baudrate, m_devCheckData,m_keySNSM,m_szModel,m_szType,m_szVendor,m_devSN/*fwb SN*/;
 	char m_buf[4];
@@ -304,7 +312,6 @@ private:
 	CSystemStaticInfo m_sysStaticInfo;
 
 	CSimpleStringA m_csAlarmMsg;
-	map<int, CtxInfo> m_mapCtx;
 	bool IsInBusiness() { return (m_iInWhatPage == PageType_Other); }
 };
 

+ 36 - 2
Module/mod_pinpad/mod_PinPad.h

@@ -13,6 +13,8 @@ public:
 	void Handle_InputWaitMore(SpOnewayCallContext<PinPadService_InputWaitMore_Info>::Pointer ctx);
 	void Handle_InputCancel(SpOnewayCallContext<PinPadService_InputCancel_Info>::Pointer ctx);
 	void Handle_Exit(SpOnewayCallContext<PinPadService_Exit_Info>::Pointer ctx);
+	void Handle_GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctx);
+	void Handle_InputCancelJS(SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx);
 	void Handle_GetDevInfo(SpReqAnsContext<PinPadService_GetDevInfo_Req, PinPadService_GetDevInfo_Ans>::Pointer ctx);
 	void Handle_GetInputSM(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctx);
 	void Handle_LoadKeysSM(SpReqAnsContext<PinPadService_LoadKeysSM_Req, PinPadService_LoadKeysSM_Ans>::Pointer ctx);
@@ -89,7 +91,29 @@ public:
 		FSMEvent *evt = new FSMEvent(USER_EVT_EXIT);
 		m_fsm.PostEventFIFO(evt);
 	}
-
+	void GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctx)
+	{
+		if (!m_fsm.GetDevInitFlag())
+			ctx->Answer(Error_DevNotAvailable, PinPad_UserErrorCode_PinPad_DevOpenFailed);
+		else {
+			m_fsm.SetJSCtx(ctx);
+			GetInputJSEvent* e = new GetInputJSEvent();
+			e->ctx = ctx;
+			m_fsm.PostEventFIFO(e);
+		}
+	}
+	void InputCancelJS(SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx)
+	{
+		if (!m_fsm.GetDevInitFlag())
+			ctx->Answer(Error_DevNotAvailable, PinPad_UserErrorCode_PinPad_DevOpenFailed);
+		else if (_stricmp(m_fsm.GetCurrStateName(), "Input") != 0)
+			ctx->Answer(Error_Unexpect, PinPad_UserErrorCode_NotInGetInput);
+		else
+		{
+			InputCancelEvent* e = new InputCancelEvent();
+			m_fsm.PostEventFIFO(e);
+		}
+	}
 	void GetInputSM(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctx)
 	{
 		if (!m_fsm.GetDevInitFlag())
@@ -163,6 +187,7 @@ public:
 		else
 			ctx->Answer(Error_DevNotAvailable, PinPad_UserErrorCode_PinPad_DevOpenFailed);
 	}
+	void DoInputCancelJS(SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx);
 	bool GetDevInitInfo() { return m_fsm.GetDevInitFlag(); }
 	virtual void OnSysVarEvent(const char *pszKey,
 		const char *pszValue, const char *pszOldValue, const char *pszEntityName);
@@ -178,5 +203,14 @@ private:
 	int m_state;
 
 };
-
+struct InputCancelJSTask : public ITaskSp
+{
+	CPinPadEntity* pEntity;
+	SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx;
+	InputCancelJSTask(CPinPadEntity* entity) : pEntity(entity) {}
+	void Process()
+	{
+		pEntity->DoInputCancelJS(ctx);
+	}
+};
 #endif //__MOD_PINPAD_H

+ 25 - 1
Module/mod_pinpad/mod_pinpad.cpp

@@ -22,7 +22,16 @@ void PinPadServerSession::Handle_Exit(SpOnewayCallContext<PinPadService_Exit_Inf
 	DbgToBeidou(ctx->link, __FUNCTION__)();
 	m_pEntity->Exit(ctx);
 }
-
+void PinPadServerSession::Handle_GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctx)
+{
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	m_pEntity->GetInputJS(ctx);
+}
+void PinPadServerSession::Handle_InputCancelJS(SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx)
+{
+	DbgToBeidou(ctx->link, __FUNCTION__)();
+	m_pEntity->InputCancelJS(ctx);
+}
 void PinPadServerSession::Handle_GetInputSM(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctx)
 {
 	DbgToBeidou(ctx->link, __FUNCTION__)();
@@ -53,6 +62,21 @@ void PinPadServerSession::Handle_GetDevInfo(SpReqAnsContext<PinPadService_GetDev
 {
 	m_pEntity->GetDevInfo(ctx);
 }
+void CPinPadEntity::DoInputCancelJS(SpReqAnsContext<PinPadService_InputCancelJS_Req, PinPadService_InputCancelJS_Ans>::Pointer ctx)
+{
+	ULLINT ullBeginTime = SP::Module::Comm::RVCGetTickCount();
+	ULLINT ullEndTime = SP::Module::Comm::RVCGetTickCount();
+	while ((ullEndTime - ullBeginTime) < 5000)
+	{
+		if (_stricmp(m_fsm.GetCurrStateName(), "Input") != 0)
+		{
+			ctx->Answer(Error_Succeed);
+			break;
+		}
+		Sleep(500);
+		ullEndTime = SP::Module::Comm::RVCGetTickCount();
+	}
+}
 void CPinPadEntity::OnSysVarEvent(const char *pszKey,
 	const char *pszValue, const char *pszOldValue, const char *pszEntityName)
 {