📄 iccard.c
字号:
*revdata = (*revdata>>1)|0x80;
}
else
*revdata = (*revdata>>1);
}
else
{
if ( CARD_RX )
*revdata = (*revdata<<1)|0x01;
else
*revdata = (*revdata<<1);
}
}
delay_one_etu(); //9.5etu
if ( CARD_RX )
{ //receive parity bit
parity_bit = 1;
if (rev_TS==TS_BIT)
{
delay_one_etu(); //10.5 etu // TS receive ok
//printk("%s: parity_bit = 1\n");
return 0;
}
}
else
{
parity_bit = 0;
if (rev_TS==TS_BIT){
//printk("PARITY1_ERR rev_TS==TS_BIT\n");
goto REV_TS_ERR;// TS receive err
}
}
if ( parity_bit == (
( *revdata >> 7)
^( (*revdata & 0x40) >> 6)
^( (*revdata & 0x20) >> 5)
^( (*revdata & 0x10) >> 4)
^( (*revdata & 0x08) >> 3)
^( (*revdata & 0x04) >> 2)
^( (*revdata & 0x02) >> 1)
^( (*revdata & 0x01) )
)
)
{
delay_one_etu(); //10.5 etu
return 0;
}
REV_TS_ERR:
//delay_one_etu(); //10.5 etu
CARD_TX_CLR;
delay_one_etu(); //11.5 etu
if (card_selected==SAMCARD) delay_half_etu_sam(); //0.5etu
else delay_half_etu_usr(); //12 etu
CARD_TX_SET;
if (card_selected==SAMCARD) delay_half_etu_sam(); //0.5etu
else delay_half_etu_usr(); //12.5 etu
re_rev_times++;
//printk("PARITY1_ERR %d\n",*revdata);
}
//temp = revdata;
//printk("%s: temp = %d",__file__,temp);
return PARITY1_ERR;
}
//*******************************************************
//*******************************************************
static int iccard_reset( unsigned char * rec_buf,
int * rec_len)
{
int rlt,i,j,m;
unsigned char * ptr;
unsigned char revT0TD;
unsigned char TCK_exist;
unsigned char TDi_exist;
unsigned char parity_TCK;
unsigned int * card_logic_mode;
*rec_len = 0;
*rec_buf = 0;
if (card_selected==SAMCARD)
{
card_logic_mode = &logic_mode_sam;
EVOC_sam_card_pwr_on();
EVOC_select_sam();
delay_cycle(2500);
EVOC_sam_set_card_rst();
delay_cycle(5000);
EVOC_sam_clr_card_rst();
}
else if(card_selected==USRCARD)
{
card_logic_mode = &logic_mode_usr;
EVOC_usr_card_pwr_on();
EVOC_select_usr();
delay_cycle(2500);
EVOC_usr_set_card_rst();
delay_cycle(5000);
EVOC_usr_clr_card_rst();
}
else return NO_SELECTED_CARD_ERR;
//delay_cycle(200);
ptr = rec_buf;
*card_logic_mode = POSITIVE_LOGIC;
/*
memset(rec_buf,0x00,20);
for(j=0;j<20;j++)
{
rlt = EVOC_rev_one_byte(ptr++,REV_TS_TIMEOUT_CYCLE,NOT_TS_BIT); //receive TS
if (rlt<0) {
*rec_len = 0;
break; // time out err or parity err
}
//if(j==2) delay_cycle(15000);
}
printk("j=%d\n",j);
printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4],
rec_buf[5],rec_buf[6],rec_buf[7],rec_buf[8],rec_buf[9],
rec_buf[10],rec_buf[11],rec_buf[12],rec_buf[13],rec_buf[14],
rec_buf[15],rec_buf[16],rec_buf[17],rec_buf[18],rec_buf[19]
);
return 0;
*/
rlt = EVOC_rev_one_byte(ptr,REV_TS_TIMEOUT_CYCLE,TS_BIT); //receive TS
if (rlt<0) {
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( *ptr == 0x3b ) {
*card_logic_mode = POSITIVE_LOGIC;
}
else if ( *ptr == 0x3f ){
*card_logic_mode = NEGATIVE_LOGIC;
}
else {
printk("%s: *ptr = %d\n",__file__,ptr[0]);
*rec_len = 0;
return CARD_ERR;
}
//printk("%s: *ptr = %d\n",__file__,ptr[0]);
if ( (++ptr) >= (ptr+ATR_MAX_LEN ) ) {
*rec_len = 0;
return ATR_LEN_ERR;
}
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT); //receive T0
if (rlt<0) {
*rec_len = 0;
return rlt; // time out err or parity err
}
revT0TD = *ptr;
i=0;
j=0;
m=0;
while (i<4)
{
if ((revT0TD>>i)&0x10)
{
if ( (++ptr) >= (ptr+ATR_MAX_LEN ) )
{
*rec_len = 0;
return ATR_LEN_ERR;
}
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT); //receive TA(i),TB(i),TC(i),TD(i)
m++;
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
i++;
/*if((i==2)&&(card_selected==SAMCARD))
{
*(++ptr) = 0;
break;
}*/
if (i==3&&j==0)
{
if (card_selected==SAMCARD)
protect_time_sam = *ptr;
else if(card_selected==USRCARD)
protect_time_usr = *ptr;
else return NO_SELECTED_CARD_ERR;
}
if (i==3&&j==1)
{
TC2_WI = *ptr;
}
if (i==4)
{
TDi_exist=1;
revT0TD = *ptr;
i=0;
j++;
}
}
else i++;
}
/*
printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
m = %d\n",
rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],
rec_buf[4],rec_buf[5],m);
*/
if (rec_buf[1]&0x80)
{ //TD exist
if (revT0TD&0x0f) TCK_exist=1;
else TCK_exist=0;
}
else
{ //TD not exist, T=0, TCK not exist
TCK_exist=0;
}
i=0;
//printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4]);
while ( i<(rec_buf[1]&0x0f) )
{
if ( (++ptr) >= (ptr+ATR_MAX_LEN ) )
{
*rec_len = 0;
return ATR_LEN_ERR;
}
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT); //receive T1,...,TK
if (rlt<0)
{
*rec_len = 0;
/*
printk("i=%d\n",i);
printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4],
rec_buf[5],rec_buf[6],rec_buf[7],rec_buf[8],rec_buf[9],
rec_buf[10],rec_buf[11],rec_buf[12],rec_buf[13],rec_buf[14],
rec_buf[15],rec_buf[16],rec_buf[17],rec_buf[18],rec_buf[19]
);*/
return rlt; // time out err or parity err
}
i++;
}
//printk("%s:line706\n",__file__);
if (TCK_exist)
{
if ( (++ptr) >= (ptr+ATR_MAX_LEN ) )
{
*rec_len = 0;
return ATR_LEN_ERR;
}
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT); //receive TCK
parity_TCK =0;
for (i=1;i<(ptr-rec_buf+1);i++)
{ //xor parity from T0 to TCK
parity_TCK ^= rec_buf[i];
}
if (parity_TCK != 0)
{
*rec_len = 0;
return ATR_XOR_ERR;
}
}
*rec_len = (ptr-rec_buf+1);
return 0;
}
//*******************************************************
//*******************************************************
static int EVOC_iccard_reset( unsigned char * rec_buf,
int * rec_len,
int cardname )
{
if (cardname==SAMCARD)
{
cardname = card_selected;
card_selected = SAMCARD;
samcard_err = iccard_reset(rec_buf,rec_len);
card_selected = cardname;
if (samcard_err<0)
{
EVOC_sam_card_release();
return samcard_err;
}
}
else if(cardname==USRCARD)
{
cardname = card_selected;
card_selected = USRCARD;
usrcard_err = iccard_reset(rec_buf,rec_len);
card_selected = cardname;
if (usrcard_err<0)
{
EVOC_usr_card_release();
return usrcard_err;
}
}
else return NO_SELECTED_CARD_ERR;
return 0;
}
//*******************************************************
//*******************************************************
static int iccard_write ( unsigned char *buff, /* the buffer to fill with data */
int len /* the length of the buffer. */
)
{
int i,retval=0;
unsigned char *txbuf;
txbuf = buff;
for(i=0;i<len;i++){
if (i==(len-1)){
retval= EVOC_send_one_byte(txbuf+i, LAST_BYTE);
if (retval<0) return retval;
}
else{
retval= EVOC_send_one_byte(txbuf+i, NOT_LAST_BYTE);
if (retval<0) return retval;
}
}
return len;
}
static int EVOC_iccard_comm( unsigned char * send_buf,
int send_len,
unsigned char * rec_buf,
int * rec_len)
{
int rlt;
int count;
int ii = 0;
unsigned char tmp[5];
unsigned char *ptr;
unsigned char INS;
unsigned char first=1;
int s3c_adpu_Lc,s3c_adpu_Le;
*rec_len=0;
if (send_len<4) return ADPU_ERR ;
if (send_len==4) {
tmp[0] = * (send_buf);
tmp[1] = * (send_buf+1);
tmp[2] = * (send_buf+2);
tmp[3] = * (send_buf+3);
tmp[4] = 0;
s3c_adpu_Le = tmp[4];
s3c_adpu_Lc = -1;
INS = tmp[1];
ptr = tmp; //CLS
}
else if (send_len==5) {
s3c_adpu_Le = *(send_buf+4);
s3c_adpu_Lc = -1;
INS = * (send_buf+1);
ptr = send_buf; //CLS
}
else{
s3c_adpu_Lc = *(send_buf+4);
if (send_len == s3c_adpu_Lc+5) s3c_adpu_Le = -1;
else if (send_len == s3c_adpu_Lc+5+1) s3c_adpu_Le = *( send_buf+send_len -1);
else
{
return ADPU_ERR;
}
INS = * (send_buf+1);
ptr = send_buf; //CLS
}
if ( ( s3c_adpu_Lc == -1 ) && (s3c_adpu_Le == -1) ) return ADPU_ERR;
if ( ( s3c_adpu_Lc >= 255 ) || (s3c_adpu_Le >= 255) ) return ADPU_ERR;
if ( ( s3c_adpu_Lc == 0 ) ) return ADPU_ERR;
rlt=iccard_write(ptr,5); //发送5字节的命令头
if (rlt<0) return rlt;
ptr = rec_buf; //接受缓冲首地址
if ( s3c_adpu_Lc != -1 ) { //写卡, Lc存在且不为0
while(1){ // receive one byte INS
rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
if (rlt<0) {
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( !(*ptr==0x60) ){ //0x60 等待;
break;
}
}
count = 0;
ptr = send_buf+5; //数据段首址
if ( ( rec_buf[0]==INS )||( rec_buf[0]==(INS^0x01) ) ){
delay_one_etu();
delay_one_etu(); // rev one byte return at 10.5 etu, if change to send data, delay at least 1.5 etu
rlt=iccard_write(ptr,s3c_adpu_Lc); //发送Lc个字节
if (rlt<0) return rlt;
//delay_one_etu();
//delay_one_etu();
ptr = rec_buf; //收的数据
first = 1; //重新等待过程字节
if ( s3c_adpu_Le == 0 ) {
while(1){
rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
if ( rlt==TIMEROUT_ERR)
{
return rlt; // time out exit
}
if ( rlt<0 ) {
*rec_len = 0;
return rlt; // parity err
}
if ( !((*ptr==0x60)&&(first==1)) ){ //0x60 等待;
first=0;
ptr++;
(*rec_len)++;
if ( *rec_len >= 256 ) return 0;
}
}
}
else if ( s3c_adpu_Le == -1 ){ // Le not exist
while(1){
rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
ii++;
if (rlt<0) {
printk("%s\n rece err\n ii = %d\n *ptr = %2x\n rec_len = %d\n",
__file__,ii,*ptr,*rec_len);
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( !((*ptr==0x60)&&(first==1)) ){ //0x60 等待;
first = 0;
ptr++;
(*rec_len)++;
if ( *rec_len >= 2 ) return 0;
}
}
}
else{ // Le exist
while(1){
rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
if (rlt<0) {
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( !((*ptr==0x60)&&(first==1)) ){ //0x60 等待;
first = 0;
ptr++;
(*rec_len)++;
if ( *rec_len >= s3c_adpu_Le+2 ) return 0;
}
}
}
}
else if( ( rec_buf[0]==(INS^0xff) )||( rec_buf[0]==(INS^0xfe) ) ){
repeat:
delay_one_etu();
delay_one_etu(); // rev one byte return at 10.5 etu, if change to send data, delay at least 1.5 etu
rlt=iccard_write(ptr,1); //发送1字节
first = 1; //重新等待过程字节
while(1){
rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
if ( rlt==TIMEROUT_ERR) return rlt; // time out exit
if ( rlt<0 ) {
*rec_len = 0;
return rlt; // parity err
}
if ( !((*ptr==0x60)&&(first==1)) )
{ //0x60 等待;
if((( *ptr==(INS^0xff) )||( *ptr==(INS^0xfe)))&&(count<s3c_adpu_Lc-1))
{
count++;
ptr = send_buf+5+count;
if(count>=s3c_adpu_Lc-1)ptr = rec_buf;
goto repeat;
}
first = 0;
ptr++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -