Added gcddump to dump parsed GCD to files which can later be reassembled
into a GCD.
This commit is contained in:
+83
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user