因为偶然的关系需要用到NFC来hack某些东西,这里用到的是DFROBOT的NFC模块,用的是串口通信的方法。
NFC近场通信(Near Field Communication,NFC),又称近距离无线通信,是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据传输(在十厘米内)交换数据。这个技术由免接触式射频识别(RFID)演变而来,并向下兼容RFID,最早由Sony和Philips各自开发成功,主要用于手机等手持设备中提供M2M(Machine to Machine)的通信。由于近场通讯具有天然的安全性,因此,NFC技术被认为在手机支付等领域具有很大的应用前景。
PN532是NXP最近推出的一款NFC芯片,支持读卡器模式和卡模式(需要卡芯片Smart MX),支持TypeA、TypeB、TypeC三个标准,内部带一个MCU51,支持命令方式,可以直接跟PC机串口连接就成为一个RFID读卡器,简单方便,成本低,性能好,是RFID发展的一个趋势。
读卡器通过串口和电脑连接,上位机可以使用libnfc,libnfc是一个开源的软件,功能特别强大,实现了很多nfc的功能。(详情见:Arduino NFC实验,Arduino读取RFID信息)
The NFC Module for Arduino is designed to extend this powerful feature for your project or application based on Arduino.It integrates a PN532 NFC controller from Philips.The driver interface for this product is UART interface of the microcontroller. So it's possible for you to test it via a USB to UART converter directly. On the other hand, for the applications with microcontroller, the module provides an event for your processor when detects the NFC tags, stickers, key fobs, or cards via high speed serial uart.
简介可以看这个http://www.dfrobot.com/wiki/index.php/NFC_Module_for_Arduino_(SKU:DFR0231)
用的是串口通信的方式。
示例代码如下,可以读取UID
const unsigned char wake[24]={
0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00};//wake up NFC module
const unsigned char firmware[9]={
0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD4, 0x02, 0x2A, 0x00};//
const unsigned char tag[11]={
0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};//detecting tag command
const unsigned char std_ACK[25] = {
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0C, \
0xF4, 0xD5, 0x4B, 0x01, 0x01, 0x00, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00};
unsigned char old_id[5];
unsigned char receive_ACK[25];//Command receiving buffer
//int inByte = 0; //incoming serial byte buffer
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#define print1Byte(args) Serial1.write(args)
#define print1lnByte(args) Serial1.write(args),Serial1.println()
#else
#include "WProgram.h"
#define print1Byte(args) Serial1.print(args,BYTE)
#define print1lnByte(args) Serial1.println(args,BYTE)
#endif
void setup()
{
Serial.begin(9600); // open serial with PC
Serial1.begin(115200); //open serial1 with device
//Serial2.begin(115200);
wake_card();
delay(100);
read_ACK(15);
delay(100);
display(15);
}
void loop()
{
send_tag();
read_ACK(25);
delay(100);
if (!cmp_id ()) {
if (test_ACK ()) {
display (25);
delay (100);
}
}
copy_id ();
}
void copy_id (void)
{//save old id
int ai, oi;
for (oi=0, ai=19; oi<5; oi++,ai++) {
old_id[oi] = receive_ACK[ai];
}
}
char cmp_id (void)
{//return true if find id is old
int ai, oi;
for (oi=0,ai=19; oi<5; oi++,ai++) {
if (old_id[oi] != receive_ACK[ai])
return 0;
}
return 1;
}
int test_ACK (void)
{// return true if receive_ACK accord with std_ACK
int i;
for (i=0; i<19; i++) {
if (receive_ACK[i] != std_ACK[i])
return 0;
}
return 1;
}
void send_id (void)
{//send id to PC
int i;
Serial.print ("ID: ");
for (i=19; i<= 23; i++) {
Serial.print (receive_ACK[i], HEX);
Serial.print (" ");
}
Serial.println ();
}
void UART1_Send_Byte(unsigned char command_data)
{//send byte to device
print1Byte(command_data);
#if defined(ARDUINO) && ARDUINO >= 100
Serial1.flush();// complete the transmission of outgoing serial data
#endif
}
void UART_Send_Byte(unsigned char command_data)
{//send byte to PC
Serial.print(command_data,HEX);
Serial.print(" ");
}
void read_ACK(unsigned char temp)
{//read ACK into reveive_ACK[]
unsigned char i;
for(i=0;i
唤醒: 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 也就是我们在代码中看到的
const unsigned char wake[24]={
0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00};//wake up NFC module
唤醒完后,会返回
00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00
获取UID: 00 00 FF 04 FC D4 4A 01 00 E1 00
上面的示例代码调用了send_tag后发送
const unsigned char tag[11]={
0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};//detecting tag command
返回了下面的数据
0 0 FF 0 FF 0 0 0 FF C F4 D5 4B 1 1 0 4 8 4 F5 FC 71 5 67 0
在上面的数据中
F5 FC 71 5
身份校验: 00 00 FF LEN LCS D4 40 01 60 Addr FF FF FF FF FF FF UID DCS 00 (还没有试过) 读操作: 00 00 FF 05 FB D4 40 01 30 Addr DCS 00
写操作: 00 00 FF 15 EB D4 40 01 A0 Addr BlockData 4F 00