add RfidAccess class
This commit is contained in:
91
Pico_example/CreateNdefTag.py
Normal file
91
Pico_example/CreateNdefTag.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
from mfrc522 import MFRC522
|
||||||
|
from RfidAccess import RfidAccess
|
||||||
|
import utime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
||||||
|
access = RfidAccess()
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("Please place card on reader")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def checksum(data):
|
||||||
|
crc = 0xc7
|
||||||
|
for byte in data:
|
||||||
|
crc ^= byte
|
||||||
|
for _ in range(8):
|
||||||
|
msb = crc & 0x80
|
||||||
|
crc = (crc << 1) & 0xff
|
||||||
|
if msb:
|
||||||
|
crc ^= 0x1d
|
||||||
|
return crc
|
||||||
|
|
||||||
|
|
||||||
|
PreviousCard = [0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
|
||||||
|
reader.init()
|
||||||
|
(stat, tag_type) = reader.request(reader.REQIDL)
|
||||||
|
if stat == reader.OK:
|
||||||
|
(stat, uid) = reader.SelectTagSN()
|
||||||
|
if uid == PreviousCard:
|
||||||
|
continue
|
||||||
|
if stat == reader.OK:
|
||||||
|
print("Card detected {} uid={}".format(hex(int.from_bytes(bytes(uid),"little",False)).upper(),reader.tohexstring(uid)))
|
||||||
|
defaultKey = [255,255,255,255,255,255]
|
||||||
|
firstSectorKey = [0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5]
|
||||||
|
nextSectorKey = [0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7]
|
||||||
|
|
||||||
|
#set MAD sector
|
||||||
|
# first fill block permission
|
||||||
|
access.setTrailerAccess(keyA_Write=access.KEYB,access_Read=access.KEYAB,access_Write=access.KEYB,
|
||||||
|
keyB_Read=access.NEVER,keyB_Write=access.KEYB)
|
||||||
|
access.setBlockAccess(access.ALLBLOCK, access_Read=access.KEYAB, access_Write=access.KEYB,
|
||||||
|
access_Inc=access.NEVER, access_Dec=access.NEVER)
|
||||||
|
block3 = access.fillBlock3(keyA=firstSectorKey,keyB=defaultKey)
|
||||||
|
#Write the sector access
|
||||||
|
if reader.writeSectorBlock(uid,0,3,block3,keyA=defaultKey) == reader.ERR:
|
||||||
|
print("Writing MAD sector failed!")
|
||||||
|
else:
|
||||||
|
print(".",end="")
|
||||||
|
b1 = [0x14,0x01,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1]
|
||||||
|
b1[0] = checksum(b1[1:]) # I know this is already ok but just to demonstrate the CRC
|
||||||
|
reader.writeSectorBlock(uid,0,1,b1,keyB=defaultKey)
|
||||||
|
b2 = [0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1,0x03,0xE1]
|
||||||
|
reader.writeSectorBlock(uid,0,2,b1,keyB=defaultKey)
|
||||||
|
#set permission for all other sectors
|
||||||
|
access.setTrailerAccess(keyA_Write=access.KEYB,access_Read=access.KEYAB,access_Write=access.KEYB,
|
||||||
|
keyB_Read=access.NEVER,keyB_Write=access.KEYB)
|
||||||
|
access.setBlockAccess(access.ALLBLOCK, access_Read=access.KEYAB, access_Write=access.KEYAB,
|
||||||
|
access_Inc=access.KEYAB, access_Dec=access.KEYAB)
|
||||||
|
block3 = access.fillBlock3(keyA=nextSectorKey,keyB=defaultKey)
|
||||||
|
#Write all next sectors access
|
||||||
|
for sector in range(1,16):
|
||||||
|
if reader.writeSectorBlock(uid,sector,3,block3,keyA=defaultKey) == reader.ERR:
|
||||||
|
print("\nWriting to sector ",sector," Failed!")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(".",end="")
|
||||||
|
#force sector 1 to be 1 record empty
|
||||||
|
block= 16 *[0]
|
||||||
|
block[2]=0xfe
|
||||||
|
if reader.writeSectorBlock(uid,1,0,block,keyB=defaultKey) == reader.ERR:
|
||||||
|
print("Unable to set first NDEF record!")
|
||||||
|
print("\nDone.")
|
||||||
|
|
||||||
|
previousCard=uid
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
PreviousCard=[0]
|
||||||
|
utime.sleep_ms(50)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Bye")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
70
Pico_example/EraseNdefTag.py
Normal file
70
Pico_example/EraseNdefTag.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
from mfrc522 import MFRC522
|
||||||
|
from RfidAccess import RfidAccess
|
||||||
|
import utime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
||||||
|
access = RfidAccess()
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("Please place card on reader")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PreviousCard = [0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
|
||||||
|
reader.init()
|
||||||
|
(stat, tag_type) = reader.request(reader.REQIDL)
|
||||||
|
if stat == reader.OK:
|
||||||
|
(stat, uid) = reader.SelectTagSN()
|
||||||
|
if uid == PreviousCard:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if stat == reader.OK:
|
||||||
|
print("Card detected {} uid={}".format(hex(int.from_bytes(bytes(uid),"little",False)).upper(),reader.tohexstring(uid)))
|
||||||
|
firstSectorKey = [0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5]
|
||||||
|
nextSectorKey = [0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7]
|
||||||
|
defaultKey = [255,255,255,255,255,255]
|
||||||
|
|
||||||
|
# set default access
|
||||||
|
access.decodeAccess(0xff,0x07,0x80)
|
||||||
|
block3 = access.fillBlock3(keyA=defaultKey,keyB=defaultKey)
|
||||||
|
print("Reset Mad Sector (first sector)")
|
||||||
|
#reset first sector
|
||||||
|
reader.writeSectorBlock(uid,0,3,block3,keyB=defaultKey)
|
||||||
|
#erase block1 and 2
|
||||||
|
datablock = 16 * [0]
|
||||||
|
reader.writeSectorBlock(uid,0,1,datablock,keyB=defaultKey)
|
||||||
|
reader.writeSectorBlock(uid,0,2,datablock,keyB=defaultKey)
|
||||||
|
|
||||||
|
#reset all other sectors
|
||||||
|
for s in range(1,16):
|
||||||
|
# permission to default
|
||||||
|
print("Reset sector ",s)
|
||||||
|
reader.writeSectorBlock(uid,s,3,block3,keyB=defaultKey)
|
||||||
|
for b in range(3):
|
||||||
|
# put all data to zero block 0,1 and 2
|
||||||
|
reader.writeSectorBlock(uid,s,b,datablock,keyB=defaultKey)
|
||||||
|
# ok dump new data
|
||||||
|
print("\n---- Dump card using defaultkeyB [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]\n")
|
||||||
|
reader.MFRC522_DumpClassic1K(uid, Start=0, End=64, keyB=defaultKey)
|
||||||
|
PreviousCard = uid
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#print("Authentication error")
|
||||||
|
else:
|
||||||
|
PreviousCard=[0]
|
||||||
|
utime.sleep_ms(50)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Bye")
|
||||||
|
|
||||||
|
print("Card done!")
|
||||||
|
|
||||||
|
|
||||||
45
Pico_example/Pico_read.py
Normal file
45
Pico_example/Pico_read.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
from mfrc522 import MFRC522
|
||||||
|
import utime
|
||||||
|
|
||||||
|
|
||||||
|
def uidToString(uid):
|
||||||
|
mystring = ""
|
||||||
|
for i in uid:
|
||||||
|
mystring = "%02X" % i + mystring
|
||||||
|
return mystring
|
||||||
|
|
||||||
|
|
||||||
|
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("Please place card on reader")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PreviousCard = [0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
|
||||||
|
reader.init()
|
||||||
|
(stat, tag_type) = reader.request(reader.REQIDL)
|
||||||
|
#print('request stat:',stat,' tag_type:',tag_type)
|
||||||
|
if stat == reader.OK:
|
||||||
|
(stat, uid) = reader.SelectTagSN()
|
||||||
|
if uid == PreviousCard:
|
||||||
|
continue
|
||||||
|
if stat == reader.OK:
|
||||||
|
print("Card detected {} uid={}".format(hex(int.from_bytes(bytes(uid),"little",False)).upper(),reader.tohexstring(uid)))
|
||||||
|
defaultKey = [255,255,255,255,255,255]
|
||||||
|
reader.MFRC522_DumpClassic1K(uid, Start=0, End=64, keyA=defaultKey)
|
||||||
|
print("Done")
|
||||||
|
PreviousCard = uid
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
PreviousCard=[0]
|
||||||
|
utime.sleep_ms(50)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
@@ -17,7 +17,7 @@ def uidToString(uid):
|
|||||||
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
print("Place card before reader to read from address 0x08")
|
print("Please place card on reader")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
|
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
|
||||||
@@ -32,7 +32,7 @@ try:
|
|||||||
if stat == reader.OK:
|
if stat == reader.OK:
|
||||||
print(uid)
|
print(uid)
|
||||||
print("Card detected %s" % uidToString(uid))
|
print("Card detected %s" % uidToString(uid))
|
||||||
reader.MFRC522_DumpClassic1K(key, uid)
|
reader.MFRC522_DumpClassic1K(uid,keyA=key)
|
||||||
print("Test ! writing sector 2, block 0 (absolute block(8)")
|
print("Test ! writing sector 2, block 0 (absolute block(8)")
|
||||||
print("with [ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 ]")
|
print("with [ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 ]")
|
||||||
absoluteBlock=8
|
absoluteBlock=8
|
||||||
@@ -43,7 +43,7 @@ try:
|
|||||||
if status == reader.OK:
|
if status == reader.OK:
|
||||||
status = reader.write(absoluteBlock,value)
|
status = reader.write(absoluteBlock,value)
|
||||||
if status == reader.OK:
|
if status == reader.OK:
|
||||||
reader.MFRC522_DumpClassic1K(key, uid)
|
reader.MFRC522_DumpClassic1K(uid,keyA=key)
|
||||||
else:
|
else:
|
||||||
print("unable to write")
|
print("unable to write")
|
||||||
else:
|
else:
|
||||||
47
Pico_example/ReadNdefTag.py
Normal file
47
Pico_example/ReadNdefTag.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
from mfrc522 import MFRC522
|
||||||
|
import utime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("Place card into reader")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PreviousCard = [0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
|
||||||
|
reader.init()
|
||||||
|
(stat, tag_type) = reader.request(reader.REQIDL)
|
||||||
|
if stat == reader.OK:
|
||||||
|
(stat, uid) = reader.SelectTagSN()
|
||||||
|
if uid == PreviousCard:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if stat == reader.OK:
|
||||||
|
print("Card detected {} uid={}".format(hex(int.from_bytes(bytes(uid),"little",False)).upper(),reader.tohexstring(uid)))
|
||||||
|
firstSectorKey = [0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5]
|
||||||
|
nextSectorKey = [0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7]
|
||||||
|
#defaultKey = [255,255,255,255,255,255]
|
||||||
|
|
||||||
|
#read MAD sector (first sector)
|
||||||
|
if reader.MFRC522_DumpClassic1K(uid, Start=0, End=4, keyA=firstSectorKey)== reader.OK:
|
||||||
|
#read the rest of the card
|
||||||
|
reader.MFRC522_DumpClassic1K(uid, Start=4, End=64, keyA=nextSectorKey)
|
||||||
|
print("Done")
|
||||||
|
PreviousCard = uid
|
||||||
|
else:
|
||||||
|
PreviousCard=[0]
|
||||||
|
utime.sleep_ms(50)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Bye")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
209
RfidAccess.py
Normal file
209
RfidAccess.py
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
class RfidAccess:
|
||||||
|
NEVER = 0
|
||||||
|
KEYA = 1
|
||||||
|
KEYB = 2
|
||||||
|
KEYAB = 3
|
||||||
|
ALLBLOCK = -1
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.C1 = 0
|
||||||
|
self.C2 = 0
|
||||||
|
self.C3 = 8
|
||||||
|
self.C1_Inv = 15
|
||||||
|
self.C2_Inv = 15
|
||||||
|
self.C3_Inv = 7
|
||||||
|
self.Valid=False
|
||||||
|
|
||||||
|
def findAccessIndex(self,table,mask,accessbits):
|
||||||
|
for i in range(8):
|
||||||
|
if table[i] == accessbits:
|
||||||
|
if (i & 1) == 0 :
|
||||||
|
self.C2 = self.C2 & ~mask
|
||||||
|
else:
|
||||||
|
self.C2 = self.C2 | mask
|
||||||
|
|
||||||
|
if (i & 2) == 0 :
|
||||||
|
self.C1 = self.C1 & ~mask
|
||||||
|
else:
|
||||||
|
self.C1 = self.C1 | mask
|
||||||
|
|
||||||
|
if (i & 4) == 0:
|
||||||
|
self.C3 = self.C3 & ~mask
|
||||||
|
else:
|
||||||
|
self.C3 = self.C3 | mask
|
||||||
|
|
||||||
|
self.C1_Inv = self.C1 ^ 0xf
|
||||||
|
self.C2_Inv = self.C2 ^ 0xf
|
||||||
|
self.C3_Inv = self.C3 ^ 0xf
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def setTrailerAccess(self,keyA_Write=KEYA, access_Read=KEYA,access_Write=KEYA,keyB_Read=KEYA,keyB_Write=KEYA):
|
||||||
|
#C1 weight 2 , C2 weight 1 , C3 weight 4
|
||||||
|
|
||||||
|
# Key A Wr Access R Access W KeyB R KEYB W
|
||||||
|
access_Index = ( (self.KEYA, self.KEYA, self.NEVER, self.KEYA,self.KEYA),
|
||||||
|
(self.NEVER,self.KEYA,self.NEVER,self.KEYA,self.NEVER),
|
||||||
|
(self.KEYB, self.KEYAB,self.NEVER,self.NEVER,self.NEVER),
|
||||||
|
(self.NEVER,self.KEYAB,self.NEVER,self.NEVER,self.NEVER),
|
||||||
|
(self.KEYA,self.KEYA,self.KEYA,self.KEYA,self.KEYA),
|
||||||
|
(self.KEYB,self.KEYAB,self.KEYB,self.NEVER,self.KEYB),
|
||||||
|
(self.NEVER,self.KEYAB,self.KEYB,self.NEVER,self.NEVER),
|
||||||
|
(self.NEVER,self.KEYAB,self.NEVER,self.NEVER,self.NEVER))
|
||||||
|
if self.findAccessIndex(access_Index,8, (keyA_Write,access_Read,access_Write,keyB_Read,keyB_Write)):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("Access Trailer method not possible")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def setBlockAccess(self, blockID, access_Read=KEYAB, access_Write=KEYAB, access_Inc=KEYAB, access_Dec=KEYAB):
|
||||||
|
# C1 weight 2 , C2 weight 1 , C3 weight 4
|
||||||
|
# Key Read Key Write INCREment decrement/transfer/etc
|
||||||
|
access_Blk_idx=((self.KEYAB, self.KEYAB, self.KEYAB, self.KEYAB,None),
|
||||||
|
(self.KEYAB, self.NEVER, self.NEVER, self.NEVER,None),
|
||||||
|
(self.KEYAB, self.KEYB, self.NEVER, self.NEVER,None),
|
||||||
|
(self.KEYAB, self.KEYB, self.KEYB, self.KEYAB,None),
|
||||||
|
(self.KEYAB, self.NEVER, self.NEVER, self.KEYAB,None),
|
||||||
|
(self.KEYB, self.KEYB, self.NEVER, self.NEVER,None),
|
||||||
|
(self.KEYB, self.NEVER, self.NEVER, self.NEVER,None),
|
||||||
|
(self.NEVER, self.NEVER, self.NEVER, self.NEVER,None))
|
||||||
|
|
||||||
|
if(blockID == self.ALLBLOCK):
|
||||||
|
Mask = 7
|
||||||
|
elif (BlockID<0) or (blockID >3):
|
||||||
|
return false
|
||||||
|
else:
|
||||||
|
Mask = 1 << blockID
|
||||||
|
|
||||||
|
if self.findAccessIndex(access_Blk_idx,Mask,( access_Read, access_Write, access_Inc, access_Dec, None)):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("**** Error Access Block method not possible")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def encodeAccess(self):
|
||||||
|
self.C1 = self.C1 & 0xf
|
||||||
|
self.C2 = self.C2 & 0xf
|
||||||
|
self.C3 = self.C3 & 0xf
|
||||||
|
self.C1_INV = self.C1 ^ 0xf
|
||||||
|
self.C2_INV = self.C2 ^ 0xf
|
||||||
|
self.C3_INV = self.C3 ^ 0xf
|
||||||
|
byte6 = self.C2_INV << 4 | self.C1_INV
|
||||||
|
byte7 = self.C1 << 4 | self.C3_INV
|
||||||
|
byte8 = self.C3 << 4 | self.C2
|
||||||
|
return (byte6, byte7, byte8)
|
||||||
|
|
||||||
|
|
||||||
|
def decodeAccess(self, byte6,byte7,byte8):
|
||||||
|
self.C1_Inv = byte6 & 0xf
|
||||||
|
self.C2_Inv = (byte6 & 0xf0) >> 4
|
||||||
|
self.C3_Inv = byte7 & 0xf
|
||||||
|
self.C1 = (byte7 & 0xf0) >> 4
|
||||||
|
self.C2 = byte8 & 0xf
|
||||||
|
self.C3 = (byte8 & 0xf0) >>4
|
||||||
|
return ((self.C1 ^ self.C1_Inv) & (self.C2 ^ self.C2_Inv) & (self.C3 ^ self.C3_Inv)) & 0xf == 0xf
|
||||||
|
|
||||||
|
|
||||||
|
def showTrailerAccess(self):
|
||||||
|
KeyAWrite = ['key A', 'never', 'key B', 'never', 'key A', 'key B', 'never', 'never']
|
||||||
|
AccessRead = ['key A', 'key A', 'key A|B', 'key A|B', 'key A','key A|B','key A|B','key A|B' ]
|
||||||
|
AccessWrite = ['never', 'never', 'never', 'never', 'key A', 'key B', 'key B', 'never']
|
||||||
|
KeyBRead = ['key A data R/W', 'key A data R', 'never', 'never', 'key A data R/W', 'never', 'never', 'never']
|
||||||
|
KeyBWrite = ['key A data R/W', 'never', 'key B', 'never', 'key A data R/W', 'key B', 'never', 'never']
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
if self.C2 & 0x8 > 0:
|
||||||
|
index = 1
|
||||||
|
if self.C1 & 0x8 > 0:
|
||||||
|
index = index + 2
|
||||||
|
if self.C3 & 0x8 > 0:
|
||||||
|
index = index + 4
|
||||||
|
|
||||||
|
|
||||||
|
#print("TrailerAccess idx=",index)
|
||||||
|
print('Access key A read => never')
|
||||||
|
print('Access key A write =>', KeyAWrite[index])
|
||||||
|
print('Access key B read =>', KeyBRead[index])
|
||||||
|
print('Access key B write =>', KeyBWrite[index])
|
||||||
|
print('Access bits read =>', AccessRead[index])
|
||||||
|
print('Access bits write =>', AccessWrite[index])
|
||||||
|
|
||||||
|
|
||||||
|
def showBlockAccess(self,blockID):
|
||||||
|
BlockRead = ['key A|B','key A|B','key A|B','key A|B','key A|B','key B', 'key B', 'never' ]
|
||||||
|
BlockWrite = ['key A|B', 'never', 'key B', 'key B', 'never', 'key B','never', 'never']
|
||||||
|
BlockIncrement = ['key A|B', 'never', 'never', 'key B', 'never', 'never', 'never', 'never']
|
||||||
|
BlockDecrement = ['key A|B', 'never', 'never', 'key A|B', 'key A|B', 'never', 'never', 'never']
|
||||||
|
if blockID == 3:
|
||||||
|
self.showTrailerAccess()
|
||||||
|
else:
|
||||||
|
mask = 1 << blockID
|
||||||
|
index = 0
|
||||||
|
if (self.C2 & mask) > 0:
|
||||||
|
index =1
|
||||||
|
if (self.C1 & mask) > 0:
|
||||||
|
index = index + 2
|
||||||
|
if (self.C3 & mask) > 0:
|
||||||
|
index = index + 4
|
||||||
|
|
||||||
|
print("Block ", blockID, " read =>", BlockRead[index])
|
||||||
|
print("Block ", blockID, " write =>", BlockWrite[index])
|
||||||
|
print("Block ", blockID, " Increment =>", BlockIncrement[index])
|
||||||
|
print("Block ", blockID, " Decrement+ =>", BlockDecrement[index])
|
||||||
|
|
||||||
|
def showAccess(self):
|
||||||
|
print("/--------- SHOW ACCESS ---------\\")
|
||||||
|
AccessB = self.encodeAccess()
|
||||||
|
print('Access Bytes (6,7,8)= (',hex(AccessB[0]),', ',hex(AccessB[1]),', ',hex(AccessB[2]),')')
|
||||||
|
print('(C1, C2, C3) = (',hex(self.C1),', ',hex(self.C2),', ',hex(self.C3),')')
|
||||||
|
for i in range(4):
|
||||||
|
self.showBlockAccess(i)
|
||||||
|
print("\\---------------------------------/")
|
||||||
|
|
||||||
|
|
||||||
|
def fillBlock3(self,keyA=None,keyB=None,block=None):
|
||||||
|
if block is None:
|
||||||
|
block = 16*[0xff]
|
||||||
|
if len(block) != 16:
|
||||||
|
block = 16*[0xff]
|
||||||
|
|
||||||
|
if keyA is not None:
|
||||||
|
if len(keyA) == 6 :
|
||||||
|
block[0:6]=keyA
|
||||||
|
|
||||||
|
if keyB is not None:
|
||||||
|
if len(keyB) == 6 :
|
||||||
|
block[10:16]=keyB
|
||||||
|
b6, b7, b8 = self.encodeAccess()
|
||||||
|
block[6]=b6
|
||||||
|
block[7]=b7
|
||||||
|
block[8]=b8
|
||||||
|
return block
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
rfid = RfidAccess()
|
||||||
|
|
||||||
|
|
||||||
|
print("\nEx: Decode access_bits for [0xff, 0x07, 0x80]")
|
||||||
|
if rfid.decodeAccess(0xFF,0x07,0x80):
|
||||||
|
rfid.showAccess()
|
||||||
|
else:
|
||||||
|
print('Invalid Access')
|
||||||
|
|
||||||
|
print("\n\nSet block 0 to 3 to be read by KEYA but R/W with KEYB")
|
||||||
|
rfid.setBlockAccess(rfid.ALLBLOCK, access_Read=rfid.KEYAB, access_Write=rfid.KEYB, access_Inc=rfid.NEVER, access_Dec=rfid.NEVER)
|
||||||
|
print("Set sector trailer to be only set by Key B");
|
||||||
|
rfid.setTrailerAccess(keyA_Write=rfid.KEYB,access_Read=rfid.KEYAB,access_Write=rfid.KEYB,keyB_Read=rfid.NEVER,keyB_Write=rfid.KEYB)
|
||||||
|
rfid.showAccess()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
from mfrc522 import MFRC522
|
|
||||||
|
|
||||||
|
|
||||||
def uidToString(uid):
|
|
||||||
mystring = ""
|
|
||||||
for i in uid:
|
|
||||||
mystring = "%02X" % i + mystring
|
|
||||||
return mystring
|
|
||||||
|
|
||||||
|
|
||||||
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
|
|
||||||
|
|
||||||
print("")
|
|
||||||
print("Place card before reader to read from address 0x08")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
|
|
||||||
(stat, tag_type) = reader.request(reader.REQIDL)
|
|
||||||
|
|
||||||
if stat == reader.OK:
|
|
||||||
|
|
||||||
(stat, uid) = reader.SelectTagSN()
|
|
||||||
|
|
||||||
if stat == reader.OK:
|
|
||||||
print("Card detected %s" % uidToString(uid))
|
|
||||||
else:
|
|
||||||
print("Authentication error")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Bye")
|
|
||||||
|
|
||||||
|
|
||||||
95
mfrc522.py
95
mfrc522.py
@@ -220,22 +220,49 @@ class MFRC522:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def SelectTag(self, uid):
|
||||||
|
byte5 = 0
|
||||||
|
|
||||||
|
#(status,puid)= self.anticoll(self.PICC_ANTICOLL1)
|
||||||
|
#print("uid",uid,"puid",puid)
|
||||||
|
for i in uid:
|
||||||
|
byte5 = byte5 ^ i
|
||||||
|
puid = uid + [byte5]
|
||||||
|
|
||||||
|
if self.PcdSelect(puid,self.PICC_ANTICOLL1) == 0:
|
||||||
|
return (self.ERR,[])
|
||||||
|
return (self.OK , uid)
|
||||||
|
|
||||||
|
def tohexstring(self,v):
|
||||||
|
s="["
|
||||||
|
for i in v:
|
||||||
|
if i != v[0]:
|
||||||
|
s = s+ ", "
|
||||||
|
s=s+ "0x{:02X}".format(i)
|
||||||
|
s= s+ "]"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def SelectTagSN(self):
|
def SelectTagSN(self):
|
||||||
valid_uid=[]
|
valid_uid=[]
|
||||||
(status,uid)= self.anticoll(self.PICC_ANTICOLL1)
|
(status,uid)= self.anticoll(self.PICC_ANTICOLL1)
|
||||||
|
#print("Select Tag 1:",self.tohexstring(uid))
|
||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR,[])
|
return (self.ERR,[])
|
||||||
|
|
||||||
if self.DEBUG: print("anticol(1) {}".format(uid))
|
if self.DEBUG: print("anticol(1) {}".format(uid))
|
||||||
if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0:
|
if self.PcdSelect(uid,self.PICC_ANTICOLL1) == 0:
|
||||||
return (self.ERR,[])
|
return (self.ERR,[])
|
||||||
if self.DEBUG: print("pcdSelect(1) {}".format(uid))
|
if self.DEBUG: print("pcdSelect(1) {}".format(uid))
|
||||||
|
|
||||||
#check if first byte is 0x88
|
#check if first byte is 0x88
|
||||||
if uid[0] == 0x88 :
|
if uid[0] == 0x88 :
|
||||||
#ok we have another type of card
|
#ok we have another type of card
|
||||||
valid_uid.extend(uid[1:4])
|
valid_uid.extend(uid[1:4])
|
||||||
(status,uid)=self.anticoll(self.PICC_ANTICOLL2)
|
(status,uid)=self.anticoll(self.PICC_ANTICOLL2)
|
||||||
|
#print("Select Tag 2:",self.tohexstring(uid))
|
||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR,[])
|
return (self.ERR,[])
|
||||||
if self.DEBUG: print("Anticol(2) {}".format(uid))
|
if self.DEBUG: print("Anticol(2) {}".format(uid))
|
||||||
@@ -248,6 +275,7 @@ class MFRC522:
|
|||||||
if uid[0] == 0x88 :
|
if uid[0] == 0x88 :
|
||||||
valid_uid.extend(uid[1:4])
|
valid_uid.extend(uid[1:4])
|
||||||
(status , uid) = self.anticoll(self.PICC_ANTICOLL3)
|
(status , uid) = self.anticoll(self.PICC_ANTICOLL3)
|
||||||
|
#print("Select Tag 3:",self.tohexstring(uid))
|
||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR,[])
|
return (self.ERR,[])
|
||||||
if self.DEBUG: print("Anticol(3) {}".format(uid))
|
if self.DEBUG: print("Anticol(3) {}".format(uid))
|
||||||
@@ -268,7 +296,15 @@ class MFRC522:
|
|||||||
|
|
||||||
def auth(self, mode, addr, sect, ser):
|
def auth(self, mode, addr, sect, ser):
|
||||||
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
|
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
|
||||||
|
|
||||||
|
def authKeys(self,uid,addr,keyA=None, keyB=None):
|
||||||
|
status = self.ERR
|
||||||
|
if keyA is not None:
|
||||||
|
status = self.auth(self.AUTHENT1A, addr, keyA, uid)
|
||||||
|
elif keyB is not None:
|
||||||
|
status = self.auth(self.AUTHENT1B, addr, keyB, uid)
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
def stop_crypto1(self):
|
def stop_crypto1(self):
|
||||||
self._cflags(0x08, 0x08)
|
self._cflags(0x08, 0x08)
|
||||||
@@ -278,7 +314,7 @@ class MFRC522:
|
|||||||
data = [0x30, addr]
|
data = [0x30, addr]
|
||||||
data += self._crc(data)
|
data += self._crc(data)
|
||||||
(stat, recv, _) = self._tocard(0x0C, data)
|
(stat, recv, _) = self._tocard(0x0C, data)
|
||||||
return recv if stat == self.OK else None
|
return stat, recv
|
||||||
|
|
||||||
def write(self, addr, data):
|
def write(self, addr, data):
|
||||||
|
|
||||||
@@ -296,22 +332,53 @@ class MFRC522:
|
|||||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||||
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
||||||
stat = self.ERR
|
stat = self.ERR
|
||||||
|
|
||||||
return stat
|
return stat
|
||||||
|
|
||||||
def MFRC522_DumpClassic1K(self, key, uid, Start=0, End=64):
|
|
||||||
for i in range(Start,End):
|
def writeSectorBlock(self,uid, sector, block, data, keyA=None, keyB = None):
|
||||||
status = self.auth(self.AUTHENT1A, i, key, uid)
|
absoluteBlock = sector * 4 + (block % 4)
|
||||||
|
if absoluteBlock > 63 :
|
||||||
|
return self.ERR
|
||||||
|
if len(data) != 16:
|
||||||
|
return self.ERR
|
||||||
|
if self.authKeys(uid,absoluteBlock,keyA,keyB) != self.ERR :
|
||||||
|
return self.write(absoluteBlock, data)
|
||||||
|
return self.ERR
|
||||||
|
|
||||||
|
def readSectorBlock(self,uid ,sector, block, data,keyA=None, keyB = None):
|
||||||
|
absoluteBlock = sector * 4 + (block % 4)
|
||||||
|
if page > 63 :
|
||||||
|
return self.ERR, None
|
||||||
|
if len(data) != 16:
|
||||||
|
return self.ERR, None
|
||||||
|
if self.authKeys(uid,page,KeyA,KeyB) != self.ERR :
|
||||||
|
return self.read(page)
|
||||||
|
return self.ERR, None
|
||||||
|
|
||||||
|
def MFRC522_DumpClassic1K(self,uid, Start=0, End=64, keyA=None, keyB=None):
|
||||||
|
for absoluteBlock in range(Start,End):
|
||||||
|
status = self.authKeys(uid,absoluteBlock,keyA,keyB)
|
||||||
# Check if authenticated
|
# Check if authenticated
|
||||||
print("{:02d}: ".format(i),end="")
|
print("{:02d} S{:02d} B{:1d}: ".format(absoluteBlock, absoluteBlock//4 , absoluteBlock % 4),end="")
|
||||||
if status == self.OK:
|
if status == self.OK:
|
||||||
block = self.read(i)
|
status, block = self.read(absoluteBlock)
|
||||||
if block is None:
|
if status == self.ERR:
|
||||||
print("-- ")
|
break
|
||||||
else:
|
else:
|
||||||
for value in block:
|
for value in block:
|
||||||
print("{:02X} ".format(value),end="")
|
print("{:02X} ".format(value),end="")
|
||||||
|
print(" ",end="")
|
||||||
|
for value in block:
|
||||||
|
if (value > 0x20) and (value < 0x7f):
|
||||||
|
print(chr(value),end="")
|
||||||
|
else:
|
||||||
|
print('.',end="")
|
||||||
print("")
|
print("")
|
||||||
else:
|
else:
|
||||||
print("Authentication error")
|
break
|
||||||
|
if status == self.ERR:
|
||||||
|
print("Authentication error")
|
||||||
|
return self.ERR
|
||||||
|
return self.OK
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user