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

📄 drv_card.c

📁 CPU卡在税控行业应用驱动,符合7816要求
💻 C
📖 第 1 页 / 共 3 页
字号:
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.11
// Additional    : 
//////////////////////////////////////////////////////////////////////
unsigned char check_atr_len(unsigned char *buf,unsigned char *tck_flag)
{
    unsigned char len;
    unsigned char temp;
    unsigned char temp2;

    *tck_flag = 0;

    temp = buf[1];         //T0
    len = temp&0x0f;
    len++;
    len++;
    temp2 = len;

    temp = temp>>4;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(!(temp&0x01))
    {
        return len;
    }
    len++;

    temp = buf[len+1-temp2];

    *tck_flag += (temp&0x0f);

    temp = temp>>4;                //TD1
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(!(temp&0x01))
    {
        if(*tck_flag)
            len++;
        return len;
    }
    len++;

    temp = buf[len+1-temp2];

    *tck_flag += (temp&0x0f);

    temp = temp>>4;             //TD2
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(temp&0x01)
        len++;

    temp = temp>>1;
    if(!(temp&0x01))
    {
        if(*tck_flag)
            len++;
        return len;
    }
    len++;

    temp = buf[len+1-temp2];

    *tck_flag += (temp&0x0f);

    temp = temp>>4;              //TD3
    if(temp&0x01)
        len++;
    temp = temp>>1;
    if(temp&0x01)
        len++;
    temp = temp>>1;
    if(temp&0x01)
        len++;
    temp = temp>>1;
    if(!(temp&0x01))
    {
        if(*tck_flag)
            len++;
        return len;
    }
    len++;

    temp = buf[len+1-temp2];      //TD4
    *tck_flag += (temp&0x0f);

    if(*tck_flag)
        len++;
    return len;
}

/*********************************************************************/
#ifdef NEW_CARD_MODE
/*********************************************************************/

//////////////////////////////////////////////////////////////////////
// Function name : scc_reset(uchar*,int,uchar)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.11
// Additional    : 
//////////////////////////////////////////////////////////////////////
int scc_reset(unsigned char *atr, int size,unsigned char detect)
{
    int i;
    int count;
    int timeout2;
    unsigned int timeout;
    struct timeval start_tv;
    struct timeval cur_tv;
    unsigned char pos;

    timeout = 5;
    while(count = read(scc_filedesc, &i,1)>0);
    while (timeout --)
    {
        /********************************************
        #if 0
        if(detect)
        {
            if (ioctl(scc_filedesc, SCCIODETECT, 0) != 1)
            {
            //  debug_step(01,01,01);
                delay_ms(100);
                continue;
            }
        }
        #endif
        *********************************************/
        if (ioctl(scc_filedesc, SCCIOCRESET, 0) < 0)
        {
            delay_ms(100);
            continue;
        }

    //  Henry 2004/08/02
    //  delay_ms(200);  //mok0623

        pos = 0;
        timeout2 = 3;
        /////////////////////////////////////////////////////////////
        //Henry 2004/08/02
        while (timeout2)
        {
            count = read(scc_filedesc, &atr[pos], size);
            if (count <= 0)
            {
                delay_ms(500);
            //  delay_ms(100);     //mok 20041122
                timeout2--;
                continue;
            }
            pos += count;
            timeout2 = 3;
        }
        ///////////////////////////////////////////////////////////////

        /*while (1)
        {
            count = read(scc_filedesc, &atr[pos], size);
            if (count <= 0)
            {
                delay_ms(500);
                if(!timeout2)  //mok
                {
                    timeout2 = -1;
                    break;
                }
                timeout2--;
                continue;
            }
            pos += count;
            timeout2 = 3;
        }*/

        if(!pos)
        return -1;

        current_slot->stat = SCC_STAT_RESETTED;
        return pos;
    }
  return -1;
}


//////////////////////////////////////////////////////////////////////
// Function name : pts_select(void)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.12
// Additional    : 
//////////////////////////////////////////////////////////////////////
void pts_select(void)
{
    unsigned char csum = 0;
    int i;
    unsigned char pts_buf[10];
    unsigned char buf_r[20];
    unsigned char len_r=0;
    unsigned int error;
    struct timeval start_tv;
    struct timeval cur_tv;
    int pos=0;

    pts_buf[0] = 0xff;
    pts_buf[1] = 0x10;
    pts_buf[1] += (current_slot->protocol & 0x0f);
    pts_buf[2] =pts1;
//  pts_buf[3] = 0;
//  pts_buf[4] = 0;

    for (i=0;i<3;i++)
    {
        csum ^= pts_buf[i];
    }
    pts_buf[3] = csum;
    memset(buf_r,0,20);

    write(scc_filedesc, pts_buf, 4);
    gettimeofday(&start_tv,0);
    error = 0;
    while(1)
    {
        while ( ( i = read(scc_filedesc, &buf_r[pos], 1))<=0) //读   //????
        {
            gettimeofday(&cur_tv,0);
            if ( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT )
            {
                error = 1;
                break;
            }
        }
        if(error) break;
        pos++;
        if(pos>=4) break;
    }
//  error = card_send_cmd(4,pts_buf,&len_r,buf_r);
    if(memcmp(pts_buf,buf_r,4)==0)
    {
        scc_set_paramfd(current_slot->scc_f,current_slot->scc_d);
        scc_set_extra_guardtime(current_slot->extra_guardtime);
        scc_set_protocol(current_slot->protocol);
        return;
    }
    else
    {
        scc_set_paramfd(372,1);
    }
}


//////////////////////////////////////////////////////////////////////
// Function name : card_reset(int)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 0--FISCAL_CARD;1--USER_CARD/CHECK_CARD
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.12
// Additional    : 
//////////////////////////////////////////////////////////////////////
int card_reset( int slot)
{
    unsigned char r_len;
    unsigned char recv_len;
    unsigned char tck_flag;

    unsigned int error;
    int count;
    int chk_sum;
    unsigned char r_buf[256];

    while(1)
    {
        error = scc_select_slot(slot);
        if(error)   //error1
        {
            error = 1;    //mok 0804  OVER_MAX_CARD_NUM
            break;
        //  continue;
        }
        scc_set_paramfd(372,1);
        count = scc_reset(r_buf, 128,slot);
        if (count <=  0) //error2
        {
        //  error = DRV_CARD_RESET_ERROR;
            error = 2;   //mok 0804
            break;
        //  continue;
        }

        r_len = count;

        recv_len = check_atr_len(r_buf,&tck_flag);
        if(recv_len!=r_len)    //error3
        {
        //  error = DRV_NO_TCK;
            error = 3;  //mok 0804
            break;
        //  continue;
        }

        if(tck_flag)
        {
            chk_sum = 0;
            chk_sum = scc_csum_check(r_buf,  count);
            if(chk_sum)         //error4
            {
            //  error = DRV_CHK_SUM_ERROR;
                error = 4;  //mok 0804
                break;
            //  continue;
            }
        }
 
        scc_decode_atr(r_buf);
 
        pts_select();

    //  scc_set_extra_guardtime(current_slot->extra_guardtime);
        #if 0   //need to update kennel before open follow program?
    //  scc_set_paramfd(current_slot->scc_f,current_slot->scc_d);
    //  scc_set_protocol(current_slot->protocol);
        #endif
    //  debug_step(01,current_slot->scc_f,current_slot->scc_d);
        error = 0;
        break;
    }
    return error;
}

#define CARD_SEND_TIMES 4

//////////////////////////////////////////////////////////////////////
// Function name : card_send_cmd(uchar,const uchar*,uchar*,uchar*)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 0--FISCAL_CARD;1--USER_CARD/CHECK_CARD
// Output value  : 
// Return value  : 0--成功;
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.12
// Additional    : 
//////////////////////////////////////////////////////////////////////
unsigned int card_send_cmd(unsigned char length,const unsigned char *buf_cmd,
                           unsigned char *len_r,unsigned char *rbuf)
{
    int i;
    int pos;
    int count;
    unsigned int error=0;
    unsigned char r_tatol_len;


    unsigned char get_ins;
    unsigned char try_times;
    unsigned char cmd_line[30];

    struct timeval start_tv;
    struct timeval cur_tv;

    for(try_times =0;try_times<CARD_SEND_TIMES;try_times++)
    {
        write(scc_filedesc, buf_cmd, 5);   //先写入命令头
        get_ins = 0;
        error = 0;
        count = 5;
    //  delay_ms(100);  //???
        while(1)
        {
            error = 0;
            get_ins = 0;
            if(count == length)                                 //命令到此结束
		 break;
            gettimeofday(&start_tv,0);

            while ( ( i = read(scc_filedesc, &get_ins, 1))<=0)  //读一个状态字
            {
                gettimeofday(&cur_tv,0);
                if ( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT )
                {
                //  error =  DRV_CARD_TIME_OUT;   
                    error = 4;
                    break;
                }
            }
            if(error)                         //读状态字超时退出命令状态
            	break;
            if(get_ins==0x60)                 //如果过程字节为0x60,则TTL提供根据额外的工作等待时间
		continue; 
            else if(get_ins == buf_cmd[1])    //如果过程字节为INS,继续向卡发送下面的字节
            {
                write( scc_filedesc, &buf_cmd[count], length - count );
                error = 0;
                break;
            }
            else if(get_ins == (0xff^buf_cmd[1]))    //如果过程字节为INS的补码,TTL继续传送下一个字节
            {
                write( scc_filedesc, &buf_cmd[count], 1 );
                count++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -