⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iccard.c

📁 单相 CPU卡表复费率电能表,内部有提供I2C驱动,CPU卡驱动,NEC单片机0513等
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -