From fcf94d7551d0417a1fac955a70b60c5d1b84a0ba Mon Sep 17 00:00:00 2001 From: Mathias Jensen Date: Mon, 23 Jun 2014 17:54:19 +0200 Subject: [PATCH] Fixed authentication, added examples, proper class without code in the end --- Dump.py | 49 ++++++++++++++++++++++++++++ MFRC522.py | 82 +++++++++++++++++++++-------------------------- README.md | 31 ++++++++++-------- Read.py | 56 ++++++++++++++++++++++++++++++++ Write.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+), 58 deletions(-) create mode 100755 Dump.py mode change 100644 => 100755 MFRC522.py create mode 100755 Read.py create mode 100755 Write.py diff --git a/Dump.py b/Dump.py new file mode 100755 index 0000000..49e6122 --- /dev/null +++ b/Dump.py @@ -0,0 +1,49 @@ +import RPi.GPIO as GPIO +import MFRC522 +import signal + +continue_reading = True + +# Capture SIGINT for cleanup when the script is aborted +def end_read(signal,frame): + global continue_reading + print "Ctrl+C captured, ending read." + continue_reading = False + GPIO.cleanup() + +# Hook the SIGINT +signal.signal(signal.SIGINT, end_read) + +# Create an object of the class MFRC522 +MIFAREReader = MFRC522.MFRC522() + +# This loop keeps checking for chips. If one is near it will get the UID and authenticate +while continue_reading: + + # Scan for cards + (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) + + # If a card is found + if status == MIFAREReader.MI_OK: + print "Card detected" + + # Get the UID of the card + (status,uid) = MIFAREReader.MFRC522_Anticoll() + + # If we have the UID, continue + if status == MIFAREReader.MI_OK: + + # Print UID + print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]) + + # This is the default key for authentication + key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] + + # Select the scanned tag + MIFAREReader.MFRC522_SelectTag(uid) + + # Dump the data + MIFAREReader.MFRC522_DumpClassic1K(key, uid) + + # Stop + MIFAREReader.MFRC522_StopCrypto1() diff --git a/MFRC522.py b/MFRC522.py old mode 100644 new mode 100755 index 2b6d746..30575bf --- a/MFRC522.py +++ b/MFRC522.py @@ -1,6 +1,7 @@ import RPi.GPIO as GPIO import spi import signal +import time class MFRC522: NRSTPD = 22 @@ -284,30 +285,46 @@ class MFRC522: if (status == self.MI_OK) and (backLen == 0x18): print "Size: " + str(backData[0]) - return backData[0] + return backData[0] else: return 0 def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum): buff = [] + + # First byte should be the authMode (A or B) buff.append(authMode) + + # Second byte is the trailerBlock (usually 7) buff.append(BlockAddr) + + # Now we need to append the authKey which usually is 6 bytes of 0xFF i = 0 while(i < len(Sectorkey)): buff.append(Sectorkey[i]) i = i + 1 i = 0 - while(i < len(serNum)): + + # Next we append the first 4 bytes of the UID + while(i < 4): buff.append(serNum[i]) i = i +1 + + # Now we start the authentication itself (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff) + + # Check if an error occurred if not(status == self.MI_OK): print "AUTH ERROR!!" if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0: print "AUTH ERROR(status2reg & 0x08) != 0" + # Return the status return status + def MFRC522_StopCrypto1(self): + self.ClearBitMask(self.Status2Reg, 0x08) + def MFRC522_Read(self, blockAddr): recvData = [] recvData.append(self.PICC_READ) @@ -318,8 +335,6 @@ class MFRC522: (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData) if not(status == self.MI_OK): print "Error while reading!" - - print "Got data size: "+str(backLen) i = 0 if len(backData) == 16: print "Sector "+str(blockAddr)+" "+str(backData) @@ -333,25 +348,35 @@ class MFRC522: buff.append(crc[1]) (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff) if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A): - status = self.MI_ERR + status = self.MI_ERR print str(backLen)+" backdata &0x0F == 0x0A "+str(backData[0]&0x0F) if status == self.MI_OK: i = 0 buf = [] while i < 16: - buf.append(writeData[i]) - i = i + 1 + buf.append(writeData[i]) + i = i + 1 crc = self.CalulateCRC(buf) buf.append(crc[0]) buf.append(crc[1]) (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,buf) if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A): - print "Error while writing" + print "Error while writing" if status == self.MI_OK: - print "Data writen" - - + print "Data written" + + def MFRC522_DumpClassic1K(self, key, uid): + i = 0 + while i < 64: + status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid) + # Check if authenticated + if status == self.MI_OK: + self.MFRC522_Read(i) + else: + print "Authentication error" + i = i+1 + def MFRC522_Init(self): GPIO.output(self.NRSTPD, 1) @@ -365,37 +390,4 @@ class MFRC522: self.Write_MFRC522(self.TxAutoReg, 0x40) self.Write_MFRC522(self.ModeReg, 0x3D) - self.AntennaOn() - -continue_reading = True -# Capture SIGINT -def end_read(signal,frame): - global continue_reading - print "Ctrl+C captured, ending read." - continue_reading = False - GPIO.cleanup() # Suggested by Marjan Trutschl - -signal.signal(signal.SIGINT, end_read) - -MIFAREReader = MFRC522() - -while continue_reading: - (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) - - if status == MIFAREReader.MI_OK: - print "Card detected" - - (status,backData) = MIFAREReader.MFRC522_Anticoll() - if status == MIFAREReader.MI_OK: - print "Card read UID: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4]) - - key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] - - MIFAREReader.MFRC522_SelectTag(backData) - - status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 11, key, backData) - if status == MIFAREReader.MI_OK: - print "AUTH OK" - else: - print "AUTH ERROR" - + self.AntennaOn() \ No newline at end of file diff --git a/README.md b/README.md index 711730e..699a45d 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,26 @@ A small class to interface with the NFC reader Module MFRC522 on the Raspberry P This is a Python port of the example code for the NFC module MF522-AN. -Pre Requisites -============== - -You will need to install SPI-Py from lthiery from the following address: - +##Requirements +This code requires you to have SPI-Py installed from the following repository: https://github.com/lthiery/SPI-Py -More Info -============== +##Examples +This repository includes a couple of examples showing how to read, write, and dump data from a chip. They are thoroughly commented, and should be easy to understand. -For more information visit: http://fuenteabierta.teubi.co/ +## Pins +You can use [this](http://i.imgur.com/y7Fnvhq.png) image for reference. -Usage -============== +| Name | Pin # | Pin name | +|------|-------|------------| +| SDA | 24 | GPIO8 | +| SCK | 23 | GPIO11 | +| MOSI | 19 | GPIO10 | +| MISO | 21 | GPIO9 | +| IRQ | None | None | +| GND | Any | Any Ground | +| RST | 22 | GPIO25 | +| 3.3V | 1 | 3V3 | -Just run the following command: - -sudo python MFRC522.py +##Usage +Import the class by importing MFRC522 in the top of your script. For more info see the examples. diff --git a/Read.py b/Read.py new file mode 100755 index 0000000..16517f2 --- /dev/null +++ b/Read.py @@ -0,0 +1,56 @@ +import RPi.GPIO as GPIO +import MFRC522 +import signal + +continue_reading = True + +# Capture SIGINT for cleanup when the script is aborted +def end_read(signal,frame): + global continue_reading + print "Ctrl+C captured, ending read." + continue_reading = False + GPIO.cleanup() + +# Hook the SIGINT +signal.signal(signal.SIGINT, end_read) + +# Create an object of the class MFRC522 +MIFAREReader = MFRC522.MFRC522() + +# This loop keeps checking for chips. If one is near it will get the UID and authenticate +while continue_reading: + + # Scan for cards + (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) + + # If a card is found + if status == MIFAREReader.MI_OK: + print "Card detected" + + # Get the UID of the card + (status,uid) = MIFAREReader.MFRC522_Anticoll() + + # If we have the UID, continue + if status == MIFAREReader.MI_OK: + + # Print UID + print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]) + + # This is the default key for authentication + key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] + + # Select the scanned tag + MIFAREReader.MFRC522_SelectTag(uid) + + # Authenticate + status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid) + + # Check if authenticated + if status == MIFAREReader.MI_OK: + MIFAREReader.MFRC522_Read(8) + MIFAREReader.MFRC522_StopCrypto1() + else: + print "Authentication error" + + # Make sure to stop scanning for cards + continue_reading = false diff --git a/Write.py b/Write.py new file mode 100755 index 0000000..154da67 --- /dev/null +++ b/Write.py @@ -0,0 +1,94 @@ +import RPi.GPIO as GPIO +import MFRC522 +import signal + +continue_reading = True + +# Capture SIGINT for cleanup when the script is aborted +def end_read(signal,frame): + global continue_reading + print "Ctrl+C captured, ending read." + continue_reading = False + GPIO.cleanup() + +# Hook the SIGINT +signal.signal(signal.SIGINT, end_read) + +# Create an object of the class MFRC522 +MIFAREReader = MFRC522.MFRC522() + +# This loop keeps checking for chips. If one is near it will get the UID and authenticate +while continue_reading: + + # Scan for cards + (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) + + # If a card is found + if status == MIFAREReader.MI_OK: + print "Card detected" + + # Get the UID of the card + (status,uid) = MIFAREReader.MFRC522_Anticoll() + + # If we have the UID, continue + if status == MIFAREReader.MI_OK: + + # Print UID + print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]) + + # This is the default key for authentication + key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF] + + # Select the scanned tag + MIFAREReader.MFRC522_SelectTag(uid) + + # Authenticate + status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid) + print "\n" + + # Check if authenticated + if status == MIFAREReader.MI_OK: + + # Variable for the data to write + data = [] + + # Fill the data with 0xFF + for x in range(0,16): + data.append(0xFF) + + print "Sector 8 looked like this:" + # Read block 8 + MIFAREReader.MFRC522_Read(8) + print "\n" + + print "Sector 8 will now be filled with 0xFF:" + # Write the data + MIFAREReader.MFRC522_Write(8, data) + print "\n" + + print "It now looks like this:" + # Check to see if it was written + MIFAREReader.MFRC522_Read(8) + print "\n" + + data = [] + # Fill the data with 0x00 + for x in range(0,16): + data.append(0x00) + + print "Now we fill it with 0x00:" + MIFAREReader.MFRC522_Write(8, data) + print "\n" + + print "It is now empty:" + # Check to see if it was written + MIFAREReader.MFRC522_Read(8) + print "\n" + + # Stop + MIFAREReader.MFRC522_StopCrypto1() + + # Make sure to stop reading for cards + continue_reading = False + else: + print "Authentication error"