diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-10-03 18:15:32 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-10-03 18:15:32 +0200 |
commit | 1fef96454d2976dbdf5e5346c34f54609bf173c2 (patch) | |
tree | 89b8d2c8d52dfc4f0cad4fba6cf0aeae5ebfe57e /edi | |
parent | 3a1ae282cb923b008725b8017b6088d8d27bc846 (diff) | |
download | mmbtools-aux-1fef96454d2976dbdf5e5346c34f54609bf173c2.tar.gz mmbtools-aux-1fef96454d2976dbdf5e5346c34f54609bf173c2.tar.bz2 mmbtools-aux-1fef96454d2976dbdf5e5346c34f54609bf173c2.zip |
improve edi debugger
Diffstat (limited to 'edi')
-rwxr-xr-x | edi/edidebug.py | 138 |
1 files changed, 111 insertions, 27 deletions
diff --git a/edi/edidebug.py b/edi/edidebug.py index d48204f..d2515ff 100755 --- a/edi/edidebug.py +++ b/edi/edidebug.py @@ -11,19 +11,57 @@ from reedsolo import RSCodec class Printer: def __init__(self): self.indent = 0 + def pr(self, s): print(" " * self.indent + s) + def hexpr(self, header, seq): if isinstance(seq, str): seq = bytearray(seq) - print(header + ": " + " ".join("{0:02x}".format(el) for el in seq)) + print(" " * self.indent + + header + + " ({}): ".format(len(seq)) + + " ".join("{0:02x}".format(el) for el in seq)) def inc(self): self.indent += 1 def dec(self): self.indent -= 1 +class BufferedFile: + def __init__(self, fname): + self.buf = [] + + if fname == "-": + self.fd = sys.stdin + else: + self.fd = open(fname, "rb") + + def read(self, n): + if not self.buf: + return self.fd.read(n) + else: + if len(self.buf) < n: + self.buf.extend(self.fd.read(n - len(self.buf))) + + if len(self.buf) == n: + ret = b"".join(self.buf) + self.buf = [] + else: + ret = b"".join(self.buf[:n]) + del self.buf[:n] + + return ret + + def peek(self, n): + dat = self.fd.read(n) + self.buf.extend(dat) + return dat + + + + p = Printer() # keys=findex @@ -33,9 +71,7 @@ def decode(stream): p.pr("start") success = False - pos = stream.tell() - sync = stream.read(2) - stream.seek(pos) + sync = stream.peek(2) if len(sync) < 2: p.pr("EOF") @@ -152,6 +188,7 @@ class Defragmenter(): self.fragments[findex] = fragment received_fragments = [f for f in self.fragments if f is not None] + p.pr("Fragments: {} (need {})".format(len(received_fragments), self.fcount)) if len(received_fragments) >= self.fcount: return self.cb(received_fragments) # The RS decoder should be able to handle partial lists @@ -162,31 +199,59 @@ class Defragmenter(): def __repr__(self): return "<Defragmenter with fcount={}>".format(self.fcount) -def get_rs_decoder(rs_k, rs_z): - p.pr("Build RS decoder for RSk={}, RSz={}".format(rs_k, rs_z)) +def get_rs_decoder(chunk_size, zeropad): + p.pr("Build RS decoder for chunk size={}, zero pad={}".format(chunk_size, zeropad)) def decode_rs(fragments): + p.pr("RS decode {} fragments of length {}".format( + len(fragments), len(fragments[0]))) + + #for f in fragments: + # p.hexpr(" ZE FRAGMENT", f); + # Transpose fragments to get an RS block - rs_blocks = zip(*fragments) + rs_block = "".join("".join(f) for f in zip(*fragments)) + + # chunks before protection have size chunk_size + # protection adds 48 bytes + # The tuples here are (data, parity) + + #p.hexpr(" ZE RS BLOCK", "".join(rs_block)) + + num_chunks = len(rs_block) / chunk_size + p.pr("{} chunks".format(num_chunks)) + + data_size = chunk_size + 48 + + af_packet_size = num_chunks * chunk_size + p.pr("AF Packet size {}".format(af_packet_size)) + + # Cut the block into list of (data, protection) tuples + rs_chunks = [ (rs_block[i*data_size:i*data_size + chunk_size], + rs_block[i*data_size + chunk_size:(i+1)*data_size]) + for i in range(num_chunks)] + + #for c in rs_chunks: + # p.hexpr(" ZE CHUNK DATA", c[0]); + # p.hexpr(" ZE CHUNK PROT", c[1]); rs_codec = RSCodec(48) - # chunks have size RSk + 48 - # The tuples here are (data, parity) + for chunk, protection in rs_chunks: + p.pr(" Protection") + recalc_protection = rs_codec.encode(bytearray(chunk))[-48:] + if (protection != recalc_protection): + p.pr(" PROTECTION ERROR") + p.hexpr(" orig", protection) + p.hexpr(" calc", recalc_protection) - rs_chunks = [ ( "".join(rs_block[:rs_k]), - "".join(rs_block[rs_k:rs_k+48]) ) - for rs_block in rs_blocks] - assert(False) + afpacket = "".join(data for (data, protection) in rs_chunks) - for chunk, ecc in rs_chunks: - p.pr("ECC") - p.hexpr(" orig", ecc) - p.hexpr(" calc", rs_codec.encode(bytearray(chunk))) + #p.hexpr(" ZE AF PACKET", afpacket) - afpacket = "".join(data for (data, parity) in rs_chunks) + assert(zeropad == 0) # not supported yet! - return afpacket + return decode_af(afpacket) return decode_rs @@ -208,6 +273,7 @@ def decode_af(in_data, is_stream=False): if sync != "AF": p.pr("No AF Sync") + p.hexpr("in", in_data) p.dec() return False @@ -266,7 +332,9 @@ def decode_tag(tagpacket): p.pr("Tag packet len={}".format(len(tagpacket))) p.inc() for item in tagitems(tagpacket): - if item['name'] == "deti": + if item['name'].startswith("*ptr"): + decode_starptr(item) + elif item['name'] == "deti": decode_deti(item) elif item['name'].startswith("est"): decode_estn(item) @@ -276,6 +344,21 @@ def decode_tag(tagpacket): p.dec() return True +item_starptr_header_struct = "!4sHH" +def decode_starptr(item): + p.pr("TAG item {} ({})".format(item['name'], item['length'])) + p.inc() + tag_value = item['value'] + + unpacked = struct.unpack(item_starptr_header_struct, tag_value) + protocol, major, minor = unpacked + + p.pr("Protocol {}, Ver {} {}".format( + protocol, major, minor) ) + + p.dec() + + item_deti_header_struct = "!BBBBH" def decode_deti(item): p.pr("TAG item {} ({})".format(item['name'], item['length'])) @@ -294,7 +377,7 @@ def decode_deti(item): ficf = flag_fcth & 0x40 != 0 rfudf = flag_fcth & 0x20 != 0 fcth = flag_fcth & 0x1F - fct = fcth << 5 | fctl + fct = (fcth * 250) + fctl mid = (mid_fp >> 6) & 0x03 fp = (mid_fp >> 3) & 0x07 @@ -329,7 +412,7 @@ def decode_deti(item): item_estn_head_struct = "!HB" def decode_estn(item): estN = chr(ord("0") + ord(item['name'][3])) - p.pr("TAG item EST{} ({})".format(estN, item['length'])) + p.pr("TAG item EST{} (len={})".format(estN, item['length'])) p.inc() tag_value = item['value'] @@ -345,16 +428,17 @@ def decode_estn(item): assert(item['length'] == len(tag_value)) p.pr("MST len = {}".format(len(tag_value) - 3)) + p.hexpr("MST {} data".format(scid), tag_value[3:]) p.dec() -if len(sys.argv) < 2: - print("Filename expected") - sys.exit(1) +if len(sys.argv) > 1: + filename = sys.argv[1] -filename = sys.argv[1] + edi_fd = BufferedFile(filename) +else: + edi_fd = BufferedFile("-") -edi_fd = open(filename, "r") while decode(edi_fd): pass |