⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m500auc.c

📁 RC500 MF1 非接触读卡器 开发板 资料
💻 C
📖 第 1 页 / 共 5 页
字号:
//          M I F A R E    A N T I C O L L I S I O N
// for extended serial numbers
///////////////////////////////////////////////////////////////////////
char M500PiccCascAnticoll (unsigned char select_code,
                           unsigned char bcnt,       
                           unsigned char *snr)       
{
   char  status = MI_OK;
   char  snr_in[4];     // copy of the input parameter snr
   char nbytes = 0;
   char  nbits = 0;
   char  complete = 0;
   char  i        = 0;
   char  byteOffset = 0;
   unsigned char  snr_crc;
   unsigned char  snr_check;
   unsigned char dummyShift1;       // dummy byte for snr shift
   unsigned char dummyShift2;       // dummy byte for snr shift   
 
   //************* Initialisation ******************************
   M500PcdSetTmo(106);
   memcpy(snr_in,snr,4);   
   
   WriteIO(RegDecoderControl,0x28); // ZeroAfterColl aktivieren   
   ClearBitMask(RegControl,0x08);    // disable crypto 1 unit
      
   //************** Anticollision Loop ***************************
   complete = 0;
//   bcnt = 0;   // no part of the snr is known
   while (!complete && (status == MI_OK) )
   {
      ResetInfo(MInfo);           
      WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
      nbits = bcnt % 8;   // remaining number of bits
      if (nbits)
      {
         WriteIO(RegBitFraming,nbits << 4 | nbits); // TxLastBits/RxAlign auf nb_bi
         nbytes = bcnt / 8 + 1;   
         // number of bytes known

         // in order to solve an inconsistancy in the anticollision sequence
         // (will be solved soon), the case of 7 bits has to be treated in a
         // separate way - please note the errata sheet
         if (nbits == 7)
         {
            MInfo.cmd = PICC_ANTICOLL1;   // pass command flag to ISR        
            WriteIO(RegBitFraming,nbits); // reset RxAlign to zero
         }
      } 
      else
      {
         nbytes = bcnt / 8;
      }

      MSndBuffer[0] = select_code;
      MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
               
      for (i = 0; i < nbytes; i++)  // Sende Buffer beschreiben
      {
         MSndBuffer[i + 2] = snr_in[i];
      }
      MInfo.nBytesToSend   = 2 + nbytes;   
 
      status = M500PcdCmd(PCD_TRANSCEIVE,
                         MSndBuffer,
                         MRcvBuffer,
                         &MInfo);
   
    
      // in order to solve an inconsistancy in the anticollision sequence
      // (will be solved soon), the case of 7 bits has to be treated in a
      // separate way 
      if (nbits == 7)
      {
         // reorder received bits
         dummyShift1 = 0x00;
         for (i = 0; i < MInfo.nBytesReceived; i++)
         {
            dummyShift2 = MRcvBuffer[i];
            MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[i] << (7-i));
            dummyShift1 = dummyShift2;
         }
         MInfo.nBitsReceived -= MInfo.nBytesReceived; // subtract received parity bits
         // recalculation of collision position
         if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
      }
         
      if ( status == MI_OK || status == MI_COLLERR)    // no other occured
      {
         // R e s p o n s e   P r o c e s s i n g   
         if ( MInfo.nBitsReceived != (40 - bcnt) ) // not 5 bytes answered
         {
            status = MI_BITCOUNTERR; // Exit with error
         } 
         else 
         {
            byteOffset = 0;
            if( nbits != 0 ) // last byte was not complete
            {
                snr_in[nbytes - 1] = snr_in[nbytes - 1] | MRcvBuffer[0];
                byteOffset = 1;
            }

            for ( i =0; i < (4 - nbytes); i++)     
            {
               snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
            }
  
            if (status != MI_COLLERR ) // no error and no collision
            {
               // SerCh check
               snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
               snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
               if (snr_crc != snr_check)
               {
                  status = MI_SERNRERR;
               } 
               else   
               {
                  complete = 1;
               }
            }
            else                   // collision occured
            {
               bcnt = bcnt + MInfo.collPos - nbits;
               status = MI_OK;
            }
         }
      }
   }
   if (status == MI_OK)
   {
      // transfer snr_in to snr
      memcpy(snr,snr_in,4);
   }
   else
   {
      memcpy(snr,"0000",4);
   }

   //----------------------Einstellungen aus Initialisierung ruecksetzen 
   ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
   
   return status;  
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E    S E L E C T 
// for std. select
///////////////////////////////////////////////////////////////////////
char M500PiccSelect(unsigned char *snr, 
                  unsigned char *sak)
{
   return M500PiccCascSelect(0x93,snr,sak); // first cascade level
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E    C A S C A D E D   S E L E C T 
//  for extended serial number
///////////////////////////////////////////////////////////////////////
char M500PiccCascSelect(unsigned char select_code, 
                        unsigned char *snr,
                        unsigned char *sak)
{
   char  status = MI_OK; 
 
   M500PcdSetTmo(3);
	
   WriteIO(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
   ClearBitMask(RegControl,0x08);    // disable crypto 1 unit

   //************* Cmd Sequence ********************************** 
   ResetInfo(MInfo);   
   MSndBuffer[0] = select_code;
   MSndBuffer[1] = 0x70;         // number of bytes send
   
   memcpy(MSndBuffer + 2,snr,4);
   MSndBuffer[6] = MSndBuffer[2] 
                   ^ MSndBuffer[3] 
                   ^ MSndBuffer[4] 
                   ^ MSndBuffer[5];
   MInfo.nBytesToSend   = 7;
   status = M500PcdCmd(PCD_TRANSCEIVE,
                       MSndBuffer,
                       MRcvBuffer,
                       &MInfo);

   *sak = 0;   
   if (status == MI_OK)    // no timeout occured
   {
      if (MInfo.nBitsReceived != 8)    // last byte is not complete
      {
         status = MI_BITCOUNTERR;
      }
      else
      {
	 *sak = MRcvBuffer[0];
         memcpy(MLastSelectedSnr,snr,4);            
      }	
   }
  
   return status;
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E      A U T H E N T I C A T I O N
//   calling compatible version    
///////////////////////////////////////////////////////////////////////
char M500PiccAuth(unsigned char keyAB,       // KEYA or KEYB
               unsigned char *snr,        // 4 bytes card serial number 
               unsigned char key_addr,    // key address in reader storage
               unsigned char block)       // block number which should be 
                                          // authenticated
{
   char   status = MI_OK;
   unsigned char   *  key = 0;
   unsigned char  keycoded[12];
   unsigned char  offset = (keyAB == PICC_AUTHENT1A) ? 0 : 6;   

   key =MKeys[key_addr] + offset;
   M500HostCodeKey(key,keycoded);
   status = M500PiccAuthKey(keyAB,
                            snr,
                            keycoded,  //modi from keycoded
                            block);  
  return status;
}

///////////////////////////////////////////////////////////////////////
//                  A U T H E N T I C A T I O N   

//             W I T H   K E Y S   F R O M   E 2 P R O M
///////////////////////////////////////////////////////////////////////
char M500PiccAuthE2( unsigned char auth_mode,   // KEYA, KEYB
                     unsigned char *snr,        // 4 bytes card serial number
                     unsigned char key_sector,  // key address in reader storage, 
						// 0 <= key_sector <= 15                     
                     unsigned char block)      // block number which should be 
                                               // authenticated
					       // 0 <= block <= 256
{
   char  status = MI_OK;
   // eeprom address calculation
   // 0x80 ... offset
   // key_sector ... sector
   // 0x18 ... 2 * 12 = 24 = 0x18
   unsigned short e2addr = 0x80 + key_sector * 0x18;
   unsigned char *e2addrbuf = (unsigned char*)&e2addr;
   

   if (auth_mode == PICC_AUTHENT1B)
      e2addr += 12; // key B offset   
   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);

   memcpy(MSndBuffer,e2addrbuf,2); // write low and high byte of address
   MSndBuffer[2] = MSndBuffer[0];          // Move the LSB of the 2-bytes
   MSndBuffer[0] = MSndBuffer[1];  // address to the first byte
   MSndBuffer[1] = MSndBuffer[2];
   MInfo.nBytesToSend   = 2;
   M500PcdSetTmo(3);
    // write load command
   if ((status=M500PcdCmd(PCD_LOADKEYE2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
   {      
    //execute authentication
      status = M500PiccAuthState(auth_mode,snr,block);  
   }
   return status;
}                        

///////////////////////////////////////////////////////////////////////
//                      C O D E   K E Y S  
///////////////////////////////////////////////////////////////////////
char M500HostCodeKey(  unsigned char *uncoded, // 6 bytes key value uncoded
                     unsigned char *coded)   // 12 bytes key value coded
{
   char  status = MI_OK;
   unsigned char  cnt = 0;
   unsigned char  ln  = 0;     // low nibble
   unsigned char  hn  = 0;     // high nibble
   
   for (cnt = 0; cnt < 6; cnt++)
   {
      ln = uncoded[cnt] & 0x0F;
      hn = uncoded[cnt] >> 4;
      coded[cnt * 2 + 1] = (~ln << 4) | ln;
      coded[cnt * 2 ] = (~hn << 4) | hn;
   }
   return MI_OK;
}

///////////////////////////////////////////////////////////////////////
//                  A U T H E N T I C A T I O N   
//             W I T H   P R O V I D E D   K E Y S
///////////////////////////////////////////////////////////////////////
char M500PiccAuthKey(  unsigned char auth_mode,
                     unsigned char *snr,       
                     unsigned char *keys,      
                     unsigned char block)      
{
    char  status = MI_OK;
   
   
   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);
   memcpy(MSndBuffer,keys,12);                  // write 12 bytes of the key
   MInfo.nBytesToSend = 12;
   // write load command
   if ((status=M500PcdCmd(PCD_LOADKEY,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
   {      
      		// execute authentication
      status = M500PiccAuthState(auth_mode,snr,block); 
   }
    
   return status;
}

///////////////////////////////////////////////////////////////////////
//        A U T H E N T I C A T I O N   S T A T E S
///////////////////////////////////////////////////////////////////////
char M500PiccAuthState( unsigned char auth_mode,
                        unsigned char *snr,
                        unsigned char block)
{
   unsigned char   status = MI_OK;
   
   WriteIO(RegChannelRedundancy,0x03); // RxCRC disable,TxCRC, Parity enable
   
   status = ReadIO(RegErrorFlag)&0x60;   // read error flags of the previous
                                    // key load
   if (status != MI_OK)
   {
      
	  if (status & 0x40)            // key error flag set
         status = MI_KEYERR,printf("\nkey error");
      else
         status = MI_AUTHERR;      // generic authentication error 
   }
   else
     {
      MSndBuffer[0] = auth_mode;        // write authentication command

      MSndBuffer[1] = block;    // write block number for authentication
      memcpy(MSndBuffer + 2,snr,4); // write 4 bytes card serial number 
      ResetInfo(MInfo);
      MInfo.nBytesToSend = 6;
	  M500PcdSetTmo(3);  
      if ((status = M500PcdCmd(PCD_AUTHENT1,
                               MSndBuffer,
                               MRcvBuffer,
                               &MInfo)) == MI_OK)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -