📄 iccard.b.c
字号:
//EVOC_select_usr();
}
else return NO_SELECTED_CARD_ERR;
count=0;
while ( CARD_RX )
{
count++;
if (count>=timeout) return TIMEROUT_ERR;
}
delay_half_etu(); //0.5etu
for( i=0;i<8;i++)
{ // receive 8 bits data
delay_one_etu(); //1.5etu - 8.5etu
if ( card_logic_mode == POSITIVE_LOGIC )
{
if ( CARD_RX )
*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
return 0;
}
}
else
{
parity_bit = 0;
if (rev_TS==TS_BIT){
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:
//parity err
delay_one_etu(); //10.5 etu
CARD_TX_CLR;
delay_one_etu(); //11.5 etu
delay_half_etu(); //12 etu
CARD_TX_SET;
delay_half_etu(); //12.5 etu
re_rev_times++;
}
return PARITY1_ERR;
}
//*******************************************************
//*******************************************************
static int iccard_reset( unsigned char * rec_buf,
int * rec_len)
{
int rlt,i,j;
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(1000);
EVOC_sam_set_card_rst();
delay_1200_cycle();
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(1000);
EVOC_usr_set_card_rst();
delay_1200_cycle();
EVOC_usr_clr_card_rst();
}
else return NO_SELECTED_CARD_ERR;
ptr = rec_buf;
*card_logic_mode = POSITIVE_LOGIC;
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 = %s\n",ptr);
*rec_len = 0;
return CARD_ERR;
}
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;
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)
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
i++;
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++;
}
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;
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;
return rlt; // time out err or parity err
}
i++;
}
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;
unsigned char tmp[5];
unsigned char *ptr;
unsigned char INS;
unsigned char first=1;
int evoc_adpu_Lc,evoc_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;
evoc_adpu_Le = tmp[4];
evoc_adpu_Lc = -1;
INS = tmp[1];
ptr = tmp; //CLS
}
else if (send_len==5)
{
evoc_adpu_Le = *(send_buf+4);
evoc_adpu_Lc = -1;
INS = * (send_buf+1);
ptr = send_buf; //CLS
}
else{
evoc_adpu_Lc = *(send_buf+4);
if (send_len == evoc_adpu_Lc+5) evoc_adpu_Le = -1;
else if (send_len == evoc_adpu_Lc+5+1) evoc_adpu_Le = *( send_buf+send_len );
else return ADPU_ERR;
INS = * (send_buf+1);
ptr = send_buf; //CLS
}
if ( ( evoc_adpu_Lc == -1 ) && (evoc_adpu_Le == -1) ) return ADPU_ERR;
if ( ( evoc_adpu_Lc >= 255 ) || (evoc_adpu_Le >= 255) ) return ADPU_ERR;
if ( ( evoc_adpu_Lc == 0 ) ) return ADPU_ERR;
rlt=iccard_write(ptr,5); //发送5字节的命令头
if (rlt<0) return rlt;
ptr = rec_buf; //接受缓冲首地址
if ( evoc_adpu_Lc != -1 )
{ //写卡, Lc存在且不为0
while(1)
{ // receive one byte INS
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( !(*ptr==0x60) )
{ //0x60 等待;
break;
}
}
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,evoc_adpu_Lc); //发送Lc个字节
if (rlt<0) return rlt;
ptr = rec_buf; //收的数据
first = 1; //重新等待过程字节
if ( evoc_adpu_Le == 0 )
{
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_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 ( evoc_adpu_Le == -1 )
{ // Le not exist
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_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 >= 2 ) return 0;
}
}
}
else
{ // Le exist
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_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 >= evoc_adpu_Le+2 ) return 0;
}
}
}
}
else if( ( rec_buf[0]==(INS^0xff) )||( rec_buf[0]==(INS^0xfe) ) )
{
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,TIMEOUT_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
{ // Sw1+ SW2, 收SW2
ptr++; //留下上一个收到的字节,是SW1
(*rec_len)++;
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
ptr++;
(*rec_len)++;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -