#!/usr/bin/env python

import serial, sys, time

ACK = chr(6)
H1LEN  = 10
H2LEN  = 8
BLEN   = 32570
OFNAME = "/tmp/vx6.out"
PORT  = "/dev/ttyUSB0"
SPEED  = 19200
BYTESIZE = serial.EIGHTBITS
PARITY   = serial.PARITY_NONE
STOPBITS = serial.STOPBITS_ONE
XONXOFF  = 0
RTSCTS   = 0
TIMEOUT  = None

def checksum(bytes):
    sum = 0
    for b in bytes:
        sum = sum + ord(b)
    return sum & 0xff

def checksum_ok(s):
    cs1_addr  = 0x024a
    bl1_start = 0x01cb
    bl1_len   = 127
    cs2_addr  = 0x7f4b
    bl2_start = 0x000f
    bl2_end   = 0x7f49 
    return (checksum(s[bl1_start:bl1_start+bl1_len]) == ord(s[cs1_addr]) and
            checksum(s[bl2_start:bl2_end+1]) == ord(s[cs2_addr]))

class Vxreader:
    def __init__(self, port=PORT):
        self.s = serial.Serial(port=PORT, baudrate=SPEED, bytesize=BYTESIZE,
                               parity=PARITY, stopbits=STOPBITS,
                               timeout=TIMEOUT, xonxoff=XONXOFF,
                               rtscts=RTSCTS)
        self.s.flushInput()

    def read_image(self):
        while self.s.inWaiting() < H1LEN:
            time.sleep(1)
        h1 = self.s.read (H1LEN)
#        for i in range(len(h1)):
#            print "h1[%d]=%d" % (i, ord(h1[i]))
           
        if (h1[0:len('AH021')] != 'AH021'):
            print "Wrong value in header"
            for i in range(len(h1)):
                print "h1[%d]=%d" % (i, ord(h1[i]))
            self.s.close ()
            return None

        self.s.write(ACK)
        self.s.flushOutput()
        h2 = self.s.read (H2LEN)
        chunk = BLEN / 25
        byte_count = 0
        str_list = []
        while byte_count < BLEN:
            this_chunk = min(chunk, BLEN - byte_count)
            block = self.s.read(this_chunk)
            byte_count += this_chunk
            print("%3d percent complete" % ((byte_count*100)/BLEN))
            str_list.append(block)
        b =''.join(str_list)
        self.s.close()

        if checksum_ok  (h1 + h2 + b):
            return h1 + h2 + b
        else:
#            print "wrong checksum"
            return h1 + h2 + b
#            return None

if __name__ == "__main__":
    try:
        if len(sys.argv) > 1:
            vxr = Vxreader(port=sys.argv[1])
        else:
            vxr = Vxreader()
        if len(sys.argv) > 2:
            ofname = sys.argv[2]
        else:
            ofname = OFNAME
        print "Reading from ", vxr.s.portstr
        print 'Turn HT on by pressing "ON/OFF" while pressing "FW".'
        print 'Next, press "BAND" on HT.'
        img = vxr.read_image()
        if img:
            open(ofname, "w").write(img)
            print str(len(img)) + " bytes read"
        else:
            print "Failed to fetch image"
    except Exception, e:
        print e
