Initial commit

This commit is contained in:
2018-07-27 19:01:49 +02:00
commit 208db43a7b
6 changed files with 716 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/.vscode
/docs
/dumps
.DS_Store

397
MFRC522.py Normal file
View File

@@ -0,0 +1,397 @@
# Created by: https://github.com/mxgxw/MFRC522-python/blob/master/MFRC522.py
# Modified by: Tobias Schneider https://github.com/tsndr/
import RPi.GPIO as GPIO
import spi
import signal
import time
class MFRC522:
NRSTPD = 25
MAX_LEN = 16
PCD_IDLE = 0x00
PCD_AUTHENT = 0x0E
PCD_RECEIVE = 0x08
PCD_TRANSMIT = 0x04
PCD_TRANSCEIVE = 0x0C
PCD_RESETPHASE = 0x0F
PCD_CALCCRC = 0x03
PICC_REQIDL = 0x26
PICC_REQALL = 0x52
PICC_ANTICOLL = 0x93
PICC_SELECTTAG = 0x93
PICC_AUTHENT1A = 0x60
PICC_AUTHENT1B = 0x61
PICC_READ = 0x30
PICC_WRITE = 0xA0
PICC_DECREMENT = 0xC0
PICC_INCREMENT = 0xC1
PICC_RESTORE = 0xC2
PICC_TRANSFER = 0xB0
PICC_HALT = 0x50
MI_OK = 0
MI_NOTAGERR = 1
MI_ERR = 2
Reserved00 = 0x00
CommandReg = 0x01
CommIEnReg = 0x02
DivlEnReg = 0x03
CommIrqReg = 0x04
DivIrqReg = 0x05
ErrorReg = 0x06
Status1Reg = 0x07
Status2Reg = 0x08
FIFODataReg = 0x09
FIFOLevelReg = 0x0A
WaterLevelReg = 0x0B
ControlReg = 0x0C
BitFramingReg = 0x0D
CollReg = 0x0E
Reserved01 = 0x0F
Reserved10 = 0x10
ModeReg = 0x11
TxModeReg = 0x12
RxModeReg = 0x13
TxControlReg = 0x14
TxAutoReg = 0x15
TxSelReg = 0x16
RxSelReg = 0x17
RxThresholdReg = 0x18
DemodReg = 0x19
Reserved11 = 0x1A
Reserved12 = 0x1B
MifareReg = 0x1C
Reserved13 = 0x1D
Reserved14 = 0x1E
SerialSpeedReg = 0x1F
Reserved20 = 0x20
CRCResultRegM = 0x21
CRCResultRegL = 0x22
Reserved21 = 0x23
ModWidthReg = 0x24
Reserved22 = 0x25
RFCfgReg = 0x26
GsNReg = 0x27
CWGsPReg = 0x28
ModGsPReg = 0x29
TModeReg = 0x2A
TPrescalerReg = 0x2B
TReloadRegH = 0x2C
TReloadRegL = 0x2D
TCounterValueRegH = 0x2E
TCounterValueRegL = 0x2F
Reserved30 = 0x30
TestSel1Reg = 0x31
TestSel2Reg = 0x32
TestPinEnReg = 0x33
TestPinValueReg = 0x34
TestBusReg = 0x35
AutoTestReg = 0x36
VersionReg = 0x37
AnalogTestReg = 0x38
TestDAC1Reg = 0x39
TestDAC2Reg = 0x3A
TestADCReg = 0x3B
Reserved31 = 0x3C
Reserved32 = 0x3D
Reserved33 = 0x3E
Reserved34 = 0x3F
serNum = []
def __init__(self, dev='/dev/spidev0.0', spd=1000000):
spi.openSPI(device=dev,speed=spd)
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
GPIO.output(self.NRSTPD, 1)
self.Init()
def Reset(self):
self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
def Write_MFRC522(self, addr, val):
spi.transfer(((addr<<1)&0x7E,val))
def Read_MFRC522(self, addr):
val = spi.transfer((((addr<<1)&0x7E) | 0x80,0))
return val[1]
def SetBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp | mask)
def ClearBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp & (~mask))
def AntennaOn(self):
temp = self.Read_MFRC522(self.TxControlReg)
if(~(temp & 0x03)):
self.SetBitMask(self.TxControlReg, 0x03)
def AntennaOff(self):
self.ClearBitMask(self.TxControlReg, 0x03)
def ToCard(self,command,sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
i = 0
if command == self.PCD_AUTHENT:
irqEn = 0x12
waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
irqEn = 0x77
waitIRq = 0x30
self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)
self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);
while(i<len(sendData)):
self.Write_MFRC522(self.FIFODataReg, sendData[i])
i = i+1
self.Write_MFRC522(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self.SetBitMask(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self.Read_MFRC522(self.CommIrqReg)
i = i - 1
if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
break
self.ClearBitMask(self.BitFramingReg, 0x80)
if i != 0:
if (self.Read_MFRC522(self.ErrorReg) & 0x1B)==0x00:
status = self.MI_OK
if n & irqEn & 0x01:
status = self.MI_NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self.Read_MFRC522(self.FIFOLevelReg)
lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
if lastBits != 0:
backLen = (n-1)*8 + lastBits
else:
backLen = n*8
if n == 0:
n = 1
if n > self.MAX_LEN:
n = self.MAX_LEN
i = 0
while i<n:
backData.append(self.Read_MFRC522(self.FIFODataReg))
i = i + 1
else:
status = self.MI_ERR
return (status,backData,backLen)
def Request(self, reqMode):
status = None
backBits = None
TagType = []
self.Write_MFRC522(self.BitFramingReg, 0x07)
TagType.append(reqMode)
(status,backData,backBits) = self.ToCard(self.PCD_TRANSCEIVE, TagType)
if ((status != self.MI_OK) | (backBits != 0x10)):
status = self.MI_ERR
return (status,backBits)
def Anticoll(self):
backData = []
serNumCheck = 0
serNum = []
self.Write_MFRC522(self.BitFramingReg, 0x00)
serNum.append(self.PICC_ANTICOLL)
serNum.append(0x20)
(status,backData,backBits) = self.ToCard(self.PCD_TRANSCEIVE,serNum)
if(status == self.MI_OK):
i = 0
if len(backData)==5:
while i<4:
serNumCheck = serNumCheck ^ backData[i]
i = i + 1
if serNumCheck != backData[i]:
status = self.MI_ERR
else:
status = self.MI_ERR
return (status,backData)
def CalulateCRC(self, pIndata):
self.ClearBitMask(self.DivIrqReg, 0x04)
self.SetBitMask(self.FIFOLevelReg, 0x80)
i = 0
while i<len(pIndata):
self.Write_MFRC522(self.FIFODataReg, pIndata[i])
i = i + 1
self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
i = 0xFF
while True:
n = self.Read_MFRC522(self.DivIrqReg)
i = i - 1
if not ((i != 0) and not (n&0x04)):
break
pOutData = []
pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
return pOutData
def SelectTag(self, serNum):
backData = []
buf = []
buf.append(self.PICC_SELECTTAG)
buf.append(0x70)
i = 0
while i<5:
buf.append(serNum[i])
i = i + 1
pOut = self.CalulateCRC(buf)
buf.append(pOut[0])
buf.append(pOut[1])
(status, backData, backLen) = self.ToCard(self.PCD_TRANSCEIVE, buf)
if (status == self.MI_OK) and (backLen == 0x18):
# print "Size: " + str(backData[0])
return backData[0]
else:
return 0
def 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
# 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.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 StopCrypto1(self):
self.ClearBitMask(self.Status2Reg, 0x08)
def Read(self, blockAddr):
recvData = []
recvData.append(self.PICC_READ)
recvData.append(blockAddr)
pOut = self.CalulateCRC(recvData)
recvData.append(pOut[0])
recvData.append(pOut[1])
(status, backData, backLen) = self.ToCard(self.PCD_TRANSCEIVE, recvData)
if not(status == self.MI_OK):
print("Error while reading!")
i = 0
# if len(backData) == 16:
return backData
# else:
# return None
def Write(self, blockAddr, writeData):
buff = []
buff.append(self.PICC_WRITE)
buff.append(blockAddr)
crc = self.CalulateCRC(buff)
buff.append(crc[0])
buff.append(crc[1])
(status, backData, backLen) = self.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
# 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
crc = self.CalulateCRC(buf)
buf.append(crc[0])
buf.append(crc[1])
(status, backData, backLen) = self.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")
# if status == self.MI_OK:
# print "Data written"
return status
def DumpClassic1K(self, key, uid):
i = 0
while i < 64:
status = self.Auth(self.PICC_AUTHENT1A, i, key, uid)
# Check if authenticated
if status == self.MI_OK:
self.Read(i)
else:
print("Authentication error")
i = i+1
def Init(self):
GPIO.output(self.NRSTPD, 1)
self.Reset()
self.Write_MFRC522(self.TModeReg, 0x8D)
self.Write_MFRC522(self.TPrescalerReg, 0x3E)
self.Write_MFRC522(self.TReloadRegL, 30)
self.Write_MFRC522(self.TReloadRegH, 0)
self.Write_MFRC522(self.TxAutoReg, 0x40)
self.Write_MFRC522(self.ModeReg, 0x3D)
self.AntennaOn()

65
README.md Normal file
View File

@@ -0,0 +1,65 @@
# MFRC522-python
Reading and Writing MiFare tags using a Raspberry Pi 3 and the RFID-RC522.
## 1. Enable SPI
Open the configuration using this command:
```
sudo raspi-config
```
In the menu select `5 Interfacing options`, then enable `P4 SPI` and reboot.
## 2. Connection
Connect the RC522's Pins to the RaspberryPi's GPIO pins.
RC522 | RaspberryPi
----: | ----------:
SDA | 24
SCK | 23
MOSI | 19
MISO | 21
IRQ | -
GND | 6
RST | 22
3.3V | 1
Dont connect the IRQ pin.
For a detailed pinout plan check [this website](https://pinout.xyz/).
## Install dependencies
First of all we need to install the `git` and `python-dev` package using this command:
```
sudo apt install git python-dev -y
```
Now we have to install `SPI-Py` using the folowing commands:
```
cd ~
git clone https://github.com/lthiery/SPI-Py.git
cd SPI-Py/
sudo python setup.py install
```
## Install MFRC522-python
Almost done, just a few commands left to install this package:
```
cd ~
git clone https://github.com/tsndr/MFRC522-python.git
cd MFRC522-python/
```
## Usage
Run one of these commands and follow the instructions:
#### Reading a tag
```
python read.py
```
#### Writing a tag
```
python write.py
```
#### Resetting a tag
```
python wipe.py
```

88
read.py Normal file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python
#!/usr/bin/env python
import RPi.GPIO as GPIO
import MFRC522
import signal
import time
import sys
# Keys
DEFAULT_KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
KEY_S0 = [0x20, 0x20, 0x20, 0x20, 0x20, 0x20]
# Selecting key
KEY = DEFAULT_KEY
MainLoop = True
WaitingForTag = True
def uid_to_num(uid):
n = 0
for i in range(0, 5):
n = n * 256 + uid[i]
return n
RFID = MFRC522.MFRC522()
# Get tag size if available
(status, TagSize) = RFID.Request(RFID.PICC_REQIDL)
while MainLoop:
if TagSize > 0:
message = "Sector [1 - %s]: " % TagSize
else:
message = "Sector: "
try:
sector = input(message)
except:
MainLoop = False
continue
else:
if status != RFID.MI_OK:
print "Waiting for Tag...\n"
else:
print ""
WaitingForTag = True
while WaitingForTag:
(status, TagSize) = RFID.Request(RFID.PICC_REQIDL)
if status != RFID.MI_OK:
continue
if sector < 1 or sector > (TagSize - 1):
print "Sector out of range (1 - %s)\n" % (TagSize - 1)
WaitingForTag = False
continue
(status, UID) = RFID.Anticoll()
if status != RFID.MI_OK:
continue
RFID.SelectTag(UID)
# Reading data
BlockAddrs = [ (sector * 4), (sector * 4 + 1), (sector * 4 + 2) ]
TrailerBlockAddr = (sector * 4 + 3)
status = RFID.Auth(RFID.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID)
data = []
text_read = ""
if status == RFID.MI_OK:
for block_num in BlockAddrs:
block = RFID.Read(block_num)
if block:
data += block
if data:
text_read = "".join(chr(i) for i in data)
print "UID: ", uid_to_num(UID)
print "Data: ", text_read,"\n"
else:
print "Can't access sector", sector, "!\n"
RFID.StopCrypto1()
WaitingForTag = False
GPIO.cleanup()

69
wipe.py Normal file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env python
#!/usr/bin/env python
import RPi.GPIO as GPIO
import MFRC522
import signal
# Keys
DEFAULT_KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
KEY_S0 = [0x20, 0x20, 0x20, 0x20, 0x20, 0x20]
# Selecting key
KEY = DEFAULT_KEY
def uid_to_num(uid):
n = 0
for i in range(0, 5):
n = n * 256 + uid[i]
return n
MIFAREReader = MFRC522.MFRC522()
print "Waiting for tag...\n"
while True:
sector = 1
while True:
(status, TagSize) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
if status != MIFAREReader.MI_OK:
continue
if sector >= TagSize:
break
print "Wiping sector", sector, "..."
# Selecting blocks
BlockAddrs = [ (sector * 4), (sector * 4 + 1), (sector * 4 + 2) ]
TrailerBlockAddr = (sector * 4 + 3)
# Writing data
(status, UID) = MIFAREReader.MFRC522_Anticoll()
if status != MIFAREReader.MI_OK:
break
MIFAREReader.MFRC522_SelectTag(UID)
status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID)
if status == MIFAREReader.MI_OK:
data = bytearray()
data.extend(bytearray("".ljust(len(BlockAddrs) * 16)))
i = 0
for block_num in BlockAddrs:
MIFAREReader.MFRC522_Write(block_num, data[(i*16):(i+1)*16])
i += 1
print "Sector", sector, "wiped!"
else:
print "Can't access sector", sector, "!"
MIFAREReader.MFRC522_StopCrypto1()
sector += 1
print "\nTag wiped!"
break
GPIO.cleanup()

93
write.py Normal file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python
#!/usr/bin/env python
import RPi.GPIO as GPIO
import MFRC522
import signal
import time
import sys
# Keys
DEFAULT_KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
KEY_S0 = [0x20, 0x20, 0x20, 0x20, 0x20, 0x20]
# Selecting key
KEY = DEFAULT_KEY
MainLoop = True
WaitingForTag = True
def uid_to_num(uid):
n = 0
for i in range(0, 5):
n = n * 256 + uid[i]
return n
RFID = MFRC522.MFRC522()
# Get tag size if available
(status, TagSize) = RFID.Request(RFID.PICC_REQIDL)
while MainLoop:
if TagSize > 0:
message = "Sector [1 - %s]: " % TagSize
else:
message = "Sector: "
try:
sector = input(message)
except:
MainLoop = False
continue
else:
try:
text = raw_input("Data: ")
except:
continue
else:
if status != RFID.MI_OK:
print "Waiting for Tag...\n"
else:
print ""
WaitingForTag = True
while WaitingForTag:
(status, TagSize) = RFID.Request(RFID.PICC_REQIDL)
if status != RFID.MI_OK:
continue
if sector < 1 or sector > (TagSize - 1):
print "Sector out of range (1 - %s)\n" % (TagSize - 1)
WaitingForTag = False
continue
(status, UID) = RFID.Anticoll()
if status != RFID.MI_OK:
continue
RFID.SelectTag(UID)
# Selecting blocks
BlockAddrs = [ (sector * 4), (sector * 4 + 1), (sector * 4 + 2) ]
TrailerBlockAddr = (sector * 4 + 3)
# Writing data
status = RFID.Auth(RFID.PICC_AUTHENT1A, TrailerBlockAddr, KEY, UID)
if status == RFID.MI_OK:
data = bytearray()
data.extend(bytearray(text.ljust(len(BlockAddrs) * 16)))
i = 0
for block_num in BlockAddrs:
RFID.Write(block_num, data[(i*16):(i+1)*16])
i += 1
print "UID: ", uid_to_num(UID)
print "Data: ", text[0:(len(BlockAddrs) * 16)], "\n"
else:
print "Can't access sector", sector, "!\n"
RFID.StopCrypto1()
WaitingForTag = False
GPIO.cleanup()