|
@@ -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;
|
|
|
+}
|