?? mifare.c
字號:
#include <api.h>
#include <console.h>
#include <mifare530.h>
#include "CPOS.h"
const unsigned char gcDefaultKeyA[6] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5};
const unsigned char gcDefaultKeyB[6] = {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5};
const unsigned char gcDefaultKeyAf[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const unsigned char gcDefaultKeyBf[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
extern unsigned char *BCD2ASC(unsigned char *strBCD, unsigned char cLenBCD);
extern unsigned char *ASC2BCD(unsigned char *strASC, unsigned char cLenASC);
extern void OverTurnString(void *strSource, void *strTarge, unsigned char cLength);
//認證卡片
unsigned char AuthenCard(unsigned long *lSerialNo, unsigned char Sector, unsigned char ModeSel)
{
unsigned char keysel1, keysel2;
// unsigned char cKey[6];
unsigned char *pKey;
int i;
if (Sector>15) return 0;
if(ModeSel == MIF_READ)
{
keysel1 = PICC_AUTHENT1A;
pKey = gstWorkCardKey.cKeyA[Sector];
}
else if(ModeSel == MIF_WRITE)
{
// if ((gstWorkCardInfomation.cKeyVerision == 0xa0)||(gstWorkCardInfomation.cKeyVerision == 0xff))
// {
// keysel1 = PICC_AUTHENT1A;
// pKey = gstWorkCardKey.cKeyA[Sector];
// }
// else
// {
keysel1 = PICC_AUTHENT1B;
pKey = gstWorkCardKey.cKeyB[Sector];
// }
}
else
return 0;
for(i=0;i<3;i++)
{
// clr_scr();
// move_cursor(i,0);
// puts("CardTypeARequest");
if (CardTypeARequest(PICC_REQIDL, gcATQ)==MI_OK)
{
// move_cursor(i,1);
// puts("CardTypeASelect");
if (CardTypeASelectLevel1((unsigned char*)lSerialNo, gcATS)==MI_OK)
{
// move_cursor(i,2);
// puts("CardMFCAuthKey");
if (CardMFCAuthKey(keysel1, (unsigned char*)lSerialNo, pKey, Sector*4+3)==MI_OK)
{
break;
}
}
}
}
if(i==3)
{
// move_cursor(i,3);
// puts("ERR");
return 0;
}
// move_cursor(i,3);
// puts("OK");
return 1;
}
//M1卡復制數據塊
unsigned char CopyBlock(unsigned char cSector, unsigned char cSource, unsigned char cTarget, unsigned char cMode)
{
unsigned char i, k;
for(k=0;k<3;k++)
{
if (CardMFCRead16Bytes(cSource, gcMifBuffer)==MI_OK)
{
if (cMode==1)
{
for(i=0;i<16;i++)
gcMifBuffer[i] = 0xff - gcMifBuffer[i];
}
if (CardMFCWrite16Bytes(cTarget, gcMifBuffer)==MI_OK)
break;
}
}
if(k==3) return 0;
return 1;
}
//M1卡比較數據塊
unsigned char CompareBlock(unsigned char cSector, unsigned char cBlock1, unsigned char cBlock2, unsigned char cMode)
{
unsigned char cBuffer[16];
unsigned char i;
if (CardMFCRead16Bytes(cBlock2, gcMifBuffer)!=MI_OK) return 0;
memcpy(cBuffer, gcMifBuffer, 16);
if (CardMFCRead16Bytes(cBlock1, gcMifBuffer)!=MI_OK) return 0;
if (cMode==1)
{
for(i=0;i<16;i++)
gcMifBuffer[i] = 0xff - gcMifBuffer[i];
}
if (memcmp(cBuffer, gcMifBuffer, 16)!=0)
return 1;
else
return 2;
}
//判斷錢包結構的合法性
unsigned char IsValidMoney(unsigned char cSector, unsigned char cBlock)
{
unsigned char i;
CardMFCRead16Bytes(cBlock, gcMifBuffer);
for(i=0;i<4;i++)
{
if(gcMifBuffer[i] != 0xff - gcMifBuffer[i+4]) return 0;
if(gcMifBuffer[i] != gcMifBuffer[i+8]) return 0;
}
if(gcMifBuffer[12] != gcMifBuffer[14]) return 0;
if(gcMifBuffer[13] != gcMifBuffer[15]) return 0;
if(gcMifBuffer[12] != 0xff - gcMifBuffer[13]) return 0;
return 1;
}
/*
//判斷是否在黑名單中
unsigned char IsInBlack(unsigned long lCardNo)
{
unsigned int i, start, end;
unsigned char buf[4], cFlag, j;
start = 0;
end = giBlackListNum - 1;
if(lCardNo < gcBlackList[start])
return 0;
else if(lCardNo == gcBlackList[start])
return 1;
if(lCardNo > gcBlackList[end])
return 0;
else if(lCardNo == gcBlackList[end])
return 1;
while(start!=end-1)
{
i = (start + end) / 2;
if(lCardNo < gcBlackList[i])
{
cFlag = 1;
break;
}
else if(lCardNo > gcBlackList[i])
{
cFlag = 2;
break;
}
else
return 1;
if(cFlag == 1)
{
end = i;
}
else
{
start = i;
}
}
return 0;
}
*/
//生成交易記錄
unsigned char BuildRecord()
{
unsigned char i;
unsigned char tmpbuf[100];
memset(&gstWorkChargeRecord, 0, sizeof(gstWorkChargeRecord));
memcpy(gstWorkChargeRecord.cSerialNo, &glSerialNo, 4);
memcpy(gstWorkChargeRecord.cCityCode, gstWorkCardInfomation.cCityCode, 2);
memcpy(gstWorkChargeRecord.cTradeCode, gstWorkCardInfomation.cTradeCode, 2);
memcpy(gstWorkChargeRecord.cCardNo, &gstWorkCardInfomation.lCardNo, 4);
memcpy(gstWorkChargeRecord.cCardAuthenCode, gstWorkCardInfomation.cAuthenCode, 4);
gstWorkChargeRecord.cCardType = gstWorkCardInfomation.cCardType;
gstWorkChargeRecord.cChargeType = gcChargeType;
memcpy((unsigned char*)&gstWorkChargeRecord.cChargeDateTime, gcNowTime, 7);
switch(gcChargeType)
{
case CHARGETYPE_LOGON:
//管理卡設置流水號
OverTurnString(gstWorkChargeRecord.cTotleChargeTimes, &gstWorkCardInfomation.iMoneyTotleTimes, 2);
//操作員編號
memcpy(gstWorkChargeRecord.cMoneyOrTimes, &gstWorkCardInfomation.lMoney, 4);
//機具編號
memcpy(gstWorkChargeRecord.cChargeMoneyOrTimes, &glChargeMoney, 3);
gstWorkChargeRecord.cDate[0] = 0xff;
gstWorkChargeRecord.cDate[1] = 0xff;
gstWorkChargeRecord.cRecordType = 2;
break;
case CHARGETYPE_SALE:
gstWorkChargeRecord.cCardType = gcNewCardType;
case CHARGETYPE_INCMONEY:
case CHARGETYPE_DECMONEY:
case CHARGETYPE_PURMONEY:
// memcpy(gstWorkChargeRecord.cTotleChargeTimes, &gstWorkCardInfomation.iMoneyTotleTimes, 2);
OverTurnString(gstWorkChargeRecord.cTotleChargeTimes, &gstWorkCardInfomation.iMoneyTotleTimes, 2);
// memcpy(gstWorkChargeRecord.cMoneyOrTimes, &gstWorkCardInfomation.lMoney, 4);
OverTurnString(gstWorkChargeRecord.cMoneyOrTimes, &gstWorkCardInfomation.lMoney, 4);
// memcpy(gstWorkChargeRecord.cChargeMoneyOrTimes, &glChargeMoney, 3);
OverTurnString(gstWorkChargeRecord.cChargeMoneyOrTimes, (unsigned char*)&glChargeMoney+1, 3);
gstWorkChargeRecord.cDate[0] = 0xff;
gstWorkChargeRecord.cDate[1] = 0xff;
gstWorkChargeRecord.cRecordType = 2;
break;
case CHARGETYPE_INCTIMES:
case CHARGETYPE_DECTIMES:
case CHARGETYPE_PURTIMES:
// memcpy(gstWorkChargeRecord.cTotleChargeTimes, &gstWorkCardInfomation.iTimesTotleTimes, 2);
OverTurnString(gstWorkChargeRecord.cTotleChargeTimes, &gstWorkCardInfomation.iTimesTotleTimes, 2);
// memcpy(gstWorkChargeRecord.cMoneyOrTimes, &gstWorkCardInfomation.lTimes, 4);
OverTurnString(gstWorkChargeRecord.cMoneyOrTimes, &gstWorkCardInfomation.lTimes, 4);
// memcpy(gstWorkChargeRecord.cChargeMoneyOrTimes, &glChargeMoney, 3);
OverTurnString(gstWorkChargeRecord.cChargeMoneyOrTimes, (unsigned char*)&glChargeMoney+1, 3);
gstWorkChargeRecord.cDate[0] = ((gcChargeTimesDate[1]/10)<<4)+gcChargeTimesDate[1]%10;
gstWorkChargeRecord.cDate[1] = ((gcChargeTimesDate[1]/10)<<4)+gcChargeTimesDate[1]%10;
gstWorkChargeRecord.cRecordType = 2;
break;
}
//for debug
/* memcpy(tmpbuf, (unsigned char*)&gstWorkChargeRecord, 36);
tmpbuf[36] = 0x80;
tmpbuf[37] = 0x00;
tmpbuf[38] = 0x00;
tmpbuf[39] = 0x00;
i = InitForDescrypt(0, tmpbuf, 0x08, gstKeyMarkSet[gstWorkCardInfomation.cCardKeyIndex].KeyTradeMAC);
if (i != 1) return ERR_PSAM_SPKEY;
delay_n_ms(2);
i = MAC(40, tmpbuf, tmpbuf);
if (i != 4) return ERR_PSAM_SPKEY;
delay_n_ms(100);
if(!GetResponse(tmpbuf, i)) return ERR_PSAM_FUNC;
memcpy(gstWorkChargeRecord.cTAC, tmpbuf, 4);
*/
memset(gstWorkChargeRecord.cTAC, 0, 4);
//for debug
i=appendTradeRecord(&gstWorkChargeRecord);
// Dispbcd(0,0,&i,1);
if(i!=ST_OK)
{
return ERR_CHG_WRITEEEPROM;
}
return ST_OK;
}
//寫交易進程標志
unsigned char WriteChargeStep(unsigned char cFlag)
{
unsigned char i;
gcSector = gstWorkCardInfomation.stCardStruct.cPublicSector;
gcBlock = gcSector * 4;
if (cFlag > 2) return 0;
if(!AuthenCard(&glSerialNo,gcSector,MIF_WRITE)) return 0;
for(i=0;i<3;i++)
{
if (CardMFCRead16Bytes(gcBlock, gcMifBuffer)==MI_OK)
break;
}
if(i==3)return 0;
gcMifBuffer[3] = cFlag;
gstWorkCardInfomation.cChargeStep = cFlag;
gcMifBuffer[15] = 0;
for(i=0;i<15;i++)
gcMifBuffer[15] ^= gcMifBuffer[i];
for(i=0;i<3;i++)
{
if (CardMFCWrite16Bytes(gcBlock, gcMifBuffer)==MI_OK)
break;
}
if(i==3)return 0;
return 1;
}
//更改錢包
unsigned char ModifyMoney(unsigned char cMode,unsigned char blck, unsigned long lMoney)
{
unsigned char i;
switch(blck)
{
case 9:
case 10:
for(i=0;i<3;i++)
{
gcSector = gstWorkCardInfomation.stCardStruct.cMoneySector;
if(AuthenCard(&glSerialNo,gcSector,MIF_WRITE))
if(CardMFCValueWithTransfer(cMode, blck, blck, lMoney)==MI_OK)
break;
}
if (i==3) return 0;
break;
case 33:
case 34:
for(i=0;i<3;i++)
{
gcSector = gstWorkCardInfomation.stCardStruct.cEveTimesSector;
if(AuthenCard(&glSerialNo,gcSector,MIF_WRITE))
if(CardMFCValueWithTransfer(cMode, blck, blck, lMoney)==MI_OK)
break;
}
if (i==3) return 0;
break;
default:
return 0;
}
return 1;
}
//更改指針
unsigned char ModifyPoint()
{
unsigned char i;
gcSector = gstWorkCardInfomation.cHisCharge / 3;
gcBlock = gstWorkCardInfomation.cHisCharge % 3;
gcSector = gstWorkCardInfomation.stCardStruct.cHistorySector[gcSector];
gcBlock += gcSector * 4;
memcpy(gcMifBuffer, gcNowTime+3, 4);
// memcpy(gcMifBuffer+4, &gstWorkCardInfomation.lMoney, 4);
OverTurnString(gcMifBuffer+4, &gstWorkCardInfomation.lMoney, 4);
// memcpy(gcMifBuffer+8, &glChargeMoney, 3);
OverTurnString(gcMifBuffer+8, (unsigned char*)&glChargeMoney+1, 3);
gcMifBuffer[11] = gcChargeType;
memcpy(gcMifBuffer+12, gcPSAMNo, 4);
if(!AuthenCard(&glSerialNo, gcSector, MIF_WRITE)) return 0;
for(i=0;i<3;i++)
if(CardMFCWrite16Bytes(gcBlock, gcMifBuffer)==MI_OK) break;
if(i==3) return 0;
if (gstWorkCardInfomation.cHisCharge < 8)
gstWorkCardInfomation.cHisCharge ++;
else
gstWorkCardInfomation.cHisCharge = 0;
switch(gcChargeType)
{
case CHARGETYPE_DECMONEY:
case CHARGETYPE_INCMONEY:
case CHARGETYPE_PURMONEY:
if (gstWorkCardInfomation.iMoneyTotleTimes < 0xffff)
gstWorkCardInfomation.iMoneyTotleTimes ++;
else
gstWorkCardInfomation.iMoneyTotleTimes = 0;
break;
case CHARGETYPE_DECTIMES:
case CHARGETYPE_INCTIMES:
case CHARGETYPE_PURTIMES:
if (gstWorkCardInfomation.iTimesTotleTimes < 0xffff)
gstWorkCardInfomation.iTimesTotleTimes ++;
else
gstWorkCardInfomation.iTimesTotleTimes = 0;
break;
}
gcSector = gstWorkCardInfomation.stCardStruct.cPublicSector;
gcBlock = gcSector * 4;
if(!AuthenCard(&glSerialNo, gcSector, MIF_WRITE)) return 0;
for(i=0;i<3;i++)
if(CardMFCRead16Bytes(gcBlock, gcMifBuffer)==MI_OK) break;
if(i==3) return 0;
gcMifBuffer[0] = gstWorkCardInfomation.cHisCharge+1;
switch(gcChargeType)
{
case CHARGETYPE_DECMONEY:
case CHARGETYPE_INCMONEY:
case CHARGETYPE_PURMONEY:
// memcpy(gcMifBuffer+1, &gstWorkCardInfomation.iMoneyTotleTimes, 2);
OverTurnString(gcMifBuffer+1, &gstWorkCardInfomation.iMoneyTotleTimes, 2);
break;
case CHARGETYPE_DECTIMES:
case CHARGETYPE_INCTIMES:
case CHARGETYPE_PURTIMES:
// memcpy(gcMifBuffer+4, &gstWorkCardInfomation.iTimesTotleTimes, 2);
OverTurnString(gcMifBuffer+4, &gstWorkCardInfomation.iTimesTotleTimes, 2);
break;
}
gcMifBuffer[15] = 0;
for(i=0;i<15;i++)
gcMifBuffer[15] ^= gcMifBuffer[i];
for(i=0;i<3;i++)
if(CardMFCWrite16Bytes(gcBlock, gcMifBuffer)==MI_OK) break;
if(i==3) return 0;
return 1;
}
//分析卡片目錄結構
void AnalyseCardStruct(unsigned char *CardDir)
{
unsigned char i, j;
j = 0;
memset((unsigned char*)&gstWorkCardInfomation.stCardStruct, 0xff, 9);
for(i=0;i<16;i++)
{
switch(CardDir[i])
{
case 0x00:
gstWorkCardInfomation.stCardStruct.cDirSector = i;
break;
case 0x01:
gstWorkCardInfomation.stCardStruct.cPublishSector = i;
break;
case 0x10:
gstWorkCardInfomation.stCardStruct.cMoneySector = i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -