#   Copyright (c) 2010 Axel Wachtler
#   All rights reserved.
#
#   Redistribution and use in source and binary forms, with or without
#   modification, are permitted provided that the following conditions
#   are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the authors nor the names of its contributors
#     may be used to endorse or promote products derived from this software
#     without specific prior written permission.
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
#   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#   POSSIBILITY OF SUCH DAMAGE.

# $Id$
"""
Dumps a intel hex file for a node config structure.

    python nodeconfig2ihex.py [OPTIONS]

    Options:
     -p PANID
        default pan id (16 bit value)
     -a SRCADDR
        fixed node short source address (16 bit value)
     -m MEMADDR
        address, where the structure will be located.
     -h
        display help and exit
     -V
        show version and exit

"""
# === import ==================================================================
import struct, getopt, sys
# === globals =================================================================

# === functions ===============================================================
##
# Format an intel hex record
# For a description of the intel hex format see:
#  http://en.wikipedia.org/wiki/Intel_HEX
#
# @param rtype
#        record type
#          00 	Data Record
#          01 	End of File Record
#          02 	Extended Segment Address Record
#          03 	Start Segment Address Record
#          04 	Extended Linear Address Record
#          05 	Start Linear Address Record
# @param addr
#           16 bit address value
# @param data
#           list with 8 bit values.
# @return string of the formated record.
#
def ihex_record(rtype, addr,data = []):
    dlen = len(data) & 0xff
    darr  = [ dlen,
             (addr >> 8) & 0xff,
             (addr & 0xff) ,
              rtype & 0xff]
    darr.extend(data)
    crc = 0
    for d in darr:
        crc += d
    crc = ((crc &0xff)^0xff) + 1
    darr.append(crc & 0xff)
    return ":"+"".join(["%02X" %d  for d in darr])


# === classes =================================================================

# === init ====================================================================
VERSION = 0.1
MEMADDR = 0xFFFC
SRCADDR = 0xBABE
PAN     = 0xCAFE

fmt = "@HH"

if __name__ == "__main__":
    opts,args = getopt.getopt(sys.argv[1:],"a:p:m:hV")

    #test vectors
    #x = ":1001600060E070E000E010E020E030E00E94D705A1"
    #addr = 0x0160
    #data = [ 0x60, 0xE0, 0x70, 0xE0, 0x00, 0xE0, 0x10, 0xE0,
    #         0x20, 0xE0, 0x30, 0xE0, 0x0E, 0x94, 0xD7, 0x05 ]
    #y = ihex_record(0,addr, data)
    #print ":00000001FF"
    #print ihex_record(1,0)
    doexit = False
    for o,v in opts:
        if o == "-a":
            SRCADDR = eval(v)
        if o == "-p":
            PAN = eval(v)
        if o == "-m":
            MEMADDR = eval(v)
        if o == "-h":
            print __doc__
            doexit = True
        if o == "-V":
            print "Version",VERSION
            doexit = True

    if doexit:
        sys.exit(0)



    data = map(ord,struct.pack(fmt, SRCADDR,PAN))
    print ihex_record(0, MEMADDR, data)
    print ihex_record(1,0)
