Detect RGN-in-RGN structure.
This commit is contained in:
parent
3545d2b12e
commit
9d9dc3671b
53
grmn/rgn.py
53
grmn/rgn.py
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Thanks to Herbert Oppmann (herby) for all your work!
|
# Thanks to Herbert Oppmann (herby) for all your work!
|
||||||
|
|
||||||
from .ansi import RESET, RED
|
from .ansi import RESET, RED, YELLOW
|
||||||
from .chksum import ChkSum
|
from .chksum import ChkSum
|
||||||
from .rgnbin import RgnBin
|
from .rgnbin import RgnBin
|
||||||
from struct import unpack
|
from struct import unpack
|
||||||
@ -38,8 +38,6 @@ class Rgn:
|
|||||||
def load(self):
|
def load(self):
|
||||||
if self.filename is None:
|
if self.filename is None:
|
||||||
return False
|
return False
|
||||||
last_tlv6 = None
|
|
||||||
last_tlv7 = None
|
|
||||||
with open(self.filename, "rb") as f:
|
with open(self.filename, "rb") as f:
|
||||||
sig = f.read(4)
|
sig = f.read(4)
|
||||||
if sig != RGN_SIG:
|
if sig != RGN_SIG:
|
||||||
@ -59,6 +57,29 @@ class Rgn:
|
|||||||
self.add_rec(rec)
|
self.add_rec(rec)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def load_from_bytes(self, payload: bytes):
|
||||||
|
pos = 0
|
||||||
|
sig = payload[pos:pos+4]
|
||||||
|
if sig != RGN_SIG:
|
||||||
|
raise ParseException("Signature mismatch ({}, should be {})!".format(repr(sig), repr(RGN_SIG)))
|
||||||
|
pos += 4
|
||||||
|
self.version = unpack("<H", payload[pos:pos+2])[0]
|
||||||
|
pos += 2
|
||||||
|
while True:
|
||||||
|
cur_offset = pos
|
||||||
|
if pos >= len(payload):
|
||||||
|
#print("End of file reached.")
|
||||||
|
break
|
||||||
|
header = payload[pos:pos+5]
|
||||||
|
pos += 5
|
||||||
|
(length, type_id) = unpack("<Lc", header)
|
||||||
|
#print("Found record type: {} with {} Bytes length.".format(type_id, length))
|
||||||
|
rec = RgnRecord.factory(type_id, length, offset=cur_offset)
|
||||||
|
inner_payload = payload[pos:pos+length]
|
||||||
|
pos += length
|
||||||
|
rec.set_payload(inner_payload)
|
||||||
|
self.add_rec(rec)
|
||||||
|
|
||||||
def add_rec(self, new_rec):
|
def add_rec(self, new_rec):
|
||||||
self.struct.append(new_rec)
|
self.struct.append(new_rec)
|
||||||
|
|
||||||
@ -66,10 +87,7 @@ class Rgn:
|
|||||||
"""
|
"""
|
||||||
Prints the structure of the parsed RGN file
|
Prints the structure of the parsed RGN file
|
||||||
"""
|
"""
|
||||||
print("RGN File Version: {}".format(self.version))
|
print(str(self))
|
||||||
print("{} records.".format(len(self.struct)))
|
|
||||||
for i, rec in enumerate(self.struct):
|
|
||||||
print("#{:03d}: {}".format(i, rec))
|
|
||||||
|
|
||||||
def print_struct_full(self):
|
def print_struct_full(self):
|
||||||
"""
|
"""
|
||||||
@ -94,6 +112,13 @@ class Rgn:
|
|||||||
def save(self, filename):
|
def save(self, filename):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
txt = "RGN File Version: {}".format(self.version)
|
||||||
|
txt += "\n{} records.".format(len(self.struct))
|
||||||
|
for i, rec in enumerate(self.struct):
|
||||||
|
txt += "\n#{:03d}: {}".format(i, rec)
|
||||||
|
return txt
|
||||||
|
|
||||||
class RgnRecord():
|
class RgnRecord():
|
||||||
def __init__(self, type_id, expected_length, payload=None, offset=None):
|
def __init__(self, type_id, expected_length, payload=None, offset=None):
|
||||||
self.type_id = type_id
|
self.type_id = type_id
|
||||||
@ -215,6 +240,11 @@ class RgnRecordR(RgnRecord):
|
|||||||
self.delay_ms = None
|
self.delay_ms = None
|
||||||
self.size = None
|
self.size = None
|
||||||
|
|
||||||
|
def id_payload(self):
|
||||||
|
if self.payload[10:10+len(RGN_SIG)] == RGN_SIG:
|
||||||
|
return "RGN"
|
||||||
|
return "BIN"
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
if self.is_parsed:
|
if self.is_parsed:
|
||||||
# already parsed
|
# already parsed
|
||||||
@ -230,4 +260,13 @@ class RgnRecordR(RgnRecord):
|
|||||||
txt += "\n - Region ID: {:04x} ({})".format(self.region_id, rgn_type)
|
txt += "\n - Region ID: {:04x} ({})".format(self.region_id, rgn_type)
|
||||||
txt += "\n - Flash delay: {} ms".format(self.delay_ms)
|
txt += "\n - Flash delay: {} ms".format(self.delay_ms)
|
||||||
txt += "\n - Binary size: {} Bytes".format(self.size)
|
txt += "\n - Binary size: {} Bytes".format(self.size)
|
||||||
|
if len(self.payload) - 10 == self.size:
|
||||||
|
txt += " (OK)"
|
||||||
|
else:
|
||||||
|
txt += " (" + RED + "MISMATCH!" + RESET + ")"
|
||||||
|
if self.id_payload() == "RGN":
|
||||||
|
txt += "\n " + YELLOW + "PAYLOAD IS ANOTHER RGN STRUCTURE:" + RESET
|
||||||
|
rgn = Rgn()
|
||||||
|
rgn.load_from_bytes(self.payload[10:])
|
||||||
|
txt += "\n " + "\n ".join(str(rgn).split("\n"))
|
||||||
return txt
|
return txt
|
||||||
|
@ -9,6 +9,8 @@ from struct import unpack
|
|||||||
# RGN = outside hull
|
# RGN = outside hull
|
||||||
# BIN = firmware + hwid + checksum
|
# BIN = firmware + hwid + checksum
|
||||||
|
|
||||||
|
END_PATTERN = b"\xff\xff\x5a\xa5\xff\xff\xff\xff"
|
||||||
|
|
||||||
class ParseException(Exception):
|
class ParseException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user