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

📄 mifare.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
/******************************* (C) Embest ***********************************
* File Name          : mifare.c
* Author             : tary
* Date               : 2009-02-26
* Version            : 0.3
* Description        : MIFARE control functions 
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "mifare.h"

#define LOCAL_DBG		(MIFARE_DBG)
#define F_MIFARE_TST		(1)

static char card_uid[8];	//保存的卡物理ID
static char key_buf[16];	//用于读写操作的key缓冲,12字节格式
static char key_old[16];	//用于mifare_key2()快速恢复key值


static int mifare_req(void) {
	int r;

	//检测卡时将卡置为IDLE(HALT)状态
	if ((r = fm1702_mif_halt()) != FM1702_OK) {
		//DBG_LINE(2, " halt", r);
		return r;
	}

#if MIFARE_DETECT_WAIT
	if (1) {
		int us_wait = 0;
		unsigned long tmr;

		sys_timeout(&tmr, 0);
		while (! sys_timeout(&tmr, FM1702_DETECT_TOUT)) {
			if ((r = fm1702_mif_req(1)) == FM1702_OK) {
				break;
			}
			sleep_us(us_wait++);
		}

		if (r != FM1702_OK) {
			//DBG_LINE(2, " req", r);
			return r;
		}
	} else
#endif
	{
		sleep_us(FM1702_HALT2REQ_T);

		if ((r = fm1702_mif_req(1)) != FM1702_OK) {
			//DBG_LINE(2, " req", r);
			return r;
		}
	}
	return r;
}

//检则天线范围内是否存在MIFARE卡
//wait_req	为0时为检测卡片,其它值表示读写数据等
int mifare_detect(int wait_req) {
	int r;

	if ((r = mifare_req()) == FM1702_OK) {
		return r;
	}
	// 10us用于关闭电磁波的发射, 不能太短(如,只有1us)
	// 2009-01-13
	fm1702_mif_no_energy(10);
	return mifare_req();
}

// 获取卡片UID
int mifare_id(char* uid) {
	int r;

	if ((r = mifare_detect(1)) != FM1702_OK) {
		DBG_LINE(2, " detect", r);
		return r;
	}

	if ((r = fm1702_mif_anticol(card_uid)) != FM1702_OK) {
		DBG_LINE(2, " anticol", r);
		memset(card_uid, '\0', 5);
		return r;
	}

	if ((r = fm1702_mif_sel(card_uid)) != FM1702_OK) {
		DBG_LINE(2, " sel", r);
		memset(card_uid, '\0', 5);
		return r;
	}

	if (uid != NULL) {
		memcpy(uid, card_uid, 5);
	}
	return r;
}

// 激活MIFARE卡命令,应用程序接口
int mifare_active(int mif_blk) {
	char uid[8];
	int r;

	if ((r = mifare_id(uid)) != FM1702_OK) {
		DBG_LINE(2, " id", r);
		return r;
	}

	//fm1702_mif_key_e2p(mif_blk >> 2);
	if ((r = fm1702_mif_key(mif_blk >> 2, key_buf)) != FM1702_OK) {
		DBG_LINE(2, " key", r);
		return r;
	}

	if ((r = fm1702_mif_auth(card_uid, mif_blk)) != FM1702_OK) {
		DBG_BUF("mifare_active(): key_buf", key_buf, 12);
		DBG_LINE(2, " auth", r);
		return r;
	}
		DBG_LINE(2, " ok", r);
	return FM1702_OK;
}

//MIF读块命令,应用程序接口
//key		不为NULL时, 则先加载key值(6字节格式)
//return	>= 0	读取的字节数
//		<0	错误码
int mifare_read(int mif_blk, char* buf, char* key) {
	int rlen;
	//static 
	int l_sec = -1;

	if (key != NULL) {
		mifare_key(mif_blk >> 2, key);
	}

	if (l_sec != (mif_blk >> 2)) {
		l_sec = (mif_blk >> 2);
		rlen = mifare_active(mif_blk);
		if (rlen < 0) {
			DBG_LINE(2, " active err", rlen);
			return rlen;
		}
	}
	//DBG_LINE(1, " active ok");
	return fm1702_mif_read(mif_blk, buf);
}

//MIF写块命令,应用程序接口
//key		不为NULL时, 则先加载key值(6字节格式)
//return	FM1702_OK	成功
//		<0		错误码
int mifare_write(int mif_blk, char* buf, char* key) {
	int rlen;
	//static 
	int l_sec = -1;

	if (key != NULL) {
		mifare_key(mif_blk >> 2, key);
	}
	
	if (l_sec != (mif_blk >> 2)) {
		l_sec = (mif_blk >> 2);
		rlen = mifare_active(mif_blk);
		if (rlen != FM1702_OK) {
			DBG_LINE(2, " active err", rlen);
			return rlen;
		}
	}
	//DBG_LINE(1, " active ok");
	return fm1702_mif_write(mif_blk, buf);
}

//由EEPROM读key到key_buf
int get_keybuf_e2p(void) {
	int rlen;
	char kbuf[0x10];
	
	rlen = fm1702_read_e2p(0x30, kbuf, 12);
	if (rlen < 0) {
		return FM1702_ERR_E2P;
	}
	memcpy(key_buf, kbuf, rlen);
	debug_buf(__FUNCTION__, kbuf, rlen);
	return FM1702_OK;
}

//写keybuf到EEPROM
int set_keybuf_e2p(void) {
	char kbuf[0x10];

	debug_buf(__FUNCTION__, key_buf, 12);
	if (FM1702_OK != fm1702_write_e2p(0x30, key_buf, 12)) {
		DBG_LINE(1, " write");
		return FM1702_ERR_E2P;
	}
	memcpy(kbuf, key_buf, 12);
	if (fm1702_read_e2p(0x30, kbuf, 12) < 0) {
		DBG_LINE(1, " read");
		return FM1702_ERR_E2P;
	}
	if (memcmp(kbuf, key_buf, 12) != 0) {
		DBG_LINE(1, " cmp");
		return FM1702_ERR_E2P;
	}
	return FM1702_OK;
}

//加载key[6]到key_buf, 用于mifare_active时载入FM1702的KEY BUFFER
int mifare_key(int mif_sec, char* key) {
	int i;
	char kbuf[0x10];
	unsigned char ch_l, ch_h;

#if 1
	for (i = 0; i < 6; i++) {
		ch_h = key[i] & 0xF0;
		ch_l = (key[i] & 0x0F);
		kbuf[2*i + 0] = (~ch_h & 0xF0) | (ch_h >> 4);
		kbuf[2*i + 1] = ch_l | (~ch_l << 4);
	}
#else
	memcpy(key_buf, key, 6);
#endif
	memcpy(key_old, key_buf, 12);
	memcpy(key_buf, kbuf, 12);
	//return set_keybuf_e2p();

	DBG_BUF("mifare_key(): key_buf", key_buf, 12);
	return FM1702_OK;
	//写key指向的KEY到EEPROM,
	//0x80开始是密钥存放区
	//并按12字节每MIFARE扇区连续存放
	//fm1702_write_e2p(mif_sec * 12 + 0x80, kbuf, 12);
}

//恢复上一次调用mifare_key的key值
int mifare_key2(void) {
	memcpy(key_buf, key_old, 12);
	return 0;
}

//FM1702 EEPROM 0地址开始16字节为厂商信息
int get_fm1702_info(char* buf, int len) {
	int rlen;

	rlen = fm1702_read_e2p(0x00, buf, len);
	if (rlen > 0)
		return rlen;
	return FM1702_ERR_E2P;
}




/////////////////////////////////////TEST CODE//////////////////////////////////

#if F_MIFARE_TST

// 测试RFID或1702内EEPROM
#define F_TEST_RFID		1
// 是否测试写操作
#define F_TEST_WR		0

char key_a[] = {
#if 1
// 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A
 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
#else
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 
#endif
};

char key_b[] = {
#if 1
 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
#else
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 
#endif
};


int mifare_dbg(void) {
	extern char key_a[];
#if F_TEST_WR
	int j;
	char data[20] = 
	  {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
	  0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE };
#endif
	char readbuf[20];
	int rlen;
	int i;
	int mif_blk
#if F_TEST_RFID
	 = 0x01;
#else
	 = 0x30;
#endif

#if 0
		
	printf("\r\nblock #?");
	ascanf("%d", &mif_blk);
#endif


#if F_TEST_RFID
	mifare_key(mif_blk >> 2, key_a);

	if ((rlen = mifare_active(mif_blk)) == FM1702_OK) {
		printf("\r\nCard Active: OK");
	} else {
		printf("\r\nCard Active: ERR %d", rlen);
	}
#endif
	i = 0;
	while (1) {
		mif_blk++;
#if F_TEST_RFID
		if (mif_blk % 4 == 3) {
			mif_blk++;
		}
		if (mif_blk >= 64) mif_blk = 0;

		while (mifare_id(NULL) != FM1702_OK) {
			printf("\r\nNO CARD");
			sleep(500);
		}
#else
		if (mif_blk + 0x10 >= 0x80) mif_blk = 0x30;
#endif
		printf("\r\n************* blk = %d *************", mif_blk);
#if F_TEST_WR
		for (j = 0; j < 16; j++)
			data[j] = j + mif_blk + i;
		debug_buf("DATA", data, 0x10);

		// sample time 5.3ms
		if ((rlen = 
#if F_TEST_RFID
		mifare_write(mif_blk, data, key_a)
#else
		fm1702_write_e2p(mif_blk, data, 0x10)
#endif
		) == FM1702_OK) {
			printf("\r\nCard Write: OK");
		} else {
			printf("\r\nCard Write: ERR %d", rlen);
		}
#endif
		sleep(100);
		memset(readbuf, '\xFF', 20);

		// sample time 2.5ms
		if ((rlen = 
#if F_TEST_RFID
		  mifare_read(mif_blk, readbuf, key_a)

#else
		  fm1702_read_e2p(mif_blk, readbuf, 0x10)
#endif
		) >= 0) {
			//printf("\r\nCard Read: OK");
			debug_buf("DATA", readbuf, rlen);
		} else {
			printf("\r\nCard Read: ERR %d", rlen);
		}

#if F_TEST_WR
		if (memcmp(readbuf, data, 0x10) != 0) {
			printf("\r\nWrite Err");
		}
#endif
		//sleep(1000);
		if (i++ % 10 == 0) {
			printf("\r\n%d", i);
			printf(" times %d ms", sys_elapse_time());
		}
	}
	//return 0;
}

#else
int mifare_dbg(void) {
	return 0;
}

#endif

/************************************END OF FILE******************************/

⌨️ 快捷键说明

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