Added gcddump to dump parsed GCD to files which can later be reassembled

into a GCD.
This commit is contained in:
2018-10-21 01:03:19 +02:00
parent c0a1d833ba
commit 27a90e8b38
3 changed files with 154 additions and 2 deletions
+83 -2
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from . import devices
from binascii import hexlify
from struct import pack, unpack
TLV_TYPES = {
@@ -22,6 +23,7 @@ TLV_TYPES = {
class TLV:
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
self.type_id = type_id
self.is_binary = False
self.offset = offset
self.comment = TLV_TYPES.get(type_id, "Type {:04x} / {:d}".format(type_id, type_id))
self.length = expected_length
@@ -33,10 +35,19 @@ class TLV:
@staticmethod
def factory(header: bytes, offset: int = None):
(type_id, length) = unpack("<HH", header)
if type_id == 0x0006:
if type_id == 0x0001:
new_tlv = TLV1(type_id, length)
elif type_id == 0x0002:
new_tlv = TLV2(type_id, length)
elif type_id == 0x0005:
new_tlv = TLV5(type_id, length)
elif type_id == 0x0006:
new_tlv = TLV6(type_id, length)
elif type_id == 0x0007:
new_tlv = TLV7(type_id, length)
elif type_id in [0x0008, 0x0401, 0x0505, 0x0555, 0x0557, 0x02bd]:
new_tlv = TLVbinary(type_id, length)
new_tlv.is_binary = True
else:
new_tlv = TLV(type_id, length)
new_tlv.offset = offset
@@ -73,6 +84,43 @@ class TLV:
return header
return header + self.value
def dump(self):
"""Should return a list of key-value-comment tuples so the object can be recreated using create_from_dump() later."""
data = []
data.append(("type", "0x{:04x}".format(self.type_id), self.comment))
data.append(("length", self.get_actual_length(), None))
if self.value is not None:
hexstr = hexlify(self.value).decode("utf-8")
hexstr = " ".join(hexstr[i:i+2] for i in range(0, len(hexstr), 2))
data.append(("value", hexstr, None))
return data
@staticmethod
def create_from_dump(values):
"""Use data exported with dump() to recreate object."""
pass
class TLV1(TLV):
def dump(self):
data = []
data.append(("type", "0x{:04x}".format(self.type_id), self.comment))
return data
class TLV2(TLV):
def dump(self):
data = []
data.append(("type", "0x{:04x}".format(self.type_id), self.comment))
data.append(("length", self.get_actual_length(), "Length of padding block"))
return data
class TLV5(TLV):
def dump(self):
data = []
data.append(("type", "0x{:04x}".format(self.type_id), self.comment))
data.append(("length", self.get_actual_length(), None))
data.append(("text", self.value.decode("utf-8"), None))
return data
class TLV6(TLV):
"""
Describes following TLV7:
@@ -90,7 +138,7 @@ class TLV6(TLV):
0x1014: ["H", "Field 1014"],
0x1015: ["H", "Field 1015"],
0x1016: ["H", "Field 1016 (WiFi fw)"],
0x2015: ["L", "Block size"],
0x2015: ["L", "Binary length"],
0x5003: ["", "End of definition marker"],
}
@@ -119,6 +167,10 @@ class TLV6(TLV):
txt += "\n - Field {:d}: {:04x} - {}".format(i+1, fid, self.fields[i])
return txt
def dump(self):
# Dump nothing as important info will be chained in binary dump
return []
class TLV7(TLV):
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
super().__init__(type_id, expected_length, value, offset)
@@ -153,3 +205,32 @@ class TLV7(TLV):
txt += "\n - Field {:d}: {:>20}: 0x{:04x} / {:d}".format(i+1, fdesc, v, v)
return txt
def dump(self):
# Dump nothing as important info will be chained in binary dump
return []
class TLVbinary(TLV):
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
super().__init__(type_id, expected_length, value, offset)
self.tlv7 = None
def set_tlv7(self, tlv7: TLV7):
self.tlv7 = tlv7
def dump(self):
data = []
# type is given in fields list from TLV7 already
if not self.tlv7.is_parsed:
self.tlv7.parse()
for i, pair in enumerate(self.tlv7.attr):
fdesc = self.tlv7.tlv6.fields[i]
valtype = self.tlv7.tlv6.format[i]
(fid, v) = pair
if valtype == "B":
valstr = "0x{:02x}".format(v)
elif valtype == "H":
valstr = "0x{:04x}".format(v)
else:
valstr = "0x{:08x}".format(v)
data.append(("0x{:04x}".format(fid), valstr, fdesc))
return data