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)
|
||||
|
||||
print("")
|
||||
print("Place card before reader to read from address 0x08")
|
||||
print("Please place card on reader")
|
||||
print("")
|
||||
|
||||
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
|
||||
@@ -32,7 +32,7 @@ try:
|
||||
if stat == reader.OK:
|
||||
print(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("with [ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 ]")
|
||||
absoluteBlock=8
|
||||
@@ -43,7 +43,7 @@ try:
|
||||
if status == reader.OK:
|
||||
status = reader.write(absoluteBlock,value)
|
||||
if status == reader.OK:
|
||||
reader.MFRC522_DumpClassic1K(key, uid)
|
||||
reader.MFRC522_DumpClassic1K(uid,keyA=key)
|
||||
else:
|
||||
print("unable to write")
|
||||
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")
|
||||
|
||||
|
||||
85
mfrc522.py
85
mfrc522.py
@@ -220,9 +220,35 @@ class MFRC522:
|
||||
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):
|
||||
valid_uid=[]
|
||||
(status,uid)= self.anticoll(self.PICC_ANTICOLL1)
|
||||
#print("Select Tag 1:",self.tohexstring(uid))
|
||||
if status != self.OK:
|
||||
return (self.ERR,[])
|
||||
|
||||
@@ -236,6 +262,7 @@ class MFRC522:
|
||||
#ok we have another type of card
|
||||
valid_uid.extend(uid[1:4])
|
||||
(status,uid)=self.anticoll(self.PICC_ANTICOLL2)
|
||||
#print("Select Tag 2:",self.tohexstring(uid))
|
||||
if status != self.OK:
|
||||
return (self.ERR,[])
|
||||
if self.DEBUG: print("Anticol(2) {}".format(uid))
|
||||
@@ -248,6 +275,7 @@ class MFRC522:
|
||||
if uid[0] == 0x88 :
|
||||
valid_uid.extend(uid[1:4])
|
||||
(status , uid) = self.anticoll(self.PICC_ANTICOLL3)
|
||||
#print("Select Tag 3:",self.tohexstring(uid))
|
||||
if status != self.OK:
|
||||
return (self.ERR,[])
|
||||
if self.DEBUG: print("Anticol(3) {}".format(uid))
|
||||
@@ -269,6 +297,14 @@ class MFRC522:
|
||||
def auth(self, mode, addr, sect, ser):
|
||||
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):
|
||||
self._cflags(0x08, 0x08)
|
||||
@@ -278,7 +314,7 @@ class MFRC522:
|
||||
data = [0x30, addr]
|
||||
data += self._crc(data)
|
||||
(stat, recv, _) = self._tocard(0x0C, data)
|
||||
return recv if stat == self.OK else None
|
||||
return stat, recv
|
||||
|
||||
def write(self, addr, data):
|
||||
|
||||
@@ -296,22 +332,53 @@ class MFRC522:
|
||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
||||
stat = self.ERR
|
||||
|
||||
return stat
|
||||
|
||||
def MFRC522_DumpClassic1K(self, key, uid, Start=0, End=64):
|
||||
for i in range(Start,End):
|
||||
status = self.auth(self.AUTHENT1A, i, key, uid)
|
||||
|
||||
def writeSectorBlock(self,uid, sector, block, data, keyA=None, keyB = None):
|
||||
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
|
||||
print("{:02d}: ".format(i),end="")
|
||||
print("{:02d} S{:02d} B{:1d}: ".format(absoluteBlock, absoluteBlock//4 , absoluteBlock % 4),end="")
|
||||
if status == self.OK:
|
||||
block = self.read(i)
|
||||
if block is None:
|
||||
print("-- ")
|
||||
status, block = self.read(absoluteBlock)
|
||||
if status == self.ERR:
|
||||
break
|
||||
else:
|
||||
for value in block:
|
||||
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("")
|
||||
else:
|
||||
break
|
||||
if status == self.ERR:
|
||||
print("Authentication error")
|
||||
return self.ERR
|
||||
return self.OK
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user