int PubReadUpCard(struct TrackInfo *TrackStru) { uint uiKey; PubClearAll(); PubDisplay(3, "正在与读卡器连接"); ASSURE_NORMAL(PubHandshakeToReader(1)); PubClearAll(); while(1) { PubDisplay(2,""); PubDisplay(3, "请把卡放到感应区"); PubDisplay(4,""); if (EA_ucKBHit()==EM_key_HIT) { uiKey=PubuiInkey(1); if (uiKey==EM_key_CANCEL) ASSURE_NORMAL(EXCEPTION); } if (FV.EmvStru.gbcExeReader != YES) { if (PubMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } else { if (EA_ucMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } } ASSERT_NORMAL(PubReadCardInfo(TrackStru)); return NORMAL; }
int PubICReadCard(char* pszOut, int *pLen) { unsigned char ucRecBuf[256]; unsigned int uiRetLen; unsigned char CFlagGetKey; EA_vCls(); CFlagGetKey = NO; EA_vCls(); if ( PubOpenUserICCardDev () != NORMAL ) return EXCEPTION; PubDisplayInv(1, "联名卡"); PubDisplayCen(2, "请插入IC卡"); PubDisplayCen(3, "按<取消>退出"); while(1) { if ( PubUserICCardIn() == NORMAL ) break; if (EA_ucKBHit () == EM_key_HIT) { if (PubuiInkey (1) == CANCEL) { return EXCEPTION; } } } if ( PubUserICCardPowerUp() != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("MF选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("EF05选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\xEF\x05", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("读文件选择",CPU_CARD, 0x00, 0xB0, 0x00, 0x00, 0x00, "", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; EA_ucCloseDevice (&gbhdlUserCard); memcpy(pszOut, ucRecBuf, uiRetLen); *pLen = uiRetLen; EA_ucCloseDevice (&gbhdlUserCard); return NORMAL; }
int PubRFReadCard(char *pszOut, int *pLen) { uint uiKey = 0; PubClearAll(); PubDisplay(3, "正在与读卡器连接"); ASSURE_NORMAL(PubHandshakeToReader(1)); PubClearAll(); while(1) { PubDisplay(2,""); PubDisplay(3, "请把卡放到感应区"); PubDisplay(4,""); if (EA_ucKBHit()==EM_key_HIT) { uiKey=PubuiInkey(1); if (uiKey==EM_key_CANCEL) ASSURE_NORMAL(EXCEPTION); } if (FV.EmvStru.gbcExeReader != YES) { if (PubMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } else { if (EA_ucMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } } ASSERT_NORMAL(EA_uiSelect_MF()); ASSERT_NORMAL(EA_uiSelect_EF05()); ASSERT_NORMAL(EA_uiSelect_bin(pszOut, pLen)); return NORMAL; }
/********************************* *功能:上送IC卡脱机成功交易 * 增加上送预授权完成通知功能 linq add ** 1.脱机拒绝交易,记录流水,不送 ** 2.脱机消费撤消了,不送 **********************************/ int PubUploadICC (int nCount) { char szBuffer[200]; int nRet; uint nRetLen; uchar ucFd; int gbnEMVUploadCount; //EMV离线上送 int nUploadCnt; char szReadBuff[sizeof(struct FileRecStru)+1024]; char cIsConfirmNotice=0; if (memcmp(AUTHENTIC_VERSION, "\x13\x03", 2) < 0) // emv二期版本1303开始才支持EMV脱机交易 return NORMAL; // 20110310 返回Z7的结算交易,不上送脱机交易 if (gbnTransType == SETTLE && gbcHostRetZ7 == 1) return NORMAL; nRetLen = 0; nUploadCnt = 0; gbnEMVUploadCount = 1; // linq add 每次都从1开始读记录 if (PubFileOpen (WATERFILE, &ucFd) != NORMAL) ASSERT_NORMAL(EXCEPTION); for (;;) { cIsConfirmNotice=0; nRet = PubFileOper (ucFd, REC_READ, gbnEMVUploadCount, 1, szReadBuff, &nRetLen); if (nRet != NORMAL) break; memcpy(&UploadFileRec, szReadBuff, sizeof(struct FileRecStru)); // 预授权完成通知未上送, 或者是IC卡脱机批准(未被脱机撤消)未上送交易 if (IsUploadTrans(&UploadFileRec) == NO) { gbnEMVUploadCount++; continue; } if (EA_ucKBHit () == EM_key_HIT) { //按键取消键退出,上送过程允许按取消退出 if(PubuiInkey (1) == EM_key_CANCEL) { EA_ucPFClose(ucFd); ASSERT_NORMAL(EXCEPTION); } } if(UploadFileRec.cTransType == CONFIRM_NOTICE) cIsConfirmNotice = 1; if (cIsConfirmNotice==0) { if (ProUploadPacket() != NORMAL) { EA_ucPFClose(ucFd); ASSERT_NORMAL(EXCEPTION); } } else { if (ProUploadPacketConfirmNotice() != NORMAL) { EA_ucPFClose(ucFd); ASSERT_NORMAL(EXCEPTION); } } PubDisplay(2, "正在上送通知交易"); nSendLen = sizeof (szSendStr); if (PubIsoToStr(szSendStr, &iso, &nSendLen) != NORMAL) { EA_ucPFClose(ucFd); ASSERT_NORMAL(EXCEPTION); } /* * 通讯失败的处理 */ if (PubUploadCommu(&CommInfo,szSendStr, nSendLen, szReadStr, &nReadLen) != NORMAL) { // linq modify 中行上送失败即按失败处理,不需连续上送 EA_ucPFClose (ucFd); ASSERT_NORMAL(EXCEPTION); } if (ProGetRetCode () != NORMAL) { EA_ucPFClose (ucFd); ASSERT_NORMAL(EXCEPTION); } // 在存储转发预授权完成通知交易或基于EMV标准的IC卡离线消费交易结果交易时,只要POS收到的响应报文响应码不是Z1或者Z7,就认为通知交易上送动作已经完成。 if ((memcmp(szErrCode, "Z1", 2) != 0 ) && (memcmp(szErrCode, "Z7", 2) != 0 )) memcpy (szErrCode, "00", 2); if (memcmp (szErrCode, "00", 2) != 0) { // linq modify 中行上送失败即按失败处理,不需连续上送 EA_ucPFClose (ucFd); // 20110310 返回Z7,设置Z7标志 if (memcmp(szErrCode, "Z7", 2)==0 ) gbcHostRetZ7 = 1; else gbcHostRetZ7 = 0; // 20110310 如果是结算前上送脱机交易,返回Z7,则直接继续结算过程即可 if (gbnTransType == SETTLE && gbcHostRetZ7 == 1) return NORMAL; PubDialOffIfNoAutovoid(); BUFCLR(szBuffer); PubGetRetInfoFromCode(szErrCode, szBuffer); if (strlen(szBuffer) > 20) { ProDispInfo2Line(szBuffer, 1); } else { ProDispInfo2Line(szBuffer, 2); } ProDispInfo2Line(UploadFileRec.AddiResponse, 3); PubuiInkey(TIPS_TIMEOUT); ASSERT_NORMAL(EXCEPTION); } //正确处理... //获得正确的返回数据 ProGetData (); //改变记录 strcpy (UploadFileRec.szReturnCode, szErrCode); UploadFileRec.cUploadFlag = '*'; if (PubFileOper(ucFd, REC_WRITE, gbnEMVUploadCount, 0, (char *) &UploadFileRec, &nRetLen) != NORMAL) { PubDialOffIfNoAutovoid(); EA_vCls (); PubDisplay (2, "更新文件失败"); EA_ucPFClose (ucFd); PubuiInkey (5); ASSERT_NORMAL(EXCEPTION); } // 如果上送的交易是末笔交易,则同步末笔交易打印结构 if (UploadFileRec.cTransType == FV.gbPrintDetail.cTransType && memcmp(UploadFileRec.szAmount, FV.gbPrintDetail.szAmount, 12) == 0 && atol(UploadFileRec.szTrace) == atol(FV.gbPrintDetail.szTrace) && atol(UploadFileRec.szCheck) == atol(FV.gbPrintDetail.szCheck)) { PubSaveDetail(&UploadFileRec); } gbnEMVUploadCount++; nUploadCnt++; FV.bank.nHasOfflineNum --; if (FV.bank.nHasOfflineNum < 0) FV.bank.nHasOfflineNum = 0; PubWriteMemFile(&FV.bank.nHasOfflineNum, sizeof(FV.bank.nHasOfflineNum)); if (gbcPosCtrlCode != '0') { // linq modify 如果DE3最后数字不为'0',先退出处理该标志 EA_ucPFClose (ucFd); ASSERT_NORMAL(EXCEPTION); } // 如果上送笔数达到规定次数,则先成功退出 if ((nCount != 0) && (nUploadCnt >= nCount)) { EA_ucPFClose (ucFd); return NORMAL; } } EA_ucPFClose (ucFd); gbnEMVUploadCount = 1; PubDisplay (2, " "); FV.bank.nHasOfflineNum = 0; PubWriteMemFile(&FV.bank.nHasOfflineNum, sizeof(FV.bank.nHasOfflineNum)); return NORMAL; }
// ***************************************************************** // 功能: QUERY_NOTE_RECORD // 说明: 查询日结小票 // 入口参数: // 出口参数: Null // 作者: // 返回值: -1 关机 // ***************************************************************** int QUERY_NOTE_RECORD(void) { int count; INT32U RecordCount = 0; uchar uckey; uint uikey; uchar ucOpenID=0; INT8U rec[60]; memset(rec, 0, sizeof(rec)); if ( EA_ucPFOpen( (uchar *)hisrecFileName, &ucOpenID) != EM_ffs_SUCCESS ) { lcddisperr("打开日结文件失败"); return 0; } // 获取有效信息条数 (void)EA_ucPFInfo(ucOpenID, EM_ffs_VALIDREC, &RecordCount); if( RecordCount == 0) { lcddisperr("没有日结信息"); (void)EA_ucPFClose(ucOpenID); return 0;//表示没有记录 } count = RecordCount;//最后一条 if(EA_ucPFReadRec(ucOpenID, count, 1, &RecordCount, rec) != EM_SUCCESS) { (void)EA_ucPFClose(ucOpenID); lcddisperr((void *)"读取不符合"); return 0; } AnalyAndDisplayNote(rec); while ( 1 ) { uckey = EA_ucKBHit(); if(uckey == EM_key_HIT) //有按键 { uikey = EA_uiInkey(0); //读取按键键值 if ( (uikey == EM_key_EXIT) || (uikey == EM_key_CANCEL) ) //退出 { (void)EA_ucPFClose(ucOpenID); return 1; } switch ( uikey ) { case EM_key_UP: // 按[2]键或往上拨动拨轮则屏幕往上滚动一行 count --; if ( count < 0 )//记录超限 { lcddisperr("最后一条"); count ++; } break; case EM_key_DOWN: // 按[8]键或往下拨动拨轮则屏幕往下滚动一行 count ++; if ( count >= RecordCount ) { lcddisperr("最后一条"); count --; } break; case EM_key_ENTER: break; default: break; } if ( (uikey==EM_key_UP) || (uikey==EM_key_DOWN) ) { if(EA_ucPFReadRec(ucOpenID, count, 1, &RecordCount, rec) != EM_SUCCESS) { (void)EA_ucPFClose(ucOpenID); lcddisperr((void *)"读取不符合"); return 0; } AnalyAndDisplayNote(rec); } if(uikey == EM_key_ENTER) { print_work_note_his(rec); (void)EA_ucPFClose(ucOpenID); return 1; } } } }
/***************************************************************** 函数原型:main() 功能描述:主函数 参数描述: 返回值: 无 作 者: 许岩/刘及华 日 期: 2012-11-24 修改历史: 日期 修改人 修改描述 ------ --------- ------------- *****************************************************************/ int main(void) { INT8U ret = 0; char mainflag = 1; INT8S buf[30]; uchar uckey; uint uikey; BUS_TIME ltime; (void)EA_ucSetStopFlag( EM_DISABLE_STOP ); //不允许系统进入睡眠状态; reboot: ret = System_Init(); //系统初始化,包括PSAM,参数表,GPRS初始化 if( ret != ok ) { lcddisperr("系统初始化失败!"); goto reboot; } Beep(1000); for ( ;; ) { Get_Time(<ime); sprintf((void *)buf, " %02X%02X-%02X-%02X %02X:%02X", ltime.century, ltime.year, ltime.month, ltime.day, ltime.hour, ltime.minute); // EA_vTextOut(0, 0, EM_key_FONT8X16, 0, 1, 1, (char *)buf); EA_vDisplay(3, (void *)buf); if( mainflag == 1 ) { DisplayWelcomeMenu(); mainflag = 0; } uckey = EA_ucKBHit(); if(uckey == EM_key_HIT) //有按键 { uikey = EA_uiInkey(0); //读取按键键值 switch ( uikey ) { case EM_key_EXIT: //关机 { mainflag = 1; goto shutdown; break; } case EM_key_F3: { Login(); //登录界面 mainflag = 1; break; } case EM_key_F1: { Parm_Setting(); //参数配置 mainflag = 1; break; } case EM_key_1: { GPRS_TEST(); //无线连接测试 mainflag = 1; break; } case EM_key_F2: { // QUERY_NOTE_RECORD(); Gprs_Upload_data(); //数据上传 mainflag = 1; break; } default: break; } } } shutdown: Power_Down(); }
uchar EI_ucDataDownload(TMS_AppScript * ptTMSHead) { ET_HostData *ptHostData = NULL; char szBuffer[100]; uchar ucRet = EM_SUCCESS; uint uiFrameNo = 0; uint uiLength; #if M3_UN_MALLOC uchar aucHostDataBuff[EM_TMS_MAXBUFSIZE]; #endif if(NULL == ptTMSHead) { EA_TMS_vLog("EI_ucDataDownload: NULL Pointer!"); return EM_ERROR; } memset(szBuffer, 0, sizeof(szBuffer)); EI_ClearAll(); // 创建进度条 if(TMS_BREAKTYPE_YES == EG_ucBreakType) { EA_face_vSetInfo("下载中(按取消退出)..."); EA_TMS_vLog("\r\n#下载中[支持中断]..."); } else { EA_face_vSetInfo("下载中..."); EA_TMS_vLog("\r\n下载中..."); } #if M3_UN_MALLOC ptHostData = (ET_HostData *)&aucHostDataBuff; #else ptHostData = (ET_HostData *)EA_pvMalloc(EG_uiFrameLen+100); if (!ptHostData) { EA_face_vSetInfo("内存分配失败"); EA_TMS_vLog("EI_ucDataDownload:EA_pvMalloc fail"); return EM_ALLOCERR; } #endif EG_ucLoadDataFlag = 1; /*设置进度条*/ EA_face_vSetProgress( (float) ((float)EG_usCurFrame/(float)EG_usAllFrame)); while(EG_usCurFrame < EG_usAllFrame) { EG_ucStepFlag =TMS_STEP_HOST_DATA; EA_TMS_vLog("\r\n# 接收第%d帧,总%d帧", EG_usCurFrame, EG_usAllFrame); /* 接收下载数据信息包*/ uiLength = 0; ucRet = EI_ucRecvHostDataPack(EG_usCurFrame, ptHostData, &uiLength); if (ucRet != EM_SUCCESS) { EA_TMS_vLog("EI_ucDataDownload: EI_ucRecvHostDataPack Fail!"); EA_TMS_vLog("# 发送下载失败应答帧[%x]",EM_TERM_DATAFEED_FAIL); EI_ucSendDataAckPack(EM_TERM_DATAFEED_FAIL); ucRet = EM_ERROR; goto DOWNEND; } /* 存储数据包信息*/ #ifdef TMS_DEBUG if (2 == EG_ucDBShowFlag) { EA_TMS_vLog("SAVE FRMAE[%d]:", EG_usCurFrame); EI_vDebugData(uiLength, (uchar*)ptHostData->acDataBuff); } #endif ucRet = EA_ucTMSSaveFrame(EG_usCurFrame, uiLength, ptHostData->acDataBuff); if ( EM_SUCCESS != ucRet) { EA_TMS_vLog("EI_ucDataDownload:EA_ucTMSSaveFrame fail[%x]", ucRet); EA_TMS_vLog("SAVE FRMAE[%d] Length[%d]:", EG_usCurFrame, uiLength); EI_vDebugData(uiLength, (uchar*)ptHostData->acDataBuff); goto DOWNEND; } /* 交互判断*/ if(EG_ucBreakType == TMS_BREAKTYPE_YES) { if(EA_ucKBHit() == EM_key_HIT && EA_uiInkeyMs(0) == EM_key_CANCEL) { EA_TMS_vLog("# 发送取消失败应答帧[%x]",EM_TERM_DATAFEED_FAIL); EI_ucSendDataAckPack(EM_TERM_DATAFEED_FAIL); ucRet = EM_ABOLISH; goto DOWNEND; } } uiFrameNo++; EG_usCurFrame++; if((uiFrameNo == EG_uiSerialPackNum) || (EG_usCurFrame == EG_usAllFrame)) { EA_TMS_vLog("\r\n# 发送应答帧[%d]\r\n", EG_usCurFrame); ucRet = EI_ucSendDataAckPack(EG_usCurFrame); if (ucRet != EM_SUCCESS) { EA_TMS_vLog("EI_ucDataDownload:send data ack pack fail[%d]\r\n", ucRet); if (EG_usCurFrame != EG_usAllFrame) { goto DOWNEND; } else { ucRet = EM_SUCCESS; } } //工行TMS流程在最后一帧接收完成后还需接收一帧,但不对数据进行校验,直接返回成功 if (TMS_AUTH_ICBC == EG_ucAuthFlag && EG_usCurFrame == EG_usAllFrame) { EA_TMS_vLog("# ICBC end!"); EA_face_vSetProgress( (float) ((float)EG_usCurFrame/(float)EG_usAllFrame)); EI_ucReadICBC(5, ptHostData->acDataBuff, &uiLength); memset(ptHostData->acDataBuff, 0, sizeof(ptHostData->acDataBuff)); uiLength = 0; } uiFrameNo = 0; } #ifdef PED // 设置进度条 if(TMS_BREAKTYPE_YES == EG_ucBreakType) { sprintf(szBuffer, "下载中[%3.1f%%](按取消退出)...", (float)((float)EG_usCurFrame/(float)EG_usAllFrame)*100); EA_face_vSetInfo(szBuffer); } else { sprintf(szBuffer, "下载中[%3.1f%%]...", (float)((float)EG_usCurFrame/(float)EG_usAllFrame)*100); EA_face_vSetInfo(szBuffer); } #endif EA_face_vSetProgress( (float) ((float)EG_usCurFrame/(float)EG_usAllFrame)); } //银联MISPOS if (TMS_AUTH_YL == EG_ucAuthFlag && 1 == EG_YL_ucSyncFlag) { EI_YL_RecvTMSSyncPack(); EA_face_vSetInfo("接收协议同步包完成"); } DOWNEND: #if M3_UN_MALLOC return ucRet; #else if(NULL != ptHostData) { EA_vFree(ptHostData); ptHostData = NULL; } return ucRet; #endif }
int read_from_EFT(int *pLen, char *readstr) { char buffer[512]; ET_ProductInfo tProductInfo; uint unActLen; uchar ucRet; DevHandle hRS232Handle = EM_INVALID_HANDLE; unActLen = 0; #ifdef EPT_A9L memset(&tProductInfo, 0x00, sizeof(ET_ProductInfo)); EA_ucGetProductInfo(&tProductInfo); if ( memcmp(tProductInfo.acName , "E520" , 4) == 0 && tProductInfo.ucMachType == 2) { ucRet = EA_ucOpenDevice("COM3", 0, &hRS232Handle); } else { ucRet = EA_ucOpenDevice(SERIAL_PORT, 0, &hRS232Handle); } #else ucRet = EA_ucOpenDevice("COM", EM_io_PORT1, &hRS232Handle); #endif if (ucRet != EM_SUCCESS || hRS232Handle == EM_INVALID_HANDLE) { EA_vCls(); EA_vDisplay(2, "打开RS232口出错[%02x]", ucRet); EA_ucCloseDevice(&hRS232Handle); PubuiInkey(3); return (EXCEPTION); } ucRet = EA_ucInitRS232(hRS232Handle, EM_232_9600BPS, EM_232_NOPAR, EM_232_8DBS); if (ucRet != EM_SUCCESS) { EA_vCls(); EA_vDisplay(2, "RS232初始化错[%02x]", ucRet); EA_ucCloseDevice(&hRS232Handle); PubuiInkey(3); return (EXCEPTION); } while (1) { *pLen = 0; /* * read STX 0x02 until time out */ memset (buffer ,0 ,sizeof(buffer)); do { if(EM_key_HIT == EA_ucKBHit()) { EA_ucCloseDevice(&hRS232Handle); return (EXCEPTION); } EA_ucReadDeviceMs(hRS232Handle, 1, 10, buffer, &unActLen); } while (buffer[0] != 0x02); //read left data ucRet = EA_ucReadDeviceMs(hRS232Handle, 200, 10, buffer+1, &unActLen); if (ucRet != EM_SUCCESS || unActLen > 200) continue; // debug_print((char*)"SERIAL CMD", buffer, unActLen + 1);//FIXME *pLen = unActLen + 1; memcpy(readstr, buffer, *pLen); break; } //end of while EA_ucCloseDevice(&hRS232Handle); return (NORMAL); }
/* * 函数功能:特殊用于离线交易上送的通讯 * 入口参数: * szSendStr ―― 待发送的数据 * nSendLen ―― 待发送数据的长度 * 出口参数: * szRecvStr ―― 收到的数据 * pnRecvLen ―― 收到的数据的长度 */ int PubUploadCommu(struct CommStru *pCommInfo, char *szSendStr, int nSendLen, char *szRecvStr, int *pnRecvLen, char *cOnline , int flag) { char szGetBuffer[30], szBuffer[10]; ISODataStru isotmp; int nLen; *cOnline = NO; if (szSendStr == NULL || szRecvStr == NULL) return EXCEPTION; if (pnRecvLen == NULL || nSendLen == 0) return EXCEPTION; //add by baijz 20110728 BCTC要求 CDMA通讯没有办法按取消键退出 EA_vDelayMs(300); if (EA_ucKBHit () == EM_key_HIT) { //有按键 if (PubuiInkey (1) == EM_key_CANCEL) { *cOnline = CANCEL; return EXCEPTION; } } //add end if (PubYlConnect (pCommInfo) != NORMAL) { *cOnline = CANCEL; return EXCEPTION; } if (gbnTransType != LOGIN) { /* * 自动冲正处理 */ //BCTST BUFCLR(szBuffer); ASSERT_NORMAL(PubGetPoscfgcAutoVoidFlag(szBuffer)); if (szBuffer[0] == 1) { PubDisplay(2, "自动冲正, 请稍候..."); BUFCLR(szGetBuffer); ASSURE_NORMAL(PubGetBankcMacChk(szGetBuffer)); PubSetBankcMacChk(MAC_ECB); //chenjs20061226 测试组反馈无法取消冲正PubAutoVoid(); //chenjs20061226 add down ASSURE_NORMAL(PubAutoVoid());//chenjs20061226 add down PubSetBankcMacChk(szGetBuffer[0]); PubClearAll(); } ProDispCommMsg(5); //END } //add end PubSetBankcMacChk(MAC_ECB); if ( flag != 2) PubCalcMac(szSendStr, nSendLen - 8, szSendStr + nSendLen - 8); /* * 通讯:发送、接收 */ /*chenjs20070105根据测试组反馈,这个提示会覆盖上面的提示 PubClearAll(); ProDispCommMsg(5); PubDisplay(2, "处理中, 请稍候..."); */ ASSURE_NORMAL(ProSendToHost(pCommInfo, nSendLen, szSendStr)); //chenjs20070105 ProDispCommMsg(6); *cOnline = YES; PubDisplay(2 , "");// 清屏 ASSURE_NORMAL(ProReadFromHost(pCommInfo, pnRecvLen, szRecvStr)); memset((char *) &isotmp, 0, sizeof(isotmp)); PubStrToIso(szRecvStr + 5, *pnRecvLen - 5, &isotmp, NULL); BUFCLR(szGetBuffer); ASSURE_NORMAL(PubGetBankcMacChk(szGetBuffer)); if (szGetBuffer[0] != MAC_NO) { BUFCLR(szBuffer); nLen = sizeof(szBuffer); PubGetBit(&isotmp, RET_CODE, szBuffer, &nLen); if (memcmp(szBuffer, "00", 2) == 0) { // 银联生产后台在电子现金离线交易上送的时候,没有送mac下来,造成计算mac错误,bctc测试是没问题的,说明按照规范,我们做法是正确的。 // if (PubChkMac(szRecvStr + *pnRecvLen - 8, szRecvStr + 5, *pnRecvLen - 8 - 5) != NORMAL) // return EXCEPTION; } } return NORMAL; }
/* * 函数功能:消费撤销交易处理 * 入口参数:无 * 出口参数:无 * 返 回 值:NORMAL -- 成功 * 非NORMAL -- 失败 */ int PubMBVoid() { uchar szRetCode[3]; uchar szPwdBuf[30]; uchar ucPasswdLen, ucFd; char szBatch[7], szGetBuffer[30], szTmpBuf[40]; int nSendLen, nTmpLen; int nTryTime,nRet; char cTimes; uchar szTrackBuf[110]; unsigned int uiKey; int i, iLen; struct TrackInfo TrackStru; /* * 数据初始化 */ BUFCLR(gbszSendStr); BUFCLR(gbszReadStr); BUFCLR(szRetCode); BUFCLR(szPwdBuf); //chenjs20060911 BUFCLR(szCheck); BUFCLR(szBatch); memset((char *) &CancelPos, 0, sizeof(struct FileRecStru)); /* * 是否批上送 */ CancelPos.cTransType = gbnTransType;//dudj20060108 modify after mobile test ASSERT_NORMAL(PubIsBatch()); /* * 主管授权,匹配原记录 */ PubClearAll(); // if (PubCheckTrans(MB_VOID) != NORMAL) // { // PubDisplayInv(1, "大额支付撤销"); // PubReject(); // return EXCEPTION; // } // ASSERT_NORMAL(PubAuthToOper("大额支付撤销")); if(gbnTransType == MB_VOID) { ASSERT_NORMAL(PubAuthToOper("手机芯片消费撤销")); } else { ASSERT_NORMAL(PubAuthToOper("手机预授权完成撤销")); } nRet = -1; nRet = ProMBReadCancelCode (); //查找原交易 if (nRet == EXCEPTION) return EXCEPTION; // PubDisplayInv(1, "大额支付撤销"); if(gbnTransType == MB_VOID) PubDisplayInv(1, "手机芯片消费撤销"); else PubDisplayInv(1, "手机预授权完成撤销"); /* * 数据采集(打基本包,刷卡) */ PubSetBankcMacChk(MAC_ECB); ASSERT_NORMAL(PubPacketFix(&CancelPos)); ASSERT_NORMAL(PubGetBankcCancelReadCardFlag(szGetBuffer)); if (szGetBuffer[0] != 1) { PubSetBitYL (&iso, PAN, CancelFileRec.szCardNo, strlen (CancelFileRec.szCardNo)); } else { PubClearAll(); PubDisplay(3, "正在与读卡器连接"); if(PubHandshakeToReader(1)!=NORMAL) return EXCEPTION; while(1) { PubDisplay(2,""); PubDisplay(3, "请把卡放到感应区"); PubDisplay(4,""); if (EA_ucKBHit()==EM_key_HIT) { uiKey=PubuiInkey(1); if (uiKey==EM_key_CANCEL) { return EXCEPTION; } } if (FV.EmvStru.gbcExeReader != YES) { if (PubMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } else { if (EA_ucMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } } if (PubReadCardInfo(&TrackStru)!=NORMAL) { return EXCEPTION; } memset(szTrackBuf, 0, sizeof(szTrackBuf)); PubHexToAsc(szTrackBuf, EG_BankCardInfo.acCardNo, 20, 0); for (i=0; i<20; i++) { if (szTrackBuf[i]<'0' || szTrackBuf[i]>'9') szTrackBuf[i]=0x00; } if (i>=20) { szTrackBuf[19]=0x00; } PubSetBitYL (&iso, PAN, szTrackBuf, strlen (szTrackBuf)); memset(szTrackBuf, 0, sizeof(szTrackBuf)); PubHexToAsc(szTrackBuf, EG_BankCardInfo.acTrack2, 40, 0); memset(szTmpBuf, 0, sizeof(szTmpBuf)); memcpy(szTmpBuf, szTrackBuf, 2); for (i=0; i<2; i++) { if (szTmpBuf[i]<'0' || szTmpBuf[i]>'9') { //PubDisplay(3, "二磁道长度信息非法"); PubWriteLog(EXCEPTION, __FILE__, __LINE__); } } iLen=atoi(szTmpBuf); if (iLen<=37) { szTrackBuf[iLen+2]=0x00; ASSURE_NORMAL(PubSetBitYL(&iso, TRACK2, szTrackBuf+2, iLen)); } memset(szTrackBuf, 0, sizeof(szTrackBuf)); PubHexToAsc(szTrackBuf, EG_BankCardInfo.acTrack3, 108, 0); memset(szTmpBuf, 0, sizeof(szTmpBuf)); memcpy(szTmpBuf, szTrackBuf, 4); for (i=0; i<4; i++) { if (szTmpBuf[i]<'0' || szTmpBuf[i]>'9') { //PubDisplay(3, "三磁道长度信息非法"); PubWriteLog(EXCEPTION, __FILE__, __LINE__); } } iLen=atoi(szTmpBuf); if (iLen<=104) { szTrackBuf[iLen+4]=0x00; ASSURE_NORMAL(PubSetBitYL(&iso, TRACK3, szTrackBuf+4, iLen)); } //有效期 //add by chenjis 20121217 for BCTC 要求上送有效期 if(strlen(TrackStru.szExpBuf)) { strcpy(CancelPos.szExpDate,TrackStru.szExpBuf); ASSURE_NORMAL(PubSetBitYL (&iso, EXPIRY, CancelPos.szExpDate, 4)); } //end chenjis BUFCLR (szField55); nLenField55 = 0; //芯片序列号 AppendTLV (szField55, &nLenField55, "\xDF\x32", 2, EG_CardInfo.acCardSerNo, 10); AppendTLV (szField55, &nLenField55, "\xDF\x33", 2, EG_BankCardInfo.acSessionKey, 8); AppendTLV (szField55, &nLenField55, "\xDF\x34", 2, EG_BankCardInfo.acDateTime, 7); PubSetBitYL (&iso, ICC_INFO, szField55, nLenField55); //55 //add by chenjis 20121227 for BCTC FV.Void.nLenVoidField55 = nLenField55; memset(FV.Void.szVoidField55,0,sizeof(FV.Void.szVoidField55)); memcpy(FV.Void.szVoidField55,szField55,FV.Void.nLenVoidField55); WRITE_nVAR(FV.Void.szVoidField55); WRITE_nVAR(FV.Void.nLenVoidField55); //end if (memcmp (CancelFileRec.szCardNo, TrackStru.szPanBuf, strlen (CancelFileRec.szCardNo)) != 0) { PubClearAll(); PubDisplay (2, "卡号与原交易不一致"); PubuiInkey (3); return EXCEPTION; } } /* * 预拨号 */ ASSURE_NORMAL(PubPreDial(&CommInfo)); sprintf(CancelPos.szOperNo, "%s", CancelFileRec.szOperNo);// ? BUFCLR(szGetBuffer); PubGetCurOper(szGetBuffer, 3); sprintf(CancelPos.szOperNo, "%s", szGetBuffer); sprintf(CancelPos.szCardNo, "%s", CancelFileRec.szCardNo); BUFCLR(szGetBuffer); sprintf(szGetBuffer, "%12.12s", CancelFileRec.szAmount); ASSURE_NORMAL(PubSetBitYL(&iso, AMOUNT, szGetBuffer, 12)); sprintf(CancelPos.szAmount, "%s", CancelFileRec.szAmount); sprintf(CancelPos.szOldDate, "%s", CancelFileRec.szDate); sprintf(CancelPos.szOldRefNum, "%s", CancelFileRec.szReferenceNum); sprintf(CancelPos.szAuthID, "%s", CancelFileRec.szAuthID); sprintf(CancelPos.szOldAuthID, "%s", CancelFileRec.szOldAuthID); sprintf(CancelPos.szOldBatchNum, "%s", CancelFileRec.szBatchNum); sprintf(CancelPos.szOldCheckNum, "%s", CancelFileRec.szTrace); if(CancelPos.cTransType == MB_VOID) { ASSURE_NORMAL(PubSetBitYL(&iso, 25, "00", 2)); } else { ASSURE_NORMAL(PubSetBitYL(&iso, 25, "06", 2)); } ASSURE_NORMAL(PubSetBitYL(&iso, RETR_NUM, CancelPos.szOldRefNum, 12)); if(CancelPos.cTransType == MB_VOID) { if (strlen(CancelPos.szAuthID) > 0) { ASSURE_NORMAL(PubSetBitYL(&iso, AUTH_ID, CancelPos.szAuthID, 6)); } } else { // ASSURE_NORMAL(PubSetBitYL(&iso, AUTH_ID, CancelPos.szAuthID, 6)); // bctc认为,只能送预授权完成相应的授权码,不能送预授权完成使用的原预授权授权码 if (strlen(CancelPos.szOldAuthID) > 0) { ASSURE_NORMAL(PubSetBitYL(&iso, AUTH_ID, CancelPos.szOldAuthID, 6)); } else { ASSURE_NORMAL(PubSetBitYL(&iso, AUTH_ID, CancelPos.szAuthID, 6)); } } ASSURE_NORMAL(PubSetBitYL(&iso, 49, "156", 3)); ASSURE_NORMAL(PubGetBankstateszBatchNum(szBatch, sizeof(szBatch))); sprintf(CancelPos.szBatchNum, "%6.6s", szBatch); BUFCLR(szGetBuffer); if(CancelPos.cTransType == MB_VOID) { sprintf (szGetBuffer, "23%6.6s000601", CancelPos.szBatchNum); ASSURE_NORMAL (PubSetBitYL (&iso, 60, szGetBuffer, 14));//modify by baijz 20120109 支持返回余额 } else { sprintf (szGetBuffer, "21%6.6s00060", CancelPos.szBatchNum); ASSURE_NORMAL (PubSetBitYL (&iso, 60, szGetBuffer, 13)); } BUFCLR(szGetBuffer); sprintf(szGetBuffer, "%6.6s%6.6s", CancelPos.szOldBatchNum, CancelPos.szOldCheckNum); //add by baijz 20120521 if (gbnTransType == CONFIRM_VOID) sprintf(szGetBuffer + 12, "%4.4s", CancelPos.szOldDate); //add end ASSURE_NORMAL(PubSetBitYL(&iso, 61, szGetBuffer, strlen(szGetBuffer))); cTimes = 1; PubGetPoscfgcPinErrNum(&cTimes); nTryTime = 1; while (1) { BUFCLR(szGetBuffer); ASSURE_NORMAL(PubGetBankcCancelPin(szGetBuffer)); if (szGetBuffer[0] != 1) cTimes = 1; /*不输入密码的情况下就发送一次 */ if (szGetBuffer[0] == 1) { ucPasswdLen = sizeof(szPwdBuf); //del by baijz 20110523 ASSURE_NORMAL(PubReadPin(ENCON, CancelFileRec.szAmount, 12, DISPOFF, // CancelFileRec.szCardNo, szPwdBuf, &ucPasswdLen , "")); //add by baijz 20110523 手机芯片密码不带主帐号加密 ASSURE_NORMAL(PubReadPin(ENCON, CancelFileRec.szAmount, 12, DISPOFF, "0000000000000000", szPwdBuf, &ucPasswdLen , "")); //modify by baijz 20120625 密码长度最大到12位 if (ucPasswdLen != 0) { CancelPos.szMode[2] = '1'; ASSURE_NORMAL(PubSetBitYL(&iso, 26, "12", 2)); //modify by baijz 20120625 密码长度最大到12位 ASSURE_NORMAL(PubSetBitYL(&iso, PIN, szPwdBuf, 8)); BUFCLR(szGetBuffer); PubGetBankcDesType(&cDesType); { if(cDesType == DES3) { ASSURE_NORMAL(PubSetBitYL(&iso, 53, "1600000000000000", 16)); } else { ASSURE_NORMAL(PubSetBitYL(&iso, 53, "1000000000000000", 16)); } } } else CancelPos.szMode[2] = '2'; } else { CancelPos.szMode[2] = '2'; } memcpy(CancelPos.szMode, "96", 2); ASSURE_NORMAL(PubSetBitYL(&iso, SERVEMODE, CancelPos.szMode, 3)); /* * 格式转换(ISO->STR),通讯 */ nSendLen = sizeof(gbszSendStr); ASSURE_NORMAL(PubIsoToStr(gbszSendStr, &iso, &nSendLen)); gbnSendLen = nSendLen; ASSERT_NORMAL(PubCommu(&CommInfo, gbszSendStr, gbnSendLen, gbszReadStr, &gbnReadLen, DIALOFF_NO)); /*检验是否串包 */ ASSURE_NORMAL(PubCheckPack(&CancelPos)); // if (memcmp(gbszErrCode, "55", 2) == 0) // { // nTryTime++; // PubSetPoscfgcAutoVoidFlag(0); // if (nTryTime > cTimes) // { // PubDialOff(&CommInfo); // PubDisplay(2, "密码输入错误"); // PubDisplay(3, "超过%d次", cTimes); // PubuiInkey(3); // return EXCEPTION; // } // PubClearAll(); // PubDisplay(2, "55密码错"); // //chenjs20060929 add down 清除26、52、53避免原来输密码后来不输密码 // PubDelOneBit(&iso,26); // PubDelOneBit(&iso,52); // PubDelOneBit(&iso,53); // //chenjs20060929 add up // PubuiInkey(1); // BUFCLR(szGetBuffer); // ASSERT_NORMAL(PubGetBankstateszTrace(szGetBuffer, sizeof(szGetBuffer))); // sprintf(CancelPos.szTrace, "%6.6s", szGetBuffer); // ASSERT_NORMAL(PubSetBitYL(&iso, TRACE, CancelPos.szTrace, 6)); // continue; // } break; } // PubDialOff(&CommInfo); /* * 格式转换(STR->ISO), 返回包处理(写流水,打印) */ ASSERT_NORMAL(PubDispRetMsg(&CancelPos)); nTmpLen = sizeof(struct FileRecStru); if(PubFileOpen(YLWATER, &ucFd)!= NORMAL) { FV.Void.gbnVoidReason = WRI_WATER_ERR; WRITE_nVAR(FV.Void.gbnVoidReason); PubWriteLog(EXCEPTION, __FILE__, __LINE__); return EXCEPTION; } if (PubFileOper(ucFd, REC_WRITE, 0, 0, (char *) &CancelPos, &nTmpLen) != NORMAL) { FV.Void.gbnVoidReason = WRI_WATER_ERR; WRITE_nVAR(FV.Void.gbnVoidReason); EA_ucPFClose(ucFd); PubWriteLog(EXCEPTION, __FILE__, __LINE__); return EXCEPTION; } CancelFileRec.cCancelFlag = '*'; if (PubFileOper(ucFd, REC_WRITE, nCancelRecPos, 0, (char *) &CancelFileRec, &nTmpLen) != NORMAL) { EA_ucPFClose(ucFd); return EXCEPTION; } EA_ucPFClose(ucFd); PubSaveDetail(&CancelPos); PubSetPoscfgcAutoVoidFlag(0); PubClearAutoVoidBuf(); // 先判断有没有脱机流水要上送,如果没有,则立刻挂断 if(PubUploadOffline(CHECKUPLOAD)!= EM_SUCCESS) PubDialOff(&CommInfo); PubSetPoscfgcPrintEndFlag(1); PubPrint(0, iPrinterType); //chenjs20060911 PubIncCheckNum(); PubuiInkey(1); //add by baijz 20110623 先上送当前联机交易,再进行离线上送 PubUploadOffline(RUNUPLOAD); PubDialOff(&CommInfo); return NORMAL; }
int PubMBPurchase() { uchar szPwdBuf[30], szAmtBuf[15], szRetCode[3], szTmpBuf[40], szTrackBuf[110]; uchar ucPasswdLen; uchar ucFd; char szGetBuffer[20]; char szBatch[7]; int nSendLen, nTmpLen; struct FileRecStru PurPos; int nTryTime; char cTimes; int i, iLen; uint uiKey; struct TrackInfo TrackStru; /* * 数据初始化 */ BUFCLR(szPwdBuf); BUFCLR(szRetCode); BUFCLR(szAmtBuf); BUFCLR(gbszSendStr); BUFCLR(gbszReadStr); memset((char *) &PurPos, 0, sizeof(struct FileRecStru)); //dudj20061215 modify after mobile test PurPos.cTransType = MB_PURCHASE; PubSetBankcMacChk(MAC_ECB); /* * 数据采集(打基本包,读卡,输金额) */ PubClearAll(); PubDisplay(2, "请输入金额:"); PubDisplay(4, "输错请按[清除]键"); BUFCLR(szAmtBuf); ASSURE_NORMAL(PubReadAmt(3, szAmtBuf, 3)); /* * 预拨号 */ ASSURE_NORMAL(PubPreDial(&CommInfo)); PubClearAll(); PubDisplay(3, "正在与读卡器连接"); ASSURE_NORMAL(PubHandshakeToReader(1)); PubClearAll(); while(1) { PubDisplay(2,""); PubDisplay(3, "请把卡放到感应区"); PubDisplay(4,""); if (EA_ucKBHit()==EM_key_HIT) { uiKey=PubuiInkey(1); if (uiKey==EM_key_CANCEL) ASSURE_NORMAL(EXCEPTION); } if (FV.EmvStru.gbcExeReader != YES) { if (PubMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } else { if (EA_ucMIFActivate(0,&mbuiRespLen,mbpvResp)==EM_SUCCESS) break; } } ASSURE_NORMAL(PubReadCardInfo(&TrackStru)); ASSERT_NORMAL(PubPacketFix(&PurPos)); memset(szTmpBuf, 0, sizeof(szTmpBuf)); PubHexToAsc(szTmpBuf, EG_BankCardInfo.acCardNo, 20, 0); for (i=0; i<20; i++) { if (szTmpBuf[i]<'0' || szTmpBuf[i]>'9') szTmpBuf[i]=0x00; } if (i>=20) { szTmpBuf[19]=0x00; } strcpy(PurPos.szCardNo,szTmpBuf); PubSetBitYL (&iso, PAN, PurPos.szCardNo, strlen (PurPos.szCardNo)); /* * 给PurPos结构赋值并且打包 */ BUFCLR(szGetBuffer); PubGetCurOper(szGetBuffer, 3); sprintf(PurPos.szOperNo, "%s", szGetBuffer); sprintf(PurPos.szAmount, "%s", szAmtBuf); /*chenjs20060911 ASSURE_NORMAL(PubGetBankstateszCheckNum(szCheck, sizeof(szCheck))); sprintf(PurPos.szCheck, "%s", szCheck); */ ASSURE_NORMAL(PubGetBankstateszBatchNum(szBatch, sizeof(szBatch))); sprintf(PurPos.szBatchNum, "%s", szBatch); memset(szTrackBuf, 0, sizeof(szTrackBuf)); PubHexToAsc(szTrackBuf, EG_BankCardInfo.acTrack2, 40, 0); memset(szTmpBuf, 0, sizeof(szTmpBuf)); memcpy(szTmpBuf, szTrackBuf, 2); for (i=0; i<2; i++) { if (szTmpBuf[i]<'0' || szTmpBuf[i]>'9') { //PubDisplay(3, "无2磁道"); PubWriteLog(EXCEPTION, __FILE__, __LINE__); } } iLen=atoi(szTmpBuf); if (iLen<=37) { szTrackBuf[iLen+2]=0x00; ASSURE_NORMAL(PubSetBitYL(&iso, TRACK2, szTrackBuf+2, iLen)); } memset(szTrackBuf, 0, sizeof(szTrackBuf)); PubHexToAsc(szTrackBuf, EG_BankCardInfo.acTrack3, 108, 0); memset(szTmpBuf, 0, sizeof(szTmpBuf)); memcpy(szTmpBuf, szTrackBuf, 4); for (i=0; i<4; i++) { if (szTmpBuf[i]<'0' || szTmpBuf[i]>'9') { //PubDisplay(3, "无3磁道"); PubWriteLog(EXCEPTION, __FILE__, __LINE__); } } iLen=atoi(szTmpBuf); if (iLen<=104) { szTrackBuf[iLen+4]=0x00; ASSURE_NORMAL(PubSetBitYL(&iso, TRACK3, szTrackBuf+4, iLen)); } //有效期 //add by chenjis 20121217 for BCTC 要求上送有效期 /* BUFCLR(szExpDate); PubHexToAsc(szExpDate, EG_BankCardInfo.acExpDate, 4, 0); memset(szTmpBuf, 0, sizeof(szTmpBuf)); for (i=0; i<4; i++) { if (szExpDate[i]<'0' || szExpDate[i]>'9') szExpDate[i]=0x00; } if (i>=4) { szExpDate[4]=0x00; } strcpy(PurPos.szExpDate,szExpDate); ASSURE_NORMAL(PubSetBitYL (&iso, EXPIRY, PurPos.szExpDate, 4)); */ if(strlen(TrackStru.szExpBuf)) { strcpy(PurPos.szExpDate,TrackStru.szExpBuf); ASSURE_NORMAL(PubSetBitYL (&iso, EXPIRY, PurPos.szExpDate, 4)); } //end chenjis ASSURE_NORMAL(PubSetBitYL(&iso, AMOUNT, szAmtBuf, 12)); ASSURE_NORMAL(PubSetBitYL(&iso, 49, "156", 3)); ASSURE_NORMAL(PubSetBitYL(&iso, 25, "00", 2)); BUFCLR (szTmpBuf); sprintf (szTmpBuf, "22%6.6s000601", PurPos.szBatchNum); PubSetBitYL (&iso, 60, szTmpBuf, 14);//modify by baijz 20120109 支持返回余额 cTimes = 1; PubGetPoscfgcPinErrNum(&cTimes); nTryTime = 1; while (1) { ucPasswdLen = sizeof(szPwdBuf); //dudj20060108 modify down after mobile test //del by baijz 20110523 ASSURE_NORMAL(PubReadPin(ENCON, PurPos.szAmount, 12, DISPOFF, PurPos.szCardNo, szPwdBuf, &ucPasswdLen , "")); //add by baijz 20110523 手机芯片密码不带主帐号加密 ASSURE_NORMAL(PubReadPin(ENCON, PurPos.szAmount, 12, DISPOFF, "0000000000000000", szPwdBuf, &ucPasswdLen , "")); //modify by baijz 20120625 密码长度最大到12位 if (ucPasswdLen != 0) { PurPos.szMode[2]='1'; ASSURE_NORMAL(PubSetBitYL(&iso, 26, "12", 2)); //modify by baijz 20120625 密码长度最大到12位 ASSURE_NORMAL(PubSetBitYL(&iso, PIN, szPwdBuf, 8)); BUFCLR(szGetBuffer); PubGetBankcDesType(&cDesType); if(cDesType == DES3) { ASSURE_NORMAL(PubSetBitYL(&iso, 53, "1600000000000000", 16)); } else { ASSURE_NORMAL(PubSetBitYL(&iso, 53, "1000000000000000", 16)); } } else { PurPos.szMode[2] = '2'; } memcpy(PurPos.szMode, "96", 2); ASSURE_NORMAL(PubSetBitYL(&iso, SERVEMODE, PurPos.szMode, 3)); BUFCLR (szField55); nLenField55 = 0; //芯片序列号 AppendTLV (szField55, &nLenField55, "\xDF\x32", 2, EG_CardInfo.acCardSerNo, 10); AppendTLV (szField55, &nLenField55, "\xDF\x33", 2, EG_BankCardInfo.acSessionKey, 8); AppendTLV (szField55, &nLenField55, "\xDF\x34", 2, EG_BankCardInfo.acDateTime, 7); PubSetBitYL (&iso, ICC_INFO, szField55, nLenField55); //55 //add by chenjis 20121227 for BCTC FV.Void.nLenVoidField55 = nLenField55; memset(FV.Void.szVoidField55,0,sizeof(FV.Void.szVoidField55)); memcpy(FV.Void.szVoidField55,szField55,FV.Void.nLenVoidField55); WRITE_nVAR(FV.Void.szVoidField55); WRITE_nVAR(FV.Void.nLenVoidField55); //end /* * 格式转换(ISO->STR),与主机通讯 */ nSendLen = sizeof(gbszSendStr); ASSURE_NORMAL(PubIsoToStr(gbszSendStr, &iso, &nSendLen)); gbnSendLen = nSendLen; ASSERT_NORMAL(PubCommu(&CommInfo, gbszSendStr, gbnSendLen, gbszReadStr, &gbnReadLen, DIALOFF_NO)); /* * 格式转换(STR->ISO), 返回包处理(返回显示,写流水,打印) */ /*检验是否串包 */ ASSURE_NORMAL(PubCheckPack(&PurPos)); //dudj20061215 modify after mobile test // if (memcmp(gbszErrCode, "55", 2) == 0) // { // nTryTime++; // PubSetPoscfgcAutoVoidFlag(0); // if (nTryTime > cTimes) // { // PubDialOff(&CommInfo); // PubDisplay(2, "密码输入错误"); // PubDisplay(3, "超过%d次", cTimes); // PubuiInkey(3); // return EXCEPTION; // } // PubClearAll(); // PubDisplay(2, "55密码错"); // //chenjs20060929 add down 清除26、52、53避免原来输密码后来不输密码 // PubDelOneBit(&iso,26); // PubDelOneBit(&iso,52); // PubDelOneBit(&iso,53); // //chenjs20060929 add up // PubuiInkey(1); ///*** modified begin by gud 20060123 ****/ // BUFCLR(szGetBuffer); // ASSERT_NORMAL(PubGetBankstateszTrace(szGetBuffer, sizeof(szGetBuffer))); // sprintf(PurPos.szTrace, "%6.6s", szGetBuffer); // ASSERT_NORMAL(PubSetBitYL(&iso, TRACE, PurPos.szTrace, 6)); ///*****modified end by gud 20060123***/ // continue; // } break; /*到这时肯定是成功的 */ } // PubDialOff(&CommInfo); ASSERT_NORMAL(PubDispRetMsg(&PurPos)); nTmpLen = sizeof(struct FileRecStru); if(PubFileOpen(YLWATER, &ucFd)!= NORMAL) { FV.Void.gbnVoidReason = WRI_WATER_ERR; WRITE_nVAR(FV.Void.gbnVoidReason); PubWriteLog(EXCEPTION, __FILE__, __LINE__); return EXCEPTION; } if (PubFileOper(ucFd, REC_WRITE, 0, 0, (char *) &PurPos, &nTmpLen) != NORMAL) { FV.Void.gbnVoidReason = WRI_WATER_ERR; WRITE_nVAR(FV.Void.gbnVoidReason); EA_ucPFClose(ucFd); PubWriteLog(EXCEPTION, __FILE__, __LINE__); return EXCEPTION; } EA_ucPFClose(ucFd); PubSaveDetail(&PurPos); PubSetPoscfgcAutoVoidFlag(0); PubClearAutoVoidBuf(); // 先判断有没有脱机流水要上送,如果没有,则立刻挂断 if(PubUploadOffline(CHECKUPLOAD)!= EM_SUCCESS) PubDialOff(&CommInfo); PubSetPoscfgcPrintEndFlag(1); PubPrint(0, iPrinterType); //chenjs20060911 PubIncCheckNum(); PubuiInkey(1); //add by baijz 20110623 先上送当前联机交易,再进行离线上送 PubUploadOffline(RUNUPLOAD); PubDialOff(&CommInfo); return NORMAL; }
// ***************************************************************** // 功能: man_set_busnum // 说明: 手动输入车号 // 入口参数: // 出口参数: Null // 作者: // 返回值: Null // ***************************************************************** void man_set_busnum(void) { INT8U i = 0; INT8U input1[20]; uchar uckey; uint uikey; uchar ret; uchar temp_uc[5]; // if ( strcmp((void *)&DevStat.bus_number[0], "12345") == 0 ) // { // goto set_bus_number; // } EA_vCls(); lcddisp(2, 1, (void *)"输入车号: "); strcpy((void *)input1, ""); for ( ;; ) { i = EA_ucGetInputStr(2, 10, 20, EM_BIG_FONT | EM_MODE_CHAR | EM_ALIGN_LEFT | EM_SHOW_ORIGINALLY , 5, 5, 0, (void *)input1); //刘及华,修改只能输入数字和字母 if ( i == EM_SUCCESS ) break; if ( i == EM_ABOLISH ) return; //do nothing } memcpy((void *)&CardInfo.bus_number[0], (void *)input1, 5); WriteParam(); EA_ucSetInverse(EM_lcd_INVON); lcddisp(3, 1, (void *)" 输入成功 "); EA_ucSetInverse(EM_lcd_INVOFF); SleepMs(1500); RESELECT: memcpy(temp_uc, &CardInfo.bus_number[0], 5); i = BlackName_Find((char *)temp_uc); //白名单判断 if ( i != ok ) //不是白名单 { lcddisperr("该卡不在白名单中"); Beeperr(); return; } EA_vCls(); EA_vDisplay(1, "车 号 :鲁C-%s", CardInfo.bus_number); lcddisp(4, 1, (void *)" 请刷员工卡 "); while(1) { if( CardInit() == ok ) break; uckey = EA_ucKBHit(); if ( uckey == EM_key_HIT ) //按下取消键 { uikey = EA_uiInkey(0); if ( uikey == EM_key_CANCEL ) //按下取消键 { return ; } } } ret = M1CardProcess(); //再检测员工卡 if(ret == ok) { ; } else { goto RESELECT; } return; }
/***************************************************************** 函数原型:main() 功能描述:主函数 参数描述: 返回值: 无 作 者: 刘及华 日 期: 2012-11-24 修改历史: 日期 修改人 修改描述 ------ --------- ------------- *****************************************************************/ int main(int argc, char **argv) { INT8U ret = 0; char mainflag = 1; uchar uckey; uint uikey; (void)EA_ucSetStopFlag( EM_DISABLE_STOP ); //不允许系统进入睡眠状态; reboot: ret = System_Init(); //系统初始化,包括PSAM,参数表,GPRS初始化 if( ret != ok ) { lcddisperr("系统初始化失败!"); goto reboot; } Beep(1000); //(void)EA_ucSetStopFlag( EM_ENABLE_STOP ); //允许系统进入睡眠状态; for ( ;; ) { if( mainflag == 1 ) { DisplayWelcomeMenu(); mainflag = 0; } uckey = EA_ucKBHit(); if(uckey == EM_key_HIT) //有按键 { uikey = EA_uiInkey(0); //读取按键键值 switch ( uikey ) { case EM_key_EXIT: //关机 { mainflag = 1; goto shutdown; break; } case EM_key_F3: { Login(); //登录界面 mainflag = 1; break; } case EM_key_F1: { Parm_Setting(); //参数设置 mainflag = 1; break; } case EM_key_1: { gprs_test(); //无线连接测试 mainflag = 1; break; } case EM_key_F2: { kuaijiefangshi(); //快捷方式 // Gprs_Upload_data(); // GPRS_Close(); mainflag = 1; break; } default: break; } } } shutdown: Power_Down(); }
//当笔闪卡处理 int PubCurSkProcess (char *pcFlg, struct FileRecStru *TmpPos) { uchar ucRet, option; DevHandle hdlClock; char cSetTime; unsigned long ulSetTime = 0; unsigned long ulPassTime = 0; char cRet1; char szTitle[100],szDispCardNo[30]; struct CardConfig card; char CanDisplay; #ifdef _ECASH_ uint mbuiRespLen; char mbpvResp[512]; #endif cSetTime = FV.Other.gbnCurrSKTime; if (EA_ucCreateTimer(&hdlClock) != EM_SUCCESS) { PubWriteLog(EXCEPTION, (char*)__FILE__, __LINE__); return EXCEPTION; } if (EA_ucResetTimer(hdlClock) != EM_SUCCESS) { EA_ucCloseTimer(&hdlClock); PubWriteLog(EXCEPTION, (char*)__FILE__, __LINE__); return EXCEPTION; } // cSetTime = FV.bank.cSKReadCardTime; EInitOpenMifCard (); //非接闪灯20140108:红灯(只有红灯)常亮 #ifndef C_RFLED if(FV.EmvStru.gbcExeReader != YES) //内置非接 { EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_BLUE, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_YELLOW, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_GREEN, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_RED, EM_LED_ON,100,EM_BLINK_STOP); } else //外置非接 { ;//暂无机器测试 } #endif CanDisplay = YES; RFPreProcess(); //非接交易,移到此处。 while (1) { if(CanDisplay) { BUFCLR(szTitle); BUFCLR(szDispCardNo); sprintf(szTitle,"(交易类型:消费%ld.%02ld)",gblTranAmt/100 , gblTranAmt%100); sprintf(szDispCardNo,"卡号%6.6s******%4.4s",TmpPos->szCardNo,TmpPos->szCardNo+(strlen(TmpPos->szCardNo)-4)); EA_vCls(); PubDisplayInv (1, szTitle); PubDisplay(2,szDispCardNo); PubDisplayCen(3,"请重新挥卡"); PubDisplayCen(4, "退出请按取消键"); EA_vBeepMs(1500); CanDisplay = NO; } if (EA_ucGetPassTimer(hdlClock, &ulPassTime) == EM_SUCCESS) { ulSetTime = cSetTime; if (ulPassTime > ulSetTime * 1000) { EA_ucCloseTimer(&hdlClock); return EM_TIMEOUT; } } ucRet = EM_FAILED; // 20110617 2张卡寻卡冲突增加 if (FV.EmvStru.gbcExeReader != YES) EA_ucMIFSetParamConfig( gbMifCardHandle, EM_mifs_PARAM_RXTHRESHOLD_A, FV.bank.nRxThresHold); else EA_ucSetRFParamLib(gbMifCardHandle, 0x20, 1); //EA_ucSetRFParamLib(gbMifCardHandle, 0, FV.bank.nRxThresHold); ucRet = PubucMIFCardActivate(gbMifCardHandle, &mbuiRespLen,mbpvResp); if (ucRet == 55)// 读卡器没有初始化好 { EA_vCls(); EA_ucCloseTimer(&hdlClock); return EM_key_FUNC; } if (ucRet == EM_SUCCESS) { //非接闪灯20140108:蓝灯黄灯常用亮 #ifndef C_RFLED if(FV.EmvStru.gbcExeReader != YES) //内置非接 { EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_YELLOW, EM_LED_ON,100,EM_BLINK_STOP); } else //外置非接 { ;//暂无机器测试 } #endif ucRet = ProcessRFIcc (&card); if (ucRet != 0) { if (FV.EmvStru.gbcExeReader != YES ) { if(ucRet==EM_ERRHANDLE) EInitOpenMifCard (); EA_ucMIFCardDeactivate(gbMifCardHandle); } else { //外置读卡器处理 2009.6.7 } CanDisplay = YES; continue; } gnCardType = MIF_CARD; if (RFICC_Process_AppSel_SK(TmpPos) != 0) { CanDisplay = YES; continue; } ucRet = EA_EMV_ucQFailRedo(); if (ucRet != 0)//返回值1 为未扣款情况下的闪卡,再次挥卡直接按正常流程处理 hejf 20151008 { switch(ucRet) { case 0xE1: EA_vBeepMs(500); /* //非接闪灯20140108:红灯(只有红灯)常亮 #ifndef C_RFLED if(FV.EmvStru.gbcExeReader != YES) //内置非接 { EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_BLUE, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_YELLOW, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_GREEN, EM_LED_OFF,100,EM_BLINK_STOP); EA_ucSetRFLedSenior(gbMifCardHandle, EM_LED_RED, EM_LED_ON,100,EM_BLINK_STOP); } else //外置非接 { ;//暂无机器测试 } #endif */ PubClearAll(); //PubDisplayInv(1,"闪卡异常"); //PubDisplayCen(3,"读数据错误"); //PubDisplayCen(3,"交易拒绝"); PubDisplayCen(2,"卡号不一致"); PubDisplayCen(3,"请使用原卡片"); PubuiInkey(2); //return EXCEPTION; CanDisplay = YES; continue; case 0xE2: EA_vBeepMs(500); PubClearAll(); //PubDisplayInv(1,"闪卡异常"); PubDisplayCen(2,"卡号不一致"); PubDisplayCen(3,"请使用原卡片"); PubuiInkey(2); CanDisplay = YES; continue; case 0xE6: //0xE1: 读数据错误, 重新回到重刷界面 //0xE2: 数据不匹配,重新回到重刷界面 //0xE6: 找不到匹配的闪卡记录 PubClearAll(); PubDisplayInv(1,"闪卡异常"); PubDisplayCen(3,"找不到匹配的闪卡记录"); PubuiInkey(3); CanDisplay = YES; continue; break; case 0xE3: //0xE3: 数据异常,需要删除失败交易记录,进入正常交易 EA_ucCloseTimer(&hdlClock); PubClearAll(); PubDisplayInv(1,"闪卡异常"); PubDisplayCen(3,"闪卡读数据异常"); PubuiInkey(3); return EXCEPTION; case 0xE4: //0xE4: 数据异常,需要保留失败交易记录,提示交易失败 EA_ucCloseTimer(&hdlClock); PubClearAll(); PubDisplayInv(1,"交易失败"); PubDisplayCen(2,"ATC异常,卡片ATC大于当"); PubDisplayCen(3,"前记录ATC."); PubuiInkey(3); return EXCEPTION; case 0xE5: //0xE4: 数据异常,需要保留失败交易记录,提示交易失败 EA_ucCloseTimer(&hdlClock); PubClearAll(); PubDisplayInv(1,"交易失败"); PubDisplayCen(3,"余额异常, 提示交易失败."); PubuiInkey(3); return EXCEPTION; case 1: //交易金额已经回滚,直接GPO开始新交易 PubDelSkFailRec(TmpPos->szCardNo,(char*)TmpPos->atc); //删除失败的闪卡流水 cRet1 = 0; cRet1 = RFICC_Process_AppGpo_SK(TmpPos); if (cRet1 == RFARQC || cRet1 == RFPBOC || cRet1 == RFQPBOC) *pcFlg = cRet1; else return EXCEPTION; break; default: EA_ucCloseTimer(&hdlClock); PubClearAll(); PubDisplayInv(1,"闪卡异常"); PubDisplay(3,"闪卡返回异常%d",ucRet); PubuiInkey(3); return EXCEPTION; } } EA_ucCloseTimer(&hdlClock); return NORMAL; } option = 0; if (EA_ucKBHit() == EM_key_HIT) { //有按键 option = PubuiInkey(1); if (option == CANCEL) { EA_ucCloseTimer(&hdlClock); return CANCEL; //按取消键 } } //sfh120509 读卡延迟100毫秒 EA_vDelayMs(100); } return EXCEPTION; }
/* * 函数功能:IC密钥卡发行 * 入口参数:无 * 出口参数:无 * 返 回 值:NORMAL ―― 成功 * EXCEPTION ―― 失败 */ int PubICCreateKey(void) { unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096]; unsigned int uiRetLen; int i, j; CARDHEADER stCardHead; KEYREC stKeyRec; unsigned char szKeyPwd[9],ucTEK1[17],ucTEK2[17],ucTMK[17],ucTMK1[17],ucTMK2[17],chLRCValue, chCheckvalue[9], kyLRCValue; unsigned char ucRandom[5], ucCardMonKey[17], ucMac[9], ucEncryptData[33]; int nKeyNum; ET_DATETIME tDateTime; char szBuffer[100], cRet; EA_vCls(); if ( PubOpenUserICCardDev () != NORMAL ) return EXCEPTION; PubDisplayInv(1, "IC密钥卡发行"); PubDisplayCen(2, "请插入密钥IC卡"); PubDisplayCen(3, "按<取消>退出"); while(1) { if ( PubUserICCardIn() == NORMAL ) break; if (EA_ucKBHit () == EM_key_HIT) { if (PubuiInkey (1) == CANCEL) { return EXCEPTION; } } } if ( PubUserICCardPowerUp() != NORMAL ) return EXCEPTION; BUFCLR(ucCardMonKey); //卡片主控密钥默认是16个0x00 PubClearAll(); PubDisplay(2,"请输入密钥卡密码"); PubKeyOff(); BUFCLR(szBuffer); cRet = PubGetAStr(3,BIGFONT,szBuffer,8); PubKeyOn(); if (cRet != NORMAL) { return EXCEPTION; } strcpy(szKeyPwd, szBuffer); //写卡时间做为一级转加密密钥(POS时间后补0xFF0xFF) BUFCLR(ucTEK1); EA_ucGetDateTime (&tDateTime); sprintf (szBuffer, "%4d%02d%02d%02d%02d%02d", tDateTime.usYear, tDateTime.ucMonth, tDateTime.ucDay,tDateTime.ucHour,tDateTime.ucMinute,tDateTime.ucSecond); memset(ucTEK1, 0xff, 16); memcpy (ucTEK1, szBuffer, 14); //手工输入的密码做为二级转加密密钥 BUFCLR(ucTEK2); memset(ucTEK2, 0xff, 8); memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd)); //获取随机数 if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf, 0x04, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucRandom,ucRecBuf,4); //外部内证 BUFCLR(szBuf); memcpy(szBuf, ucRandom, 4); DES(ucCardMonKey, szBuf, ucSedBuf); if ( ProICCComm1 ("EXT AUTH",CPU_CARD, 0x00, 0x82, 0x00, 0x00, 0x08, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //擦除目录 if ( ProICCComm1 ("CLEAR MF",CPU_CARD, 0x80, 0xee, 0x00, 0x00, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //建立安全文件 memcpy(ucSedBuf, "\x1E\x00\x00\x01\x00\xF0\xF0\x00\xFF\x00\xFF", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //写入MF下密钥 memcpy(ucSedBuf, "\x39\xF0\xF0\x33\x02", 5); memcpy(ucSedBuf+5, ucCardMonKey, 16); if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x80, 0xd4, 0x01, 0x00, 0x15, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //创建卡信息记录文件 memcpy(ucSedBuf, "\x00\x00\x03\x00\x20\xF0\xF0\x03\x00\xFF\x00", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //创建密钥信息记录文件 memcpy(ucSedBuf, "\x00\x00\x02\x08\x00\xF0\xF0\x02\x00\xFF\x00", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //计算密钥的密文 BUFCLR(ucEncryptData); memcpy(ucEncryptData, "\x13\x48\x03\x00", 4); memcpy(ucEncryptData+4, ucTEK1, 16); memcpy(ucEncryptData+20, "\x80\x00\x00\x00", 4); DES(ucCardMonKey, ucEncryptData, ucEncryptData); _DES(ucCardMonKey+8, ucEncryptData, ucEncryptData); DES(ucCardMonKey, ucEncryptData, ucEncryptData); DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8); _DES(ucCardMonKey+8, ucEncryptData+8, ucEncryptData+8); DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8); DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16); _DES(ucCardMonKey+8, ucEncryptData+16, ucEncryptData+16); DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16); //获取随机数 BUFCLR(ucRecBuf); if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf, 0x04, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucRandom,ucRecBuf,4); //计算MAC BUFCLR(ucMac); memcpy(ucMac, ucRandom, 4); BUFCLR(ucSedBuf); memcpy(ucSedBuf, "\x84\xd4\x00\x00\x1c", 5); memcpy(ucSedBuf+5, ucEncryptData, 24); memcpy(ucSedBuf+29, "\x80\x00\x00", 3); for (i = 0; i < 4; i++) { for (j = 0; j < 8; j++) { ucMac[j] ^= ucSedBuf[i * 8 + j]; } DES(ucCardMonKey, ucMac, ucMac); } _DES(ucCardMonKey+8, ucMac, ucMac); DES(ucCardMonKey, ucMac, ucMac); //写密钥 memcpy(ucSedBuf, ucEncryptData, 24); memcpy(ucSedBuf+24, ucMac, 4); if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x84, 0xd4, 0x00, 0x00, 0x1c, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //写卡信息文件 BUFCLR(szBuffer); DES(ucTEK2, szBuffer, chCheckvalue); memset(&stCardHead, 0, sizeof(CARDHEADER)); stCardHead.KeyNum[0] = 0x00; //密钥数量 根据实际情况填写 最大66条 在此做为测试只写一条 stCardHead.KeyNum[1] = 0x01; memcpy(stCardHead.chExpireDate, "\x20\x99\x12\x31", 4);//有效期 memset(stCardHead.chReserved, 0xff, 16); memcpy(stCardHead.chCheckvalue, chCheckvalue, 4); memcpy(szBuf, &stCardHead, 27); chLRCValue = 0; for(i=0;i<26;i++) chLRCValue ^= szBuf[i]; stCardHead.chLRCValue = chLRCValue; if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; BUFCLR(ucSedBuf); memcpy(ucSedBuf, &stCardHead, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; for(i=0; i<nKeyNum; i++) { BUFCLR(ucTMK); //终端主密钥明文 根据实际情况填写 在此做为测试固定8个0x31 8个0x32 memset(ucTMK, 0x31, 8); memset(ucTMK+8, 0x32, 8); //初始化加密指令 if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //加密 memcpy(ucSedBuf, ucTMK, 16); if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x00, 0x00, 0x10, ucSedBuf, 0x10, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucTMK1, ucRecBuf, 16); //使用手工输入的密码加密,生成二级转加密密钥 BUFCLR(ucTMK2); DES(ucTEK2, ucTMK1, ucTMK2); DES(ucTEK2, ucTMK1+8, ucTMK2+8); //写密钥信息文件 nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; memset(&stKeyRec, 0, sizeof(stKeyRec)); stKeyRec.kyIndex = 0x00; //密钥索引 默认值为0x00 实际并没有使用 stKeyRec.kyNum = 0x01; //可用次数 0-9 做为预留值 暂时没有使用 PubAscToHex(stKeyRec.kyMechID, "123456789111115F", 16, 0); //商户号 根据实际情况填写 记住后补F 在此做为测试 PubAscToHex(stKeyRec.kyTermID, "11115010", 8, 0); //终端号 根据实际情况填写 在此做为测试 memcpy(stKeyRec.kyEncryptMKey, ucTMK2, 16); //密钥密文 BUFCLR(szBuf); memcpy(szBuf, &stKeyRec, 31); kyLRCValue = 0; for(i=0;i<29;i++) kyLRCValue ^= szBuf[i]; stKeyRec.kyLRCValue = kyLRCValue; //校验位 memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; } EA_ucCloseDevice (&gbhdlUserCard); EA_vCls(); PubDisplay(2, "发卡成功!"); PubDisplay(3, "密钥总数:%d", nKeyNum); PubuiInkey(20); return NORMAL; }
/* * 函数功能:IC卡下载密钥 * 入口参数:无 * 出口参数:无 * 返 回 值:NORMAL ―― 成功 * EXCEPTION ―― 失败 */ int PubICDownKey(void) { unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096]; unsigned int uiRetLen,uiRet; unsigned char Cp1,Cp2,Cle,CFlagGetKey; int len; char szGetBuffer[30],szGetBuffer1[30],szGetBuffer2[30],szGetBuffer3[30]; int i, nBufSize; CARDHEADER stCardHead; KEYREC stKeyRec; unsigned char szKeyPwd[9],ucTEK2[17],ucTMK[17],ucTMK1[17],chLRCValue, chCheckvalue[9], kyLRCValue; int nKeyNum, nKeyLen; ET_DATETIME tDateTime; char szBuffer[100], cRet; int nTmpFlag, nIndex = 5; DevHandle phPinpad; EA_vCls(); PubDisplayInv(1, "IC卡导入密钥"); PubDisplay(2, "主密钥索引号(0-31)"); //PubDisplay(3, "[%d]",nIndex); nTmpFlag = 1; do { BUFCLR(szBuffer); cRet = PubGetNStr(4, 0, szBuffer, 2); if (cRet == CANCELED||cRet == APPTIMEOUT) { nTmpFlag = 0; break; } if (strlen(szBuffer) > 2) continue; nIndex = atoi(szBuffer); } while (nIndex > 31); if (nTmpFlag == 0) return EXCEPTION; PubGetBankcDesType(&cDesType); CFlagGetKey = NO; EA_vCls(); if ( PubOpenUserICCardDev () != NORMAL ) return EXCEPTION; //EA_vCls(); PubDisplayInv(1, "IC卡导入密钥"); PubDisplayCen(2, "请插入密钥IC卡"); PubDisplayCen(3, "按<取消>退出"); while(1) { if ( PubUserICCardIn() == NORMAL ) break; if (EA_ucKBHit () == EM_key_HIT) { if (PubuiInkey (1) == CANCEL) { return EXCEPTION; } } } if ( PubUserICCardPowerUp() != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, 0x83, 0x00, 0x00, ucSedBuf, 0x1b, ucRecBuf, &uiRetLen)!= NORMAL ) return EXCEPTION; memcpy(&stCardHead, ucRecBuf, 27); chLRCValue = 0; for(i=0;i<26;i++) chLRCValue ^= ucRecBuf[i]; if(chLRCValue != stCardHead.chLRCValue) { PubClearAll(); PubDisplayCen(2, "IC卡错误"); PubuiInkey(20); return EXCEPTION; } EA_ucGetDateTime (&tDateTime); sprintf (szBuffer, "%4d%02d%02d", tDateTime.usYear, tDateTime.ucMonth, tDateTime.ucDay); PubAscToHex (szGetBuffer, szBuffer, 8, 0); if(memcmp(stCardHead.chExpireDate, szGetBuffer, 4) < 0) { PubClearAll(); PubDisplayCen(2, "此卡已过期"); PubuiInkey(20); return EXCEPTION; } if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; nBufSize = sizeof(szGetBuffer); BUFCLR(szGetBuffer); ASSERT_NORMAL(PubGetBankszCust(szGetBuffer, nBufSize)); nBufSize = sizeof(szGetBuffer); BUFCLR(szGetBuffer1); ASSERT_NORMAL(PubGetBankszTerminal(szGetBuffer1, nBufSize)); strcat(szGetBuffer, "F"); //商户号是右补F PubAscToHex(szGetBuffer2, szGetBuffer, 16, 0); PubAscToHex(szGetBuffer3, szGetBuffer1, 8, 0); nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; BUFCLR(szBuf); i=0; while(1) { len = i * 31; Cp1 = (uchar)(len/256); Cp2 = (uchar)(len%256); Cle = 31; if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, Cp1, Cp2, 0x00, ucSedBuf, Cle, ucRecBuf, &uiRetLen)!= NORMAL ) return EXCEPTION; if (CARD_SW1 == 0x6B ) break; memcpy(&stKeyRec, ucRecBuf, 31); if(!memcmp(stKeyRec.kyMechID,szGetBuffer2,8) && !memcmp(stKeyRec.kyTermID,szGetBuffer3,4)) { CFlagGetKey = YES; break; } i++; if(i > nKeyNum) break; } if ( CFlagGetKey == NO ) { PubClearAll(); PubDisplayCen(2, "主密钥未找到"); PubuiInkey (20); return EXCEPTION; } // 银商规范修改,这个值无效,不用判断了。 // if(stKeyRec.kyNum < 1) // { // PubClearAll(); // PubDisplayCen(2, "该密钥已无法使用"); // PubuiInkey(20); // return EXCEPTION; // } BUFCLR(szBuf); memcpy(szBuf, &stKeyRec, 31); kyLRCValue = 0; for(i=0;i<29;i++) kyLRCValue ^= szBuf[i]; if(kyLRCValue != stKeyRec.kyLRCValue) { /*银商总公司沈进要求不写卡 //可用次数减1 stKeyRec.kyNum--; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ PubClearAll(); PubDisplayCen(2, "主密钥有误"); PubuiInkey(20); return EXCEPTION; } PubClearAll(); PubDisplay(2,"请输入密钥卡密码"); PubKeyOff(); BUFCLR(szBuffer); uiRet = PubGetAStr(3,BIGFONT,szBuffer,8); PubKeyOn(); if (uiRet != NORMAL) { return EXCEPTION; } strcpy(szKeyPwd, szBuffer); BUFCLR(ucTEK2); memset(ucTEK2, 0xff, 8); memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd)); BUFCLR(szBuffer); DES(ucTEK2, szBuffer, chCheckvalue); if(memcmp(stCardHead.chCheckvalue, chCheckvalue, 4)) { /*银商总公司沈进要求不写卡 //可用次数减1 stKeyRec.kyNum--; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ PubClearAll(); PubDisplayCen(2, "密码错误"); PubuiInkey(20); return EXCEPTION; } //使用手工输入的密码对IC卡中存在的二级转加密主密钥TMK2进行Des解密,获得TMK1 BUFCLR(ucTMK1); _DES(ucTEK2, stKeyRec.kyEncryptMKey, ucTMK1); _DES(ucTEK2, stKeyRec.kyEncryptMKey+8, ucTMK1+8); //初始化加密指令 if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //解密 if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x80, 0x00, 0x10, ucTMK1, 0x10, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucTMK, ucRecBuf, 16); if (PubOpenDevice("PINPAD", EM_io_EPP, &phPinpad) != EM_SUCCESS) { PubDisplay(2, "密码键盘打开失败!"); EA_vBeepMs(50); return EXCEPTION;; } nKeyLen = 16; while (PubLoadKey(phPinpad, EM_pin_MASTERKEY, nIndex, nKeyLen, ucTMK) != NORMAL) { PubDisplay(2, "请接好密码键盘!"); EA_vBeepMs(50); PubuiInkey(1); } EA_ucCloseDevice(&phPinpad); PubSetBankcDesType(DES3); //设定密钥类型为3DES /*银商总公司沈进要求不写卡 //可用次数置0 stKeyRec.kyNum=0; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ EA_ucCloseDevice (&gbhdlUserCard); EA_vCls(); PubDisplay(2, "主密钥导入成功!"); PubuiInkey(20); return NORMAL; }