"""Portable, read-only TMS firmware verification against an immutable BIN.""" from protocan.tms2812 import build_upload_request, decode_upload_reply from .bin_compare import compare_sha256 class TmsFirmwareCheck: def __init__(self, controller, word_address, image, block_size=256): self.image = bytes(image) if not 1 <= controller <= 255: raise ValueError("Для проверки нужен адрес контроллера 1..255") if not self.image or len(self.image) > 4 * 1024 * 1024: raise ValueError("Размер BIN должен быть 1..4194304 байт") if not 0 <= word_address <= 0xFFFFFFFF or word_address + (len(self.image) + 1) // 2 > 0x100000000: raise ValueError("Диапазон памяти вне 32-битного адресного пространства") if not 2 <= block_size <= 65534 or block_size % 2: raise ValueError("Размер блока должен быть чётным: 2..65534 байт") self.controller, self.word_address = controller, word_address self.block_size = block_size self.readback = bytearray() @property def done(self): return len(self.readback) == len(self.image) @property def count(self): return min(self.block_size, len(self.image) - len(self.readback)) def request(self): if self.done: raise ValueError("Проверка уже завершена") return build_upload_request(self.controller, self.word_address + len(self.readback) // 2, self.count) def accept(self, reply): if self.done: raise ValueError("Проверка уже завершена") self.readback.extend(decode_upload_reply(reply, self.controller, self.count)) def result(self): return compare_sha256(self.image, bytes(self.readback))