📄 card.c
字号:
#include "my_head.H"
#include "RfModuleFunc.H"
#include "DataFlash.H"
//#define _DEBUG
#ifdef _DEBUG
#include "Debug.h"
#endif
#define YES 1
#define NO 0
#define COMPANY_INFO_SECTOR 2 //公司信息
#define CARDHOLDER_INFO_SECTOR 3 //持卡人信息
#define PUBLIC_MONEY_SECTOR 4 //公共钱包
#define BUSINESS_INFO_SECTOR 5 //交易信息
#define TIME_COUNT_SECTOR 6 //计时信息
#define ORDER_DINNER_SECTOR 7 //订餐信息
#define BUSINESS_LIMIT_INFO_SECTOR 8 //交易特别限制信息
#define SYSTEMCARD_SECTOR 0
#define SEEDCARD_SECTOR 1
#define MAKER_CODE_SECT 0
#define SYSTEM_SECT_1 1
#define SYSTEM_SECT_2 2
#define YSN_SYSPWD_SECT 3
#define SEED_CARD_SECT 4 //UNIT_INFO_SECT
#define OPUSER_CARD_SECT 5 //管理员或操作员
//UNIT(SEED) INFO
#define CARD_LEVEL_DDR 0
#define UNIT_CODE_ADDR 1 //1-3
#define UNIT_PWD_ADDR 4 //4-6
#define PUBLIC_SECTOR_ADDR 7
#define FUC_TYPE_ADDR 8 //子功能类型
#define FUC_SECTOR_ADDR 9 //子功能占用扇区
#define SEED_DATE_ADDR 10 //10-12
#define SEEDUSECOUNTS_ADDR 13 //13-14
//===============================================
//卡级别定义
#define CONUSER_CARD 3 //- 普通用户卡,
#define MANAGE_CARD 6 //- 维护管理卡,
#define SEED_CARD 7 //- 系统子卡,
#define SYSTEM_CARD 8 //- 系统母卡,
#define EMPTYUSER_CARD 0x3f //- 单位白卡
unsigned char code Nkey_a[6] = {'Y', 's','n', 'O', 'y', 's'};
unsigned char code Nkey_b[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
sttCardholderInfo xdata stCardholderInfo; //持卡人信息
sttBusinessInfo xdata stBusinessInfo; //交易信息
unsigned char xdata CardSerialNo[4]; //作为最后一次操作的卡系列号存贮用(必须全局)
unsigned char xdata CardOperateStep; //卡操作步骤标志(必须全局)
unsigned char xdata gcDateTime[7]; //全局时钟
extern void ReadClock(unsigned char ClockData[]);
extern sttOtherTableInfo xdata stOtherTableInfo;
extern Equip_Addr pdata equip_addr;
//====================================================
void Count_Sector_PWD(unsigned char pbuf[],
unsigned char card_snr[4],
unsigned char sector)
{
memcpy(pbuf,Nkey_a,6);
pbuf[0] *= card_snr[0]+sector*1;
pbuf[1] *= card_snr[1]+sector*2;
pbuf[2] *= card_snr[2]+sector*3;
pbuf[3] *= card_snr[3]+sector*4;
pbuf[4] *= pbuf[0]+sector*5;
pbuf[5] *= pbuf[1]+sector*6;
}
//读系统卡
BYTE GetSEEDCardTest(SeedCard_Info *card)
{
BYTE idata tt[2];
BYTE idata card_snr[4];
BYTE idata bankdata[16];
BYTE size,err;
int i=0;
//Init_Rfic();
mifs_reset(20);
for(i=45;--i;)
{
if(!mifs_request(ALL_CARD,tt))break;
}
if(!i)return(CARD_NO_FINED);
for(i=45;--i;)
{
if((mifs_request(IDLE_CARD,tt))!=MI_OK)continue;
if((mifs_anticoll(0,card_snr))!=MI_OK)continue;
if((mifs_select(card_snr,&size))!=MI_OK)continue;
break;
}
if(!i)return(CARD_ERR_CODE);//return(40+err);
Count_Sector_PWD(bankdata,card_snr,SEEDCARD_SECTOR);
err=mifs_load_key(KEYA,SEEDCARD_SECTOR,bankdata);
//err=mifs_load_key(KEYA,SEEDCARD_SECTOR,Nkey_b);
if(err!=MI_OK)return(50+err);
for(i=15;--i;)
{
if((mifs_authentication(KEYA,SEEDCARD_SECTOR))!=MI_OK)continue;
//if((mifs_authKey(KEYA,SEEDCARD_SECTOR,Nkey_b))!=MI_OK)continue;
if((mifs_read(SEED_CARD_SECT,bankdata))!=MI_OK)continue;
break;
}
if(!i)return(CARD_ERR_CODE);//return(40+err);
//do_buzzer(1);
mifs_halt();
//mifs_close();
if(bankdata[CARD_LEVEL_DDR] != SEED_CARD)
{
return(CARD_NO_SEED);
}
memcpy(card->unit_code,&bankdata[UNIT_CODE_ADDR],3);
memcpy(card->unit_password,&bankdata[UNIT_PWD_ADDR],3);
card->fuc_type=bankdata[FUC_TYPE_ADDR];
card->fuc_sector=bankdata[FUC_SECTOR_ADDR];
card->public_sector=bankdata[PUBLIC_SECTOR_ADDR];
memcpy(card->date,&bankdata[SEED_DATE_ADDR],3); //6
return(SUCCESS);
}
unsigned char Check_Card_Event(unsigned char cardmode)
{
unsigned char idata tt[2];
if(cardmode)
{
if(mifs_request(ALL_CARD,tt))return(1);
}
else
{
if(mifs_request(IDLE_CARD,tt))return(1);
}
Stop_Timer(DIS_CLOCKEVENT_Tevent);//must!
Stop_Timer(WAIT_CARD_Tevent);
PostMessage(FIND_CARD_EVENT,0);
return(0);
}
//===============================
char RfModule_Init()
{
unsigned char i,rst;
sttCardStruct xdata stCardStruct;
Rf_Init();
memset(&stCardStruct,0xFF,16);
stCardStruct.cCompanyInfoSector = COMPANY_INFO_SECTOR;
stCardStruct.cCardholderInfoSector = CARDHOLDER_INFO_SECTOR;
stCardStruct.cPublicMoneySector = PUBLIC_MONEY_SECTOR;
stCardStruct.cBusinessInfoSector = BUSINESS_INFO_SECTOR;
stCardStruct.cTimeCounterSector = TIME_COUNT_SECTOR;
stCardStruct.cOrderDinnerSector = ORDER_DINNER_SECTOR;
stCardStruct.cBusinessLimitInfoSector = BUSINESS_LIMIT_INFO_SECTOR;
i=10;
while(i--)
{
if((rst=SetCardApplicationSector(&stCardStruct))== MI_OK)
break;
#ifdef _DEBUG
DebugString("Set Card Application Sector Value Result:");
DebugData(1,1,&rst);
#endif
}
return rst;
}
//充值操作
char FillMoneyOrTime()
{
unsigned char result;
unsigned long idata lSerialNo;
unsigned char xdata Buffer[18];
unsigned int iOffSet;
sttFillPara xdata stFillPara; //充值信息表数据
sttFillLimitInfo xdata stFillLimitInfo;//充值限制信息
//读取充值时间限制表
result = ReadFillLimitInfo(&stFillLimitInfo);
if(result != SUCCESS) return result;
#ifdef _DEBUG
DebugString("Read Fill Limit Info OK, the Data:");
DebugData(12,12,(unsigned char *)&stFillLimitInfo);
#endif
//读系统时钟
ReadClock(gcDateTime);
#ifdef _DEBUG
DebugString("Read Clock OK, the Data:");
DebugData(7,7,gcDateTime);
#endif
if(memcmp(stFillLimitInfo.cStartTime,gcDateTime,6) > 0)
return NO_IN_CONSUMETIME; //未到充值时间
if(memcmp(stFillLimitInfo.cEndTime,gcDateTime,6) < 0)
return NO_IN_CONSUMETIME; //已过充值时间
#ifdef _DEBUG
DebugString("\r\n\r\nBegin Order Dinner Operate \r\n");
#endif
//检查是否有卡
result=mifs_anticoll(0,Buffer);
if(result != MI_OK) return FAILURE;
#ifdef _DEBUG
DebugString("Anticoll OK\r\n");
#endif
result=mifs_select(Buffer,&Buffer[4]);
if(result != MI_OK) return FAILURE;
#ifdef _DEBUG
DebugString("Select OK\r\n");
#endif
//判断是否为最后操作的那张卡
if(memcmp(CardSerialNo,Buffer,4)!=0) //若不是同一张卡
{
CardOperateStep = 0; //清卡操作步骤,即另一张卡需重头开始
memcpy(CardSerialNo,Buffer,4); //保存当前卡系列号
#ifdef _DEBUG
DebugString("A New Card In\r\n");
#endif
}
#ifdef _DEBUG
else //若是同一张卡,则看上次完成操作的步骤
{
DebugString("Last Operation Card In\r\n");
}
#endif
//具体分步操作读写卡
switch(CardOperateStep)
{
case 0: //读持卡人信息
#ifdef _DEBUG
DebugString("Read Cardholder Info...\r\n");
#endif
Count_Sector_PWD(Buffer,CardSerialNo,CARDHOLDER_INFO_SECTOR); //计算密钥
//memset(Buffer,0xFF,6);
result=ReadCardholderInfo(CardSerialNo,KEYA,Buffer,&stCardholderInfo);
#ifdef _DEBUG
DebugString("Read Cardholder Info Result:");
DebugData(1,1,&result);
#endif
if(result != MI_OK) return FAILURE;
#ifdef _DEBUG
DebugString("Read Cardholder Info OK, the Data:");
DebugData(41,28,(unsigned char *)&stCardholderInfo);
#endif
CardOperateStep = 1;
case 1: //判断卡状态、启用日期、有效期等
#ifdef _DEBUG
DebugString("Check Cardholder Info...\r\n");
#endif
//1、判断卡状态标志
if(stCardholderInfo.cState) //无效卡
{
mifs_halt();
#ifdef _DEBUG
DebugString("Current Card Status is Invalid\r\n");
#endif
return CARD_LOSTED_CODE;
}
//2、检查卡启用日期、有效期
ReadClock(gcDateTime); //读时钟
#ifdef _DEBUG
DebugString("Read Clock OK, the Data:");
DebugData(7,7,gcDateTime);
#endif
if(memcmp(gcDateTime,stCardholderInfo.cActiveDate,3) < 0)
{
mifs_halt();
#ifdef _DEBUG
DebugString("未到使用期\r\n");
#endif
return CARD_OVERDUE_CODE; //未到启用日期
}
if(memcmp(gcDateTime,stCardholderInfo.cInvalidDate,3) > 0)
{
mifs_halt();
#ifdef _DEBUG
DebugString("已过有效期\r\n");
#endif
return CARD_OVERDUE_CODE; //未已过有效日期
}
//3、检查卡状态表
memcpy(&lSerialNo,CardSerialNo,4);
result = FoundCardStatusTable(lSerialNo);
#ifdef _DEBUG
DebugString("Found Card Status Table Result:");
DebugData(1,1,&result);
#endif
switch(result)
{
case SUCCESS: //找到
result = SetCardState(CardSerialNo,KEYA,Buffer,2);
if(result==MI_OK)
return CARD_LOSTED_CODE;
else
return FAILURE;
case FAILURE: //未找到
CardOperateStep = 2;
break;
default:
return result;
}
case 2: //查找充值信息数据
#ifdef _DEBUG
DebugString("Read Fill Para Info...\r\n");
#endif
memcpy(stFillPara.CardIndex,stCardholderInfo.cSerialNo,3);
result = FoundFillPara(&stFillPara,&iOffSet);
#ifdef _DEBUG
DebugString("stFillPara Data:");
DebugData(8,8,(unsigned char *)&stFillPara);
#endif
if(result != SUCCESS) return result;
if(stFillPara.cCurrentStatus == 0)
return KQ_REPEAT_CODE; //已充过值
CardOperateStep = 3;
case 3: //读卡上交易数据
#ifdef _DEBUG
DebugString("Read Cardholder Info...\r\n");
#endif
Count_Sector_PWD(&Buffer[0],CardSerialNo,PUBLIC_MONEY_SECTOR); //计算密钥
Count_Sector_PWD(&Buffer[6],CardSerialNo,BUSINESS_INFO_SECTOR); //计算密钥
Count_Sector_PWD(&Buffer[12],CardSerialNo,BUSINESS_LIMIT_INFO_SECTOR); //计算密钥
//memset(Buffer,0xFF,18);
result=ReadBusinessInfo(CardSerialNo,KEYA,Buffer,&stBusinessInfo);
if(result != MI_OK) return FAILURE;
#ifdef _DEBUG
DebugString("Read Business Info OK, the Data:");
DebugData(44,44,(unsigned char *)&stBusinessInfo);
#endif
CardOperateStep = 4;
case 4: //判断卡上充值记录是否为当前充值段内
if(stFillPara.cCurrentStatus == stBusinessInfo.stFillInfo.cMode)
{
if(!((memcmp(stBusinessInfo.stFillInfo.cDateTime,stFillLimitInfo.cStartTime,6) < 0)
|| (memcmp(stBusinessInfo.stFillInfo.cDateTime,stFillLimitInfo.cEndTime,6) > 0)))
{
UpdateFillParaStatus(iOffSet); //补更新充值参数标记
return KQ_REPEAT_CODE; //已充过值
}
}
CardOperateStep = 5;
case 5: //准备充值数据
memcpy(stBusinessInfo.stFillInfo.cDateTime,gcDateTime,6); //充值日期时间,格式:YY MM DD HH MM SS
if(stFillPara.cCurrentStatus==FILL_MONEY) //充钱
{
stBusinessInfo.stFillInfo.lMoney=stFillPara.Value; //充值金额
stBusinessInfo.stFillInfo.iTimes=0; //充值次数
}else
if(stFillPara.cCurrentStatus==FILL_TIMES)//充次
{
stBusinessInfo.stFillInfo.lMoney=0; //充值金额
stBusinessInfo.stFillInfo.iTimes=stFillPara.Value; //充值次数
}
memcpy(stBusinessInfo.stFillInfo.cDeviceNo,(unsigned char*)&equip_addr.number_addr,2); //设备编号
stBusinessInfo.stFillInfo.cMode=stFillPara.cCurrentStatus; //充值类别
CardOperateStep = 6;
case 6: //进行充值
result = Fill(CardSerialNo,&stBusinessInfo);
#ifdef _DEBUG
DebugString("Fill Result:");
DebugData(1,1,&result);
DebugString("Read Business Info OK, the Data:");
DebugData(44,44,(unsigned char *)&stBusinessInfo);
#endif
if(result ==ERROR_NO_COMPLITE) return 60;
if(result != MI_OK) return FAILURE;
mifs_halt();
CardOperateStep = 2; //若下次也是当前这张卡,则直接跳到读卡上订餐数据
UpdateFillParaStatus(iOffSet);
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -