# @author Razvan Musaloiu-E. <razvanm@cs.jhu.edu>
# @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
-import sys, stat, struct, subprocess, time
-import tinyos
+import sys, stat, struct, subprocess, time, os.path
+try:
+ import tos
+except ImportError:
+ import posix
+ sys.path = [os.path.join(posix.environ['TOSROOT'], 'support', 'sdk', 'python')] + sys.path
+ import tos
from datetime import datetime
-import os.path
# Path to the python script that builds Deluge image from XML
PATH_PY_BUILD_IMAGE = os.path.join(os.path.dirname(sys.argv[0]), 'tos-build-deluge-image')
# TinyOS serial communication parameters
-FM_AMID = 0xAB
-DM_AMID = 0xAC
+FM_AMID = 0x53
+DM_AMID = 0x54
SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2
-BAUDRATES = {'micaz': 57600,
- 'telosb': 115200}
# Commands for FlashManager
FM_CMD_ERASE = 0
DELUGE_IDENT_OFFSET = 0
DELUGE_IDENT_SIZE = 128
-class FMReqPacket(tinyos.GenericPacket):
+class FMReqPacket(tos.Packet):
def __init__(self, packet = None):
- tinyos.GenericPacket.__init__(self,
- [('cmd', 'int', 1),
- ('imgNum', 'int', 1),
- ('offset', 'int', 2),
- ('length', 'int', 2),
- ('data', 'blob', None)],
- packet)
-
-class DMReqPacket(tinyos.GenericPacket):
+ tos.Packet.__init__(self,
+ [('cmd', 'int', 1),
+ ('imgNum', 'int', 1),
+ ('offset', 'int', 4),
+ ('length', 'int', 2),
+ ('data', 'blob', None)],
+ packet)
+
+class DMReqPacket(tos.Packet):
def __init__(self, packet = None):
- tinyos.GenericPacket.__init__(self,
- [('cmd', 'int', 1),
- ('imgNum', 'int', 1)],
- packet)
+ tos.Packet.__init__(self,
+ [('cmd', 'int', 1),
+ ('imgNum', 'int', 1)],
+ packet)
-class SerialReplyPacket(tinyos.GenericPacket):
+class SerialReplyPacket(tos.Packet):
def __init__(self, packet = None):
- tinyos.GenericPacket.__init__(self,
- [('error', 'int', 1),
- ('data', 'blob', None)],
- packet)
+ tos.Packet.__init__(self,
+ [('error', 'int', 1),
+ ('data', 'blob', None)],
+ packet)
-class Ident(tinyos.GenericPacket):
+class Ident(tos.Packet):
def __init__(self, packet = None):
- tinyos.GenericPacket.__init__(self,
- [('uidhash', 'int', 4),
- ('size', 'int', 4),
- ('pages', 'int', 1),
- ('reserved', 'int', 1),
- ('crc', 'int', 2),
- ('appname', 'string', 16),
- ('username', 'string', 16),
- ('hostname', 'string', 16),
- ('platform', 'string', 16),
- ('timestamp','int', 4),
- ('userhash', 'int', 4)],
- packet)
-
-class ShortIdent(tinyos.GenericPacket):
+ tos.Packet.__init__(self,
+ [('uidhash', 'int', 4),
+ ('size', 'int', 4),
+ ('pages', 'int', 1),
+ ('reserved', 'int', 1),
+ ('crc', 'int', 2),
+ ('appname', 'string', 16),
+ ('username', 'string', 16),
+ ('hostname', 'string', 16),
+ ('platform', 'string', 16),
+ ('timestamp','int', 4),
+ ('userhash', 'int', 4)],
+ packet)
+
+class ShortIdent(tos.Packet):
def __init__(self, packet = None):
- tinyos.GenericPacket.__init__(self,
- [('appname', 'string', 16),
- ('timestamp','int', 4),
- ('uidhash', 'int', 4),
- ('nodeid', 'int', 2)],
- packet)
+ tos.Packet.__init__(self,
+ [('appname', 'string', 16),
+ ('timestamp','int', 4),
+ ('uidhash', 'int', 4),
+ ('nodeid', 'int', 2)],
+ packet)
# Computes 16-bit CRC
else:
crc = crc << 1
crc = crc & 0xffff
-
+
return crc
def handleResponse(success, msg):
if success == True:
- packet = s.sniff_am()
+ packet = am.read(timeout=2)
while packet and packet.type == 100:
print "".join([chr(i) for i in packet.data])
- packet = s.sniff_am()
+ packet = am.read()
+ if not packet:
+ print "No response"
+ return False
reply = SerialReplyPacket(packet.data)
if reply.error == ERROR_SUCCESS:
- print reply
return True
else:
print msg, reply
return False
-
+
print "ERROR: Unable to send the command"
return False
-def ident():
+def ident(timeout=None):
sreqpkt = FMReqPacket((FM_CMD_IDENT, 0, 0, 0, []))
- if s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)):
- packet = s.sniff_am()
+ if am.write(sreqpkt, FM_AMID, timeout=timeout):
+ packet = am.read(timeout=timeout)
reply = SerialReplyPacket(packet.data)
if reply.error == ERROR_SUCCESS:
return ShortIdent(reply.data)
def read(imgNum, offset, length):
r = []
-
+
sreqpkt = FMReqPacket((FM_CMD_READ, imgNum, offset, length, []))
while True:
if sreqpkt.length > SERIAL_DATA_LENGTH:
sreqpkt.length = SERIAL_DATA_LENGTH
-
- if s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)):
- packet = s.sniff_am()
+
+ if am.write(sreqpkt, FM_AMID):
+ packet = am.read()
reply = SerialReplyPacket(packet.data)
if reply.error == ERROR_SUCCESS:
r.extend(reply.data)
else:
r = None
break
-
+
sreqpkt.offset += sreqpkt.length
if sreqpkt.offset >= (offset + length):
break
return r
def erase(imgNum):
+ # Note: the normal erase doesn't work properly on AT45DB. A
+ # workaround is to do the normal erase (to make happy STM25P)
+ # and then overwrite the metadata (to make happy AT45DB).
+
sreqpkt = FMReqPacket((FM_CMD_ERASE, imgNum, 0, 0, []))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID))
- return handleResponse(success, "ERROR: Unable to erase the flash volume")
+ success = am.write(sreqpkt, FM_AMID)
+ result = handleResponse(success, "ERROR: Unable to erase the flash volume")
+ if result: return True;
+
+ print 'Attempt the workaround for AT45DB...'
+ sreqpkt = FMReqPacket((FM_CMD_WRITE, imgNum, 0, 0, []))
+ sreqpkt.data = [0xFF] * DELUGE_IDENT_SIZE
+ sreqpkt.length = DELUGE_IDENT_SIZE
+ success = am.write(sreqpkt, FM_AMID)
+ result = handleResponse(success, "ERROR: Unable to erase the flash volume")
+ if not result: return False;
+ return sync(imgNum)
def sync(imgNum):
sreqpkt = FMReqPacket((FM_CMD_SYNC, imgNum, 0, 0, []))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID))
+ success = am.write(sreqpkt, FM_AMID)
return handleResponse(success, "ERROR: Unable to sync the flash volume")
def write(imgNum, data):
total_length = length # For progress bar
next_tick = 100 # For progress bar
start_time = time.time()
-
+
print "[0% 25% 50% 75% 100%]\r[",
-
+
sreqpkt.offset = 0
while length > 0:
if ((length * 100) / total_length) < next_tick:
next_tick = next_tick - 2
sys.stdout.write('-')
sys.stdout.flush()
-
+
# Calculates the payload size for the current packet
if length >= SERIAL_DATA_LENGTH:
sreqpkt.length = SERIAL_DATA_LENGTH
else:
sreqpkt.length = length
sreqpkt.data = data[sreqpkt.offset:sreqpkt.offset+sreqpkt.length]
-
+
# Sends over serial to the mote
- if not s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)):
+ if not am.write(sreqpkt, FM_AMID):
print
print "ERROR: Unable to send the last serial packet (file offset: %d)" % sreqpkt.offset
return False
-
+
# Waiting for confirmation
- packet = s.sniff_am()
+ packet = am.read()
reply = SerialReplyPacket(packet.data)
if reply.error != ERROR_SUCCESS:
print
print "ERROR: Unable to write to the flash volume (file offset: %d)" % sreqpkt.offset
return False
-
+
length -= sreqpkt.length
sreqpkt.offset += sreqpkt.length
elasped_time = time.time() - start_time
print "\r%s bytes in %.2f seconds (%.4f bytes/s)" % (total_length, elasped_time, int(total_length) / (elasped_time))
return True
-
+
# Checks for valid CRC and timestamp
def verifyIdent(i):
if i != None:
except:
print "ERROR: Unable to find the image building utility, \"%s\"" % PATH_PY_BUILD_IMAGE
return False
-
+
# Gets status information of stored image
i = getIdent(imgNum)
if ident:
cmd = [PATH_PY_BUILD_IMAGE, "-i", str(imgNum), tos_image_xml]
print "Create image:", ' '.join(cmd)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- print p.stderr.read(),
+ (out, err) = p.communicate(None)
+ print err,
print "--------------------------------------------------"
-
+
# Writes the new binary image
- image = [struct.unpack("B", c)[0] for c in p.stdout.read()]
+ image = [struct.unpack("B", c)[0] for c in out]
if len(image) > 0 and erase(imgNum):
if write(imgNum, image):
if sync(imgNum):
print "Replace image with:"
print formatIdent(getIdent(imgNum))
print "--------------------------------------------------"
-
+
return False
def ping(imgNum):
print formatIdent(i)
print "--------------------------------------------------"
return True
-
+
print "--------------------------------------------------"
return False
def boot():
sreqpkt = DMReqPacket((DM_CMD_BOOT, 0))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to boot the mote")
def reprogram(imgNum):
sreqpkt = DMReqPacket((DM_CMD_REPROGRAM, imgNum))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to reprogram the mote")
def disseminate(imgNum):
sreqpkt = DMReqPacket((DM_CMD_ONLY_DISSEMINATE, imgNum))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to disseminate")
def disseminateAndReboot(imgNum):
sreqpkt = DMReqPacket((DM_CMD_DISSEMINATE_AND_REPROGRAM, imgNum))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to disseminate-and-reboot")
def stop():
sreqpkt = DMReqPacket((DM_CMD_STOP, 0))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to initiate the stop")
def localstop():
sreqpkt = DMReqPacket((DM_CMD_LOCAL_STOP, 0))
- success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=DM_AMID))
+ success = am.write(sreqpkt, DM_AMID)
return handleResponse(success, "ERROR: Unable to initiate the local stop")
def print_usage():
- print "Usage: %s <device_port> <baud_rate> <-p|-i|-r|-d|-e|-s> image_number [options]" % sys.argv[0]
- print " <baud_rate> Either the platform name (micaz or telosv) or a baudrate value"
+ print "Usage: %s <source> <-p|-i|-r|-d|-e|-s> image_number [options]" % sys.argv[0]
+ print " <source> can be:"
+ print " serial@PORT:SPEED Serial ports"
+ print " network@HOST:PORT MIB600"
print " -p --ping Provide status of the image in the external flash"
print " -i --inject Inject a compiled TinyOS application"
print " [options]: tos_image.xml file path"
global imgNum
# Checks for valid image number format
try:
- imgNum = int(sys.argv[4])
+ imgNum = int(sys.argv[3])
except:
print "ERROR: Image number is not valid"
sys.exit(-1)
return imgNum
# ======== MAIN ======== #
-if len(sys.argv) >= 4:
+if len(sys.argv) >= 3:
+
+ am = tos.AM()
- if sys.argv[2] in BAUDRATES:
- baudrate = BAUDRATES[sys.argv[2]]
- else:
- try:
- baudrate = int(sys.argv[2])
- except:
- print "ERROR: Wrong baudrate"
- sys.exit(-1)
-
- # Initializes serial port communication
try:
- s = tinyos.Serial(sys.argv[1], baudrate, flush=False)
- except:
- print "ERROR: Unable to initialize serial port connection to", sys.argv[1]
+ print "Checking if node is a Deluge T2 base station ..."
+ ident(timeout=1)
+ except tos.Timeout:
+ print "ERROR: Timeout. Is the node a Deluge T2 base station?"
sys.exit(-1)
- if sys.argv[3] in ["-p", "--ping"]:
+ if sys.argv[2] in ["-p", "--ping"]:
checkImgNum()
print "Pinging node ..."
- ping(imgNum)
- elif sys.argv[3] in ["-i", "--inject"] and len(sys.argv) == 6:
+ ping(imgNum)
+ elif sys.argv[2] in ["-i", "--inject"] and len(sys.argv) == 5:
checkImgNum()
print "Pinging node ..."
- inject(imgNum, sys.argv[5])
- elif sys.argv[3] in ["-e", "--erase"]:
+ inject(imgNum, sys.argv[4])
+ elif sys.argv[2] in ["-e", "--erase"]:
checkImgNum()
if erase(imgNum):
print "Image number %d erased" % imgNum
- elif sys.argv[3] in ["-b", "--boot"]:
+ elif sys.argv[2] in ["-b", "--boot"]:
if boot():
print "Command sent"
- elif sys.argv[3] in ["-r", "--reprogram"]:
+ elif sys.argv[2] in ["-r", "--reprogram"]:
checkImgNum()
if reprogram(imgNum):
print "Command sent"
- elif sys.argv[3] in ["-d", "--disseminate"]:
+ elif sys.argv[2] in ["-d", "--disseminate"]:
checkImgNum()
if disseminate(imgNum):
print "Command sent"
- elif sys.argv[3] in ["-dr", "--disseminate-and-reboot"]:
+ elif sys.argv[2] in ["-dr", "--disseminate-and-reboot"]:
checkImgNum()
if disseminateAndReboot(imgNum):
print "Command sent"
- elif sys.argv[3] in ["-s", "--stop"]:
+ elif sys.argv[2] in ["-s", "--stop"]:
if stop():
print "Command sent"
- elif sys.argv[3] in ["-ls", "--local-stop"]:
+ elif sys.argv[2] in ["-ls", "--local-stop"]:
if localstop():
print "Command sent"
else: