📄 mfrc500uc.c
字号:
sel_code = cmdASEL + (2 * cascade_level);
cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
//ANTICOLLISION
status = Mf500PiccCascAnticoll(sel_code, 0, &uid[uid_index]);
//SELECT
if (status == MI_OK)
{
status = Mf500PiccCascSelect(sel_code, &uid[uid_index], sak);
if (status == MI_OK)
{
cascade_level++;
//we differ cascaded and uncascaded UIDs
if (*sak & 0x04) // if cascaded, bit 2 is set in answer to select
{
//this UID is cascaded, remove the cascaded tag that is
//0x88 as first of the 4 byte received
memmove(&uid[uid_index], &uid[uid_index + 1], 3);
uid_index += 3;
*uid_len += 3;
}
else
{
//this UID is not cascaded -> the length is 4 bytes
uid_index += 4;
*uid_len += 4;
}
}
}
}
while((status == MI_OK) // error status
&& (*sak & 0x04) // no further cascade level
&& (cascade_level < 3)); // highest cascade level is reached
}
if (status == MI_OK)
{
//Exit function, if cascade level is triple and sak indicates another
//cascase level.
if ((cascade_level == 3) && (*sak & 0x04))
{
*uid_len = 0;
status = MI_SERNRERR;
}
}
return (status);
}
///////////////////////////////////////////////////////////////////////
// M I F A R E P I C C A C T I V A T I O N S E Q E N C E
///////////////////////////////////////////////////////////////////////
char Mf500PiccActivateWakeup(unsigned char br,
unsigned char *atq,
unsigned char *sak,
unsigned char *uid,
unsigned char uid_len)
{
unsigned char cascade_level;
unsigned char uid_index;
unsigned char tmpuid[4];
unsigned char sel_code;
unsigned char cmdASEL;
signed char status;
//call activation with def. divs
status = Mf500PcdSetDefaultAttrib();
if (status == MI_OK)
{
status = Mf500PiccCommonRequest(PICC_REQIDL,atq);
}
if (status == MI_OK)
{
if ((atq[0] & 0x1F) == 0x00) // check lower 5 bits, for tag-type
// all tags within this 5 bits have to
// provide a bitwise anticollision
{
status = MI_NOBITWISEANTICOLL;
}
}
if (status == MI_OK)
{
//Get UID in 1 - 3 levels (standard, [double], [triple] )
//-------
switch(br)
{
case 0: cmdASEL = PICC_ANTICOLL1; break;
default:
status = MI_BAUDRATE_NOT_SUPPORTED; break;
}
}
if (status == MI_OK)
{
//Select UID in up to 3 cascade levels (standard, [double], [triple] )
//------------------------------------
cascade_level = 0;
uid_index = 0;
tmpuid[0] = 0x88; //first byte of cascaded UIDs is 0x88 (cascaded tag)
do
{
sel_code = cmdASEL + (2 * cascade_level);
cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
//get the next UID part if we need to cascade
if((uid_len - uid_index) > 4)
{
//ok, we need to cascade the UID
memcpy(&tmpuid[1], &uid[uid_index], 3);
uid_index += 3;
}
else
{
//ah, how nice. no need to cascade
memcpy(tmpuid, &uid[uid_index], 4);
uid_index += 4;
}
status = Mf500PiccCascSelect(sel_code, tmpuid, sak);
if(status == MI_OK)
{
cascade_level++;
}
}
while((status == MI_OK ) // error occured
&& (*sak & 0x04) // no further cascade level
&& ((uid_index + 1) < uid_len) // all bytes of snr sent
&& (cascade_level < 3)); // highest cascade level reached
}
if ( status == MI_OK)
{
//Exit function, if UID length is not of expected length
if ((uid_index) != uid_len)
{
status = MI_SERNRERR ;
}
}
if (status == MI_OK)
{
//Exit function, if cascade level is triple and sak indicates another
//cascase level.
if ((cascade_level == 3) && (*sak & 0x04))
{
status = MI_SERNRERR;
}
}
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 Mf500PiccAuth(unsigned char key_type, // PICC_AUTHENT1A or PICC_AUTHENT1B
unsigned char key_addr, // key address in reader storage
unsigned char block) // block number which should be
// authenticated
{
char status = MI_OK;
status = Mf500PiccAuthE2( key_type,
MLastSelectedSnr,
key_addr,
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 Mf500PiccAuthE2( unsigned char auth_mode, // PICC_AUTHENT1A or PICC_AUTHENT1B
unsigned char *snr, // 4 bytes card serial number
unsigned char key_sector, // 0 <= key_sector <= 15
unsigned char block) // 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;
PcdSetTmo(106);
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
MInfo.nBytesToSend = 2;
// write load command
if ((status=PcdSingleResponseCmd(PCD_LOADKEYE2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
{
// execute authentication
status = Mf500PiccAuthState(auth_mode,snr,block);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// C O D E K E Y S
///////////////////////////////////////////////////////////////////////
char Mf500HostCodeKey( 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 Mf500PiccAuthKey( unsigned char auth_mode,
unsigned char *snr,
unsigned char *keys,
unsigned char block)
{
char status = MI_OK;
unsigned char i = 0;
PcdSetTmo(106);
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
memcpy(MSndBuffer,keys,12); // write 12 bytes of the key
MInfo.nBytesToSend = 12;
// write load command
if ((status=PcdSingleResponseCmd(PCD_LOADKEY,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
{
// execute authentication
status = Mf500PiccAuthState(auth_mode,snr,block);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// S T O R E K E Y S I N E E P R O M
///////////////////////////////////////////////////////////////////////
char Mf500PcdLoadKeyE2(unsigned char key_type,
unsigned char sector,
unsigned char *uncoded_keys)
{
// eeprom address calculation
// 0x80 ... offset
// key_sector ... sector
// 0x18 ... 2 * 12 = 24 = 0x18
signed char status = MI_OK;
unsigned short e2addr = 0x80 + sector * 0x18;
unsigned char coded_keys[12];
if (key_type == PICC_AUTHENT1B)
e2addr += 12; // key B offset
if ((status = Mf500HostCodeKey(uncoded_keys,coded_keys)) == MI_OK)
status = PcdWriteE2( e2addr,12,coded_keys);
return status;
}
///////////////////////////////////////////////////////////////////////
// A U T H E N T I C A T I O N S T A T E S
///////////////////////////////////////////////////////////////////////
char Mf500PiccAuthState( unsigned char auth_mode,
unsigned char *snr,
unsigned char block)
{
char status = MI_OK;
unsigned char i = 0;
status = ReadRC(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
{
PcdSetTmo(106);
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 = PcdSingleResponseCmd(PCD_AUTHENT1,
MSndBuffer,
MRcvBuffer,
&MInfo)) == MI_OK)
{
if (ReadRC(RegSecondaryStatus) & 0x07) // RxLastBits mu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -