Finish creating structure from recipe. TODO: Storing to GCD file.
This commit is contained in:
parent
becb94eb88
commit
70c0734d34
36
grmn/gcd.py
36
grmn/gcd.py
@ -2,7 +2,7 @@
|
|||||||
# Thanks to TurboCCC and kunix for all your work!
|
# Thanks to TurboCCC and kunix for all your work!
|
||||||
|
|
||||||
from .chksum import ChkSum
|
from .chksum import ChkSum
|
||||||
from .tlv import TLV, TLV6, TLV7
|
from .tlv import TLV, TLV6, TLV7, TLVbinary
|
||||||
from struct import unpack
|
from struct import unpack
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
@ -166,13 +166,39 @@ class Gcd:
|
|||||||
if s == "GCD_DUMP":
|
if s == "GCD_DUMP":
|
||||||
continue
|
continue
|
||||||
print("Parsing {}".format(s))
|
print("Parsing {}".format(s))
|
||||||
|
params = []
|
||||||
|
for k in rcp[s]:
|
||||||
|
params.append((k, rcp[s][k]))
|
||||||
if "from_file" in rcp[s]:
|
if "from_file" in rcp[s]:
|
||||||
# BINARY! Must create type 0006, 0007 and actual binary blocks
|
# BINARY! Must create type 0006, 0007 and actual binary block(s)
|
||||||
|
tlv6 = TLV6(0x0006, None)
|
||||||
|
tlv6.load_dump(params)
|
||||||
|
gcd.struct.append(tlv6)
|
||||||
|
|
||||||
|
tlv7 = TLV7(0x0007, None)
|
||||||
|
tlv7.set_tlv6(tlv6)
|
||||||
|
tlv7.load_dump(params)
|
||||||
|
gcd.struct.append(tlv7)
|
||||||
|
|
||||||
|
tlv7.parse()
|
||||||
|
filename = rcp[s]["from_file"]
|
||||||
|
file_type_id = tlv7.binary_type_id
|
||||||
|
|
||||||
|
with open(filename, "rb") as bf:
|
||||||
|
while True:
|
||||||
|
read_bytes = bf.read(0xff00)
|
||||||
|
btlv = TLVbinary(file_type_id, len(read_bytes))
|
||||||
|
btlv.value = read_bytes
|
||||||
|
gcd.struct.append(btlv)
|
||||||
|
if len(read_bytes) < 0xff00:
|
||||||
|
break
|
||||||
|
bf.close()
|
||||||
|
|
||||||
print("Binary block")
|
print("Binary block")
|
||||||
else:
|
else:
|
||||||
params = []
|
|
||||||
for k in rcp[s]:
|
|
||||||
params.append((k, rcp[s][k]))
|
|
||||||
tlv = TLV.create_from_dump(params)
|
tlv = TLV.create_from_dump(params)
|
||||||
gcd.struct.append(tlv)
|
gcd.struct.append(tlv)
|
||||||
return gcd
|
return gcd
|
||||||
|
|
||||||
|
def save(self, filename):
|
||||||
|
self.filename = filename
|
||||||
|
60
grmn/tlv.py
60
grmn/tlv.py
@ -180,20 +180,28 @@ class TLV6(TLV):
|
|||||||
0x5003: ["", "End of definition marker"],
|
0x5003: ["", "End of definition marker"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse(self):
|
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
|
||||||
if len(self.value) % 2 != 0:
|
super().__init__(type_id, expected_length, value, offset)
|
||||||
raise Exception("Invalid TLV6 payload length!")
|
|
||||||
|
|
||||||
self.fids = []
|
self.fids = []
|
||||||
self.format = ""
|
self.format = ""
|
||||||
self.fields = []
|
self.fields = []
|
||||||
|
|
||||||
|
def add_fid(self, fid: int):
|
||||||
|
fdef = self.FIELD_TYPES[fid]
|
||||||
|
self.fids.append(fid)
|
||||||
|
self.format += fdef[0]
|
||||||
|
self.fields.append(fdef[1])
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
if self.is_parsed:
|
||||||
|
# already parsed
|
||||||
|
return
|
||||||
|
if len(self.value) % 2 != 0:
|
||||||
|
raise Exception("Invalid TLV6 payload length!")
|
||||||
|
|
||||||
for i in range(0, len(self.value), 2):
|
for i in range(0, len(self.value), 2):
|
||||||
fid = unpack("H", self.value[i:i+2])[0]
|
fid = unpack("<H", self.value[i:i+2])[0]
|
||||||
fdef = self.FIELD_TYPES[fid]
|
self.add_fid(fid)
|
||||||
self.fids.append(fid)
|
|
||||||
self.format += fdef[0]
|
|
||||||
self.fields.append(fdef[1])
|
|
||||||
|
|
||||||
self.is_parsed = True
|
self.is_parsed = True
|
||||||
|
|
||||||
@ -209,16 +217,32 @@ class TLV6(TLV):
|
|||||||
# Dump nothing as important info will be chained in binary dump
|
# Dump nothing as important info will be chained in binary dump
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def load_dump(self, values):
|
||||||
|
self.value = b""
|
||||||
|
for (k, v) in values:
|
||||||
|
if k == "from_file":
|
||||||
|
continue
|
||||||
|
elif k[0:2] != "0x":
|
||||||
|
continue
|
||||||
|
fid = int(k, 0)
|
||||||
|
self.value += pack("<H", fid)
|
||||||
|
self.value += pack("<H", 0x5003)
|
||||||
|
self.length = len(self.value)
|
||||||
|
|
||||||
class TLV7(TLV):
|
class TLV7(TLV):
|
||||||
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
|
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
|
||||||
super().__init__(type_id, expected_length, value, offset)
|
super().__init__(type_id, expected_length, value, offset)
|
||||||
self.tlv6 = None
|
self.tlv6 = None
|
||||||
|
self.binary_type_id = None
|
||||||
self.attr = []
|
self.attr = []
|
||||||
|
|
||||||
def set_tlv6(self, tlv6: TLV6):
|
def set_tlv6(self, tlv6: TLV6):
|
||||||
self.tlv6 = tlv6
|
self.tlv6 = tlv6
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
|
if self.is_parsed:
|
||||||
|
# already parsed
|
||||||
|
return
|
||||||
if not self.tlv6.is_parsed:
|
if not self.tlv6.is_parsed:
|
||||||
# Make sure we have the structure analysed
|
# Make sure we have the structure analysed
|
||||||
self.tlv6.parse()
|
self.tlv6.parse()
|
||||||
@ -226,6 +250,8 @@ class TLV7(TLV):
|
|||||||
for i, v in enumerate(values):
|
for i, v in enumerate(values):
|
||||||
fid = self.tlv6.fids[i]
|
fid = self.tlv6.fids[i]
|
||||||
self.attr.append((fid, v))
|
self.attr.append((fid, v))
|
||||||
|
if fid == 0x100a:
|
||||||
|
self.binary_type_id = v
|
||||||
self.is_parsed = True
|
self.is_parsed = True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -247,6 +273,22 @@ class TLV7(TLV):
|
|||||||
# Dump nothing as important info will be chained in binary dump
|
# Dump nothing as important info will be chained in binary dump
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def load_dump(self, values):
|
||||||
|
self.value = b""
|
||||||
|
new_values = []
|
||||||
|
for (k, v) in values:
|
||||||
|
if k == "from_file":
|
||||||
|
continue
|
||||||
|
elif k[0:2] != "0x":
|
||||||
|
continue
|
||||||
|
numval = int(v, 0)
|
||||||
|
new_values.append(numval)
|
||||||
|
if not self.tlv6.is_parsed:
|
||||||
|
# Make sure we have the structure analysed (need format attr)
|
||||||
|
self.tlv6.parse()
|
||||||
|
self.value = pack("<" + self.tlv6.format, *new_values)
|
||||||
|
self.length = len(self.value)
|
||||||
|
|
||||||
class TLVbinary(TLV):
|
class TLVbinary(TLV):
|
||||||
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
|
def __init__(self, type_id: int, expected_length: int, value=None, offset: int=None):
|
||||||
super().__init__(type_id, expected_length, value, offset)
|
super().__init__(type_id, expected_length, value, offset)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user