109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
__name__ = "ExtendedMFRC522"
|
||
|
|
||
|
from mfrc522 import SimpleMFRC522
|
||
|
|
||
|
|
||
|
class ExtendedMFRC522(SimpleMFRC522):
|
||
|
|
||
|
def __init__(self, start_section=1, sections=0, blocks_per_section=4, block_size=16, encoding='utf8'):
|
||
|
self.START_SECTION = start_section
|
||
|
self.SECTIONS = sections
|
||
|
self.BLOCKS_PER_SECTIONS = blocks_per_section
|
||
|
self.DATA_BLOCKS = self.BLOCKS_PER_SECTIONS - 1
|
||
|
self.BLOCK_SIZE = block_size
|
||
|
self.ENCODING = encoding
|
||
|
if self.START_SECTION < 1:
|
||
|
self.START_SECTION = 1
|
||
|
super().__init__()
|
||
|
|
||
|
def read_no_block(self):
|
||
|
(status, size) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
|
||
|
if status != self.READER.MI_OK:
|
||
|
return None, None
|
||
|
(status, uid) = self.READER.MFRC522_Anticoll()
|
||
|
if status != self.READER.MI_OK:
|
||
|
return None, None
|
||
|
id = self.uid_to_num(uid)
|
||
|
self.READER.MFRC522_SelectTag(uid)
|
||
|
data = bytearray()
|
||
|
|
||
|
start_section = self.START_SECTION
|
||
|
if start_section > size:
|
||
|
start_section = size - 1
|
||
|
|
||
|
sections = size - start_section
|
||
|
if self.SECTIONS > 0 and self.SECTIONS <= sections:
|
||
|
sections = self.SECTIONS
|
||
|
|
||
|
for section in range(start_section, start_section + sections):
|
||
|
trailer_block = section * self.BLOCKS_PER_SECTIONS + self.DATA_BLOCKS
|
||
|
status = self.READER.MFRC522_Auth(
|
||
|
self.READER.PICC_AUTHENT1A, trailer_block, self.KEY, uid)
|
||
|
if status == self.READER.MI_OK:
|
||
|
for i in range(self.DATA_BLOCKS):
|
||
|
block_addr = section * self.BLOCKS_PER_SECTIONS + i
|
||
|
block = self.READER.MFRC522_Read(block_addr)
|
||
|
if block:
|
||
|
data.extend(bytearray(block))
|
||
|
else:
|
||
|
return None, None
|
||
|
|
||
|
text_read = ''
|
||
|
if data:
|
||
|
while data and data[0] == 0:
|
||
|
data.pop(0)
|
||
|
while data and data[-1] == 0:
|
||
|
data.pop()
|
||
|
if data:
|
||
|
text_read = data.decode(self.ENCODING)
|
||
|
self.READER.MFRC522_StopCrypto1()
|
||
|
return id, text_read
|
||
|
|
||
|
def write_no_block(self, text):
|
||
|
(status, size) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
|
||
|
if status != self.READER.MI_OK:
|
||
|
return None, None
|
||
|
(status, uid) = self.READER.MFRC522_Anticoll()
|
||
|
if status != self.READER.MI_OK:
|
||
|
return None, None
|
||
|
id = self.uid_to_num(uid)
|
||
|
self.READER.MFRC522_SelectTag(uid)
|
||
|
|
||
|
start_section = self.START_SECTION
|
||
|
if start_section > size:
|
||
|
start_section = size - 1
|
||
|
|
||
|
sections = size - start_section
|
||
|
if self.SECTIONS > 0 and self.SECTIONS <= sections:
|
||
|
sections = self.SECTIONS
|
||
|
|
||
|
data = text.strip().encode(self.ENCODING)
|
||
|
data_sections = [data[i:i + self.BLOCK_SIZE * self.DATA_BLOCKS]
|
||
|
for i in range(0, len(data), self.BLOCK_SIZE * self.DATA_BLOCKS)]
|
||
|
|
||
|
for section in range(start_section, start_section + sections):
|
||
|
trailer_block = section * self.BLOCKS_PER_SECTIONS + self.DATA_BLOCKS
|
||
|
status = self.READER.MFRC522_Auth(
|
||
|
self.READER.PICC_AUTHENT1A, trailer_block, self.KEY, uid)
|
||
|
self.READER.MFRC522_Read(trailer_block)
|
||
|
|
||
|
section_data = bytearray(self.DATA_BLOCKS * self.BLOCK_SIZE)
|
||
|
if len(data_sections) > (section - start_section):
|
||
|
section_data = bytearray(
|
||
|
data_sections[section - start_section])
|
||
|
section_data.extend(
|
||
|
bytearray(self.DATA_BLOCKS * self.BLOCK_SIZE - len(section_data)))
|
||
|
|
||
|
if status == self.READER.MI_OK:
|
||
|
for i in range(self.DATA_BLOCKS):
|
||
|
block_addr = section * self.BLOCKS_PER_SECTIONS + i
|
||
|
block_data = section_data[(
|
||
|
i*self.BLOCK_SIZE):(i+1)*self.BLOCK_SIZE]
|
||
|
self.READER.MFRC522_Write(
|
||
|
block_addr, block_data)
|
||
|
self.READER.MFRC522_StopCrypto1()
|
||
|
return id, data[0:(len(self.BLOCK_ADDRS) * self.BLOCK_SIZE * sections)].decode(self.ENCODING)
|