ISO14443-4块传输协议的实现

ISO1444-3块传输协议主要用于应用数据的传输,其实现如下:

unsigned char Apdu(unsigned char *comm,unsigned short  len,unsigned char *resp,unsigned short  *rlen)
{
  unsigned char   IPCB;
  unsigned ;
  unsigned char   OPCB;
  unsigned ];
  unsigned ];
  unsigned short  outlen;
  unsigned short  inlen;
  unsigned char   temp;
  unsigned ,OutOffSet=;
  unsigned ;
  unsigned short  stemplen=len;
  unsigned char   RfMlen;
  unsigned ;
  unsigned ;
  *rlen =;
  RfMlen= Frame_Data_Len_Rf--(unsigned char)RCid_En;
  )
  {
    )
    {
        OPCB = RCid_En?0X0A:0x02;
        OPCB =(stemplen>RfMlen)?(OPCB|0X10):OPCB;
        OPCB = OPCB|rblock_num;
        otempbuf[] = OPCB;
        otempbuf[] = RCID;
        xtemplen = (stemplen>=RfMlen)?RfMlen:stemplen;
        memcpy(&otempbuf[(unsigned ],&comm[OutOffSet],xtemplen);
        outlen = xtemplen +  + (unsigned char)RCid_En;
    }
//    PutDatUart(otempbuf,outlen);
    temp =  I_Block(otempbuf,(unsigned char)outlen,itempbuf,&inlen);
//    PutDatUart(itempbuf,inlen);
    )
    {
        tcount++;
        )
        {
             *rlen = ;
             return temp;
        }
        otempbuf[] =RCid_En?(0XBA|rblock_num):(0XB2|rblock_num);
        otempbuf[] = RCID;
        outlen = +(unsigned char)RCid_En;
        Flag = ;
    }
    else
    {
       tcount = ;
       IPCB=itempbuf[];
       if((IPCB&0XC2)==0X02)  //i-block
       {
            if((IPCB&0x01)==rblock_num)
            {
               rblock_num=!rblock_num;
               )
               {
                   templen = inlen--(unsigned char)RCid_En;
                   memcpy(&resp[InOffSet],&itempbuf[(unsigned ],templen);
                   InOffSet = InOffSet + templen;
                   *rlen = InOffSet;
                   return RF_OK;
                }
                else
                {
                     templen = inlen--(unsigned char)RCid_En;
                     memcpy(&resp[InOffSet], &itempbuf[(unsigned ],templen);
                     InOffSet = InOffSet + templen;
                     //ACK
                     otempbuf[] =0XA2|rblock_num;
                     otempbuf[] =RCid_En?(otempbuf[]|];
                     otempbuf[] =RCID;
                     outlen =  + (unsigned char)RCid_En;
                     Flag = ;
                 }
           }
      }
      else if((IPCB&0XF2)==0XF2) //WTX
      {
            outlen = inlen;
            memcpy(otempbuf,itempbuf,inlen);
            Flag = ;
      }
      else if((IPCB&0XB2)==0XA2)// ack
      {
         if((IPCB&0x01)==rblock_num) //next frame
         {
             rblock_num = !rblock_num;
             OutOffSet = OutOffSet+xtemplen;
             stemplen  = stemplen -xtemplen;
         }
         Flag = ;
      }
      else
      {
            tcount++;
            ) return FM_OVERTIME;
            if((IPCB&0X10)==0X00)
            {
                 otempbuf[] =0XB2|rblock_num;
            }
            else
            {
              otempbuf[] =0XA2|rblock_num;
            }
            otempbuf[] = RCid_En?(otempbuf[]|];
            otempbuf[] = RCID;
            outlen =  + (unsigned char)RCid_En;
            Flag = ;
       }
     }
  }
}
unsigned char I_Block(unsigned char *comm,unsigned char len,unsigned char *resp,unsigned short *rlen)
{
 unsigned char  temp, old_TimerReload;
 unsigned int  xtemp1;
 old_TimerReload=TimerReload;
 ]&0xf7)==0xf2)
 {
      temp=(comm[]&]:comm[];
       && temp<)
      {
           xtemp1=TimerReload*temp;
           )
           {
                TimerReload=;
           }else
           {
                while(TimerReload!=(unsigned char)xtemp1)
                TimerReload=(unsigned char)xtemp1;
           }
           while(TimerReload!=(unsigned char)xtemp1);
      }
 }
 temp = CmdSend(len, comm, Transceive);
 TimerReload=old_TimerReload;
 if (temp == FALSE)
 {
      return OVERTIME;
 }
 temp = ErrorFlag;
 if ((temp & 0x02) == 0x02)
  return PARITYERR;
 if((temp & 0x04) == 0x04)
  return FRAMINGERR;
 if ((temp & 0x08) == 0x08)
  return CRCERR;
 *rlen=Read_FIFO(resp);
 return OK;
}

unsigned char CmdSend(unsigned char count,unsigned char * buff,unsigned char Comm_Set)
{
 unsigned char  temp;
 unsigned char   ctemp1;
 unsigned long   cj;
 unsigned short  near atime1,atime2;
 Command = Idle_Command;
 Clear_FIFO();
 Int_Req=0x7f;
 )
 {
      Write_FIFO(count, buff);
  }
 ; cj< RF_Time2; cj++) //延时500ms
 {
     ) break;
 }
 ))
 return HARDWARE_ERR;
 Command = Comm_Set;     //命令执行
 ; cj< TIMEDELAY; cj++)    //至少延时5s
 {
      temp = Command;
      ctemp1 = Int_Req;
      if(temp == 0x00   || (ctemp1 & 0x0C))   return TRUE;
      else if((ctemp1&0x20)==0x20)            return FALSE;
  }
  return FALSE;
}

实现本功能需要注意到是rblock_num属于全局变量,在RATS中被初始化为0

Frame_Data_Len_Rf在RATS中被初始化为最大帧长度

RCid_En根据RATS中的参数确定为支持CID或者不支持CID

上一篇:text-decoration


下一篇:剑指Offer:树的子结构【26】