summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-12-11 22:40:08 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-12-11 22:40:08 +0100
commitfbd4dad04f1951874f10b71bdcb646cb74915665 (patch)
tree3106e42943f6736f95b53b58a7d13c20e171141e
parent5abefc8051cdd0b3368f7934d23c604f523e7adb (diff)
update: First discovery of information about the file format..
-rw-r--r--update-ec20/README.ascii8
-rw-r--r--update-ec20/dissect.py68
2 files changed, 76 insertions, 0 deletions
diff --git a/update-ec20/README.ascii b/update-ec20/README.ascii
new file mode 100644
index 0000000..6ed7ce9
--- /dev/null
+++ b/update-ec20/README.ascii
@@ -0,0 +1,8 @@
+Handling of EC20 FOTA updates
+=============================
+
+See https://osmocom.org/projects/quectel-modems/wiki/EC20_DFOTA
+for general information. This is a script to dissect and maybe
+re-assemble the system.diff file. Let's see how far we get.
+
+
diff --git a/update-ec20/dissect.py b/update-ec20/dissect.py
new file mode 100644
index 0000000..4127ed7
--- /dev/null
+++ b/update-ec20/dissect.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python3
+"""
+Dissect a redbend/quectel EC20 system.diff
+All rights reversed
+"""
+
+import sys
+import struct
+import io
+import binascii
+from PyCRC import CRC32
+
+# initialize the tables once
+crc32 = CRC32.CRC32()
+
+def hexstring(array):
+ return "".join(map(lambda b: format(b, "02x"), array))
+
+filename = sys.argv[1]
+print("Working on {}".format(filename))
+
+data = open(filename, 'rb').read()
+rstr = io.BytesIO(data)
+
+
+# A chunk ....
+# 32bit crc32 checksum
+# 32bit len
+# len-8 bytes of data..
+# 0-3 bytes padding to the next chunk but not at the end
+# of thr file and not accounted for in the len. See the
+# dsp2.diff as an example?
+
+# Parse the chunk..
+checksum = rstr.read(4)
+blen = rstr.read(4)
+flen = struct.unpack("<I", blen)[0]
+chunk1 = rstr.read(flen - 8)
+
+print("Guessing CRC to match {} {}".format(
+ struct.unpack("<I", checksum)[0],
+ crc32.calculate(blen+chunk1)))
+
+# read padding
+if len(chunk1) % 4 > 0:
+ rstr.read(4 - (len(chunk1) % 4))
+
+# Parse the trailer
+t_chksum = rstr.read(4)
+t_blen = rstr.read(4)
+t_flen = struct.unpack("<I", t_blen)[0]
+t_chnk = rstr.read(t_flen - 8)
+assert len(t_chnk) == t_flen - 8
+
+print("Guessing CRC to match {} {}".format(
+ struct.unpack("<I", t_chksum)[0],
+ crc32.calculate(t_blen+t_chnk)))
+print(len(t_chnk)%4)
+trailer = rstr.read()
+print("REST {} {}".format(len(trailer), hexstring(trailer)))
+
+#wanted_le = struct.unpack("<I", checksum)[0]
+#wanted_be = struct.unpack(">I", checksum)[0]
+#for i in range(0, len(data)):
+# for j in range(0, len(data)):
+# crc = crc32.calculate(data[i:j])
+# if crc == wanted_le or wanted_be == crc:
+# print("Got it with {} {}".format(i, j))