📄 card_pro.c
字号:
for(i=0;i<5;i++) buf[i]=out_buf[i];
if(!lc) //只读数据
{
le=out_buf[7];
buf[4]=le;
}
lout=le;
ins=buf[1];
pp=(uchar*)&out_buf[5];
out=*pp;
pp=(uchar*)&in_buf[1];
in=*pp;
bw.word=0;
while(1)
{
if(!send_flag) //发送命令
{
send_flag=1;
//if(testbuf[0]==0xaa)send_str(5,buf);
for(i=0;i<5;i++)
{
error=send_sam_byte(buf[i]);
if(error) //奇偶错
{
EA=1;
return error;
}
}
}
error=rece_sam_byte(); //读ACK1
//if(testbuf[0]==0xaa){send_char(r_w_byte);} //A4 61 C0 90 A4 61 C0 90 B0
if(error)
{
EA=1;
return error;
}
bw.byte.Hi=r_w_byte;
if(r_w_byte==0x60) continue; //CPU卡忙
if(((r_w_byte&0xf0)==0x60)||((r_w_byte&0xf0)==0x90)) //此时SW1=ACK1
{
error=rece_sam_byte(); //读SW2
//if(testbuf[0]==0xaa)send_char(r_w_byte);
if(error)
{
EA=1;
return error;
}
bw.byte.Lo=r_w_byte;
send_flag=0;
if(bw.byte.Hi==0x61) //lc,le同时有效 获得回应的数据
{//读取数据长度与文件实际长度不匹配,重发
buf[0]=0;
buf[1]=0xc0;
buf[2]=0;
buf[3]=0;
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
ins=buf[1];
continue;
}
else if(bw.byte.Hi==0x6c) //没有lc时有效
{//读取剩余数据
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
continue;
}
else
{
if(lout==le) lout=0; //没有读取到数据
in_buf[0]=lout;
in_buf[3]=bw.byte.Hi;
in_buf[4]=bw.byte.Lo;
//send_str(10,in_buf);//0C 06 72 90 00
EA=1;
return 0;
}
}//SW1,SW2--0x60-0x9f
if(r_w_byte==ins) //命令完成,可以传输数据块
{
// card_vcc(1);
if(lc) //写数据
{
do
{
//if(testbuf[0]==0xaa)send_char(*out);
error=send_sam_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
}while(--lc);
continue;
}
else if(le) //读本记录的有效存储数据
{
do
{
error=rece_sam_byte(); //读数据
//if(testbuf[0]==0xaa)send_char(r_w_byte);
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
}while(--le);
continue;
}
continue;
}//SW1==ins
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //命令完成,只可以传输单字节数据
{
if(lc) //写数据
{
error=send_sam_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
--lc;
continue;
}
else if(le) //读1字节本记录的有效存储数据
{
error=rece_sam_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
--le;
continue;
}
continue;
}//SW1==/ins
ins++;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return 1;
}//SW1==/(ins+1)
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return 1;
}//SW1==ins+1;
else //通信出错
{
EA=1;
return 1;
}
}//while(1)
}
//===============================================================================
uchar Cpu_Apdu(uchar xdata *out_buf,uchar xdata *in_buf)
{
uchar data ins;
uchar i,lc,le,lout,error,send_flag=0;
uchar xdata buf[10];
uchar xdata *out,*in;
uchar xdata **pp;
//uchar xdata r_w_byte=0;
UNST bw;
EA=0;
card_vcc(1);
le=0;
lc=out_buf[4];
for(i=0;i<5;i++) buf[i]=out_buf[i];
if(!lc) //只读数据
{
le=out_buf[7];
buf[4]=le;
}
lout=le;
ins=buf[1];
pp=(uchar *)&out_buf[5];
out=*pp;
pp=(uchar *)&in_buf[1];
in=*pp;
bw.word=0;
while(1)
{
if(!send_flag) //发送命令
{
send_flag=1;
//if(testbuf[0]==0xaa)send_str(5,buf);
for(i=0;i<5;i++)
{
error=send_cpu_byte(buf[i]);
if(error) //奇偶错
{
EA=1;
return error;
}
}
}
error=rece_cpu_byte(); //读ACK1
//if(testbuf[0]==0xaa)send_char(r_w_byte);
if(error)
{ // E4 61 04 C0 00 19
EA=1;
return error;
}
bw.byte.Hi=r_w_byte;
if(r_w_byte==0x60) continue; //CPU卡忙
if(((r_w_byte&0xf0)==0x60)||((r_w_byte&0xf0)==0x90)) //此时SW1=ACK1
{
error=rece_cpu_byte(); //读SW2
//if(testbuf[0]==0xaa){send_char(bw.byte.Hi);send_char(r_w_byte); }
if(error)
{
EA=1;
return error;
}
bw.byte.Lo=r_w_byte;
send_flag=0;
if(bw.byte.Hi==0x61) //lc,le同时有效 从CPU卡取响应数据 与
//uchar GetResponse(uchar which_card, uchar len, uchar *content)
//作用相同
{//读取数据长度与文件实际长度不匹配,重发
buf[0]=0;
buf[1]=0xc0;
buf[2]=0;
buf[3]=0;
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
ins=buf[1];
continue;
}
else if(bw.byte.Hi==0x6c) //没有lc时有效
{//读取剩余数据
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
continue;
}
else
{
if(lout==le) lout=0; //没有读取到数据
in_buf[0]=lout;
//if(testbuf[0]==0xaa)send_char(in_buf[0]);
in_buf[3]=bw.byte.Hi;
in_buf[4]=bw.byte.Lo;
EA=1;
return 0;
}
}//SW1,SW2--0x60-0x9f
if(r_w_byte==ins) //命令完成,可以传输数据块
{
if(lc) //写数据
{
do
{
//if(testbuf[0]==0xaa)send_char(*out);
error=send_cpu_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
}while(--lc);
continue;
}
else if(le) //读本记录的有效存储数据
{
do
{
error=rece_cpu_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
}while(--le);
continue;
}
continue;
}//SW1==ins
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //命令完成,只可以传输单字节数据
{
if(lc) //写数据
{
error=send_cpu_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
--lc;
continue;
}
else if(le) //读1字节本记录的有效存储数据
{
error=rece_cpu_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
--le;
continue;
}
continue;
}//SW1==/ins
ins++;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return 1;
}//SW1==/(ins+1)
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return 1;
}//SW1==ins+1;
else //通信出错
{
EA=1;
return 1;
}
}//while(1)
}
//=========================================================
// 函 数 名:card_send_cmd
//
//
//
//*buf_cmd --
//length --
//
//rbuf
//*len_r
// 返 回 值:0--成功;
//=========================================================
/*uchar card_send_cmd(uchar card_type,uchar xdata *buf_cmd)
{
uchar xdata out_bufdata[8];
uchar xdata in_bufdata[5];
uchar xdata *len_r;
uchar xdata *rbuf;
uchar x;
memcpy(out_bufdata,buf_cmd+3,5);
out_bufdata[5]=(uchar)((uint)&buf_cmd[8]>>8); //cpu输出
out_bufdata[6]=(uchar)(&buf_cmd[8]);
out_bufdata[7]=buf_cmd[5+buf_cmd[7]];
in_bufdata[0]=0;
in_bufdata[1]=(uchar)((uint)&rbuf[0]>>8);
in_bufdata[2]=(uchar)(&rbuf[0]);
in_bufdata[3]=0;
in_bufdata[4]=0;
if(card_type==0) //税控卡
{ x=Sam_Apdu(out_bufdata,in_bufdata);
if(x)
{//send_char(x);
return 1;
}
//send_str(5,in_buf);
}
else
{
if(Cpu_Apdu(out_bufdata,in_bufdata))
return 1;
//send_str(5,in_buf);
}
*len_r=in_bufdata[0]+2;
rbuf[in_bufdata[0]]=in_bufdata[3];
rbuf[in_bufdata[0]+1]=in_bufdata[4];
//send_str(10,rbuf);
if(*len_r>2)
{
memcpy(buf_cmd+3,rbuf+1,in_bufdata[0]);
buf_cmd[1]=in_bufdata[0];
}
buf_cmd[in_bufdata[0]+3]=0x90;
buf_cmd[in_bufdata[0]+4]=0x0;
return 0;
}*/
//=================================================================================
uchar card_send_cmd(unsigned char card_type,const unsigned char xdata *buf_cmd,
unsigned char *len_r,unsigned char xdata *rbuf)
{
uchar out_buf[8];
uchar in_buf[5];
memcpy(out_buf,buf_cmd,5);
out_buf[5]=(uchar)((uint)&buf_cmd[5]>>8);
out_buf[6]=(uchar)(&buf_cmd[5]);
out_buf[7]=buf_cmd[5+buf_cmd[4]];
in_buf[0]=0;
in_buf[1]=(uchar)((uint)&rbuf[0]>>8);//指向*rbuf 的地址 UINT 型
in_buf[2]=(uchar)(&rbuf[0]);
in_buf[3]=0;
in_buf[4]=0;
if(card_type==0)
{
if(Sam_Apdu(out_buf,in_buf))
return 1;
//send_str(5,in_buf);
}
else
{
if(Cpu_Apdu(out_buf,in_buf))
return 1;
//send_str(5,in_buf);
}
*len_r=in_buf[0]+2;
//if(testbuf[0]==0xaa)send_char(*len_r);
rbuf[in_buf[0]]=in_buf[3]; //sw1
rbuf[in_buf[0]+1]=in_buf[4];//sw2
return 0;
}
//=================================================================================
uchar id_iso(uchar xdata *ptr)
{
if(Card_coumm(1,ptr))
return 1;
return 0;
}
//================================================================================
uchar sam_iso(uchar xdata *ptr)
{
if(Card_coumm(0,ptr))
return 1;
return 0;
}
//===================================================================================
uchar Card_coumm(uchar card_type,uchar *cmdbuf)
{
uchar i;
uchar len_r;
uint error;
uchar xdata buf_cmd[300];
uchar xdata buf_r[300];
//write_data_flg=1;
len_r = cmdbuf[cmdbuf[1]+1];
if(cmdbuf[1]<9) //补成统一格式
{
i=9-cmdbuf[1];
cmdbuf[10]=cmdbuf[cmdbuf[1]+1];
for(len_r=0;len_r<i;len_r++)cmdbuf[cmdbuf[1]+1+len_r]=0;
}
for(i=0;i<4;i++)
buf_cmd[i]=cmdbuf[i+3];
if(cmdbuf[7])
{
buf_cmd[4]=cmdbuf[7];
memcpy(&buf_cmd[5], cmdbuf+8, cmdbuf[7]);
//if(cmdbuf[10])
//buf_cmd[5+cmdbuf[7]]=cmdbuf[10];
if(cmdbuf[buf_cmd[4]+8])
buf_cmd[5+cmdbuf[7]]=cmdbuf[buf_cmd[4]+8];
//if(testbuf[0]==0xcc){send_str2(77,buf_cmd);while(1);}
//len = gst_apdu.lc+5;
}
else//此时必有le不等于0
{
buf_cmd[4]=cmdbuf[7];
buf_cmd[5]=cmdbuf[10];
}
/*if(cmdbuf[1]<10)
len_r = cmdbuf[10]+2;
else len_r = cmdbuf[cmdbuf[1]+1];//注册命令
*/
if(low_pwr==1) {shut_bat(0);}
error = card_send_cmd(card_type,buf_cmd,&len_r,buf_r);
if(error)
{
//write_data_flg=0;
return error;
}
cmdbuf[1]=len_r-2;
//if(testbuf[0]==0xaa)send_char(cmdbuf[1]);
cmdbuf[len_r+1]=buf_r[len_r-2];
cmdbuf[len_r+2]=buf_r[len_r-1];
if(len_r>2)
{
memcpy(cmdbuf+3,buf_r,(len_r-2));
}
// write_data_flg=0;
return 0;
}
//================================================================================
uchar atr_cupcard(uchar xdata *ptr)
{
char xdata i,temp,atr_len,error,cpu_tck=0,ti=0;
uchar xdata *p;
uint j=10000;
UNST bw;
atr_len=0;
p=ptr;
bw.word=0;
card_vcc(1);
cpu_ta1=0x11,cpu_d=1,cpu_tc1=0,cpu_tc2=10;
EA=0;
Writ_cpld(Sm_rst,0);
do //等待起始位
{
if(!IC_CARD_IO) break;
}while(j--);
Writ_cpld(Sm_rst,1);
cpu_t=1; //以正向协议传输
if(rece_cpu_byte()) //TS
{
EA=1;
bw.byte.Lo=1; //非CPU卡
return bw.word;
}
if(r_w_byte==0x03) //反向传输
{
cpu_t=0;
r_w_byte=0x3f;
}
else if(r_w_byte!=0x3b) //正向传输
{
EA=1;
bw.byte.Lo=1; //非CPU卡
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
error=rece_cpu_byte(); //接收T0
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
bw.byte.Hi=r_w_byte&0x0f; //保存历史字节数据长度
if((r_w_byte&0x0f)>32) //历史字节数据超长出错
{
EA=1;
bw.byte.Lo=1;
return bw.word;
}
atr_cpu1:
temp=r_w_byte>>4;
i=4;
do //Td1...Tdi
{
if(temp&0x01)
{
error=rece_cpu_byte();
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
if(atr_len==32) //数据超长出错
{
EA=1;
bw.byte.Lo=1;
return bw.word;
}
if(i==4) //TAi
{
if(!ti) cpu_ta1=r_w_byte; //TA1决定接收字符间最大时间
else if(ti==1) cpu_tck=1; //TA2...N表示有TCK校验
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -