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

📄 drv_card.c

📁 CPU卡在税控行业应用驱动,符合7816要求
💻 C
📖 第 1 页 / 共 3 页
字号:
                continue;
            }
            else if((get_ins&0xf0)==0x90||(get_ins&0xf0)==0x60)      //如果过程字节为0x6x或0x9x(!=0x60),TTL等待下一个过程字节或状态码
            {
                pos = 0;    
                rbuf[pos] = get_ins;                                 //存储第一个过程字节
                pos++;
                error = 0;
                gettimeofday(&start_tv,0);
                while ( ( i = read(scc_filedesc, &rbuf[pos], 1))<=0) //读第二个过程字节或状态码  
                {
                    gettimeofday(&cur_tv,0);
                    if( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT )
                    {
                    //  error =  DRV_CARD_TIME_OUT;    //mok 0804
                        error = 4;
                        break;
                    }
                }
                if(error) 
			return error;
                pos++;        //读完两个过程字节  
                *len_r = pos; //pos = 2
                return 0;     //如果第一个过程字节为0x6x或0x9x(!=0x60),且第二个过程字节正确,本次命令执行完毕
            }
            else              //其他过程字节结束命令 response non-defined status
            {
                error = 1;    //cmd error
            //  sprintf(cmd_line,"error1 ins %02x",get_ins);
            //  lcd_disp(1,0,0,cmd_line);
            //  while(!getkey());
            //  debug_step(11,error,get_ins);
                return error;
            //  continue;
            }
        }                  //end of while(1)

        if(error)
	      continue;   //如果命令执行过程有错,最多重复4次
        break;            //如果命令执行无误,则跳出for循环继续向下执行
     }                    //end of for(try_times =0;try_times<CARD_SEND_TIMES;try_times++)

    if(try_times == CARD_SEND_TIMES )   //retry times
    {
        return 5;                       //DRV_CARD_SEND_FAIL  
    }

    if( length > 5)
        r_tatol_len = 2;
    else
        r_tatol_len = 2 + buf_cmd[4];

    pos = 0;
   
//如果命令只有5个字节,这里第一次接收第一个状态字
//如果第一次收到的第一个状态字为INS,发送了余下的字节后从这里开始接收处理
    while(1)
    {
        error = 0;
        get_ins = 0;
        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;    //mok 0804
                error = 4;
                break;
            }
        }

        if(error)
		 return error;     

        if(get_ins == buf_cmd[1])  //如果第二次读出的第一个张状态字为INS,则TTL准备接收所有来自IC卡的数据 read all  one time, including sw1&sw2
        {
            do{
                error = 0;
                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;    //mok 0804
                        error = 4;
                        break;
                    }
                }

                if(error)
			 return error;

                if(pos == r_tatol_len - 2 && get_ins == 0x60) 
			continue;

                rbuf[pos] = get_ins;
                pos++;
            }while(r_tatol_len - pos);
            *len_r = pos;
            
            /*************************************
            if(length==5 && buf_cmd[4]!=0)
            {
                if((pos-2)<buf_cmd[4])
                {
                    error = 2;
                    return error;
                }
            }
            ************************************/

            if(rbuf[pos-2]==0x90)
            {
                if(rbuf[pos-1]==0)
                {
                    return 0;
                }
                else
                {
                    error = 2;                 //cmd error
                    return error;
                }
            }
            break;
        } /*end of if(get_ins == buf_cmd[1])*/
        else if(get_ins == (0xff^buf_cmd[1]))    //read one byte
        {
            error = 0;
            gettimeofday(&start_tv,0);
            while ( ( i = read(scc_filedesc, &rbuf[pos], 1))<=0) //读   //????
            {
                gettimeofday(&cur_tv,0);
                if( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT )
                {
                //  error =  DRV_CARD_TIME_OUT;   //mok 0804
                    error = 4;
                    break;
                }
            }
            if(error)
		 return error;
            pos++;
            continue;
        }
        else if(get_ins == 0x60)        //waiting for next status byte
        {
            continue;
        }
        else if((get_ins&0xf0)==0x90||(get_ins&0xf0)==0x60)  //get next byte
        {
            rbuf[pos] = get_ins;
            pos++;
            error = 0;
            gettimeofday(&start_tv,0);
            while(( i = read(scc_filedesc, &rbuf[pos], 1))<=0)  //读   
            {
                gettimeofday(&cur_tv,0);
                if( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT )
                {
                //  error =  DRV_CARD_TIME_OUT;     //mok 0804
                    error = 4;
                    break;
                }
            }
            if(error) return error;
            pos++;
            *len_r = pos;
        
            /////////////////////////////////// check length
            if(length==5 && buf_cmd[4]!=0)
            {
                if((pos-2)<buf_cmd[4])
                {
                  
                    error = 3;
                    return error;
                }
            }
            ////////////////////////////////////////////////
            if(rbuf[pos-2]==0x90)
            {
                if(rbuf[pos-1]==0)
                {
                    return 0;
                }
                else
                {

                    error = 3;  //cmd error
                    return error;
                }
            }
            break;   
        }/*end of else if((get_ins&0xf0)==0x90||(get_ins&0xf0)==0x60)*/
    }/*end of while(1)*/
    return 0;
}

/*********************************************************************/
#else
/*********************************************************************/

//////////////////////////////////////////////////////////////////////
// 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.14
// Additional    : 
//////////////////////////////////////////////////////////////////////
int scc_reset(unsigned char *atr, int size,unsigned char detect)
{
    int i;
    int pos;
    int count;
    int timeout2;
    unsigned int timeout;

    // clear the tty buffer content, it is NEED 
    while( (count = read (scc_filedesc, &i, 1))> 0 );
    
    timeout = 5;

    while (timeout --)
    {
        /**************************************************
        if(detect)
        {
            if (ioctl(scc_filedesc, SCCIODETECT, 0) != 1)
            {
                delay_ms(100);
                continue;
            }
        }
        **************************************************/
        if (ioctl(scc_filedesc, SCCIOCRESET, 0) < 0)
        {
            delay_ms(100);
            continue;
        }

    //  delay_ms(100);
        delay_ms(200);

    //  timeout2 = 3;
        timeout2 = 30;
    //  pos = 0;
        while (timeout2-- > 0)
        {
            count = read(scc_filedesc, atr, size);
            if (count <= 0)
            {
                delay_ms(100);
                continue;
            }
            break;

            /***********************************************
            count = read(scc_filedesc, &atr[pos], size-pos);
            if (count <= 0)
            {
                delay_ms(100);
                continue;
            }
            pos += count;
            if(pos>1)break;
            ***********************************************/
        }

        if (timeout2 <= 0) // bad card insert
            return -1;


        current_slot->stat = SCC_STAT_RESETTED;

        return count;
    }
    return -1;
}


//////////////////////////////////////////////////////////////////////
// Function name : card_reset(int)
// Version       : Ver 1.0
// Discriptions  : 税控卡/用户卡/税务管理卡复位
// Input value   : 0--FISCAL_CARD;1--USER_CARD/CHECK_CARD
// Output value  : none
// Return value  : ==0, SUCCESS; !=0, FAIL
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.10
// Additional    : 
//////////////////////////////////////////////////////////////////////
int card_reset( int slot)
{
    int error;
    int count;
    int chk_sum;
    unsigned char buf[BUF_LEN];

    while(1)
    {
        error = scc_select_slot(slot);
        if(error)
        {
            error = 1;    //mok 0804
            break;
        }

        // I will enable the clock in reset process 
        count = scc_reset(buf, 128,slot);
        if (count <=  0)
        {
            //error = DRV_CARD_RESET_ERROR;  //mok 0804
            error = 2;
            break;
        }

        scc_decode_atr(buf);
        chk_sum = 0;
        if (current_slot->protocol == 1)
        {
            chk_sum = scc_csum_check(buf,  count);
        }

        if(chk_sum)
        {
            //error = DRV_CHK_SUM_ERROR;   //mok 0804
            error = 4;
            break;
        }
        error = 0;
        break;
    }
    return error;
}


//////////////////////////////////////////////////////////////////////
// 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.14
// Additional    : 
//////////////////////////////////////////////////////////////////////
//unsigned int card_send_cmd_old(unsigned char length,const unsigned char *buf_cmd,
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 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<3;try_times++)
    {
        count = 0;

        for (i=0;i<5;i++)
            cmd_line[count ++] = buf_cmd[i];

    //  if ( count > length)
    //  count = length;

        write(scc_filedesc, cmd_line, count);

    //  delay_ms(100);  //???

        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 )
        //  return DRV_CARD_TIME_OUT;     //mok 0804
            return 4;
        }

        if( get_ins == buf_cmd[1] ) break;
    }

    if (try_times == 3)
    {
    //  return DRV_CARD_SEND_FAIL;   //mok 0804
        return 5;
    }

    if (length > count)
    {
        count = length -count;
        write( scc_filedesc, &buf_cmd[5], count );
    }

//  delay_ms(100);  //???

    pos = 0;

    gettimeofday(&start_tv,0);

    do
    {
        count = read( scc_filedesc, &rbuf[pos], *len_r - pos );
        if (count >0)
        {
            pos += count;
            gettimeofday(&start_tv,0);
        }

        gettimeofday(&cur_tv,0);

        if ( cur_tv.tv_sec - start_tv.tv_sec > WMI_TIMEOUT)break;

        if ((rbuf[0]==0x61)&&(pos==2)) break;  //hhhh

    }while(pos<*len_r);

    if(pos<2)
    //  return DRV_CARD_SEND_FAIL;     //mok 0804
        return 5;

    *len_r = pos;
    return 0;
}

/*********************************************************************/
#endif
/*********************************************************************/

⌨️ 快捷键说明

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