📄 rc500.c
字号:
{
_nop_();
}
ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
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 <= 63
{
char status = MI_OK;
// char i;
// 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(2);
if (auth_mode == PICC_AUTHENT1B)
e2addr += 12; // key B offset
FlushFIFO(); // empty FIFO
ResetInfo();
//memcpy(MSndBuffer,e2addrbuf,2); // write low and high byte of address
///////////////////////////////////////////////////
MSndBuffer[0] = e2addr & 0xFF;
MSndBuffer[1] = (e2addr >> 8) & 0xFF;
///////////////////////////////////////////////////////
// for(i=0;i<2;i++) MSndBuffer[i]=e2addrbuf[i];
MInfo.nBytesToSend = 2;
// write load command
status=PcdSingleResponseCmd(PCD_LOADKEYE2);
if(status==MI_OK)
{
// execute authentication
status = Mf500PiccAuthState(auth_mode,snr,block);
}
return status;
}
//////////////////////////////////////////////////////////
//注意程序只能读出非密钥存贮区
///////////////////////////////////////////////////////////
char PcdReadE2(unsigned char sector,
unsigned char length,
unsigned char *mdata)
{
unsigned char status = MI_OK;
unsigned short e2addr = 0x30 + sector * 0x18; ///非密钥存贮区地址偏移,30为可读出的起始地址偏移
ResetInfo();
MSndBuffer[0] = e2addr & 0xFF;
MSndBuffer[1] = (e2addr >> 8) & 0xFF;
MSndBuffer[2] = length;
MInfo.nBytesToSend = 3;
status = PcdSingleResponseCmd(PCD_READE2);
if (status == MI_OK)
{
memcpy(mdata,MRcvBuffer,length);
}
else // Response Processing
{
mdata[0] = 0;
}
return status ;
}
//////////////////////////////////////////////////
//////////////////////////////////////////////////
char PcdWriteE2( unsigned int startaddr,
unsigned char length,
unsigned char *mdata)
{
char status = MI_OK;
ResetInfo();
MSndBuffer[0] = startaddr & 0xFF;
MSndBuffer[1] = (startaddr >> 8) & 0xFF;
memcpy(MSndBuffer + 2,mdata,length);
MInfo.nBytesToSend = length + 2;
status = PcdSingleResponseCmd(PCD_WRITEE2); // write e2
return status;
}
///////////////////////////////////////////////////////////////////////
// C O D E K E Y S 将密钥转换成RC500格式
///////////////////////////////////////////////////////////////////////
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;
}
///////////////////////////////////////////////////////////////////////
//认证操作函数
//MCU将运算获得的数据,备存储到卡片上的存储器之前,或MCU希望能读取Mifare 1
//卡片上的数据之前,程序员必须证明他的读/写请求操作是被允许的。
// 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
// auth_mode =0x60 KEYA ,61 KEYB; *snr CARD NOM.;keys key;block
///////////////////////////////////////////////////////////////////////
char Mf500PiccAuthKey( unsigned char auth_mode,
unsigned char *snr,
unsigned char *keys,
unsigned char block)
{
char status = MI_OK;
unsigned char i = 0;
PcdSetTmo(2);
FlushFIFO(); // empty FIFO
ResetInfo();
//memcpy(MSndBuffer,keys,12); // write 12 bytes of the key
for(i=0;i<12;i++) MSndBuffer[i]=keys[i];
// for(i=0;i<12;i++) MSndBuffer[i]=0x0f;
MInfo.nBytesToSend = 12;
// write load command
status=PcdSingleResponseCmd(PCD_LOADKEY);
if (status == MI_OK)
{
// execute authentication
status = Mf500PiccAuthState(auth_mode,snr,block);
}else {
printf("\n the key is lose\n");
}
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
unsigned char status = MI_OK;
unsigned short e2addr = 0x80 + sector * 0x18;
// unsigned short e2addr = 0x30 + sector * 0x18; ///非密钥存贮区地址偏移
unsigned char coded_keys[12];
if (key_type == PICC_AUTHENT1B)
e2addr += 12; // key B offset
status = Mf500HostCodeKey(uncoded_keys,coded_keys);
if(status == 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) & 0xff; // read error flags of the previous
// key load
if(status&0x40){
SendData("key erro is found");
}
if(status&0x20){
SendData("access erro");
}
if (status != MI_OK)
{
SendData("erro have 1");
if (status & 0x40) // key error flag set
status = MI_KEYERR;
else
status = MI_AUTHERR; // generic authentication error
}
else
{
PcdSetTmo(2);
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
for(i=0;i<4;i++) MSndBuffer[i+2]=snr[i];
ResetInfo();
MInfo.nBytesToSend = 6;
status = PcdSingleResponseCmd(PCD_AUTHENT1);
if (status == MI_OK)
{
if (ReadRC(RegSecondaryStatus) & 0x07) // RxLastBits mu?nbsp;leer sein
{
status = MI_BITCOUNTERR;
}
else
{
ResetInfo();
MInfo.nBytesToSend = 0;
if ((status = PcdSingleResponseCmd(PCD_AUTHENT2)) == MI_OK)
{
if ( ReadRC(RegControl) & 0x08 ) // Crypto1 activated
{
status = MI_OK;
}
else
{
status = MI_AUTHERR;
}
}
}
}
}
return status;
}
/****************************************************************************
* *
* Function: mifs_read *
* *
* Input: Adr //块 *
* Output: Data //读出的数据 *
* *
****************************************************************************/
char Mf500PiccRead( unsigned char addr,
unsigned char *mdata)
{
char status = MI_OK;
char tmp = 0;
char i;
FlushFIFO(); // empty FIFO
PcdSetTmo(4); // long timeout 设置定时器的分频值以及定时器重装载值
WriteRC(RegChannelRedundancy,0x0F); // RxCRC, TxCRC, Parity enable
ResetInfo();
MSndBuffer[0] = PICC_READ; // read command code
MSndBuffer[1] = addr;
MInfo.nBytesToSend = 2;
status = PcdSingleResponseCmd(PCD_TRANSCEIVE);
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;
}
}
}
for(i=0;i<16;i++) mdata[i]=0;
}
else // Response Processing
{
if (MInfo.nBytesReceived != 16)
{
status = MI_BYTECOUNTERR;
for(i=0;i<16;i++) mdata[i]=0;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -