📄 iccard.c
字号:
return ERROR;
}
if( OK != IC_get_data_back( SEL_ESAM, 0x27 + 0x04 ) )
{
return ERROR;
}
memcpy( fn_data, &Cpu_card_comm.Serial_Buffer[1], 0x27 + 0x04 );
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR], fn_data, 0x27 + 0x04 );
if( OK != IC_write_file_MAC( SEL_CARD, 2, 0, 0x27 + 0x04 ) )
{
return ERROR;
}
return OK;
}
uchar IC_checking_writeback(uchar rec_num)
{
ulong buy_times;
uchar *fn_data = cd_data;
load_data( &fn_data[1], DB_YH, USER_CODE_LEN );
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR] = 0x68;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 1] = 0x80;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 2] = 0x22;
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 3], (uchar *)&fn_data[1], USER_CODE_LEN );
//save buy times
load_data( (uchar *)&buy_times, DB_GDCS, 4 );
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x2A], (uchar *)&buy_times, 4 );
//非法插卡次数清零
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x1C] = 0;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x1D] = 0;
//卡序号清空
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x29] = 0;
//保存校验和
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x3C] = GetSum( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 1], 0x3B );
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x3D] = 0x16;
if(OK != IC_write_file_ex( SEL_CARD, 1 + (ushort)0x3E * ((ushort)rec_num), 0x3E ) )
{
return ERROR;
}
return OK;
}
/*
* 初始化卡:
* 格式:68H+01H+31+用户号(5)+购电量(3)+购电次数(2)+报警电量1(3)+报警电量2(3)+
* 拉闸负荷(2)+应急赊欠门限(3)+囤积电量(3)+脉冲常数(2)+密码数据(5)+CSUM+16H
* 售电卡:
* 格式:68H+02H+31+用户号(5)+购电量(3)+购电次数(2)+报警电量1(3)+报警电量2(3)+
* 拉闸负荷(2)+应急赊欠门限(3)+囤积电量(3)+脉冲常数(2)+密码数据(5)+CSUM+16H
* 反写数据:
* 格式:68H+81H+44+剩余电量(3)+累计购电量(3)+累计用电量(3)+过零电量(3)+应急赊欠电量(3)+
* 囤积电量(3)+购电次数(2)+应急赊欠门限(3)+脉冲常数(2)+拉闸负荷(2)+电表表号(5)+
* 用户号(5)+电表状态(2)+报警电量1(3)+报警电量2(3)+CSUM+16H
*/
uchar ic_refilling(void)
{
ulong buy_times, buy_times_hex, new_buy;
uchar *fn_data = cd_data, new_flag = 0, cd_code = OK;
uchar recv_buf[0x2e], card_sn, err_num = 0;
uchar flag = 0;
memcpy( recv_buf, &Cpu_card_comm.Serial_Buffer[1], 0x2e );
card_sn = recv_buf[0x2b];
/*********************相互内部认证***********************/
if( ( cd_code = UNIC_internal_auth_proc() ) != OK )
{
return EPM_E__6;
}
/*********************内部认证 结束***********************/
/*********************ESAM外部认证*************************/
if( ( cd_code = UNIC_esam_external_auth_proc() ) != OK )
{
return EPM_E__7;
}
/*********************ESAM外部结束*************************/
/*********************CPU Card 外部认证*********************/
if( ( cd_code = UNIC_ic_external_auth_proc()) != OK )
{
return EPM_E__8;
}
/*********************CPU Card 外部认证结束***************/
load_data( &fn_data[0], DB_ST, 1 );
if( fn_data[0] != USED_METER )
{
// 第一次购电,购电次数为1
buy_times = *( (ulong *)( recv_buf + IC_BUY_TIMES_POS ) );
ExchangeData( (uchar *)&buy_times );
if( buy_times != 1 )
{
IC_Card_flag |= IC_CARD_BUY_ERR;
return EPM_E__23;
}
new_flag = 1;
buy_times = 1;
FramWrite( DB_GDCS, (uchar *)&buy_times, 4 );
ExchangeData( (uchar *)&buy_times );
memcpy( fn_data + 1, &recv_buf[IC_USERCODE_START_POS], USER_CODE_LEN );
memcpy( fn_data + 10, &recv_buf[IC_METERCODE_START_POS], USER_METER_LEN );
*( (ulong *)(recv_buf + IC_BUY_TIMES_POS) ) = 1;
}
else
{
/* 读取用户号 */
load_data( &fn_data[1], DB_YH, USER_CODE_LEN );
/* 读取购电次数*/
load_data( (uchar *)&buy_times, DB_GDCS, 4 );
/* 读取表号*/
load_data( &fn_data[10], DB_BH, USER_METER_LEN );
/* 看用户号是否相同*/
if( OK != IsEqual( fn_data + 1, &recv_buf[IC_USERCODE_START_POS], USER_CODE_LEN ) )
{
IC_Card_flag |= IC_CARD_BUY_ERR;
return EPM_E__11;
}
/* 看表号是否相同*/
if( OK != IsEqual( fn_data + 10, &recv_buf[IC_METERCODE_START_POS], USER_METER_LEN ) )
{
IC_Card_flag |= IC_CARD_BUY_ERR;
return EPM_E__17;
}
/* 看购电次数是否相差为1 */
buy_times_hex = Bcd2HexLong(buy_times);
buy_times = *( (ulong *)( recv_buf + IC_BUY_TIMES_POS ) );
ExchangeData( (uchar *)&buy_times );
buy_times = Bcd2HexLong( buy_times );
/* 如果不等于1 返回错误*/
if( ( buy_times - buy_times_hex ) != 1 )
{
IC_Card_flag |= IC_CARD_BUY_ERR;
return EPM_E__23;
}
#if 0
/* 保存购电次数*/
buy_times_hex = Hex2BcdLong(buy_times_hex + 1);
buy_times = buy_times_hex;
FramWrite( DB_GDCS, (uchar *)&buy_times, 4 );
/* 反写购电次数*/
ExchangeData( (uchar *)&buy_times );
*( (ulong *)( recv_buf + IC_BUY_TIMES_POS ) ) = buy_times;
#endif
flag |= BIT0;
}
/* 最大囤积电量*/
PrePayData.CornerSum = *( (ulong *)(recv_buf + IC_CONER_PWR_POS ) );
ExchangeData( (uchar *)&PrePayData.CornerSum );
FramWrite( DB_XGDL, (uchar *)&PrePayData.CornerSum, POWER_DATA_LEN );
/* 新购电量*/
ExchangeData( &recv_buf[IC_MONEY_START_POS] );
new_buy = Hex2BcdLong(*( (unsigned long *)(&recv_buf[IC_MONEY_START_POS] ) ) );
/* 反写新购电量*/
memcpy( &recv_buf[IC_MONEY_START_POS], &new_buy, POWER_DATA_LEN );
ExchangeData( &recv_buf[IC_MONEY_START_POS] );
// 保存最后购电量
FramWrite( DB_ZHGDL, (unsigned char *)&new_buy, POWER_DATA_LEN );
//保存累计购电量
FramRead( DB_LJGDL, (unsigned char *)&PrePayData.CumulateBuySum, POWER_DATA_LEN );
PrePayData.CumulateBuySum = BcdAddOrSubLong( PrePayData.CumulateBuySum, new_buy, 0 );
FramWrite( DB_LJGDL, (unsigned char *)&PrePayData.CumulateBuySum, POWER_DATA_LEN );
//判断当前剩余电量是否为零
if( PrePayData.BalanceSum == 0 )
{
//判断过零电量是否为零
if( PrePayData.OverZeroSum )
{
//比较过零电量与新购电量
if( PrePayData.OverZeroSum >= new_buy )
{
//从过零电量中减去新购电量
PrePayData.OverZeroSum = BcdAddOrSubLong( PrePayData.OverZeroSum, new_buy, 1 );
}
else
{
//从新购电量中减去过零电量
new_buy = BcdAddOrSubLong( new_buy, PrePayData.OverZeroSum, 1 );
//保存剩余电量
PrePayData.BalanceSum = new_buy;
//清空过零电量
PrePayData.OverZeroSum = 0;
flag |= BIT1;
}
}
else
{
//保存剩余电量
PrePayData.BalanceSum = new_buy;
flag |= BIT1;
}
}
else
{
//剩余电量加上新购电量
PrePayData.BalanceSum = BcdAddOrSubLong( PrePayData.BalanceSum, new_buy, 0 );
flag |= BIT1;
}
if( flag & BIT0 )
{
/* 保存购电次数*/
buy_times_hex = Hex2BcdLong(buy_times_hex + 1);
buy_times = buy_times_hex;
FramWrite( DB_GDCS, (uchar *)&buy_times, 4 );
/* 反写购电次数*/
ExchangeData( (uchar *)&buy_times );
*( (ulong *)( recv_buf + IC_BUY_TIMES_POS ) ) = buy_times;
}
if( flag & BIT1 )
{
if( RELAYPARA.EnableFlag & BIT0 )
{
RELAY0_ON();
RELAY1_ON();
RELAYPARA.Status &=~ BIT0;
}
#if 0
if( RELAYPARA.EnableFlag & BIT1 )
{
RELAY1_ON();
RELAYPARA.Status &=~ BIT1;
}
#endif
FramWrite( ADDR_OF_RELAY_PARA+OFFSET_RELAY_STATUS, &RELAYPARA.Status, 1 );
}
// 保存过零电量
FramWrite( DB_GLDL, (uchar *)&PrePayData.OverZeroSum, POWER_DATA_LEN );
// 保存剩余电量
FramWrite( DB_SYDL, (uchar *)&PrePayData.BalanceSum, POWER_DATA_LEN );
IC_WRITE_BUFFER[0] = 0x68;
IC_WRITE_BUFFER[1] = 0x02;
IC_WRITE_BUFFER[2] = 0x1E;
//保存用户号
memcpy( &IC_WRITE_BUFFER[3], &fn_data[1], USER_CODE_LEN );
IC_WRITE_BUFFER[0x0c] = recv_buf[0x0c];
memcpy( &IC_WRITE_BUFFER[0x0d], &recv_buf[0x17], 21 );
IC_WRITE_BUFFER[0x22] = GetSum(&IC_WRITE_BUFFER[1], 0x21 );
IC_WRITE_BUFFER[0x23] = 0x16;
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR], IC_WRITE_BUFFER, FILE_APP_BIN_LEN );
if( OK != IC_write_file( SEL_ESAM, FILE_ID_ESAM_APPLICATION, 0, FILE_APP_BIN_LEN ) )
{
cd_code = EPM_E__22;
}
if( OK != ic_refill_writeback( &fn_data[10], &buy_times, card_sn ) )
{
cd_code = EPM_E__15;
}
if( new_flag )
{
// 保存用户号
save_data( &fn_data[1], DB_YH, USER_CODE_LEN );
// 保存表号
save_data( &fn_data[10], DB_BH, USER_METER_LEN );
// 保存状态字
fn_data[0] = USED_METER;
save_data( &fn_data[0], DB_ST, 1 );
}
return cd_code;
}
uchar IC_select_file(uchar sel_type, ushort file_id)
{
Cpu_card_comm.Serial_Buffer[0] = 0;
Cpu_card_comm.Serial_Buffer[1] = 0xA4;
Cpu_card_comm.Serial_Buffer[2] = sel_type;
Cpu_card_comm.Serial_Buffer[3] = 0;
Cpu_card_comm.Serial_Buffer[4] = 2;
CPU_card_send_command( 0, 5 );
CPU_card_read_response(1);
//选择电表应用
Cpu_card_comm.Serial_Buffer[0] = (uchar)( file_id >> 8 );
Cpu_card_comm.Serial_Buffer[1] = (uchar)( file_id & 0xff );
CPU_card_send_command(0, 2);
CPU_card_read_response(2);
if( ( Cpu_card_comm.Serial_Buffer[0] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[1] != 0x00 ) )
{
return ERROR;
}
return OK;
}
uchar IC_read_file(uchar sel_dev, uchar file_id, uchar s_pos, uchar read_len)
{
uchar old_dev = Cpu_card_comm.selectDevice;
Cpu_card_comm.selectDevice = sel_dev;
Cpu_card_comm.Serial_Buffer[0] = 0;
Cpu_card_comm.Serial_Buffer[1] = 0xb0;
Cpu_card_comm.Serial_Buffer[2] = file_id | 0x80;
Cpu_card_comm.Serial_Buffer[3] = s_pos;
Cpu_card_comm.Serial_Buffer[4] = read_len;
CPU_card_send_command(0, 5);
Cpu_card_comm.Serial_Buffer[read_len + 1] = 0;
CPU_card_read_response(read_len + 3);
Cpu_card_comm.selectDevice = old_dev;
if( ( Cpu_card_comm.Serial_Buffer[read_len + 1] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[read_len + 2] != 0x00 ) )
{
return ERROR;
}
return OK;
}
uchar IC_get_ATR(void)
{
Cpu_card_comm.Serial_Buffer[0] = 0x00;
Cpu_card_comm.Serial_Buffer[1] = 0xB0;
Cpu_card_comm.Serial_Buffer[2] = 0x90;
Cpu_card_comm.Serial_Buffer[3] = 0x01;
Cpu_card_comm.Serial_Buffer[4] = 0x08;
CPU_card_send_command(0, 5);
CPU_card_read_response(11);
if( ( Cpu_card_comm.Serial_Buffer[9] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[10] != 0x00 ) )
{
return ERROR;
}
memcpy( IC_ATR_DATA, &Cpu_card_comm.Serial_Buffer[1], 8 );
return OK;
}
uchar IC_get_data_back(uchar sel_dev, uchar len)
{
uchar old_dev = Cpu_card_comm.selectDevice;
Cpu_card_comm.selectDevice = sel_dev;
Cpu_card_comm.Serial_Buffer[0] = 0x0;
Cpu_card_comm.Serial_Buffer[1] = 0xC0;
Cpu_card_comm.Serial_Buffer[2] = 0x00;
Cpu_card_comm.Serial_Buffer[3] = 0x00;
Cpu_card_comm.Serial_Buffer[4] = len;
CPU_card_send_command(0, 5);
CPU_card_read_response(3 + len);
if( ( Cpu_card_comm.Serial_Buffer[1 + len] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[2 + len] != 0x00 ) )
{
if( Cpu_card_comm.Serial_Buffer[1 + len] != 0x61 )
{
Cpu_card_comm.selectDevice = old_dev;
return ERROR;
}
}
Cpu_card_comm.selectDevice = old_dev;
return OK;
}
uchar IC_get_rand_data(uchar sel_dev, uchar len)
{
uchar old_dev = Cpu_card_comm.selectDevice;
Cpu_card_comm.selectDevice = sel_dev;
Cpu_card_comm.Serial_Buffer[0] = 0x0;
Cpu_card_comm.Serial_Buffer[1] = 0x84;
Cpu_card_comm.Serial_Buffer[2] = 0x00;
Cpu_card_comm.Serial_Buffer[3] = 0x00;
Cpu_card_comm.Serial_Buffer[4] = len;
CPU_card_send_command(0, 5);
CPU_card_read_response(3 + len);
if( ( Cpu_card_comm.Serial_Buffer[1 + len] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[2 + len] != 0x00 ) )
{
return ERROR;
}
if( Cpu_card_comm.selectDevice == SEL_ESAM )
memcpy( IC_ESAM_RAND_DATA, &Cpu_card_comm.Serial_Buffer[1], len );
else
memcpy( IC_CPU_RAND_DATA, &Cpu_card_comm.Serial_Buffer[1], len );
Cpu_card_comm.selectDevice = old_dev;
return OK;
}
uchar IC_internal_auth(uchar auth_type)
{
Cpu_card_comm.Serial_Buffer[0] = 0x0;
Cpu_card_comm.Serial_Buffer[1] = 0x88;
Cpu_card_comm.Serial_Buffer[2] = 0x00;
Cpu_card_comm.Serial_Buffer[3] = auth_type;
Cpu_card_comm.Serial_Buffer[4] = 0x08;
if( AUTH_ESAM_EXTERNAL == auth_type )
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR], IC_ESAM_RAND_DATA, 8 );
else if(AUTH_CPU_INTERNAL== auth_type)
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR], IC_CPU_RAND_DATA, 8 );
else
return ERROR;
CPU_card_send_command(0, 5);
CPU_card_read_response(1);
CPU_card_send_command(IC_WRITE_START_ADDR, 8);
CPU_card_read_response(2);
if( ( Cpu_card_comm.Serial_Buffer[0] != 0x61 ) ||( Cpu_card_comm.Serial_Buffer[1] != 0x08 ) )
{
return ERROR;
}
return OK;
}
uchar IC_external_auth(void)
{
Cpu_card_comm.Serial_Buffer[0] = 0x0;
Cpu_card_comm.Serial_Buffer[1] = 0x82;
Cpu_card_comm.Serial_Buffer[2] = 0x00;
Cpu_card_comm.Serial_Buffer[3] = 0x06;
Cpu_card_comm.Serial_Buffer[4] = 0x08;
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR], IC_ESAM_ENCRYPT_DATA, 8 );
CPU_card_send_command(0, 5);
CPU_card_read_response(1);
CPU_card_send_command(IC_WRITE_START_ADDR, 8);
CPU_card_read_response(2);
if( ( Cpu_card_comm.Serial_Buffer[0] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[1] != 0x00 ) )
{
return ERROR;
}
return OK;
}
uchar IC_write_file(uchar sel_dev, uchar file_id, uchar s_pos, uchar w_len)
{
uchar old_dev = Cpu_card_comm.selectDevice;
Cpu_card_comm.selectDevice = sel_dev;
Cpu_card_comm.Serial_Buffer[0] = 0x0;
Cpu_card_comm.Serial_Buffer[1] = 0xd6;
Cpu_card_comm.Serial_Buffer[2] = file_id | 0x80;
Cpu_card_comm.Serial_Buffer[3] = s_pos & 0xff;
Cpu_card_comm.Serial_Buffer[4] = w_len;
CPU_card_send_command(0, 5);
CPU_card_read_response(1);
CPU_card_send_command(5, w_len);
CPU_card_read_response(2);
Cpu_card_comm.selectDevice = old_dev;
if( ( Cpu_card_comm.Serial_Buffer[0] != 0x90 ) ||( Cpu_card_comm.Serial_Buffer[1] != 0x00 ) )
{
return ERROR;
}
return OK;
}
uchar IC_write_file_MAC(uchar sel_dev, uchar file_id, uchar s_pos, uchar w_len)
{
uchar old_dev = Cpu_card_comm.selectDevice;
Cpu_card_comm.selectDevice = sel_dev;
Cpu_card_comm.Serial_Buffer[0] = 0x04;
Cpu_card_comm.Serial_Buffer[1] = 0xd6;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -