📄 m500auc.c
字号:
}
}
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(tByte *snr,
tByte *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(tByte select_code,
tByte *snr,
tByte *sak)
{
char idata status = MI_OK;
M500PcdSetTmo(106);
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(tByte keyAB, // KEYA or KEYB
tByte *snr, // 4 bytes card serial number
tByte key_addr, // key address in reader storage
tByte block) // block number which should be
// authenticated
{
char idata status = MI_OK;
tByte xdata * key = 0;
tByte idata keycoded[12];
tByte idata offset = (keyAB == PICC_AUTHENT1A) ? 0 : 6;
key = MKeys[key_addr] + offset;
M500HostCodeKey(key,keycoded);
status = M500PiccAuthKey(keyAB,
snr,
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( tByte auth_mode, // KEYA, KEYB
tByte *snr, // 4 bytes card serial number
tByte key_sector, // key address in reader storage,
// 0 <= key_sector <= 15
tByte block) // block number which should be
// authenticated
// 0 <= block <= 256
{
char idata status = MI_OK;
// eeprom address calculation
// 0x80 ... offset
// key_sector ... sector
// 0x18 ... 2 * 12 = 24 = 0x18
unsigned short e2addr = 0x80 + key_sector * 0x18;
tByte *e2addrbuf = (tByte*)&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;
// 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( tByte *uncoded, // 6 bytes key value uncoded
tByte *coded) // 12 bytes key value coded
{
char idata status = MI_OK;
tByte idata cnt = 0;
tByte idata ln = 0; // low nibble
tByte idata 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( tByte auth_mode,
tByte *snr,
tByte *keys,
tByte block)
{
char idata status = MI_OK;
tByte idata i = 0;
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( tByte auth_mode,
tByte *snr,
tByte block)
{
char idata status = MI_OK;
tByte idata i = 0;
status = ReadIO(RegErrorFlag); // read error flags of the previous
// key load
if (status != MI_OK)
{
if (status & 0x40) // key error flag set
status = MI_KEYERR;
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;
if ((status = M500PcdCmd(PCD_AUTHENT1,
MSndBuffer,
MRcvBuffer,
&MInfo)) == MI_OK)
{
if (ReadIO(RegSecondaryStatus) & 0x07) // Check RxLastBits for error
{
status = MI_BITCOUNTERR;
}
else
{
ResetInfo(MInfo);
MInfo.nBytesToSend = 0;
if ((status = M500PcdCmd(PCD_AUTHENT2,
MSndBuffer,
MRcvBuffer,
&MInfo)) == MI_OK)
{
if ( ReadIO(RegControl) & 0x08 ) // Crypto1 activated
{
status = MI_OK;
}
else
{
status = MI_AUTHERR;
}
}
}
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E A D
///////////////////////////////////////////////////////////////////////
char M500PiccRead( tByte addr,
tByte *_data)
{
char idata status = MI_OK;
char idata tmp = 0;
FlushFIFO(); // empty FIFO
M500PcdSetTmo(3); // long timeout
WriteIO(RegChannelRedundancy,0x0F); // RxCRC, TxCRC, Parity enable
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = PICC_READ; // read command code
MSndBuffer[1] = addr;
MInfo.nBytesToSend = 2;
status = M500PcdCmd(PCD_TRANSCEIVE,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (status != MI_OK)
{
if (status != MI_NOTAGERR ) // no timeout occured
{
if (MInfo.nBitsReceived == 4) // NACK
{
MRcvBuffer[0] &= 0x0f; // mask out upper nibble
if ((MRcvBuffer[0] & 0x0a) == 0)
{
status = MI_NOTAUTHERR;
}
else
{
status = MI_CODEERR;
}
}
}
memcpy(_data,"0000000000000000",16); // in case of an error initialise
// data
}
else // Response Processing
{
// printf("status == MI_OK Response Processing\r\n");
if (MInfo.nBytesReceived != 16)
{
status = MI_BYTECOUNTERR;
memcpy(_data,"0000000000000000",16);
}
else
{
memcpy(_data,MRcvBuffer,16);
}
}
M500PcdSetTmo(1); // short timeout
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E W R I T E
///////////////////////////////////////////////////////////////////////
char M500PiccWrite( tByte addr,
tByte *_data)
{
char idata status = MI_OK;
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = PICC_WRITE; // Write command code
MSndBuffer[1] = addr;
MInfo.nBytesToSend = 2;
WriteIO(RegChannelRedundancy,0x07);
status = M500PcdCmd(PCD_TRANSCEIVE,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (status != MI_NOTAGERR) // no timeout error
{
if (MInfo.nBitsReceived != 4) // 4 bits are necessary
{
status = MI_BITCOUNTERR;
}
else // 4 bit received
{
MRcvBuffer[0] &= 0x0f; // mask out upper nibble
if ((MRcvBuffer[0] & 0x0a) == 0)
{
status = MI_NOTAUTHERR;
}
else
{
if (MRcvBuffer[0] == 0x0a)
{
status = MI_OK;
}
else
{
status = MI_CODEERR;
}
}
}
}
if ( status == MI_OK)
{
M500PcdSetTmo(3); // long timeout
ResetInfo(MInfo);
memcpy(MSndBuffer,_data,16);
MInfo.nBytesToSend = 16;
status = M500PcdCmd(PCD_TRANSCEIVE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -