ISO14443-4块传输的实现(卡)

来源:互联网 发布:10086网上营业厅软件 编辑:程序博客网 时间:2024/06/05 05:11

原文地址::http://blog.sina.com.cn/s/blog_a20257d80101cju7.html


相关文章

1、

ISO14443-4块传输协议的实现

 ----http://blog.sina.com.cn/s/blog_a20257d80101cju3.html


贴上自己的代码,目前测试通过,但我感觉结构不是很好,希望和大家交流共同提高。

.H文件

#define  ACKN          -1
#define  ACKY          -2
#define  RESEND        -3
#define  ONSENDNEXT    -4
#define  SENDDEL        -5
#define  SENDWTX        -6
#define  DONOTHING        -12

 

#define  BLOCK_MASK       0XC0
#define  IBLOCK           0X00
#define  RBLOCK           0X80
#define  SBLOCK           0XC0
#define  NACK_MASK        0X10
#define  CID_MASK         0X08
#define  BNUM_MASK        0X01
#define  WTX_DEL_MASK     0X30
#define  LINK_MASK        0X10
#define  WTX     0X30
#define  DELSECT          0X00 

 

.c文件

unsigned char near     CCID;

unsigned char near  Frame_Data_Len_Card;
unsigned char  near currentflag;
unsigned char  near lastframe[64];
unsigned char  near lastframelen;

unsigned char  near PBuffer[270],CardBuffer[270];

unsigned short near PBufferLength,PBufferPoint,CardBufPoint,CardBufferLength;
bit cblock_num,CCid_En; 

 

unsigned char AckN(void)
{
  unsigned char near buf[4];
  buf[0] 0XA2|cblock_num;
  buf[0] CCid_En?buf[0]|0x08:buf[0];
  buf[1] CCID;
  WriteCardFifo(buf,2);  
  SetRecvOrSend(START_SEND_AND_RECV);
//  PutDatUart(buf, 2);
  return OK; 
}
unsigned char AckY(void)
{
  unsigned char near buf[4];
  cblock_num=!cblock_num;
  buf[0] 0XA2|cblock_num;
  buf[0] CCid_En?buf[0]|0x08:buf[0];
  buf[1] CCID;  
  WriteCardFifo(buf,(unsigned char)((unsigned char)CCid_En+1));
//  PutDatUart(buf, 2); 
  return SetRecvOrSend(START_SEND_AND_RECV);
}


char CardRecvFrameProcess(unsigned char *tempbuf,unsigned char inlen)
{
   unsigned short near len;
   unsigned char near PCB;
   unsigned char near Cid;
   unsigned char near lastflag currentflag;
   len inlen;
   if(len==0)
   {
      return DONOTHING;
   
   PCB tempbuf[0];
   Cid PCB&CID_MASK;
   if(((CCid_En==1)&&(CCID!=0)&&(Cid==0)) || ((CCid_En==0)&&(Cid==1))) return DONOTHING; 
   if((PCB&BLOCK_MASK) ==IBLOCK)//i-block
   {
     if(PCB&CID_MASK)//带CID时,长度应该不少于2字节
     {
        if(len<=2) return DONOTHING;
     }
     else //不带CID时长度不应少于1个字节
     {
        if(len<2)  return DONOTHING;
           
     if((PCB&0X02)!=0X02) return DONOTHING;
     currentflag PCB LINK_MASK;                                       
     if(currentflag) 
                 
       if(lastflag)
       {
          if((PBufferLength len (unsigned char)CCid_En)>BUFFERLENGTH)
          {
             PBufferLength=0;
             PBufferPoint =0;
             return DONOTHING; 
          }
          memcpy(&PBuffer[PBufferPoint],&tempbuf[1+(unsigned char)CCid_En],len-1-(unsigned char)CCid_En);
          PBufferPoint PBufferPoint len (unsigned char)CCid_En;
          PBufferLength PBufferLength len (unsigned char)CCid_En; 
       }
       else 
       {
          PBufferPoint  0;
          PBufferLength  0;
          memcpy(&PBuffer[PBufferPoint],&tempbuf[1+(unsigned char)CCid_En],len-1-(unsigned char)CCid_En);
          PBufferPoint PBufferPoint len (unsigned char)CCid_En; 
          PBufferLength PBufferLength len (unsigned char)CCid_En;           
        }
        return ACKY;
      }
      else
      {
        if(lastflag) 
        {
          if((PBufferLength len (unsigned char)CCid_En)>BUFFERLENGTH)
          {
            PBufferLength=0;
            PBufferPoint =0;
            return DONOTHING; 
          }
          memcpy(&PBuffer[PBufferPoint],&tempbuf[1+(unsigned char)CCid_En],len-1-(unsigned char)CCid_En);
          PBufferPoint PBufferPoint len (unsigned char)CCid_En; 
          PBufferLength PBufferLength len (unsigned char)CCid_En;          
       }
       else  
       {
         PBufferPoint  0;
         PBufferLength 0;
         memcpy(&PBuffer[PBufferPoint],&tempbuf[1+(unsigned char)CCid_En],len-1-(unsigned char)CCid_En);
         PBufferPoint PBufferPoint len (unsigned char)CCid_En; 
         PBufferLength PBufferLength len (unsigned char)CCid_En;
                             
       return FM_OK;
    }
        
 else if((PCB&BLOCK_MASK) ==RBLOCK) //rblock        
 {
  if(PCB&CID_MASK)//带CID时,长度应该不少于2字节
  {
    if(len!=2) return DONOTHING;
  }
  else //不带CID时长度不应少于1个字节
  {
    if(len!=1)  return DONOTHING;
        
  if((PCB&0X40)==0X00)   return DONOTHING;                                 
  if(PCB&NACK_MASK) 
  {
   if((PCB&BNUM_MASK)!=cblock_num)
   {
    return ACKN;//表示重发NAK,因帧号不对
   }
   else
   {
    return RESEND; //表示重发上一帧
   }
  }
  else  //ack
  {
   if((PCB&BNUM_MASK)!=cblock_num)
           
    return SENDNEXT; //表示继续发下一帧
   }
   else
   {
    return RESEND; //表示重发上一帧
   }
        
    }
 else if((PCB&BLOCK_MASK) ==SBLOCK) //sblock 
 {
   if((PCB&0X04)!=0X00)   return DONOTHING;         
  if((PCB&WTX_DEL_MASK)==DESELECT)     
  {
   if(PCB&CID_MASK)
   {
    if(len!=0x02)         return  DONOTHING;
    else                  return    SENDDEL;
   }
   else
   {
    if(len!=0x01)   return  DONOTHING;
    else                    return  SENDDEL;
         
  }
  else if((PCB&WTX_DEL_MASK)==WTX)  
  {
   if(PCB&CID_MASK)
   {
    if(len!=0x03)         return  DONOTHING;
    else                  return    SENDWTX;
   }
   else
   {
    if(len!=0x02)    return    DONOTHING;
    else                  return  SENDWTX;
   }
  }
  else
  {
   return DONOTHING;
                
 }
 else
 {
    return  DONOTHING;
 
}

char CardCosInsProcess()
{
 Timer0Delay(FIFTY_MINISECOND); //这个时间根据卡返回的ATS中的参数确定,默认为4.8ms,在定时器中断中发WTX,并禁止再次中断,停止定时器
 EnableTimer0Int();
 
 StopTimer0();
 return OK;

 }

char CardSendFrameProcess(char STA)
{
 unsigned char  near  tempbuf[64]; 
 unsigned char  near  len;
 char  near Sta=STA;
 unsigned char near CardMLen Frame_Data_Len_Card-2-(unsigned char)CCid_En -1;
 //WTimeS 0;
 switch(Sta)
 {
  case ACKY:
       AckY();
       break;
  case ACKN:
       AckN();
       break;
  case RESEND:
       memcpy(tempbuf,lastframe,lastframelen);
    WriteCardFifo(tempbuf,lastframelen);
       SetRecvOrSend(START_SEND_AND_RECV);
//     PutDatUart(tempbuf,lastframelen);
       break;
  case ONSENDNEXT:       
       cblock_num !cblock_num;
       wtempfc[0] CCid_En?0X0A:0X02;    
       wtempfc[0]=  CardBufferLength>CardMLen?((tempbuf[0] 0X10) cblock_num):(tempbuf[0] cblock_num);
       wtempfc[1] CCID;
       len  (CardBufferLength>(CardMLen))?CardMLen:CardBufferLength;      
       memcpy(&tempbuf[(unsigned char)CCid_En+1],&CardBuffer[CardBufPoint],len);
       WriteCardFifo(tempbuf,(unsigned char)(len+(unsigned char)CCid_En+1));    
       SetRecvOrSend(START_SEND_AND_RECV);
//     PutDatUart(tempbuf,(unsigned char)(len+((unsigned char)CCid_En)+1));
       CardBufPoint CardBufPoint len;
       CardBufferLength CardBufferLength len;
       break;
  case SENDDEL:
       SDeselect();
       SetCardIdle();
       break;
  case SENDWTX:       
       Timer0Delay(FIFTY_MINISECOND); 

       //这个时间根据卡返回的ATS中的参数确定,默认为4.8ms,在定时器中断中发WTX,并禁止再次中断,停止定时器
       EnableTimer0Int();
       break;
  case GETDATA:
       cblock_num= !cblock_num;       
       tempbuf[0] CCid_En?0X0A:0X02;    
       tempbuf[0] CardBufferLength>CardMLen?((tempbuf[0] 0X10) cblock_num):(tempbuf[0] cblock_num)
       tempbuf[1] CCID;
       CardBufPoint 0;
       len (CardBufferLength>CardMLen)?CardMLen:CardBufferLength;       
       memcpy(&tempbuf[(unsigned char)CCid_En+1],&CardBuffer[CardBufPoint],len+(unsigned char)CCid_En+1);      
    WriteCardFifo(tempbuf,(unsigned char)(len+((unsigned char)CCid_En)+1));
    SetRecvOrSend(START_SEND_AND_RECV);
//    PutDatUart(tempbuf,(unsigned char)(len+((unsigned char)CCid_En)+1));     
    CardBufPoint CardBufPoint len;
    CardBufferLength CardBufferLength len;    
    break;
  case DONOTHING:
  default:break;       
 return OK;
}最后,关于WTX的处理,需要一个定时器,其初值由ATS的内容确定,这里不再叙述


0 0
原创粉丝点击