#include "stdafx.h" #include //CSimpleStringA ambigulous #if (defined(_WIN32) || defined(_WIN64)) #define _ATL_NO_AUTOMATIC_NAMESPACE #include #endif // #include "CardAssist.h" #include "SpBase.h" #ifndef _MSC_VER unsigned long GetTickCount() { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); } #endif #define DbgSysInfoWithLink DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM) #define DbgUserInfoWithLink DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER) #define DbgSysWarnWithLink DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM) void DbgInfo(CSimpleStringA apiName, long beginTime, long endTime, ErrorCodeEnum errCode, CSimpleStringA msg) { DbgSysInfoWithLink.setAPI(apiName).setBeginTime(beginTime).setEndTime(endTime).setResultCode(std::to_string((unsigned long)errCode).c_str())(msg.GetData()); } void DbgInfo(CSimpleStringA msg) { DbgSysInfoWithLink(msg.GetData()); } void DbgWarn(CSimpleStringA apiName, long beginTime, long endTime, ErrorCodeEnum errCode, CSimpleStringA msg) { DbgSysWarnWithLink.setAPI(apiName).setBeginTime(beginTime).setEndTime(endTime).setResultCode(std::to_string((unsigned long)errCode).c_str())(msg.GetData()); } void DbgWarn(CSimpleStringA msg) { DbgSysWarnWithLink(msg.GetData()); } char TTtmpxx[1024]; char TtestIC[1024]; bool compare_icdata (ICData d1,ICData d2) { unsigned int i1 = (d1.tag[0]<<8)+d1.tag[1]; unsigned int i2 = (d2.tag[0]<<8)+d2.tag[1]; return (i1 < i2); } bool IsSamePositionSet(LPBYTE p1,LPBYTE p2,int len) { int i = 0; while (i < len) { if ((*(p1 + i) & *(p2 + i)) != 0) { return true; } i++; } return false; } bool IsDoubleByteFlag(BYTE data) { if ((data&0x1f) == 0x1f) return true; else return false; } bool IsForm(LPBYTE data,int flagLen) { if (((*data)&0x20) == 0x20) return true; else return false; //if (flagLen == 1) //{ // if (*data == 0x6f || *data == 0xa5 || *data == 0x70 || *data == 0x61 // ||*data == 0x73) // return true; //}else if (flagLen == 2) //{ // if ((*data == 0xbf && *(data+1) == 0x0c) // ) // return true; //} //return false; } int SplitICData(vector& vResult, LPBYTE* origData, int start, int dataLen, int level , int origDataLen) { LPBYTE pData = *origData; DWORD len,tagLen,lenLen; len=tagLen=lenLen=0; int tmpDataStart = 0; int tagNum = 0; do { if (start >= origDataLen - 1) { DbgWarn(CSimpleStringA::Format("Wrong start %d,%d,%d", start, origDataLen,dataLen)); return 0; } if (!IsDoubleByteFlag(pData[start])) { tagLen = 1; BYTE dd = DATALENFLAG; BYTE dd2 = pData[start+tagLen]&DATALENFLAG; if (DATALENFLAG == (pData[start+tagLen]&DATALENFLAG)) {//长度为'8x'表示此字节表示长度所占的字节 lenLen = pData[start+tagLen]&DATALENVALUE; len = 0; memcpy(&len, pData+start+tagLen+1,lenLen); lenLen++;//加上8x的长度 } else { lenLen = 1; len = pData[start+1]; //Dbg("single len[%x],[%d]",pData[start+1],len); } if (tmpDataStart+tagLen+lenLen+len <= dataLen) { if (IsForm(pData+start,1)) { ICData tmpData(true,pData[start],0x00,level,len); vResult.push_back(tmpData); int tmpPos = vResult.size(); int tmpNum = SplitICData(vResult, origData, start + tagLen + lenLen, len, level + 1, origDataLen); tagNum += tmpNum; vResult.at(tmpPos-1).num = tagNum; } else { tagNum++; //sprintf(Ttmpxx+jxx*2,"L%d",level); //jxx++; //char Ttmpxx[512]; //for (int i = start + tagLen+lenLen; i < start + tagLen+lenLen+len; ++i,++jxx) //{ // sprintf(Ttmpxx+jxx*2,"%02x",pData[i]); //} ICData tmpData(false,pData[start],0x00,level,len); tmpData.value = new BYTE[len]; memcpy(tmpData.value,pData+start+tagLen+lenLen,len); vResult.push_back(tmpData); //start += tagLen+lenLen+len; //return true; } tmpDataStart += tagLen+lenLen+len; } } else { tagLen = 2; if (DATALENFLAG == (pData[start+tagLen]&DATALENFLAG)) {//长度为'8x'表示此字节表示长度所占的字节 lenLen = pData[start+tagLen]&DATALENVALUE; len = 0; memcpy(&len, pData+start+tagLen+1,lenLen); lenLen++;//加上8x的长度 } else { lenLen = 1; len = pData[start+tagLen]; //Dbg("single len[%x],[%d]",pData[start+tagLen],len); } if (tmpDataStart+tagLen+lenLen+len <= dataLen) { if (IsForm(pData+start,2)) { ICData tmpData; tmpData.level = level; tmpData.bForm = true; tmpData.tag[0] = pData[start]; tmpData.tag[1] = pData[start+1]; tmpData.lenth = len; vResult.push_back(tmpData); int tmpPos = vResult.size(); int tmpNum = SplitICData(vResult, origData, start + tagLen + lenLen, len, level + 1, origDataLen); tagNum += tmpNum; vResult.at(tmpPos-1).num = tagNum; } else { tagNum++; ICData tmpData; tmpData.level = level; tmpData.bForm = false; tmpData.tag[0] = pData[start]; tmpData.tag[1] = pData[start+1]; tmpData.lenth = len; tmpData.value = new BYTE[len]; memcpy(tmpData.value,pData+start+tagLen+lenLen,len); vResult.push_back(tmpData); //char Ttmpxx[512]; //sprintf(Ttmpxx+jxx*2,"L%d",level); //jxx++; //for (int i = start +tagLen+lenLen; i < start +tagLen+lenLen+len; ++i,++jxx) //{ // sprintf(Ttmpxx+jxx*2,"%02x",pData[i]); //} //return true; } tmpDataStart += tagLen+lenLen+len; } } start += tagLen+lenLen+len; }while(tmpDataStart < dataLen); //Dbg("Ttmpxx[%s]",Ttmpxx); return tagNum; } int SplitFormString(vector &vResult,const char *pData,int size,char fstP,char sndP) { //"ARPC,34A2BE5D78C32EE8|ARC,00|SCRIPT,32423424" int dataLen = strlen(pData); if (dataLen <= 0 || dataLen != size) { DbgWarn(CSimpleStringA::Format("Split form string failed.[%d,%s]",size,pData)); return -1; } for (int i = 0,j = 0; i < size; ++i) { FormUnit formUnit; char ch = *(pData+i); if (ch != fstP) { int sndLen; if (i == size-1) { sndLen = i-j+1; formUnit.pSnd = new char[sndLen]; ZeroMemory(formUnit.pSnd,sndLen); memcpy(formUnit.pSnd,pData+j+1,sndLen-1); formUnit.sndSize = sndLen-1; vResult.push_back(formUnit); break; } if (ch == sndP) { sndLen = i-j; formUnit.pSnd = new char[sndLen]; ZeroMemory(formUnit.pSnd,sndLen); memcpy(formUnit.pSnd,pData+j+1,sndLen-1); formUnit.sndSize = sndLen-1; vResult.push_back(formUnit); j = i; } } else { int fstLen,fstStart; if (j == 0) { fstStart = j; fstLen = i-j+1; } else { fstStart = j+1; fstLen = i-j; } formUnit.pFst = new char[fstLen]; ZeroMemory(formUnit.pFst,fstLen); memcpy(formUnit.pFst,pData+fstStart,fstLen-1); formUnit.fstSize = fstLen-1; j = i; } } return 0; } int char2int(char ch) { int ret = 0; if ('0' <= ch && ch <='9') ret = atoi(&ch); else { if ('a' <= ch && ch <= 'f') { ret = ch - 'a' + 10; } else if ('A' <= ch && ch <= 'F') { ret = ch - 'A' + 10; } } return ret; } CCardProcess::~CCardProcess() { } void CCardProcess::DataInit() { //m_cardType = CI_CARDTYPE_MAG; //data clear vector::iterator itIC; for (itIC = m_vICData.begin(); itIC != m_vICData.end(); ++itIC) if (itIC->value != NULL) delete []itIC->value; m_vICData.clear(); vector::iterator itBus; for (itBus = m_vBusData.begin(); itBus != m_vBusData.end(); ++itBus) if (itBus->value != NULL) delete []itBus->value; m_vBusData.clear(); vector::iterator itAdf; for (itAdf = m_vADFRec.begin(); itAdf != m_vADFRec.end(); ++itAdf) { if (itAdf->name != NULL) delete []itAdf->name; if (itAdf->appLabel != NULL) delete []itAdf->appLabel; if (itAdf->priName != NULL) delete []itAdf->priName; } m_vADFRec.clear(); vector::iterator itOnReply; m_vOnlineReplyData; for (itOnReply = m_vOnlineReplyData.begin(); itOnReply != m_vOnlineReplyData.end(); ++itOnReply) { if (itOnReply->pSnd != NULL) { delete []itOnReply->pSnd; itOnReply->pFst = NULL; itOnReply->pSnd = NULL; } } ZeroMemory(m_AIP,2); ZeroMemory(m_appVersion,2); ZeroMemory(m_TSI,2); ZeroMemory(m_TVR,5); ZeroMemory(m_IACReject,5); ZeroMemory(m_IACOnline,5); ZeroMemory(m_IACDefault,5); ZeroMemory(m_AuthCode,2); ZeroMemory(m_randData,4); ZeroMemory(m_CVR,4); if (m_pTACReject != NULL) { delete []m_pTACReject; m_pTACReject = NULL; } if (m_pIACOnline != NULL) { delete []m_pIACOnline; m_pIACOnline = NULL; } if (m_pTACOnline != NULL) { delete []m_pTACOnline; m_pTACOnline = NULL; } if (m_pIACDefault != NULL) { delete []m_pIACDefault; m_pIACDefault = NULL; } if (m_pTACDefault != NULL) { delete []m_pTACDefault; m_pTACDefault = NULL; } ZeroMemory(m_APDUsendBuf,MAX_SEND_BUF); //m_bCDA = false; } bool CCardProcess::DetectIfICCard(CardReadType eType, DeviceBaseClass *pCardX, int &cardType, bool bIssue) { //DbgInfo(", to detect card type."); long l_beginTime, l_endTime; cardType = 0; ErrorCodeEnum eErr; CSimpleStringA errMsg(true); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); l_beginTime = GetTickCount(); eErr = pCardI->ContactIC(); l_endTime = GetTickCount(); if(eErr != Error_Succeed){ QueryLastErr(eType, errMsg); setCardAssistLastErr(eErr,errMsg,"DevAdapter::ContactIC"); errMsg = CSimpleStringA::Format("DetectIfICCard::ContactIC failed(%s):%s", SpStrError(eErr), errMsg.GetData()); if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ContactIC").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C7")("DetectIfICCard::ContactIC err=%s", SpStrError(eErr)); LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ContactIC_Failed, errMsg.GetData()); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ContactIC").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC7")("DetectIfICCard::ContactIC err=%s", SpStrError(eErr)); LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_ContactIC_Failed, errMsg.GetData()); } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ContactIC").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ContactIC"); } l_beginTime = GetTickCount(); eErr = pCardI->ActiveICCard(); l_endTime = GetTickCount(); if (eErr != Error_Succeed) { QueryLastErr(eType, errMsg); setCardAssistLastErr(eErr,errMsg,"DevAdapter::ActiveICCard"); errMsg = CSimpleStringA::Format("DetectIfICCard::ActiveICCard failed(%s):%s", SpStrError(eErr), errMsg.GetData()); if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveICCard").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23CT")("DetectIfICCard::ActiveICCard err=%s", SpStrError(eErr)); if (bIssue) { LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_IssueCard_ActiveICCard_Failed, errMsg.GetData()); } else { LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveICCard_Failed, errMsg.GetData()); } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveICCard").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WCT")("DetectIfICCard::ActiveICCard err=%s", SpStrError(eErr)); if (bIssue) { LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_IssueCard_ActiveICCard_Failed, errMsg.GetData()); } else { LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_ActiveICCard_Failed, errMsg.GetData()); } } pCardI->DeactivateICCard(); pCardI->ReleaseIC(); return false; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveICCard"); } } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); char ch; l_beginTime = GetTickCount(); eErr = pCardR->ActiveContactlessICCard('A','B','M',ch); l_endTime = GetTickCount(); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J01")("DetectIfICCard::ActiveContactlessICCard err=%s", SpStrError(eErr)); QueryLastErr(eType, errMsg); setCardAssistLastErr(eErr,errMsg, "DevAdapter::ActiveContactlessICCard"); errMsg = CSimpleStringA::Format("DetectIfICCard::ActiveContactlessICCard failed(%s):%s", SpStrError(eErr), errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, ContactlessCard_UserErrorCode_ActiveContactlessICCard_Failed, errMsg.GetData()); return false; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard"); } cardType = ch; DbgInfo(CSimpleStringA::Format("Detect contactless card type %d",ch)); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); char ch; l_beginTime = GetTickCount(); eErr = pCardI->ActiveContactlessICCard('A', 'B', 'M', ch); l_endTime = GetTickCount(); if (eErr != Error_Succeed) { QueryLastErr(eType, errMsg); setCardAssistLastErr(eErr,errMsg,"DevAdapter::ActiveContactlessICCard"); errMsg = CSimpleStringA::Format("(CardIssuer)DetectIfICCard::ActiveContactlessICCard failed(%s):%s", SpStrError(eErr), errMsg.GetData()); if (eType == CARD_MACHINE_ISSUER_RF) { LogWarn(Severity_Middle, Error_Unexpect, CardIssuer_UserErrorCode_ActiveContactlessICCard_Failed, errMsg.GetData()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C6")("DetectIfICCard::ActiveContactlessICCard err=%s", SpStrError(eErr)); } else { LogWarn(Severity_Middle, Error_Unexpect, CardIssuerStore_UserErrorCode_ActiveContactlessICCard_Failed, errMsg.GetData()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC6")("DetectIfICCard::ActiveContactlessICCard err=%s", SpStrError(eErr)); } return false; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ActiveContactlessICCard").setCostTime(l_endTime - l_beginTime)("DetectIfICCard::ActiveContactlessICCard"); } cardType = ch; DbgInfo(CSimpleStringA::Format("(CardIssuer)Detect contactless card type %d", ch)); } return true; } ErrorCodeEnum CCardProcess::BuildSupportedAppList(CardReadType eType,DeviceBaseClass *pCardX,vector& vAIDFromTerm) { LOG_FUNCTION(); long l_beginTime, l_endTime; //MessageBoxA(0,0,0,0); //首先用PSE选择应用 BYTE zz = 0x00; BYTE cls = 0x00; BYTE ins = 0xa4; BYTE p1 = 0x04; BYTE p2 = 0x00; BYTE le = NULL; BYTE tmpPse1,tmpPse2; LPBYTE pData; char *pse1 = "1PAY.SYS.DDF01"; char *pse2 = "2PAY.SYS.DDF01";//oiltmp 20160107 should change to "2PAY.SYS.DDF01" if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE || eType == CARD_MACHINE_SWIPER) { tmpPse1 = strlen(pse1); pData = new BYTE[tmpPse1+1]; ZeroMemory(pData, tmpPse1 + 1); memcpy(pData, pse1, tmpPse1); ConstructAPDU(cls, ins, p1, p2, tmpPse1, pData, &le); } else if (eType == CARD_MACHINE_RFIC || eType == CARD_MACHINE_SWIPER_RF || eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { tmpPse2 = strlen(pse2); pData = new BYTE[tmpPse2+1]; ZeroMemory(pData, tmpPse2 + 1); memcpy(pData, pse2, tmpPse2); ConstructAPDU(cls, ins, p1, p2, tmpPse2, pData, &le); } else return Error_Param; //delete[] pData;//oiltest改成统一清理格式 int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); CSimpleStringA errMsg(true); ErrorCodeEnum eErr = Error_Unexpect; DWORD errICCommand = 0; l_beginTime = GetTickCount(); l_endTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); errICCommand = CardIssuer_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend, cmdRecv); errICCommand = CardIssuerStore_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } memset(TtestIC,0,1024); int showLen = 0; TtestIC[showLen++] = 'a'; if (eErr == Error_Succeed) TtestIC[showLen++] = (char)eErr+48; else TtestIC[showLen++] = (char)eErr; if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("BuildSupportedAppList::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("BuildSupportedAppList::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; TtestIC[showLen++] = 'b'; DbgInfo(CSimpleStringA::Format(", recv %d len",lenRecv)); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { HexBuf2StrBuf(recvBuf,&show,lenRecv); //DbgInfo(CSimpleStringA::Format(", [%s]", show)); TtestIC[showLen++] = 'c'; TtestIC[showLen++] = 'c'; memcpy(TtestIC+showLen,cmdRecv.data,cmdRecv.dwSize); vector vPSEData; SplitICData(vPSEData, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); //oilyang add to find aid 20160108 ICData aidData(false, 0x4f, 0x00); if (ToFindTagValue(vPSEData, aidData, false, 0, vPSEData.size() - 1) != -1) { vAIDFromTerm.clear(); AIDData aidFromCard; aidFromCard.aid = new BYTE[aidData.lenth + 1]; memcpy(aidFromCard.aid, aidData.value, aidData.lenth); aidFromCard.len = aidData.lenth; aidFromCard.asiFlag = 1; vAIDFromTerm.push_back(aidFromCard); } LPBYTE pSFI = new BYTE[2]; ICData testData(false,0x88,0x00,2); if (ToFindTagValue(vPSEData,testData,true,0,vPSEData.size()-1) != -1) { BYTE tmpSFI = testData.value[0]; BYTE tmpP2 = (tmpSFI<<3)+0x04; delete[] testData.value; bool bNoMoreRec = false,bFirstRead = true; do { ConstructAPDU(0x00,0xb2,tmpSFI,tmpP2,NULL,NULL,&zz); //rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); l_beginTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); errICCommand = CardIssuer_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend, cmdRecv); errICCommand = CardIssuerStore_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("BuildSupportedAppList::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("BuildSupportedAppList::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); DbgInfo(CSimpleStringA::Format("show[%s]",show)); if(recvBuf[lenRecv-2] == 0x6A && recvBuf[lenRecv-1] == 0x83) { bNoMoreRec = true; if (bFirstRead) { delete[] recvBuf; return BuildAppListByAIDs(eType,pCardX,vAIDFromTerm); } } else if(recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { bFirstRead = false; vector vDirRec; SplitICData(vDirRec, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); ICData dirData(true,0x61,0x00,1); int start = 0; for (int ret = 0; start < vDirRec.size();) { //dirData.bForm = true; //dirData.tag[0] = 0x61; //dirData.tag[1] = 0x00; //dirData.level = 1; ret = ToFindTagValue(vDirRec,dirData,true,start,vDirRec.size()-1); if (ret == -1 ) break; start += ret; if (start >= vDirRec.size()-1) break; if (vDirRec.at(start+1).tag[0] == 0x4F && vDirRec.at(start+1).tag[1] == 0x00) { ProcessADFRecord(vDirRec,start); } else if (vDirRec.at(start+1).tag[0] == 0x9D && vDirRec.at(start+1).tag[1] == 0x00) { //oiltmp ProcessDDFRecord(eType,pCardX,vAIDFromTerm,vDirRec.at(start+1).value,vDirRec.at(start+1).lenth); } start++; } tmpSFI++; continue; } else { delete[] recvBuf; return BuildAppListByAIDs(eType,pCardX,vAIDFromTerm); } } else { if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("BuildSupportedAppList::ICCommand 2 failed(%d):%s", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); return Error_Interact; } }while(!bNoMoreRec); } } else{ switch(eType) { case CARD_MACHINE_ISSUER: errICCommand = CardIssuer_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_STORE: errICCommand = CardIssuerStore_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_RF: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_STORE_RF: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_RFIC: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; } if (recvBuf[lenRecv-2] == 0x6a && recvBuf[lenRecv-1] == 0x81) { //6A81 - 卡片被锁或命令不支持; //以上情况中止交易oiltmp LogWarn(Severity_Middle, Error_Unexpect, errICCommand, ", Build from PSE return 6a81,to term trans."); return Error_DevMedia; //return Error_Interact;//20220526@zjw 这里暂时按照需要循环重试来返回。这里实际应该是卡片数据问题,但部分厂商处理有问题,导致卡片时正常的,但快速拿走时,导致这里的数据异常 } else { //6A82 - 所选的文件未找到; //——情形 1:PSE 未找到,即卡片不支持目录选择方法; //——情形 2:P2 设为读取具有相同 AID 前缀的其它应用时卡片中已没有其它应用。 //6283 - 选择文件无效。 errMsg = CSimpleStringA::Format(", Build from PSE failed. recv data:%x,%x", recvBuf[lenRecv-2], recvBuf[lenRecv-1]); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); delete[] recvBuf; return BuildAppListByAIDs(eType,pCardX,vAIDFromTerm); } } } else { if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if(eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("BuildSupportedAppList::ICCommand failed(%d):%s", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); delete[] recvBuf; return Error_Interact; } return Error_Succeed; } ErrorCodeEnum CCardProcess::BuildAppListByAIDs(CardReadType eType,DeviceBaseClass *pCardX,vector& vAIDFromTerm) { LOG_FUNCTION(); long l_beginTime, l_endTime; BYTE zz = 0x00; BYTE cls = 0x00; BYTE ins = 0xa4; BYTE p1 = 0x04; BYTE p2 = 0x00; BYTE le = NULL; vector::iterator it; CmdInfo cmdSend,cmdRecv; ErrorCodeEnum eErr = Error_Unexpect; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); } for (it = vAIDFromTerm.begin(); it != vAIDFromTerm.end(); ++it) { BYTE* pData = new BYTE[it->len]; if (pData == NULL) continue; memcpy(pData,it->aid,it->len); Step7: ConstructAPDU(cls,ins,p1,p2,it->len,pData,&le); bool bAddADF = false,b9000 = false,b6283 = false; int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); l_beginTime = GetTickCount(); l_endTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } if (eErr == 0) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("BuildAppListByAIDs::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("BuildAppListByAIDs::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; DbgInfo(CSimpleStringA::Format(", recv:%d,%x%x",lenRecv,recvBuf[lenRecv-2],recvBuf[lenRecv-1])); if (recvBuf[lenRecv-2] == 0x6a && recvBuf[lenRecv-1] == 0x81) return Error_DevMedia;//oiltmp 终止选择过程 if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) b9000 = true; if (recvBuf[lenRecv-2] == 0x62 && recvBuf[lenRecv-1] == 0x83) b6283 = true; if (!b9000 && !b6283) { DbgWarn(", not 9000 or 6283,failed."); return Error_DevMedia; } vector vSelectedData; SplitICData(vSelectedData, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); ICData dfData(false,0x84,0x00,2); if (ToFindTagValue(vSelectedData,dfData,true,0,vSelectedData.size()-1) == -1) continue; if (b9000 || b6283) { if (dfData.lenth < it->len) continue; if (memcmp(it->aid,dfData.value,it->len) == 0) { if (dfData.lenth > it->len) { if (it->asiFlag == 1) { p2 = 0x02; goto Step7; } else { if (!b9000) { p2 = 0x02; goto Step7; } else { p2 = 0x02; bAddADF = true; } } } else { if (b6283) continue; } } ICData data50(false,0x50,0x00),data9f12(false,0x9f,0x12),data87(false,0x87,0x00); ADFRecord adfRec; adfRec.name = new BYTE[dfData.lenth+1]; memcpy(adfRec.name,dfData.value,dfData.lenth); adfRec.nameLen = dfData.lenth; if (dfData.value != NULL) delete[] dfData.value; HexBuf2StrBuf(adfRec.name,&show,adfRec.nameLen); if (ToFindTagValue(vSelectedData,data50,false,0,vSelectedData.size()-1) != -1) { adfRec.appLabel = new BYTE[data50.lenth+1]; memcpy(adfRec.appLabel,data50.value,data50.lenth); adfRec.appLabelLen = data50.lenth; if (data50.value != NULL) delete[] data50.value; HexBuf2StrBuf(adfRec.appLabel,&show,adfRec.appLabelLen); } if (ToFindTagValue(vSelectedData,data9f12,false,0,vSelectedData.size()-1) != -1) { adfRec.priName = new BYTE[data9f12.lenth+1]; memcpy(adfRec.priName,data9f12.value,data9f12.lenth); adfRec.priNameLen = data9f12.lenth; if(data9f12.value != NULL) delete[] data9f12.value; HexBuf2StrBuf(adfRec.priName,&show,adfRec.priNameLen); } if (ToFindTagValue(vSelectedData,data87,false,0,vSelectedData.size()-1) != -1) { adfRec.appPriID = *data87.value; adfRec.appPriIDLen = 1; } m_vADFRec.push_back(adfRec); if (bAddADF) goto Step7; } else continue; }else{ if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("BuildAppListByAIDs::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("BuildAppListByAIDs::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("BuildAppListByAIDs::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("BuildAppListByAIDs::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("BuildAppListByAIDs::RFTypeABCommand err=%s", SpStrError(eErr)); } CSimpleStringA errMsg(""); QueryLastErr(eType, errMsg); DbgWarn(CSimpleStringA::Format(", ICCommand failed with errCode:%d(0x%x), errMsg:%s", eErr, eErr, errMsg.GetData())); return Error_Interact; } } return Error_Succeed; } ErrorCodeEnum CCardProcess::AppSelected(CardReadType eType,DeviceBaseClass *pCardX,LPBYTE aid,BYTE lenAID) { LOG_FUNCTION(); long l_beginTime, l_endTime; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(aid,&show,lenAID); BYTE zz = 0x00; //oiltmp添加判断aid是否存在于aid列表?目前先不做 BYTE le = 0x00; ConstructAPDU(0x00,0xa4,0x04,0x00,lenAID,aid,&le); int lenRecv; LPBYTE recvBuf = new BYTE[1024]; //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(m_APDUsendBuf,&show,m_lenAPDU); //DbgInfo(CSimpleStringA::Format(", to appselect[%d][%s][%d]",eType,show,m_lenAPDU)); ErrorCodeEnum eErr = Error_Unexpect; CSimpleStringA errMsg(true); DWORD errICCommand = 0; l_beginTime = GetTickCount(); l_endTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); errICCommand = CardIssuer_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend, cmdRecv); errICCommand = CardIssuerStore_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("AppSelected::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("AppSelected::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(recvBuf,&show,lenRecv); //DbgInfo(CSimpleStringA::Format(", after appselect[%s]",show)); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { vector vGPOData; SplitICData(vGPOData, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); ICData pdol(false,0x9f,0x38); DWORD lenPDOLVal; LPBYTE pPDOLVal = NULL; LPBYTE tmpBuf = NULL; if (ToFindTagValue(vGPOData,pdol,false,0,vGPOData.size()-1) == -1) { lenPDOLVal = 0; } else FillPDOL(pdol,&pPDOLVal,lenPDOLVal); tmpBuf = new BYTE[lenPDOLVal+2];//oiltmp数据长度字段暂时默认1字节 tmpBuf[0] = 0x83; tmpBuf[1] = (BYTE)lenPDOLVal; memcpy(tmpBuf+2,pPDOLVal,lenPDOLVal); ConstructAPDU(0x80,0xa8,0x00,0x00,lenPDOLVal+2,tmpBuf,&le); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); l_beginTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); errICCommand = CardIssuer_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend, cmdRecv); errICCommand = CardIssuerStore_UserErrorCode_ICCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); errICCommand = ContactlessCard_UserErrorCode_RFTypeABCommand_Failed; l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("AppSelected::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("AppSelected::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(recvBuf,&show,lenRecv); //DbgInfo(CSimpleStringA::Format("gpo result [%s]",show)); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { if (recvBuf[0] == 0x80) { ICData gpoData; if (gpoData.value != NULL) delete[] gpoData.value; gpoData.value = new BYTE[recvBuf[1]]; gpoData.lenth = recvBuf[1]; memcpy(gpoData.value,recvBuf+2,gpoData.lenth); //pGpo[0] = gpoData.value[0]; //pGpo[1] = gpoData.value[1]; eErr = ReadData(eType,pCardX,gpoData.value,gpoData.lenth); if (eErr == Error_Succeed) stable_sort(m_vICData.begin(),m_vICData.end(),compare_icdata); else { DbgWarn(CSimpleStringA::Format(", ReadData failed:%d(0x%x)",eErr, eErr)); return Error_Interact; } int noneofone = 0; } } } else{ if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("AppSelected::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("AppSelected::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("AppSelected::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("AppSelected::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("AppSelected::RFTypeABCommand err=%s", SpStrError(eErr)); } QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("AppSelected::ICCommand 2 failed(%d):%s", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); return Error_Interact; } } else { switch(eType) { case CARD_MACHINE_ISSUER: errICCommand = CardIssuer_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_STORE: errICCommand = CardIssuerStore_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_RF: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_ISSUER_STORE_RF: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; case CARD_MACHINE_RFIC: errICCommand = ContactlessCard_UserErrorCode_ICCommand_RecvData_Invalid; break; } errMsg = CSimpleStringA::Format(", app selected failed. end data not 9000:%x,%x",recvBuf[lenRecv-2],recvBuf[lenRecv-1]); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); return Error_DevCommFailed; //return Error_Interact;//这里暂时按照需要循环重试来返回。这里实际应该是卡片数据问题,但部分厂商处理有问题,导致卡片时正常的,但快速拿走时,导致这里的数据异常 } } else { if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("BuildSupportedAppList::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("BuildSupportedAppList::RFTypeABCommand err=%s", SpStrError(eErr)); } QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("AppSelected::ICCommand failed(%d):%s", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errICCommand, errMsg.GetData()); return Error_Interact; } return Error_Succeed; } ErrorCodeEnum CCardProcess::ReadData(CardReadType eType,DeviceBaseClass *pCardX,LPBYTE data,DWORD len) { long l_beginTime, l_endTime; int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); ZeroMemory(recvBuf,1024); m_AIP[0] = data[0]; m_AIP[1] = data[1]; ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); } for (int i = 2; i < len;) { BYTE afl[4]; memcpy(afl,data+i,4); i += 4; BYTE recordSeq,le=0x00; BYTE sfi = afl[0]>>3; BYTE p2 = (sfi<<3)+0x04; for(recordSeq = afl[1]; recordSeq <= afl[2]; ++recordSeq) { ConstructAPDU(0x00,0xb2,recordSeq,p2,NULL,NULL,&le); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; ZeroMemory(cmdSend.data,sizeof(cmdSend.data)); ZeroMemory(cmdRecv.data,sizeof(cmdRecv.data)); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); l_beginTime = GetTickCount(); l_endTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("ReadData::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("ReadData::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); //Dbg("ReadData[%s]",show); //DbgInfo(CSimpleStringA::Format(", read record i(%d),p1.record(%d),p2(%d)",i,recordSeq,p2)); SplitICData(m_vICData, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); } else { if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("ReadData::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("ReadData::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("ReadData::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("ReadData::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("ReadData::RFTypeABCommand err=%s", SpStrError(eErr)); } CSimpleStringA errMsg(""); QueryLastErr(eType, errMsg); DbgWarn(CSimpleStringA::Format(", ICCommand failed with errCode:%d(0x%x), errMsg:%s", eErr, eErr, errMsg.GetData())); return Error_Interact; } } } //DbgInfo("read data end"); delete[] recvBuf; delete[] show; return Error_Succeed; } void CCardProcess::ProcessADFRecord(vector& record,int start) { LOG_FUNCTION(); char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); ICData data4f(false,0x4f,0x00),data50(false,0x50,0x00),data9f12(false,0x9f,0x12),data87(false,0x87,0x00); if (ToFindTagValue(record,data4f,false,start,start+record.at(start).num) != -1 && ToFindTagValue(record,data50,false,start,start+record.at(start).num) != -1) { ADFRecord adfRec; adfRec.name = new BYTE[data4f.lenth+1]; memcpy(adfRec.name,data4f.value,data4f.lenth); adfRec.nameLen = data4f.lenth; if (data4f.value != NULL) delete[] data4f.value; HexBuf2StrBuf(adfRec.name,&show,adfRec.nameLen); adfRec.appLabel = new BYTE[data50.lenth+1]; memcpy(adfRec.appLabel,data50.value,data50.lenth); adfRec.appLabelLen = data50.lenth; if (data50.value != NULL) delete[] data50.value; HexBuf2StrBuf(adfRec.appLabel,&show,adfRec.appLabelLen); if (ToFindTagValue(record,data9f12,false,start,start+record.at(start).num) != -1) { adfRec.priName = new BYTE[data9f12.lenth+1]; memcpy(adfRec.priName,data9f12.value,data9f12.lenth); adfRec.priNameLen = data9f12.lenth; if(data9f12.value != NULL) delete[] data9f12.value; HexBuf2StrBuf(adfRec.priName,&show,adfRec.priNameLen); } if (ToFindTagValue(record,data87,false,start,start+record.at(start).num) != -1) { adfRec.appPriID = *data87.value; adfRec.appPriIDLen = 1; } m_vADFRec.push_back(adfRec); } } void CCardProcess::ProcessDDFRecord(CardReadType eType,DeviceBaseClass *pCardX,vector& vAIDFromTerm,LPBYTE pDDF,int length) { long l_beginTime, l_endTime; BYTE zz = 0x00; BYTE cls = 0x00; BYTE ins = 0xa4; BYTE p1 = 0x04; BYTE p2 = 0x00; BYTE le = NULL; LPBYTE pData = new BYTE[length]; if (pData == NULL) return ; memcpy(pData,pDDF,length); ConstructAPDU(cls,ins,p1,p2,length,pData,&le); int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ErrorCodeEnum eErr; l_beginTime = GetTickCount(); l_endTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("ProcessDDFRecord::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("ProcessDDFRecord::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { HexBuf2StrBuf(recvBuf,&show,lenRecv); vector vPSEData; SplitICData(vPSEData, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); ICData testData(false,0x88,0x00,2); if (ToFindTagValue(vPSEData,testData,true,0,vPSEData.size()-1) != -1) { BYTE tmpSFI = testData.value[0]; BYTE tmpP2 = (tmpSFI<<3)+0x04; delete[] testData.value; bool bNoMoreRec = false,bFirstRead = true; do { ConstructAPDU(0x00,0xb2,tmpSFI,tmpP2,NULL,NULL,&zz); //rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); l_beginTime = GetTickCount(); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); l_endTime = GetTickCount(); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); l_endTime = GetTickCount(); } if (eErr == Error_Succeed) { if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime)("ProcessDDFRecord::ICCommand"); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime)("ProcessDDFRecord::RFTypeABCommand"); } memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); if(recvBuf[lenRecv-2] == 0x6A && recvBuf[lenRecv-1] == 0x83) { bNoMoreRec = true; if (bFirstRead) break; } else if(recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { bFirstRead = false; vector vDirRec; SplitICData(vDirRec, &recvBuf, 0, lenRecv - 2, 0, lenRecv - 2); ICData dirData(true,0x61,0x00,1); int start = 0; for (int ret = 0; start < vDirRec.size();) { ret = ToFindTagValue(vDirRec,dirData,true,start,vDirRec.size()-1); if (ret == -1 ) break; start += ret; if (vDirRec.at(start+1).tag[0] == 0x4F && vDirRec.at(start+1).tag[1] == 0x00) { ProcessADFRecord(vDirRec,start); } else if (vDirRec.at(start+1).tag[0] == 0x9D && vDirRec.at(start+1).tag[1] == 0x00) { //oiltmp ProcessDDFRecord(eType,pCardX,vAIDFromTerm,vDirRec.at(start+1).value,vDirRec.at(start+1).lenth); } } tmpSFI++; continue; } } else{ if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("ProcessDDFRecord::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("ProcessDDFRecord::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } CSimpleStringA errMsg(""); QueryLastErr(eType, errMsg); DbgWarn(CSimpleStringA::Format(", ICCommand 2 failed with errCode:%d(0x%x), errMsg:%s", eErr, eErr, errMsg.GetData())); break; } }while(!bNoMoreRec); } } }else{ if (eType == CARD_MACHINE_ISSUER) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2302")("ProcessDDFRecord::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::ICCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2W02")("ProcessDDFRecord::ICCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA23C9")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_ISSUER_STORE_RF) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2WC9")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } else if (eType == CARD_MACHINE_RFIC) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DevAdapter::RFTypeABCommand").setCostTime(l_endTime - l_beginTime).setResultCode("RTA2J02")("ProcessDDFRecord::RFTypeABCommand err=%s", SpStrError(eErr)); } CSimpleStringA errMsg(""); QueryLastErr(eType, errMsg); DbgWarn(CSimpleStringA::Format(", ICCommand failed with errCode:%d(0x%x), errMsg:%s", eErr, eErr, errMsg.GetData())); } delete[] recvBuf; delete[] show; return; } bool CCardProcess::FillPDOL(ICData& pdol,LPBYTE* ppBYTE,DWORD& lenPDOL) { char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(pdol.value,&show,pdol.lenth); //oiltmp 20141021 for temp ICData data(false,0x9f,0x66); data.value = new BYTE[4]; data.lenth = 4; ZeroMemory(data.value,4); data.value[0] = 0xff; data.value[1] = 0x80; data.value[2] = 0x0; data.value[3] = 0x0; m_vBusData.push_back(data); //DbgInfo(CSimpleStringA::Format(", to fill pdol [%s]",show)); //6f458408a000000333010101a539500a50424f432044454249548701019f38099f7a019f0206 //5f2a025f2d027a689f1101019f120ad5d0d0d0d2bbbfa8cda8bf0c059f4d020b0a9000 //9f38099f7a019f02065f2a02 char* test = "000102030405060708"; char tmpBuf[512]; lenPDOL = 0; for (int i = 0; i < pdol.lenth;) { if (IsDoubleByteFlag(pdol.value[i])) { ICData tagValue(false,pdol.value[i],pdol.value[i+1]); if (ToFindTagValue(m_vBusData,tagValue,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenPDOL,tagValue.value,tagValue.lenth); else memset(tmpBuf+lenPDOL,0,pdol.value[i+2]); lenPDOL += pdol.value[i+2]; i += 3; } else { memset(tmpBuf+lenPDOL,0,pdol.value[i+1]); //memcpy(tmpBuf+lenPDOL,test,pdol.value[i+1]); lenPDOL += pdol.value[i+1]; i += 2; } } *ppBYTE = new BYTE[lenPDOL]; memcpy(*ppBYTE,tmpBuf,lenPDOL); //char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(*ppBYTE,&show,lenPDOL); return true; } void CCardProcess::ProcessSFIRecord(LPBYTE* rec,int lenRec) { // char* show = new char[MAX_TEST_SHOW]; //ZeroMemory(show,MAX_TEST_SHOW); //HexBuf2StrBuf(*rec,&show,lenRec-2); ////DeleteICData(); //vector vSFIRec; //SplitICData(vSFIRec,rec,0,lenRec,0); //ICData testData; //int start = 0; //for (int ret = 0; start < vSFIRec.size();) //{ // testData.bForm = true; // testData.tag[0] = 0x61; // testData.tag[1] = 0x00; // testData.level = 1; // ret = FindTagValue(vSFIRec,testData,true,start,vSFIRec.size()-1); // if (ret == -1 ) // break; // start = start+ret+1; // //oiltest M标签固定排序? // if (vICData.at(start).tag[0] == 0x4F && vICData.at(start).tag[1] == 0x00) // { // //ADF,取相应的数据 // } // else if (vICData.at(start).tag[0] == 0x9D && vICData.at(start).tag[1] == 0x00) // { // BYTE zz = 0x00; // BYTE le = NULL; // //DDF // ICData ddfData(false,0x9d,0x00); // FindTagValue(vICData,ddfData,false,start,start+vICData.at(start-1).num-1); // ConstructAPDU(0x00,0xa4,04,00,ddfData.lenth,ddfData.value,&le); // int lenRecv; // LPBYTE recvBuf = new BYTE[1024]; // char* show = new char[MAX_TEST_SHOW]; // ZeroMemory(show,MAX_TEST_SHOW); // int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); // if (rc == 0) // { // if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) // { // BYTE tmpSFI = ddfData.value[0]; // BYTE tmpP2 = (tmpSFI<<3)+0x04; // delete[] ddfData.value; // bool bNoMoreRec = false; // do // { // ConstructAPDU(0x00,0xb2,tmpSFI,tmpP2,NULL,NULL,&zz); // rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); // if (rc == 0) // { // HexBuf2StrBuf(recvBuf,&show,lenRecv); // if(recvBuf[lenRecv-2] == 0x6A && recvBuf[lenRecv-1] == 0x83) // bNoMoreRec = true; // else if(recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) // { // ProcessSFIRecord(&recvBuf,lenRecv-2); // //DeleteICData(); // tmpSFI++; // continue; // } // } // else // break; // }while(!bNoMoreRec); // } // } // } //} } void CCardProcess::ProcessRestrict() { LOG_FUNCTION(); //应用版本号检查 ICData appVersion(false,0x9f,0x08); if (ToFindTagValue(m_vICData,appVersion,false,0,m_vICData.size()-1) == -1) { return; } if (m_appVersion[0] != appVersion.value[0] || m_appVersion[1] != appVersion.value[1]) { DbgInfo(CSimpleStringA::Format(", app version not match.%x.%x:%x.%x", m_appVersion[0], m_appVersion[1], appVersion.value[0], appVersion.value[1])); m_TVR[1] |= TVR_APP_VERSION_UNMATCH; return; } //AUC检查 //... //发卡行国家代码 //应用用途控制检查 Opt //应用失效日期检查 ICData appExpiryDate(false,0x5f,0x24); if (ToFindTagValue(m_vICData,appExpiryDate,false,0,m_vICData.size()-1) == -1) { return; } DWORD exYear = (appExpiryDate.value[0] >> 4) * 10 + (appExpiryDate.value[0] & 0x0f) + 2000; DWORD exMonth = (appExpiryDate.value[1] >> 4) * 10 + (appExpiryDate.value[1] & 0x0f); DWORD exDay = (appExpiryDate.value[2] >> 4) * 10 + (appExpiryDate.value[2] & 0x0f); #if (defined(_WIN32) || defined(_WIN64)) SYSTEMTIME localTime; GetLocalTime(&localTime); ATL::CTime currTime(localTime.wYear, localTime.wMonth, localTime.wDay, 0, 0, 0); ATL::CTime exTime(exYear, exMonth, exDay, 0, 0, 0); if (exTime <= currTime) { return; } #else time_t t; time(&t); struct tm* t1; t1 = localtime(&t); t1->tm_year += 1900; t1->tm_mon += 1; /*TO COMFIRM*/ if (exYear < t1->tm_year || (exYear == t1->tm_year && exMonth < t1->tm_mon) || (exYear == t1->tm_year && exMonth == t1->tm_mon && exDay < t1->tm_yday)) { return; } #endif //_WIN32 //应用生效日期检查 Opt } void CCardProcess::CardholderVerify() { LOG_FUNCTION(); //oiltmp目前只支持联机密码验证 return; //bool bCardhoderVerify = false; //if (CARDHOLDERVERIFYFLAG == m_AIP[0]&CARDHOLDERVERIFYFLAG) // bCardhoderVerify = true; //ICData CVMList(false,0x8e,0x00); //int start = 0; ////逐一处理CVMList //do //{ // int tmpPos = FindTagValue(m_vICData,CVMList,false,start,m_vICData.size()-1); // if (tmpPos == -1) // { // if (start == 1) // m_TVR[0] |= TVR_IC_Data_Miss;//设置TVR ‘IC卡数据缺失’ // break; // } // do // { // //oiltest暂时只处理‘总是’选项 // if (CVMList.value[9] != 0x00) // break; // if ((CVMList.value[8]&0x3f) == 0x01 || CVMList.value[8]&0x3f) == 0x02 || CVMList.value[8]&0x3f) == 0x1f) // { // } // else // { // m_TVR[2] |= TVR_CVM_Unkown; // break; // } // }while(false); // if (0x00 == (CVMList.value[8]&0x40)) // { // m_TVR[2] |= TVR_CVM_Failed; // break; // } // start = tmpPos; //}while(start < m_vICData.size()); //m_TSI[0] |= TSI_Cardholder; } void CCardProcess::TermRiskManage() { LOG_FUNCTION(); //终端异常文件检查 ICData pan(false,0x5a,0x00); if (ToFindTagValue(m_vICData,pan,false,0,m_vICData.size()-1) == -1) { } //商户强制交易联机 //最低限额检查 //随机交易选择 //频度检查 //新卡检查 } int CCardProcess::TermActionAnalyze(CardReadType eType,DeviceBaseClass *pCardX,CSimpleStringA &result,bool bOnlineOnly,bool bCDA,BYTE &d9f27) { LOG_FUNCTION(); //9F0D缺省 9F0E拒绝 9F0F联机 ICData iacDefault(false,0x9f,0x0d); ICData iacReject(false,0x9f,0x0e); ICData iacOnline(false,0x9f,0x0f); BYTE p1; do { if (ToFindTagValue(m_vICData,iacReject,0,0,m_vICData.size()-1) == -1) memset(m_IACReject,0,5); else memcpy(m_IACReject,iacReject.value,5); if (m_pTACReject == NULL) { m_pTACReject = new BYTE[5]; memset(m_pTACReject,0,5); } if (IsSamePositionSet(m_IACReject,m_TVR,5) || IsSamePositionSet(m_pTACReject,m_TVR,5)) { DbgInfo(CSimpleStringA::Format(", iacreject:%x%x%x%x%x,tvr:%x%x%x%x%x", m_IACReject[0], m_IACReject[1], m_IACReject[2], m_IACReject[3], m_IACReject[4], m_TVR[0], m_TVR[1], m_TVR[2], m_TVR[3], m_TVR[4])); m_AuthCode[0] = 'Z'; m_AuthCode[1] = '1'; p1 = P1_GENAC_AAC; break; } if (bOnlineOnly) { p1 = P1_GENAC_ARQC; break; } else { if (ToFindTagValue(m_vICData,iacOnline,0,0,m_vICData.size()-1) == -1) memset(m_IACOnline,0xff,5); else memcpy(m_IACOnline,iacOnline.value,5); if (m_pTACOnline == NULL) { m_pTACOnline = new BYTE[5]; memset(m_pTACOnline,0,5); } if (IsSamePositionSet(m_IACOnline,m_TVR,5) || IsSamePositionSet(m_pTACOnline,m_TVR,5)) { p1 = P1_GENAC_ARQC; break; } if (ToFindTagValue(m_vICData,iacDefault,0,0,m_vICData.size()-1) == -1) memset(m_IACDefault,0xff,5); else memcpy(m_IACDefault,iacDefault.value,5); if (m_pTACDefault == NULL) { m_pTACDefault = new BYTE[5]; memset(m_pTACDefault,0,5); } if (IsSamePositionSet(m_IACDefault,m_TVR,5) || IsSamePositionSet(m_pTACDefault,m_TVR,5)) { m_AuthCode[0] = 'Z'; m_AuthCode[1] = '3'; p1 = P1_GENAC_AAC; break; } } m_AuthCode[0] = 'Y'; m_AuthCode[1] = '1'; p1 = P1_GENAC_TC; }while(false); if (bCDA) { p1 |= 0x10;//设置执行CDA标识 } d9f27 = p1; //DbgInfo(CSimpleStringA::Format(", to do 1st gen ac bCDA(%d)(%d)",bCDA,p1)); //1st genarate ac ICData cdol1(false,0x8c,0x00); if (ToFindTagValue(m_vICData,cdol1,0,0,m_vICData.size()-1) == -1) { DbgWarn(", can't find cdol1."); return -1; } PBYTE pCDOL1; DWORD lenCDOL1=0; FillCDOL(cdol1,pCDOL1,lenCDOL1); ConstructAPDU(CLS_GENAC,INS_GENAC,p1,0x00,lenCDOL1,pCDOL1,0x00); int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); //int rc = CPU_T0_C_APDU(m_hIDCCOM,m_lenAPDU,m_APDUsendBuf,recvBuf,&lenRecv); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); HexBuf2StrBuf(cmdSend.data,&show,m_lenAPDU); //DbgInfo(CSimpleStringA::Format(", 1st GenAc cmd[%s]",show)); ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } bool bFirstGenAC = false; if (eErr == Error_Succeed) { memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(recvBuf,&show,lenRecv); //DbgInfo(CSimpleStringA::Format("1stGenAc recv[%s]",show)); if (recvBuf[lenRecv-2] == 0x61) { BYTE btLen = recvBuf[lenRecv-1]; ConstructAPDU(CLS_GET_RESPONSE,INS_GET_RESPONSE,0x00,0x00,NULL,NULL,&btLen); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(cmdSend.data,&show,m_lenAPDU); DbgInfo(CSimpleStringA::Format("get response cmd[%s]",show)); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } if (eErr == Error_Succeed) { ZeroMemory(show,MAX_TEST_SHOW); ZeroMemory(recvBuf,1024); memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); //Dbg("oiltest get response recv[%s]",show); if (recvBuf[lenRecv - 2] == 0x90 && recvBuf[lenRecv - 1] == 0x00) { bFirstGenAC = true; DbgInfo("first generate ac suc."); } else { DbgInfo(CSimpleStringA::Format("first generate ac failed.%x%x", recvBuf[lenRecv - 2], recvBuf[lenRecv - 1])); } } } else if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) bFirstGenAC = true; else if (recvBuf[lenRecv-2] == 0x69 && recvBuf[lenRecv-1] == 0x85) { //>2 generate ac } if (bFirstGenAC) { //form2 '77'暂不考虑 //form1 '80' if (recvBuf[0] == 0x80) { //80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000 //密文信息数据 1B,ATC 2B,AC 8B,发卡行数据 opt //暂不执行CDA oiltmp BYTE cryptInfo = recvBuf[2]; m_TSI[0] |= TSI_TERM_RISK_MANAGE; if (((p1&P1_GENAC_TC) == P1_GENAC_TC || (p1&P1_GENAC_ARQC) == P1_GENAC_ARQC) && ((cryptInfo & 0xc0) == P1_GENAC_ARQC)) { //同时终端有联机能力则执行联机请求 if ((p1&P1_GENAC_ARQC) == P1_GENAC_ARQC) m_P1 = 1; else m_P1 = 0; m_CVR[0] = recvBuf[16]; m_CVR[1] = recvBuf[17]; m_CVR[2] = recvBuf[18]; m_CVR[3] = recvBuf[19]; result = show; return 0; } else if ((((p1&P1_GENAC_AAC) == P1_GENAC_AAC) && (((cryptInfo & 0xc0) == 0x40) || ((cryptInfo & 0xc0) == 0x80))) || (((p1&P1_GENAC_ARQC) == P1_GENAC_ARQC) && ((cryptInfo&0xc0) == 0x40))) { //终止交易 return 1; } else { //满足 //1.执行了CDA但结果失败;2.卡片响应AAC或者TC;3.卡片响应ARQC但终端没联机能力 //之一则执行‘交易结束流程’ return 2; } } } } if (recvBuf != NULL) delete []recvBuf; if (show != NULL) delete []show; return 0; } bool CCardProcess::FillCDOL(ICData& cdol,PBYTE &pBYTE,DWORD &lenCDOL) { //DbgInfo("Fill CDOL"); char* test = "000102030405060708"; char tmpBuf[512] = {0}; char *pShow = new char[32]; lenCDOL = 0; //9f0206 9f0306 9f1a02 9505 5f2a02 9a03 9c01 9f3704 9f2103 9f4e14 //9f0206授权金额 ( 6 ), 9f0306其它金额 ( 6), 9f1a02终端国家代码( 2) //,5f2a02交易货币代码( 2), 9a03交易日期( 3), 9c01交易类型( 1), //9f2103交易时间( 3), 9f4e14商户名称( 14,16进制的,换成10进制是20字节) for (int i = 0; i < cdol.lenth;) { if (IsDoubleByteFlag(cdol.value[i])) { ZeroMemory(pShow,32); HexBuf2StrBuf(cdol.value+i,&pShow,2); //Dbg("double flag:[%s]",pShow); //memcpy(tmpBuf+lenCDOL,test,cdol.value[i+2]); ICData authAmount(false,0x9f,0x02),otherAmount(false,0x9f,0x03),ctyCode(false,0x9f,0x1a) ,currCode(false,0x5f,0x2a),transTime(false,0x9f,0x21),custName(false,0x9f,0x4e); if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x02) { if (ToFindTagValue(m_vBusData,authAmount,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,authAmount.value,authAmount.lenth); } else if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x03) { if (ToFindTagValue(m_vBusData,otherAmount,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,otherAmount.value,otherAmount.lenth); } //terminal country code "0156" else if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x1a) { if (ToFindTagValue(m_vBusData,ctyCode,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,ctyCode.value,ctyCode.lenth); } //currency code else if (cdol.value[i] == 0x5f && cdol.value[i+1] == 0x2a) { if (ToFindTagValue(m_vBusData,currCode,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,currCode.value,currCode.lenth); } else if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x37) { unsigned int ram; #if (defined(_WIN32) || defined(_WIN64)) int ret = rand_s(&ram); if(ret == 0) #else ram = rand(); if(ram != 0) #endif //_WIN32 { m_randData[0] = tmpBuf[lenCDOL] = ((ram&0xff000000)>>24); m_randData[1] = tmpBuf[lenCDOL+1] = ((ram&0x00ff0000)>>16); m_randData[2] = tmpBuf[lenCDOL+2] = ((ram&0x0000ff00)>>8); m_randData[3] = tmpBuf[lenCDOL+3] = (ram&0x000000ff); } else { DbgWarn(CSimpleStringA::Format("get ram err %d",GetLastError())); } } //trans time else if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x21) { if (ToFindTagValue(m_vBusData,transTime,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,transTime.value,transTime.lenth); } else if (cdol.value[i] == 0x9f && cdol.value[i+1] == 0x4e) { if (ToFindTagValue(m_vBusData,custName,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,custName.value,custName.lenth); } else { DbgInfo(CSimpleStringA::Format("unknown cdol tag...%x%x",cdol.value[i],cdol.value[i+1])); memset(tmpBuf+lenCDOL,0,cdol.value[i+2]); } lenCDOL += cdol.value[i+2]; i += 3; } else { ZeroMemory(pShow,32); HexBuf2StrBuf(cdol.value+i,&pShow,1); //Dbg("single flag:[%s]",pShow); ICData transDate(false,0x9a,0x00),transType(false,0x9c,0x00); if (cdol.value[i] == 0x95) { tmpBuf[lenCDOL] = 0x00; tmpBuf[lenCDOL+1] = 0x00; tmpBuf[lenCDOL+2] = 0x00; tmpBuf[lenCDOL+3] = 0x00; tmpBuf[lenCDOL+4] = 0x00; } else if (cdol.value[i] == 0x9a) { if (ToFindTagValue(m_vBusData,transDate,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,transDate.value,transDate.lenth); } else if (cdol.value[i] == 0x9c) { if (ToFindTagValue(m_vBusData,transType,false,0,m_vBusData.size()-1) != -1) memcpy(tmpBuf+lenCDOL,transType.value,transType.lenth); } else { DbgWarn(CSimpleStringA::Format("unknown cdol tag...%x",cdol.value[i])); memset(tmpBuf+lenCDOL,0,cdol.value[i+1]); } //memcpy(tmpBuf+lenCDOL,test,cdol.value[i+1]); lenCDOL += cdol.value[i+1]; i += 2; } } pBYTE = new BYTE[lenCDOL]; memcpy(pBYTE,tmpBuf,lenCDOL); char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(pBYTE,&show,lenCDOL); //DbgInfo(CSimpleStringA::Format("filled..cdol[%s],len[%d]",show,lenCDOL)); return true; } int CCardProcess::IssueBankAuth(CardReadType eType,DeviceBaseClass *pCardX) { LOG_FUNCTION(); //如果联机授权响应包含发卡行认证数据&卡和终端支持发卡行认证 if (AIP_ISSUER_BANK_AUTH != m_AIP[0]&AIP_ISSUER_BANK_AUTH) { DbgWarn("Term don't support issuer bank authorize."); return -1;//oiltmp ? } m_TSI[0] |= TSI_ISSUER_BANK_AUTH; BYTE p1,p2; p1 = p2 = 0x00; LPBYTE pData = NULL; int iH1,iH2,iL1,iL2,sizeARPC; iH1 = iH2 = iL1 = iL2 = sizeARPC = 0; vector::iterator it; bool bARPC,bARC; bARPC = bARC = false; for (it = m_vOnlineReplyData.begin(); it != m_vOnlineReplyData.end(); ++it) { if (!_strnicmp(it->pFst,"ARPC",it->fstSize)) { pData = new BYTE[it->sndSize/2+1+1]; ZeroMemory(pData,it->sndSize/2+1+1); int ret = StrBuf2HexBuf(it->pSnd,&pData); if (ret == 0) { DbgWarn("Wrong ARPC size."); delete []pData; return -1; } sizeARPC = it->sndSize/2; bARPC = true; } else if (!_strnicmp(it->pFst,"ARC",it->fstSize)) { iH1 = char2int(*(it->pSnd)); iL1 = char2int(*(it->pSnd+1)); iH2 = char2int(*(it->pSnd+2)); iL2 = char2int(*(it->pSnd+3)); bARC = true; } } if (!bARPC || !bARC) { DbgWarn(CSimpleStringA::Format("no arpc or arc(%d)(%d).",bARPC,bARC)); return -1; } pData[sizeARPC] = iH1*16 + iL1; pData[sizeARPC+1] = iH2*16 + iL2; BYTE lc = sizeARPC + 2; DbgInfo(CSimpleStringA::Format("issue bank authorize lc [%d]",lc)); ConstructAPDU(CLS_EX_AUTH,INS_EX_AUTH,p1,p2,lc,pData,NULL); char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); int lenRecv; BYTE* recvBuf = new BYTE[1024]; CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } if (eErr == Error_Succeed) { memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); DbgInfo(CSimpleStringA::Format("issue bank auth[%s]",show)); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { } else { DbgWarn("issue bank auth failed."); m_TVR[4] |= TVR_ISSUER_BANK_AUTH_FAIL; return -1; } } return 0; //if (recvBuf != NULL) //{ // delete []recvBuf; // recvBuf = NULL; //} } void CCardProcess::ExecuteIssuerScript(CardReadType eType,DeviceBaseClass *pCardX) { vector::iterator it; PBYTE pScript = NULL; for (it = m_vOnlineReplyData.begin(); it != m_vOnlineReplyData.end(); ++it) { if (!_strnicmp(it->pFst,"SCRIPT",it->fstSize)) { pScript = new BYTE[it->sndSize/2+1]; ZeroMemory(pScript,it->sndSize/2+1); int ret = StrBuf2HexBuf(it->pSnd,&pScript); if (ret == 0) { DbgWarn("Wrong issuer script size."); delete []pScript; return; } if (pScript[0] != 0x72) { DbgWarn("Wrong issuer script."); delete []pScript; return; } } } if (pScript == NULL) { DbgWarn("No script?"); return; } CardIssuerClass *pCardI; ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); } int len = pScript[1]; for (int i = 2; i < len;) { if (pScript[i] == 0x86) { i++; int cmdLen = pScript[i]; CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = cmdLen; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); i++; memcpy(cmdSend.data,(void*)(pScript+i),cmdLen); //the following just for test oiltmp char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(cmdSend.data,&show,cmdSend.dwSize); DbgInfo(CSimpleStringA::Format("issuer script[%s].",show)); delete []show; // if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } if (eErr == Error_Succeed) { if (cmdRecv.data[cmdRecv.dwSize-2] == 0x90 || cmdRecv.data[cmdRecv.dwSize-2] == 0x62) { DbgInfo(CSimpleStringA::Format("Execute script command [%d][%d].",cmdRecv.data[cmdRecv.dwSize-2],cmdRecv.data[cmdRecv.dwSize-1])); } else { DbgWarn(CSimpleStringA::Format("Execute script command error [%d][%d].",cmdRecv.data[cmdRecv.dwSize-2],cmdRecv.data[cmdRecv.dwSize-1])); } } else { CSimpleStringA errMsg; QueryLastErr(eType, errMsg); DbgWarn(CSimpleStringA::Format(", Execute script command error [%d][%d].errCode:%d, errMsg:%s", cmdRecv.data[cmdRecv.dwSize-2],cmdRecv.data[cmdRecv.dwSize-1], eErr, errMsg.GetData())); } i += cmdLen; } else i++; } if (pScript != NULL) delete []pScript; } int CCardProcess::TransEnd(CardReadType eType,DeviceBaseClass *pCardX,bool bCDA) { LOG_FUNCTION(); int procResult = 0; //second genarate ac ICData cdol2(false,0x8d,0x00); if (ToFindTagValue(m_vICData,cdol2,0,0,m_vICData.size()-1) == -1) { DbgWarn("can't find cdol2."); return -1; } //find arc to decide P1 (currently no CDA) //'00','10','11'-->TC //'01','02',other -->AAC BYTE p1; vector::iterator it; for (it = m_vOnlineReplyData.begin(); it != m_vOnlineReplyData.end(); ++it) { if (!_strnicmp(it->pFst,"ARC",it->fstSize)) { if (!_strnicmp(it->pSnd,"00",it->sndSize) || !strnicmp(it->pSnd,"10",it->sndSize) || !strnicmp(it->pSnd,"11",it->sndSize)) p1 = P1_GENAC_TC; else p1 = P1_GENAC_AAC; } } PBYTE pCDOL2; DWORD lenCDOL2=0; FillCDOL(cdol2,pCDOL2,lenCDOL2); ConstructAPDU(CLS_GENAC,INS_GENAC,p1,0x00,lenCDOL2,pCDOL2,0x00); int lenRecv; LPBYTE recvBuf = new BYTE[1024]; char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); HexBuf2StrBuf(cmdSend.data,&show,m_lenAPDU); DbgInfo(CSimpleStringA::Format("2nd GenAc cmd[%s]",show)); ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } bool bGenAC = false; if (eErr == Error_Succeed) { memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(recvBuf,&show,lenRecv); DbgInfo(CSimpleStringA::Format("2ndGenAc recv[%s]",show)); if (recvBuf[lenRecv-2] == 0x61) { BYTE btLen = recvBuf[lenRecv-1]; ConstructAPDU(CLS_GET_RESPONSE,INS_GET_RESPONSE,0x00,0x00,NULL,NULL,&btLen); CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ZeroMemory(show,MAX_TEST_SHOW); HexBuf2StrBuf(cmdSend.data,&show,m_lenAPDU); DbgInfo(CSimpleStringA::Format("get response cmd[%s]",show)); if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } if (eErr == Error_Succeed) { ZeroMemory(show,MAX_TEST_SHOW); ZeroMemory(recvBuf,1024); memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); //Dbg("get response recv[%s]",show); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) bGenAC = true; } } else if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) bGenAC = true; else if (recvBuf[lenRecv-2] == 0x69 && recvBuf[lenRecv-1] == 0x85) { DbgWarn("no more than 2 generate ac command"); return -1; } if (bGenAC) { ExecuteIssuerScript(eType,pCardX); //to send back issuer script execute result? oiltmp //form2 '77'暂不考虑 //form1 '80' if (recvBuf[0] == 0x80) { //2nd gen ac response:CID,ATC,AC,[ISSUER...],CVR //80 1e 80 0008 328ab54bfc986b85 07010103a0b000010a010000000000754048769000 //密文信息数据 1B,ATC 2B,AC 8B,发卡行数据 opt //暂不执行CDA oiltmp BYTE cryptInfo = recvBuf[2]; if (p1 == P1_GENAC_AAC) { //reject trans } else if (p1 == P1_GENAC_TC) { //if response is tc,as no CDA,trans end //else if response is aac,reject trans and send reversal if ((cryptInfo&0xc0) == P1_GENAC_TC) procResult = 0; else if ((cryptInfo&0xc0) == P1_GENAC_AAC) { //to be added... oiltmp procResult = 1; } } } } } if (recvBuf != NULL) delete []recvBuf; if (show != NULL) delete []show; return procResult; } void CCardProcess::GetBaseInfoNotInRecord(CardReadType eType,DeviceBaseClass *pCardX) { char* show = new char[MAX_TEST_SHOW]; ZeroMemory(show,MAX_TEST_SHOW); BYTE zz = 0x00; BYTE le = 0x00; ConstructAPDU(0x80,0xca,0x9f,0x36,NULL,NULL,&le); int lenRecv; LPBYTE recvBuf = new BYTE[1024]; CmdInfo cmdSend,cmdRecv; cmdSend.dwSize = m_lenAPDU; memset(cmdSend.data,0,MAX_IC_BUFFER_SIZE); memcpy(cmdSend.data,m_APDUsendBuf,m_lenAPDU); ErrorCodeEnum eErr; if (eType == CARD_MACHINE_ISSUER || eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); eErr = pCardI->ICCommand(cmdSend,cmdRecv); } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); eErr = pCardI->RFTypeABCommand(cmdSend, cmdRecv); } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); eErr = pCardR->RFTypeABCommand(cmdSend,cmdRecv); } if (eErr == Error_Succeed) { memcpy(recvBuf,cmdRecv.data,cmdRecv.dwSize); lenRecv = cmdRecv.dwSize; HexBuf2StrBuf(recvBuf,&show,lenRecv); DbgInfo(CSimpleStringA::Format("base info not in record[%s]",show)); if (recvBuf[lenRecv-2] == 0x90 && recvBuf[lenRecv-1] == 0x00) { } } } void CCardProcess::SplitBusinessData(const char *pData,int size) { //not support ultra-lenth!!!oilyang PBYTE pBtData = new BYTE[MAX_IC_BUFFER_SIZE]; ZeroMemory(pBtData,MAX_IC_BUFFER_SIZE); int len = StrBuf2HexBuf(pData,&pBtData); for (int i = 0; i < len;) { if (IsDoubleByteFlag(*(pBtData+i))) { int dataLen = *(pBtData+i+2); ICData data(false,*(pBtData+i),*(pBtData+i+1)); data.value = new BYTE[dataLen]; data.lenth = dataLen; ZeroMemory(data.value,dataLen); memcpy(data.value,pBtData+i+3,dataLen); m_vBusData.push_back(data); i = i + dataLen + 2 + 1; } else { int dataLen = *(pBtData+i+1); ICData data(false,*(pBtData+i),0x00); data.value = new BYTE[dataLen]; data.lenth = dataLen; ZeroMemory(data.value,dataLen); memcpy(data.value,pBtData+i+2,dataLen); m_vBusData.push_back(data); i = i + dataLen + 1 + 1; } } return ; } int CCardProcess::SplitOnlineReplyData(const char *pData,int size) { //"ARPC,34A2BE5D78C32EE8|ARC,00|SCRIPT,32423424" m_vOnlineReplyData.clear(); int ret = SplitFormString(m_vOnlineReplyData,pData,size,',','|'); if (ret != 0) { DbgWarn("Split form string failed."); return -1; } return 0; } int CCardProcess::DetectAndReadICData(CardReadType eType, DeviceBaseClass *pCardX, CAutoArraypAIDs, int &cardType, bool bIssue) { LOG_FUNCTION(); bool bIC = DetectIfICCard(eType,pCardX,cardType,bIssue); if (!bIC) { DbgWarn(", not ic card."); return -1; } int bGetICData = -3; bGetICData = GetICDataFromCard(eType,pCardX,pAIDs); if (bGetICData != 0) { CSimpleStringA errMsg = CSimpleStringA::Format("GetICDataFromCard failed(%d)", bGetICData); DbgWarn(errMsg.GetData()); return bGetICData; } GetBaseInfoNotInRecord(eType,pCardX); return 0; } int CCardProcess::GetICDataFromCard(CardReadType eType,DeviceBaseClass *pCardX, CAutoArray pAIDs) { LOG_FUNCTION(); CSimpleStringA errMsg(true); DWORD errBuildAppList = 0; AIDData aidData; aidData.aid = new BYTE[32];//oiltmp memset(aidData.aid,0,32); for (int index = 0; index < pAIDs.GetCount(); ++index) { int aidLen = StrBuf2HexBuf(pAIDs[index].GetData(),&aidData.aid); aidData.len = aidLen; char* aidTest = new char[128]; int aidStrLen = HexBuf2StrBuf(aidData.aid,&aidTest,5); //DbgInfo(CSimpleStringA::Format(", aid[%s][%s]",pAIDs[index].GetData(),aidTest)); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(", aid[%s][%s]", pAIDs[index].GetData(), aidTest); vector vAIDs; vAIDs.push_back(aidData); ErrorCodeEnum eErr = Error_Unexpect; if (eType == CARD_MACHINE_ISSUER) { pCardI = dynamic_cast(pCardX); errBuildAppList = CardIssuer_UserErrorCode_BuildSupportedAppList_Failed; } else if (eType == CARD_MACHINE_ISSUER_STORE) { pCardI = dynamic_cast(pCardX); errBuildAppList = CardIssuerStore_UserErrorCode_BuildSupportedAppList_Failed; } else if (eType == CARD_MACHINE_ISSUER_RF || eType == CARD_MACHINE_ISSUER_STORE_RF) { pCardI = dynamic_cast(pCardX); errBuildAppList = ContactlessCard_UserErrorCode_BuildSupportedAppList_Failed; } else if (eType == CARD_MACHINE_RFIC) { pCardR = dynamic_cast(pCardX); errBuildAppList = ContactlessCard_UserErrorCode_BuildSupportedAppList_Failed; } eErr = BuildSupportedAppList(eType,pCardX,vAIDs); if (eErr != Error_Succeed) { QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("GetICDataFromCard::BuildSupportedAppList failed(%d):%s.", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errBuildAppList, errMsg.GetData()); if(eErr == Error_Interact) return -2; else continue; } //Dbg("[%s]",testIC); eErr = AppSelected(eType,pCardX,vAIDs.at(0).aid,vAIDs.at(0).len); if (eErr == Error_Succeed) return 0; else { QueryLastErr(eType, errMsg); errMsg = CSimpleStringA::Format("GetICDataFromCard::AppSelected failed(%d):%s.", eErr, errMsg.GetData()); LogWarn(Severity_Middle, Error_Unexpect, errBuildAppList, errMsg.GetData()); if(eErr == Error_Interact) return -2; else continue; } } return -3; } int CCardProcess::ConstructARQCData(const char *pATC, char *&pDataToARQC, char *&pSomeICData) { //9f0206 9f0306 9f1a02 9505 5f2a02 9a03 9c01 9f3704 9f2103 9f4e14 //9f0206授权金额 ( 6 ), 9f0306其它金额 ( 6), 9f1a02终端国家代码( 2) //,5f2a02交易货币代码( 2), 9a03交易日期( 3), 9c01交易类型( 1), pDataToARQC = new char[1024]; ZeroMemory(pDataToARQC,1024); //DbgInfo(CSimpleStringA::Format(", atc %s",pATC)); ICData authAmount(false,0x9f,0x02),otherAmount(false,0x9f,0x03),ctyCode(false,0x9f,0x1a) ,currCode(false,0x5f,0x2a),transTime(false,0x9f,0x21),transDate(false,0x9a,0x00) ,transType(false,0x9c,0x00); PBYTE tmpARQCData = new BYTE[512]; PBYTE tmpSomeICData = new BYTE[512]; ZeroMemory(tmpARQCData,512); ZeroMemory(tmpSomeICData, 512); int len = 0, iclen = 0; tmpSomeICData[iclen++] = 0x9f; tmpSomeICData[iclen++] = 0x02; tmpSomeICData[iclen++] = 0x06; if (ToFindTagValue(m_vBusData, authAmount, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, authAmount.value, authAmount.lenth); memcpy(tmpSomeICData + iclen, authAmount.value, authAmount.lenth); } else { memset(tmpARQCData + len, 0, 6); memset(tmpSomeICData + iclen, 0, 6); } len += 6; iclen += 6; tmpSomeICData[iclen++] = 0x9f; tmpSomeICData[iclen++] = 0x03; tmpSomeICData[iclen++] = 0x06; if (ToFindTagValue(m_vBusData, otherAmount, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, otherAmount.value, otherAmount.lenth); memcpy(tmpSomeICData + iclen, otherAmount.value, otherAmount.lenth); } else { memset(tmpARQCData + len, 0, 6); memset(tmpSomeICData + iclen, 0, 6); } len += 6; iclen += 6; //terminal country code "0156" tmpSomeICData[iclen++] = 0x9f; tmpSomeICData[iclen++] = 0x1a; tmpSomeICData[iclen++] = 0x02; if (ToFindTagValue(m_vBusData, ctyCode, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, ctyCode.value, ctyCode.lenth); memcpy(tmpSomeICData + iclen, ctyCode.value, ctyCode.lenth); } else { memset(tmpARQCData + len, 0, 2); memset(tmpSomeICData + iclen, 0, 2); } len += 2; iclen += 2; //TVR tmpSomeICData[iclen++] = 0x95; tmpSomeICData[iclen++] = 0x05; memcpy(tmpARQCData + len,m_TVR,5); memcpy(tmpSomeICData + iclen, m_TVR, 5); len += 5; iclen += 5; //currency code tmpSomeICData[iclen++] = 0x5f; tmpSomeICData[iclen++] = 0x2a; tmpSomeICData[iclen++] = 0x02; if (ToFindTagValue(m_vBusData, currCode, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, currCode.value, currCode.lenth); memcpy(tmpSomeICData + iclen, currCode.value, currCode.lenth); } else { memset(tmpARQCData + len, 0, 2); memset(tmpSomeICData + iclen, 0, 2); } len += 2; iclen += 2; //trans date tmpSomeICData[iclen++] = 0x9a; tmpSomeICData[iclen++] = 0x03; if (ToFindTagValue(m_vBusData, transDate, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, transDate.value, transDate.lenth); memcpy(tmpSomeICData + iclen, transDate.value, transDate.lenth); } else { memset(tmpARQCData + len, 0, 3); memset(tmpSomeICData + iclen, 0, 3); } len += 3; iclen += 3; //trans type tmpSomeICData[iclen++] = 0x9c; tmpSomeICData[iclen++] = 0x01; if (ToFindTagValue(m_vBusData, transType, false, 0, m_vBusData.size() - 1) != -1) { memcpy(tmpARQCData + len, transType.value, transType.lenth); memcpy(tmpSomeICData + iclen, transType.value, transType.lenth); } else { memset(tmpARQCData + len, 0, 1); memset(tmpSomeICData + iclen, 0, 1); } len += 1; iclen += 1; //for temp oiltmp tmpARQCData[len++] = m_randData[0]; tmpARQCData[len++] = m_randData[1]; tmpARQCData[len++] = m_randData[2]; tmpARQCData[len++] = m_randData[3]; tmpSomeICData[iclen++] = 0x9f; tmpSomeICData[iclen++] = 0x37; tmpSomeICData[iclen++] = 0x04; tmpSomeICData[iclen++] = m_randData[0]; tmpSomeICData[iclen++] = m_randData[1]; tmpSomeICData[iclen++] = m_randData[2]; tmpSomeICData[iclen++] = m_randData[3]; //aip tmpARQCData[len++] = m_AIP[0]; tmpARQCData[len++] = m_AIP[1]; tmpSomeICData[iclen++] = 0x82; tmpSomeICData[iclen++] = 0x02; tmpSomeICData[iclen++] = m_AIP[0]; tmpSomeICData[iclen++] = m_AIP[1]; //ATC PBYTE tmpATC = new BYTE[2]; ZeroMemory(tmpATC,2); StrBuf2HexBuf(pATC,&tmpATC); tmpARQCData[len++] = tmpATC[0]; tmpARQCData[len++] = tmpATC[1]; tmpSomeICData[iclen++] = 0x9f; tmpSomeICData[iclen++] = 0x36; tmpSomeICData[iclen++] = 0x02; tmpSomeICData[iclen++] = tmpATC[0]; tmpSomeICData[iclen++] = tmpATC[1]; //CVR oiltmp 20140415 //03A0B000 tmpARQCData[len++] = m_CVR[0]; tmpARQCData[len++] = m_CVR[1]; tmpARQCData[len++] = m_CVR[2]; tmpARQCData[len++] = m_CVR[3]; //DbgInfo(CSimpleStringA::Format("term2arqcdata,len[%d]",len)); HexBuf2StrBuf(tmpARQCData,&pDataToARQC,len); HexBuf2StrBuf(tmpSomeICData, &pSomeICData, iclen); //Dbg("[%s]",pDataToARQC); if (tmpARQCData != NULL) { delete[]tmpARQCData; } return len; } int CCardProcess::FindTagValue(TagVectorType eType,ICData& data,bool bLevel,int start,int end) { switch(eType) { case TAG_VECTOR_IC: return ToFindTagValue(m_vICData,data,bLevel,start,m_vICData.size()-1); break; case TAG_VECTOR_BUS: return ToFindTagValue(m_vBusData,data,bLevel,start,m_vBusData.size()-1); break; default: break; } return -1; } int CCardProcess::ToFindTagValue(vector& vData,ICData& data,bool bLevel,int start,int end) { //LPBYTE pData = *data; int ret = -1; vector::iterator it = vData.begin(); if (start < 0 || start >= vData.size()) return ret; for (it += start,ret = start; it != vData.end(); ++it,++ret) { if (ret > end) break; if (bLevel && data.level != it->level) continue; if (data.bForm && it->bForm) { if (data.tag[0] == it->tag[0] && data.tag[1] == it->tag[1]) { data.bForm = true; data.level = it->level; return ret; } else continue; } else if(!data.bForm && !it->bForm) { if (data.tag[0] == it->tag[0] && data.tag[1] == it->tag[1]) { data.bForm = false; data.value = new BYTE[it->lenth]; memcpy(data.value,it->value,it->lenth); data.lenth = it->lenth; data.level = it->level; return ret; } else continue; } } return -1; } void CCardProcess::ConstructAPDU(BYTE cls,BYTE ins,BYTE p1,BYTE p2,BYTE lc,LPBYTE data,LPBYTE le) { ZeroMemory(m_APDUsendBuf,sizeof(m_APDUsendBuf)); m_lenAPDU = 0; m_APDUsendBuf[0] = cls; m_APDUsendBuf[1] = ins; m_APDUsendBuf[2] = p1; m_APDUsendBuf[3] = p2; m_lenAPDU = 4; if (lc != NULL && data != NULL) { m_APDUsendBuf[4] = lc; m_lenAPDU++; if (lc != 0) { memcpy(m_APDUsendBuf+m_lenAPDU,data,lc); m_lenAPDU += lc; } } if (le != NULL) m_APDUsendBuf[m_lenAPDU++] = (*le); if (!data) { delete[] data; data = NULL; } } int StrBuf2HexBuf(LPCTSTR strBuf,PBYTE* hexBuf) { int len = strlen(strBuf); if (len == 0 || len%2 != 0) return 0; BYTE* buf = new BYTE[len/2]; if (buf == NULL) return 0; int j = 0; for (int i = 0; i < len;) { int tmpVal; sscanf(strBuf+i,"%2X",&tmpVal); buf[j] = tmpVal; //buf[j] = char2int(strBuf[i])*16 + char2int(strBuf[i+1]); i += 2; j++; } //memcpy(buf,strBuf,len); *hexBuf = buf; return j; } int HexBuf2StrBuf(PBYTE hexBuf,char** strBuf,DWORD len) { char* tmpStr = *strBuf; int count = 0; for (int i = 0; i < len; ++i) { sprintf(tmpStr+count,"%0.2X",hexBuf[i]); count += 2; } return 0; }