text: #!/usr/bin/env python
  """Parses a DVB stream dump and creates a binary FW file.
  """
  
  from __future__ import print_function
  
  import argparse
  import crcmod
  import logging
  import struct
  import sys
  
  
  def read_block(infile, crc_func, verbose=False):
  
      while True:
          crc_block = []
  
          rec = infile.read(4)
          if len(rec) != 4:
              break
  
          crc_block.append(rec)
  
          (val,) = struct.unpack('>I', rec)
  
          logging.debug("val: %08X", val)
  
          rec = infile.read(4)
          if len(rec) != 4:
              break
  
          crc_block.append(rec)
  
          (seq,) = struct.unpack('>I', rec)
          blocklen = (val >> 8) & 0xfff
          table = seq >> 24
  
          logging.debug("seq: %08X, blocklen: %u, table: %08X",
                        seq, blocklen, table)
  
          rec = infile.read(14)
          if len(rec) != 14:
              break
  
          crc_block.append(rec)
  
          block_data = infile.read(blocklen - 23)
          if len(block_data) != blocklen - 23:
              break
  
          crc_block.append(block_data)
  
          rec = infile.read(4)
          if len(rec) != 4:
              break
  
          crc_block.append(rec)
  
          (block_crc,) = struct.unpack('>I', rec)
  
          crc = crc_func(b''.join(crc_block))
  
          block_number = ((seq >> 16) & 0xff00) | ((seq >> 8) & 0xff)
          block_number &= 0x1fff
  
          logging.debug("block_crc: %08X, block_number:%u, crc:%08X",
                        block_crc, block_number, crc)
  
          yield block_number, block_data, crc
  
  
  def _main(argv):
      parser = argparse.ArgumentParser(argv)
      parser.add_argument("-v", "--verbose",
                          help="increase output verbosity",
                          action="store_true")
      parser.add_argument("-i", "--infile",
                          help="file to read",
                          required=True)
      parser.add_argument("-o", "--outfile",
                          help="file to write",
                          required=True)
      args = parser.parse_args()
  
      if args.verbose:
          logging.basicConfig(level=logging.DEBUG, format="%(message)s")
  
      with open(args.infile, mode='rb') as infile, open(
              args.outfile, mode='wb') as outfile:
  
          dvb_crc32 = crcmod.mkCrcFun(0x104c11db7,
                                      rev=False,
                                      initCrc=0xFFFFFFFF,
                                      xorOut=0)
          blocks = [None] * 8192
          max_block = 0
  
          for block_number, block_data, crc in (
                  read_block(infile, dvb_crc32, args.verbose)):
  
              if crc == 0:
                  if block_number > max_block:
                      max_block = block_number
  
                  blocks[block_number] = block_data
  
          for index, block in enumerate(blocks):
              if index > max_block:
                  break
              if not block:
                  print("Missing block: {}".format(index), file=sys.stderr)
                  break
              else:
                  outfile.write(block)
  
  
  if __name__ == "__main__":
      _main(sys.argv)
  