]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Improvements to tos.py.
authorrazvanm <razvanm>
Mon, 15 Dec 2008 00:50:37 +0000 (00:50 +0000)
committerrazvanm <razvanm>
Mon, 15 Dec 2008 00:50:37 +0000 (00:50 +0000)
This latest version includes:
  * support for MIB600
  * a generic dump program (tos-dump) that has support for decoding the
    printf packets
  * a few example programs for some of the applications (Oscilloscope,
    MultihopOscilloscope, TestFtsp, TestLocalTime).

12 files changed:
apps/MultihopOscilloscope/oscilloscope.py [new file with mode: 0644]
apps/Oscilloscope/oscilloscope.py [new file with mode: 0644]
apps/tests/TestFtsp/FtspDataLogger.py [new file with mode: 0644]
apps/tests/TestLocalTime/README.txt
apps/tests/TestLocalTime/dump.py [new file with mode: 0644]
apps/tests/TestSerial/README.txt
apps/tests/deluge/Blink/burn
apps/tests/deluge/Blink/burn-net
support/sdk/python/tos.py
tools/tinyos/misc/Makefile.am
tools/tinyos/misc/tos-deluge
tools/tinyos/misc/tos-dump.py [new file with mode: 0644]

diff --git a/apps/MultihopOscilloscope/oscilloscope.py b/apps/MultihopOscilloscope/oscilloscope.py
new file mode 100644 (file)
index 0000000..de29c89
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+import sys
+import tos
+
+AM_OSCILLOSCOPE = 0x93
+
+class OscilloscopeMsg(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('version',  'int', 2),
+                             ('interval', 'int', 2),
+                             ('id',       'int', 2),
+                             ('count',    'int', 2),
+                             ('readings', 'blob', None)],
+                            packet)
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p and p.type == AM_OSCILLOSCOPE:
+        msg = OscilloscopeMsg(p.data)
+        print msg.id, msg.count, [i<<8 | j for (i,j) in zip(msg.readings[::2], msg.readings[1::2])]
+        #print msg
+
diff --git a/apps/Oscilloscope/oscilloscope.py b/apps/Oscilloscope/oscilloscope.py
new file mode 100644 (file)
index 0000000..3b881ad
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+import sys
+import tos
+
+AM_OSCILLOSCOPE = 0x93
+
+class OscilloscopeMsg(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('version',  'int', 2),
+                             ('interval', 'int', 2),
+                             ('id',       'int', 2),
+                             ('count',    'int', 2),
+                             ('readings', 'blob', None)],
+                            packet)
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p and p.type == AM_OSCILLOSCOPE:
+        msg = OscilloscopeMsg(p.data)
+        print msg.id, msg.count, [i<<8 | j for (i,j) in zip(msg.readings[::2], msg.readings[1::2])]
+        #print msg
+
diff --git a/apps/tests/TestFtsp/FtspDataLogger.py b/apps/tests/TestFtsp/FtspDataLogger.py
new file mode 100644 (file)
index 0000000..0c5687b
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import sys, time
+import tos
+
+AM_TEST_FTSP_MSG = 137
+
+class FtspMsg(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('src_addr',            'int', 2),
+                             ('counter',             'int', 2),
+                             ('local_rx_timestamp',  'int', 4),
+                             ('global_rx_timestamp', 'int', 4),
+                             ('skew_times_1000000',  'int', 4),
+                             ('is_synced',           'int', 1),
+                             ('ftsp_root_addr',      'int', 2),
+                             ('ftsp_seq',            'int', 1),
+                             ('ftsp_table_entries',  'int', 2)],
+                            packet)
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p and p.type == AM_TEST_FTSP_MSG:
+        msg = FtspMsg(p.data)
+        print int(time.time()), msg.src_addr, msg.counter, msg.global_rx_timestamp, msg.is_synced
+        #print msg
index 5fac5fae78755b805b362bf5a8712433d6ea532b..825967f4979abf6dc0760a70e58cc5a673d57815 100644 (file)
@@ -6,6 +6,9 @@ Description:
 TestLocalTime is a simple application that tests the LocalTimeMilliC component
 by sending the current time over the serial port once per second.
 
+dump.py is a Python script that can be used to read and format the values from
+the serial port.
+
 Tools:
 
 None.
diff --git a/apps/tests/TestLocalTime/dump.py b/apps/tests/TestLocalTime/dump.py
new file mode 100644 (file)
index 0000000..e8dea05
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import sys
+import tos
+
+class Localtime(tos.Packet):
+    def __init__(self, packet = None):
+        tos.Packet.__init__(self,
+                            [('time', 'int', 4)],
+                            packet)
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p:
+        msg = Localtime(p.data)
+        print msg
index ca16d9b15dc712057cd39452b239120cbac41e2f..1a8e56d5667b1735304964887b77b1b747f5a847 100644 (file)
@@ -19,6 +19,9 @@ Java Application Usage:
   If not specified, the <packetsource> defaults to sf@localhost:9002 or
   to your MOTECOM environment variable (if defined).
 
+Python Usage:
+  tos-dump /dev/ttyUSB0 57600
+
 Tools:
 
 Known bugs/limitations:
index e43e7b0c71bd8254f1a77441fa4137000257fca6..5622fdfc32906a5d77c11b9e4ff894174cd90df2 100755 (executable)
@@ -1,41 +1,35 @@
 #!/bin/bash
 
-python -c '
-import sys
-try: 
-  import serial
-except ImportError, e: 
-  sys.exit(1)'
+TOS_DELUGE=`type -p tos-deluge`
+if [[ ! -x ${TOS_DELUGE} ]] ; then 
+    TOS_DELUGE=../../../../tools/tinyos/misc/tos-deluge
+fi 
+
+$TOS_DELUGE > /dev/null
 
 if [[ $? != 0 ]]
 then
-  echo "Please install PySerial first." 
+  echo "Unable to locate tos-deluge."
   exit 2
 fi
 
-TOS_DELUGE=`type -p tos-deluge`
-if [[ ! -x ${TOS_DELUGE} ]] ; then 
-    TOS_DELUGE=../../../../tools/tinyos/misc/tos-deluge
-fi 
-
 if [[ $# -ne 2 && $# -ne 3 ]]; then
-  echo "Usage: $0 <port> [<comm_port>] <platform>"
-  echo "  <port>       /dev/ttyUSB0"
-  echo "  <comm_port>  /dev/ttyUSB1"
-  echo "  <platform>   micaz, telosb, iris or epic"
+  echo "Usage: $0 <prog_source> <comm_source> <platform>"
+  echo "  <prog_source> bsl,PORT | mib510,PORT | eprb,PORT"
+  echo "  <comm_source> serial@PORT:SPEED | network@HOST:PORT"
+  echo "  <platform>    micaz | telosb | iris | epic"
   exit 2
 fi
 
 PPORT=$1
-CPORT=$1
-PLATFORM=$2
-
-if [ $# -eq 3 ]; then
- CPORT=$2
- PLATFORM=$3
-fi
+CPORT=$2
+PLATFORM=$3
 
-if [ ${PLATFORM} != 'micaz' -a ${PLATFORM} != 'telosb' -a ${PLATFORM} != 'iris' -a ${PLATFORM} != 'epic' ]; then
+if [ ${PLATFORM} != 'micaz' -a \
+     ${PLATFORM} != 'telosb' -a \
+     ${PLATFORM} != 'iris' -a \
+     ${PLATFORM} != 'epic' ]
+then
   echo "\"${PLATFORM}\" is not a supported platform"
   exit 2
 fi
@@ -49,16 +43,7 @@ fi
 make clean
 
 echo ============================ Compile and load Blink ============================
-if [ $PLATFORM == 'micaz' ]
-then
-  CFLAGS=-DDELUGE_BASESTATION make ${PLATFORM} install mib510,${PPORT}
-elif [ $PLATFORM == 'telosb' -o $PLATFORM == 'epic' ]
-then
-  CFLAGS=-DDELUGE_BASESTATION make ${PLATFORM} install bsl,${PPORT}
-elif [ $PLATFORM == 'iris' ]
-then
-  CFLAGS=-DDELUGE_BASESTATION make ${PLATFORM} install mib510,${PPORT}
-fi
+CFLAGS=-DDELUGE_BASESTATION make ${PLATFORM} install ${PPORT}
 
 
 echo '           +-------------------------------------------------------+'
@@ -74,7 +59,7 @@ echo  ============================= Compile a new Blink ========================
 CFLAGS=-DBLINK_REVERSE\ -DDELUGE_BASESTATION make ${PLATFORM}
 
 echo =============================== Upload the image ===============================
-${TOS_DELUGE} ${CPORT} ${PLATFORM} -i 1 build/${PLATFORM}/tos_image.xml
+${TOS_DELUGE} ${CPORT} -i 1 build/${PLATFORM}/tos_image.xml
 
 echo '       +----------------------------------------------------------------+'
 echo '       |                                                                |'
@@ -91,4 +76,4 @@ echo '       +----------------------------------------------------------------+'
 read
 
 echo =========================== Reboot the base station ============================
-${TOS_DELUGE} ${CPORT} ${PLATFORM} -r 1 
+${TOS_DELUGE} ${CPORT} -r 1 
index cc14666103f45bec4c182d6d0994cfee0e61a281..8c0bc609a041a353bfcc6d1640f2a0c47642cfc1 100755 (executable)
@@ -5,6 +5,14 @@ if [[ ! -x ${TOS_DELUGE} ]] ; then
     TOS_DELUGE=../../../../tools/tinyos/misc/tos-deluge
 fi 
 
+$TOS_DELUGE > /dev/null
+
+if [[ $? != 0 ]]
+then
+  echo "Unable to locate tos-deluge."
+  exit 2
+fi
+
 if [ $# -ne 2 ]; then
   echo "Usage: $0 <platform> <number of motes>"
   echo "  <platform>         micaz, telosb or iris"
@@ -15,7 +23,11 @@ fi
 PLATFORM=$1
 NO_MOTES=$2
 
-if [ ${PLATFORM} != 'micaz' -a ${PLATFORM} != 'telosb' -a ${PLATFORM} != 'iris' ]; then
+if [ ${PLATFORM} != 'micaz' -a \
+     ${PLATFORM} != 'telosb' -a \
+     ${PLATFORM} != 'iris' \
+     ${PLATFORM} != 'epic' ]
+then
   echo "\"${PLAFTORM}\" is not a supported platform"
   exit 2
 fi
@@ -32,19 +44,10 @@ ID=0
 
 function burn_one() {
     ID=`expr $ID + 1`
-    echo -n ">>> Please plug mote $ID and type the programming port to continue: "
+    echo -n ">>> Please plug mote $ID and type the programming sorce (bsl,PORT | mib510,PORT | eprb,PORT): "
     read PORT
 
-    if [ ${PLATFORM} == 'micaz' ]
-    then
-       CFLAGS=$1 make ${PLATFORM} install,$ID mib510,${PORT}
-    elif [ ${PLATFORM} == 'telosb' ]
-    then
-       CFLAGS=$1 make ${PLATFORM} install,$ID bsl,${PORT}
-    elif [ ${PLATFORM} == 'iris' ]
-    then
-       CFLAGS=$1 make ${PLATFORM} install,$ID mib510,${PORT}
-    fi
+    CFLAGS=$1 make ${PLATFORM} install,$ID ${PORT}
 }
 
 while [[ ${NO_MOTES} > 1 ]]
@@ -54,9 +57,8 @@ do
 done
 echo ">>> Note: this last mote will be the basestation! <<<"
 burn_one -DDELUGE_BASESTATION
-echo -n ">>> Please plug mote $ID and type the communication port to continue: "
-read PORT
-BASESTATION_PORT=$PORT
+echo -n ">>> Please plug mote $ID and type the communication sorce (serial@PORT:SPEED | network@HOST:PORT) to continue: "
+read CPORT
 
 echo '   +------------------------------------------------------------------------+'
 echo '   |                                                                        |'
@@ -71,7 +73,7 @@ echo ============================= Compile a new Blink =========================
 CFLAGS=-DBLINK_REVERSE\ -DDELUGE_LIGHT_BASESTATION make ${PLATFORM} 
 
 echo ========= Upload the new image to the external flash of the last mote ==========
-${TOS_DELUGE} ${BASESTATION_PORT} ${PLATFORM} -i 1 build/${PLATFORM}/tos_image.xml
+${TOS_DELUGE} ${CPORT} -i 1 build/${PLATFORM}/tos_image.xml
 
 echo '            +-----------------------------------------------------+'
 echo '            |                                                     |'
@@ -85,7 +87,7 @@ echo '            +-----------------------------------------------------+'
 read
 
 echo ============================= Start dissemination ==============================
-${TOS_DELUGE} ${BASESTATION_PORT} ${PLATFORM} -dr 1
+${TOS_DELUGE} ${CPORT} -dr 1
 
 echo '         +------------------------------------------------------------+'
 echo '         |                                                            |'
index 7aaf760c99629cb3b44fc6b76e15a02541587c93..85f283b72e63d0ae3e0775dc67072af5502f5bac 100644 (file)
 # @author Razvan Musaloiu-E. <razvanm@cs.jhu.edu>
 # @author David Purdy <david@radioretail.co.za>
 
-"""A library that implements the T2 serial communication.
+"""
+A library that implements the T2 serial communication.
 
 This library has two parts: one that deals with sending and receiving
 packets using the serial format from T2 (TEP113) and a second one that
 tries to simplifies the work with arbitrary packets.
-
 """
 
-import sys, struct, time, serial, socket, operator, thread
-from Queue import Queue
-from threading import Lock, Condition
+import sys, struct, time, socket, operator, os
+
+try: 
+    import serial
+except ImportError, e: 
+    print "Please install PySerial first."
+    sys.exit(1)
 
 __version__ = "$Id$"
 
@@ -40,124 +44,121 @@ __all__ = ['Serial', 'AM',
            'AckFrame', 'DataFrame', 'NoAckDataFrame',
            'ActiveMessage']
 
-ACK_WAIT = 0.2 # Maximum amount of time to wait for an ack
-ACK_WARN = 0.2 # Warn if acks take longer than this to arrive
-
-def list2hex(v):
-    return " ".join(["%02x" % p for p in v])
-
-
-class Error(Exception):
-    """Base error class for this module"""
-    pass
-
-
-class TimeoutError(Error):
-    """Thrown when a serial operation times out"""
-    pass
-
+HDLC_FLAG_BYTE = 0x7e
+HDLC_CTLESC_BYTE = 0x7d
 
-class ReadError(Error):
-    """Base class for read error exceptions"""
-    pass
-
-
-class WriteError(Error):
-    """Base class for write error exceptions"""
-    pass
-
-
-class ReadTimeoutError(TimeoutError, ReadError):
-    """Thrown when a serial read operation times out"""
-    pass
+TOS_SERIAL_ACTIVE_MESSAGE_ID = 0
+TOS_SERIAL_CC1000_ID = 1
+TOS_SERIAL_802_15_4_ID = 2
+TOS_SERIAL_UNKNOWN_ID = 255
 
+SERIAL_PROTO_ACK = 67
+SERIAL_PROTO_PACKET_ACK = 68
+SERIAL_PROTO_PACKET_NOACK = 69
+SERIAL_PROTO_PACKET_UNKNOWN = 255
 
-class ReadCRCError(ReadError):
-    """Thrown when a read packet fails a CRC check"""
-    pass
-
-
-class BadAckSeqnoError(ReadError):
-    """Thrown if an ack packet has an unexpected sequenc number"""
-    pass
-
+def list2hex(v):
+    return " ".join(["%02x" % p for p in v])
 
-class WriteTimeoutError(TimeoutError, WriteError):
-    """Thrown when a serial write operation times out"""
+class Timeout(Exception):
     pass
 
+def getSource(comm):
+    source = comm.split('@')
+    params = source[1].split(':')
+    if source[0] == 'serial':
+        try:
+            return Serial(params[0], int(params[1]), flush=True, debug=False)
+        except:
+            print "ERROR: Unable to initialize serial port connection to", comm
+            sys.exit(-1)
+    elif source[0] == 'network':
+        try:
+            return SerialMIB600(params[0], int(params[1]), debug=False)
+        except:
+            print "ERROR: Unable to initialize serial port connection to", comm
+            sys.exit(-1)
+    raise Exception
 
-class SimpleSerial:
-    """
-    A SimpleSerial object offers a way to send and data using a HDLC-like
-    formating.
-
-    Use SimpleSerial objects for basic low-level serial communications. Use
-    Serial objects for higher level logic (retry sends, log printfs, etc).
-    """
-
-    HDLC_FLAG_BYTE = 0x7e
-    HDLC_CTLESC_BYTE = 0x7d
-
-    TOS_SERIAL_ACTIVE_MESSAGE_ID = 0
-    TOS_SERIAL_CC1000_ID = 1
-    TOS_SERIAL_802_15_4_ID = 2
-    TOS_SERIAL_UNKNOWN_ID = 255
-
-    SERIAL_PROTO_ACK = 67
-    SERIAL_PROTO_PACKET_ACK = 68
-    SERIAL_PROTO_PACKET_NOACK = 69
-    SERIAL_PROTO_PACKET_UNKNOWN = 255
-
-    def __init__(self, port, baudrate, flush=False, debug=False, qsize=10,
-                 timeout=None):
-        self._debug = debug
-        self._in_queue = []
-        self._qsize = qsize
-        self._ack = None
-        self._write_counter = 0
-        self._write_counter_failures = 0
-        self._read_counter = 0
+class Serial:
+    def __init__(self, port, baudrate, flush=False, debug=False, timeout=None):
+        self.debug = debug
+        self.timeout = timeout
         self._ts = None
-        self.timeout = timeout # Public attribute
-        self._received_packet_filters = [] # filter functions for received packets
-
-        # Remember sent (and unacknowledged) seqno numbers for 15 seconds:
-        self._unacked_seqnos = SeqTracker(15.0)
 
-        self._s = serial.Serial(port, baudrate, rtscts=0, timeout=0.5)
+        self._s = serial.Serial(port, int(baudrate), rtscts=0, timeout=0.5)
         self._s.flushInput()
         if flush:
             print >>sys.stdout, "Flushing the serial port",
             endtime = time.time() + 1
             while time.time() < endtime:
-                try:
-                    self._read()
-                except ReadError:
-                    pass
+                self._s.read()
                 sys.stdout.write(".")
-            if not self._debug:
+            if not self.debug:
                 sys.stdout.write("\n")
         self._s.close()
         self._s = serial.Serial(port, baudrate, rtscts=0, timeout=timeout)
 
-        # Add a filter for received 'write ack' packets
-        self.add_received_packet_filter(self._write_ack_filter)
+    def getByte(self):
+        c = self._s.read()
+        if c == '':
+            raise Timeout
+        #print 'Serial:getByte: 0x%02x' % ord(c)
+        return ord(c)
 
-    # Returns the next incoming serial packet
-    def _read(self, timeout=None):
-        """Wait for a packet and return it as a RawPacket.
+    def putBytes(self, data):
+        #print "DEBUG: putBytes:", data
+        for b in data:
+            self._s.write(struct.pack('B', b))
 
-        Throws:
-         - ReadCRCError if a CRC check fails
-         - ReadTimeoutError if the timeout expires.
+    def getTimeout(self):
+        return self._s.timeout
 
-        """
+    def setTimeout(self, timeout):
+        self._s.timeout = timeout
+
+class SerialMIB600:
+    def __init__(self, host, port=10002, debug=False):
+        self.debug = debug
+        self._ts = None
+        self._s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._s.connect((host, port))
+        print "Connected"
+
+    def getByte(self):
+        c = self._s.recv(1)
+        if c == '':
+            raise Timeout
+        #print 'Serial:getByte: 0x%02x' % ord(c)
+        return ord(c)
+
+    def putBytes(self, data):
+        #print "DEBUG: putBytes:", data
+        for b in data:
+            self._s.send(struct.pack('B', b))
+
+    def getTimeout(self):
+        return self._s.gettimeout()
+
+    def setTimeout(self, timeout):
+        self._s.settimeout(timeout)
+
+class HDLC:
+    """
+    An HDLC object offers a way to send and receive data on a byte
+    source using a HDLC-like formating.
+    """
+    def __init__(self, source):
+        self._s = source
+
+    # Returns the next incoming serial packet
+    def read(self, timeout=None):
+        """Wait for a packet and return it as a RawPacket."""
 
         # Developer notes:
         #
-        # Packet data read from Serial is in this format:
-        # [HDLC_FLAG_BYTE][Escaped data][HDLC_FLAG_BYTE]
+        # Packet data read is in this format:
+        #     [HDLC_FLAG_BYTE][Escaped data][HDLC_FLAG_BYTE]
         #
         # [Escaped data] is encoded so that [HDLC_FLAG_BYTE] byte
         # values cannot occur within it. When [Escaped data] has been
@@ -167,57 +168,72 @@ class SimpleSerial:
         #
         # It's also possible that the serial device was half-way
         # through transmitting a packet when this function was called
-        # (app was just started). So we also neeed to handle this case:
+        # (app was just started). So we also neeed to handle this
+        # case:
         #
-        # [Incomplete escaped data][HDLC_FLAG_BYTE][HDLC_FLAG_BYTE][Escaped data][HDLC_FLAG_BYTE]
+        #     [Incomplete escaped data][HDLC_FLAG_BYTE][HDLC_FLAG_BYTE][Escaped data][HDLC_FLAG_BYTE]
         #
         # In this case we skip over the first (incomplete) packet.
         #
 
-        if self._s.timeout != timeout and timeout != None:
-            if self._debug:
-                print "Set the timeout to %s, previous one was %s" % (timeout, self._s.timeout)
-            self._s.timeout = timeout
+        if self._s.getTimeout() != timeout and timeout != None:
+            self.log("Set the timeout to %s, previous one was %s" % (timeout, self._s.getTimeout()))
+            self._s.setTimeout(timeout)
+
+        #    +--- FLAG -----+
+        #    |              |  ___________
+        #    v              | /           |
+        #  >(1)-- !FLAG -->(2)<-- !FLAG --+
+        #    |
+        #   FLAG
+        #    |  ___________
+        #    v /           |
+        #   (3)<-- FLAG ---+
+        #    |
+        #  !FLAG
+        #    |  ___________
+        #    v /           |
+        #   (4)<-- !FLAG --+
+        #    |
+        #   FLAG
+        #    |
+        #    v
+        #   (5)
 
         try:
             # Read bytes until we get to a HDLC_FLAG_BYTE value
             # (either the end of a packet, or the start of a new one)
-            d = self._get_byte(timeout)
+            d = self._s.getByte()
             ts = time.time()
-            if self._debug and d != self.HDLC_FLAG_BYTE:
-                print "Skipping incomplete packet"
-            while d != self.HDLC_FLAG_BYTE:
-                d = self._get_byte(timeout)
-                ts = time.time()
+            if d != HDLC_FLAG_BYTE:
+                self.log("Skipping byte %d" % d)
+                while d != HDLC_FLAG_BYTE:
+                    d = self._s.getByte()
+                    self.log("Skipping byte %d" % d)
+                    ts = time.time()
 
             # Store HDLC_FLAG_BYTE at the start of the retrieved packet
             # data:
             packet = [d]
 
             # Is the next byte also HDLC_FLAG_BYTE?
-            d = self._get_byte(timeout)
-            if d == self.HDLC_FLAG_BYTE:
-                # Yes. This means that the previous byte was for
-                # the end of the previous packet, and this byte is for
-                # the start of the next packet.
-
-                # Get the 2nd byte of the new packet:
-                d = self._get_byte(timeout)
+            d = self._s.getByte()
+            while d == HDLC_FLAG_BYTE:
+                d = self._s.getByte()
                 ts = time.time()
 
             # We are now on the 2nd byte of the packet. Add it to
             # our retrieved packet data:
             packet.append(d)
 
-            # Read bytes from serial until we read another
-            # HDLC_FLAG_BYTE value (end of the current packet):
-            while d != self.HDLC_FLAG_BYTE:
-                d = self._get_byte(timeout)
+            # Read bytes from serial until we read another HDLC_FLAG_BYTE
+            # value (end of the current packet):
+            while d != HDLC_FLAG_BYTE:
+                d = self._s.getByte()
                 packet.append(d)
 
             # Done reading a whole packet from serial
-            if self._debug:
-                print "SimpleSerial:_read: unescaped", packet
+            self.log("SimpleSerial:_read: unescaped %s" % packet)
 
             # Decode the packet, and check CRC:
             packet = self._unescape(packet)
@@ -227,112 +243,17 @@ class SimpleSerial:
 
             if crc != packet_crc:
                 print "Warning: wrong CRC! %x != %x %s" % (crc, packet_crc, ["%2x" % i for i in packet])
-                raise ReadCRCError
-            if self._debug:
-                if self._ts == None:
-                    self._ts = ts
-                else:
-                    print "Serial:_read: %.4f (%.4f) Recv:" % (ts, ts - self._ts), self._format_packet(packet[1:-3])
-                self._ts = ts
+            if not self._s._ts:
+                self._s._ts = ts
+            self.log("Serial:_read: %.4f (%.4f) Recv: %s" % (ts, ts - self._s._ts, self._format(packet[1:-3])))
+            self._ts = ts
 
             # Packet was successfully retrieved, so return it in a
-            # RawPacket wrapper object (but leave out the
-            # HDLC_FLAG_BYTE and CRC bytes)
+            # RawPacket wrapper object (but leave out the HDLC_FLAG_BYTE
+            # and CRC bytes)
             return RawPacket(ts, packet[1:-3])
-        except socket.timeout:
-            raise ReadTimeoutError
-
-    def _write_ack_filter(self, packet):
-        """Filter for recieved write acknowledgement packets"""
-        ack = AckFrame(packet.data)
-        if ack.protocol == self.SERIAL_PROTO_ACK:
-            if self._debug:
-                print "_filter_read: got an ack:", ack
-            self._ack = ack
-            packet = None # No further processing of received ack packet
-        return packet
-
-    def _filter_read(self, timeout=None):
-        """Read a packet from the serial device, perform filtering, and return
-        the packet if it hasn't been processed yet.
-
-        """
-        p = self._read(timeout)
-        self._read_counter += 1
-        if self._debug:
-            print "_filter_read: got a packet(%d): %s" % (self._read_counter, p)
-
-        # Pass the received packet through the filter functions:
-        if p is not None:
-            for filter_func in self._received_packet_filters:
-                p = filter_func(p)
-                # Stop now if the packet doesn't need further processing:
-                if p is None:
-                    break
-
-        # Return the packet (if there was no timeout and it wasn't filtered)
-        return p
-
-    def _get_ack(self, timeout, expected_seqno):
-        """Get the next ack packet
-
-        Read packets from the serial device until we get the next ack (which
-        then gets stored in self._ack), or the timeout expires. non-ack packets
-        are buffered.
-
-        Throws:
-         - ReadTimeoutError if the timeout expires.
-         - BadAckSeqnoError if an ack with a bad sequence number is received
-
-        """
-        endtime = time.time() + timeout
-        while time.time() < endtime:
-            # Read the a packet over serial
-            self._ack = None
-            remaining = endtime - time.time()
-            p = self._filter_read(timeout)
-
-            # Was the packet filtered?
-            if p:
-                # Got an unfiltered packet
-                if len(self._in_queue) >= self._qsize:
-                    print "Warning: Buffer overflow"
-                    self._in_queue.pop(0)
-                self._in_queue.append(p)
-            else:
-                # Packet was filtered. Was it an ack?
-                if self._ack is not None:
-                    # The packet was an ack, so remove it from our
-                    # 'unacknowledged seqnos' list (or raise a BadAckSeqnoError
-                    # error if it isn't in the list)
-                    self._unacked_seqnos.seqno_acked(self._ack.seqno)
-
-                    # Stop reading packets if it's the ack we are waiting for:
-                    if self._ack.seqno == expected_seqno:
-                        return
-
-        # Timed out
-        raise ReadTimeoutError
-
-    def close(self):
-        """Close the serial device"""
-        self._s.close()
-
-    def read(self, timeout=None):
-        """Read a packet, either from the input buffer or from the serial
-        device.
-
-        Returns a RawPacket object, otherwise None if the packet was filtered
-        (by eg: Serial's printf-filtering function)
-
-        Does not retry reads if the first one fails. Use Serial.read() for
-        that.
-
-        """
-        if self._in_queue:
-            return self._in_queue.pop(0)
-        else:
-            return self._filter_read(timeout)
+        except Timeout:
+            return None
 
     def write(self, payload, seqno, timeout=0.2):
         """
@@ -340,24 +261,14 @@ class SimpleSerial:
         assumed to be exactly the payload. Otherwise the payload is
         assume to be a Packet and the real payload is obtain by
         calling the .payload().
-
-        Only attempts to write once, and times out if an ack packet is not
-        received within [timeout] seconds. Use Serial.write() if you want
-        automatic write retries.
-
-        seqno should be an integer between 0 and 99 which changes each time you
-        send a new packet. The value should remain the same when you are
-        retrying a packet write that just failed.
-
-        Raises WriteTimeoutError if the write times out (ack packet doesn't
-        arrive within [timeout] seconds).
-
         """
-        if type(payload) != type([]):
-            # Assume this will be derived from Packet
+
+        if isinstance(payload, Packet):
             payload = payload.payload()
+
         packet = DataFrame();
-        packet.protocol = self.SERIAL_PROTO_PACKET_ACK
+        # We need to always request for acks
+        packet.protocol = SERIAL_PROTO_PACKET_ACK
         packet.seqno = seqno
         packet.dispatch = 0
         packet.data = payload
@@ -365,59 +276,14 @@ class SimpleSerial:
         crc = self._crc16(0, packet)
         packet.append(crc & 0xff)
         packet.append((crc >> 8) & 0xff)
-        packet = [self.HDLC_FLAG_BYTE] + self._escape(packet) + [self.HDLC_FLAG_BYTE]
-
-        # Write the packet:
-        self._unacked_seqnos.seqno_sent(seqno) # Keep track of sent seqno's
-        self._put_bytes(packet)
-        self._write_counter += 1
-
-        # Wait for an ack packet:
-        if self._debug:
-            print "Send(%d/%d): %s" % (self._write_counter, self._write_counter_failures, packet)
-            print "Wait for ack %d ..." % (seqno)
-
-        try:
-            self._get_ack(timeout, seqno)
-        except ReadTimeoutError:
-            # Re-raise read timeouts (of ack packets) as write timeouts (of
-            # the write operation)
-            self._write_counter_failures += 1
-            raise WriteTimeoutError
-
-        # Received an ack packet, with the expected sequence number
-        if self._debug:
-            print "Wait for ack %d done. Latest ack:" % (seqno), self._ack
-            print "The packet was acked."
-            print "Returning from SimpleSerial.write..."
-
-    def add_received_packet_filter(self, filter_func):
-        """Register a received packet-filtering callback function
-
-        _filter_read() calls all of the registered filter functions for each
-        packet received over serial. Registered filter functions are called in
-        the order they were registered.
+        packet = [HDLC_FLAG_BYTE] + self._escape(packet) + [HDLC_FLAG_BYTE]
 
-        Filter functions are called like this: filter_func(packet)
+        self.log("Serial: write %s" % packet)
+        self._s.putBytes(packet)
 
-        When a filter function recognises and handles a received packet it
-        should return a None value to indicate that no further processing
-        is required for the packet.
-
-        When a filter function skips a packet (or for some reason you want
-        further processing to happen on a packet you've just processed), the
-        function should return the packet that was passed to it as an argument.
-
-        """
-        self._received_packet_filters.append(filter_func)
-
-    def remove_received_packet_filter(self, filter_func):
-        """Remove a filter function added with add_received_packet_filter()"""
-        self._received_packet_filters.remove(filter_func)
-
-    def _format_packet(self, payload):
+    def _format(self, payload):
         f = NoAckDataFrame(payload)
-        if f.protocol == self.SERIAL_PROTO_ACK:
+        if f.protocol == SERIAL_PROTO_ACK:
             rpacket = AckFrame(payload)
             return "Ack seqno: %d" % (rpacket.seqno)
         else:
@@ -452,24 +318,6 @@ class SimpleSerial:
             r = (r << 8) + i
         return r
 
-    def _get_byte(self, timeout=None):
-#        old_timeout = self._s.timeout
-#        if timeout is not None:
-#            self._s.timeout = timeout
-        try:
-            r = struct.unpack("B", self._s.read())[0]
-            return r
-        except struct.error:
-            # Serial port read timeout
-            raise socket.timeout
-#        finally:
-#            self._s.timeout = old_timeout
-
-    def _put_bytes(self, data):
-        #print "DEBUG: _put_bytes:", data
-        for b in data:
-            self._s.write(struct.pack('B', b))
-
     def _unescape(self, packet):
         r = []
         esc = False
@@ -477,7 +325,7 @@ class SimpleSerial:
             if esc:
                 r.append(b ^ 0x20)
                 esc = False
-            elif b == self.HDLC_CTLESC_BYTE:
+            elif b == HDLC_CTLESC_BYTE:
                 esc = True
             else:
                 r.append(b)
@@ -486,285 +334,140 @@ class SimpleSerial:
     def _escape(self, packet):
         r = []
         for b in packet:
-            if b == self.HDLC_FLAG_BYTE or b == self.HDLC_CTLESC_BYTE:
-                r.append(self.HDLC_CTLESC_BYTE)
+            if b == HDLC_FLAG_BYTE or b == HDLC_CTLESC_BYTE:
+                r.append(HDLC_CTLESC_BYTE)
                 r.append(b ^ 0x20)
             else:
                 r.append(b)
         return r
 
-    def debug(self, debug):
-        self._debug = debug
-
-
-class SeqTracker:
-    """Class for keeping track of unacknowledged packet sequence numbers.
-
-    SeqTracker is used by SimpleSerial to keep track of sequence numbers which
-    have been sent with write packets, but not yet acknowledged by received
-    write ack packets.
+    def log(self, s):
+        if self._s.debug:
+            print s
 
-    """
-    def __init__(self, keep_for):
-        """Initialise a SeqTracker object.
-
-        args:
-
-         - keep_for is the length of time for which unacknowledged sequence
-           numbers should be remembered. After this period has elapsed, the
-           sequence numbers should be forgotten. If the sequence number is
-           acknowledged later, it will be treated as unkown
-
-        """
-        self._keep_for = keep_for
-        self._queue = []
-
-    def seqno_sent(self, seqno):
-        """Register that a packet with the specified sequence number was just
-           sent."""
-        self._gc()
-        self._queue.append((seqno, time.time()))
-
-    def seqno_acked(self, seqno):
-        """Register that a sequence number was just acknowledged.
+class SimpleAM(object):
+    def __init__(self, s, oobHook=None):
+        self._s = HDLC(s)
+        self.seqno = 0
+        self.oobHook = oobHook
 
-        Find the oldest-known occurance of seqno in the queue and remove it. If
-        not found then raise a BadAckSeqnoError to inform applications that
-        the sequence number is not known.
+    def read(self, timeout=None):
+        f = self._s.read(timeout)
+        if f:
+            return ActiveMessage(NoAckDataFrame(f))
+        return None
 
-        """
-        self._gc()
-        for item in self._queue:
-            if item[0] == seqno:
-                # Found seqno
-                self._queue.remove(item)
-                return
-        # seqno not found!
-        raise BadAckSeqnoError
-
-    def get_seqno_sent_times(self, seqno):
-        """Return the times when packets with the given sequence number were
-        sent."""
-        self._gc()
-        return [item[1] for item in self._queue if item[0] == seqno]
-
-    def __contains__(self, seqno):
-        """Return True if the seqno was sent recently (and not acknowledged
-        yet)"""
-        self._gc()
-        for item in self._queue:
-            if item[0] == seqno:
+    def write(self, packet, amId, timeout=None, blocking=True, inc=1):
+        self.seqno = (self.seqno + inc) % 256
+        while True:
+            self._s.write(ActiveMessage(packet, amId=amId), seqno=self.seqno, timeout=timeout)
+            if not blocking:
                 return True
-        return False
-
-    def _gc(self):
-        """Remove old items from the queue"""
-        remove_before = time.time() - self._keep_for
-        for item in self._queue:
-            # Time for the sequence to be removed?
-            if item[1] < remove_before:
-                # Sequence data is old, so remove it
-                self._queue.remove(item)
-            else:
-                # Sequence number was added recently, so don't remove it. Also
-                # stop processing the queue because all later items will be
-                # newer
+            f = self._s.read(timeout)
+            if f == None:
+                continue
+            ack = AckFrame(f)
+            while ack.protocol != SERIAL_PROTO_ACK:
+                if self.oobHook:
+                    self.oobHook(ActiveMessage(NoAckDataFrame(f)))
+                else:
+                    print 'SimpleAM:write: skip', ack, f
+                f = self._s.read(timeout)
+                if f == None:
+                    break
+                ack = AckFrame(f)
+            if f != None:
                 break
-
-
-class Serial:
-    """
-    Wraps a SimpleSerial object, and provides some higher-level functionality
-    like retrying writes and logging printf packets.
-    """
-    def __init__(self, port, baudrate, flush=False, debug=False, qsize=10,
-                 timeout=None):
-        """Initialise a Serial object"""
-        self._debug = debug
-        self.timeout = timeout # Public attribute
-        self._seqno = 0
-        self._simple_serial = SimpleSerial(port, baudrate, flush, debug, qsize,
-                                           timeout)
-
-        # Setup automatic logging of received printf packets:
-        self._printf_msg = ""
-        self._simple_serial.add_received_packet_filter(self._printf_filter)
-
-    def close(self):
-        """Close the serial device"""
-        self._simple_serial.close()
-
-    def read(self, timeout=None):
-        """Read a packet from the serial port.
-
-        Retries packet reads until the timeout expires.
-
-        Throws ReadTimeoutError if a a packet can't be read within the timeout.
-
-        """
-        if timeout is None:
-            timeout = self.timeout
-        endtime = None
-
-        if timeout is not None:
-            endtime = time.time() + timeout
-
-        while endtime is None or time.time() < endtime:
-            remaining = None
-            if endtime is not None:
-                remaining = endtime - time.time()
+        #print 'SimpleAM:write: got an ack:', ack, ack.seqno == self.seqno
+        return ack.seqno == self.seqno
+
+    def setOobHook(self, oobHook):
+        self.oobHook = oobHook
+
+def printfHook(packet):
+    if packet == None:
+        return
+    if packet.type == 100:
+        s = "".join([chr(i) for i in packet.data]).strip('\0')
+        lines = s.split('\n')
+        for line in lines:
+            print "PRINTF:", line
+        packet = None # No further processing for the printf packet
+    return packet    
+
+class AM(SimpleAM):
+    def __init__(self, s=None, oobHook=None):
+        if s == None:
             try:
-                p = self._simple_serial.read(remaining)
-            except ReadError:
-                if self._debug:
-                    print "Packet read failed. Try again."
-            else:
-                # Was the packet filtered?
-                if p is not None:
-                    # Not filtered, so return it.
-                    # In the current TinyOS the packets from the mote are
-                    # always NoAckDataFrame
-                    return NoAckDataFrame(p.data)
-
-        # Read timeout expired
-        raise ReadTimeoutError
-
-    def write(self, payload, timeout=None):
-        """Write a packet to the serial port
-
-        Keeps retrying endlessly, unless a timeout is set. If the timeout
-        expires then WriteTimeoutError is thrown.
-
-        """
-        if timeout is None:
-            timeout = self.timeout
-
-        endtime = None
-        if timeout is not None:
-            endtime = time.time() + timeout
-
-        # Generate the next sequence number:
-        self._seqno = (self._seqno + 1) % 100
-
-        while endtime is None or time.time() < endtime:
-            try:
-                ackwait = ACK_WAIT
-                if endtime is not None:
-                    remaining = endtime - time.time()
-                    ackwait = min(ACK_WAIT, remaining)
-
-                before = time.time()
-                self._simple_serial.write(payload, self._seqno, ackwait)
-                length = time.time() - before
-
-                if length >= ACK_WARN:
-                    print "Warning: Packet write took %.3fs!" % (length)
-                return True
-            except Error:
-                if self._debug:
-                    print "The packet was not acked. Try again."
-
-        # Write operation timed out
-        raise WriteTimeoutError
-
-    def _printf_filter(self, packet):
-        """Filter for recieved printf packets"""
-        ampkt = ActiveMessage(NoAckDataFrame(packet.data).data)
-        if ampkt.type == 100:
-            self._printf_msg += "".join([chr(i) for i in ampkt.data]).strip('\0')
-            # Split printf data on newline character:
-            # (last string in the split list doesn't have a newline after
-            # it, so we keep it until next time)
-            lines = self._printf_msg.split('\n')
-            for line in lines[:-1]:
-                print "PRINTF:", line
-            self._printf_msg = lines[-1]
-            packet = None # No further processing for the printf packet
-        return packet
-
-class SFClient:
-    def __init__(self, host, port, qsize=10):
-        self._in_queue = Queue(qsize)
-        self._s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self._s.connect((host, port))
-        data = self._s.recv(2)
-        if data != 'U ':
-            print "Wrong handshake"
-        self._s.send("U ")
-        print "Connected"
-        thread.start_new_thread(self.run, ())
-
-    def run(self):
-        while True:
-            length = ord(self._s.recv(1))
-            data = self._s.recv(length)
-            data = [ord(c) for c in data][1:]
-            #print "Recv %d bytes" % (length), ActiveMessage(data)
-            if self._in_queue.full():
-                print "Warning: Buffer overflow"
-                self._in_queue.get()
-            p = RawPacket()
-            p.data = data
-            self._in_queue.put(p, block=False)
-
-    def read(self, timeout=0):
-        return self._in_queue.get()
-
-    def write(self, payload):
-        print "SFClient: write:", payload
-        if type(payload) != type([]):
-            # Assume this will be derived from Packet
-            payload = payload.payload()
-        payload = [0] + payload
-        self._s.send(chr(len(payload)))
-        self._s.send(''.join([chr(c) for c in payload]))
-        return True
-
-class AM:
-    def __init__(self, s):
-        self._s = s
+                s = getSource(sys.argv[1])
+            except:
+                try:
+                    for (i, j) in zip(sys.argv[1::2], sys.argv[2::2]):
+                        if i == '-comm':
+                            s = getSource(j)
+                    if s == None:
+                        raise Exception
+                except:
+                    try:
+                        s = getSource(os.environ['MOTECOM'])
+                        print 'third'
+                    except:
+                        print "ERROR: please indicate a way to connect to the mote"
+                        sys.exit(-1)
+        if oobHook == None:
+            oobHook = printfHook
+        super(AM, self).__init__(s, oobHook)
 
     def read(self, timeout=None):
-        return ActiveMessage(self._s.read(timeout).data)
-
-    def write(self, packet, amid, timeout=None):
-        return self._s.write(ActiveMessage(packet, amid=amid), timeout=timeout)
-
-
-class SimpleSerialAM(SimpleSerial):
-    """A derived class of SimpleSerial so that apps can read and write using
-    higher-level packet structures.
+        return self.oobHook(super(AM, self).read(timeout))
 
-    Serves a simalar purpose to the AM class, but for SimpleSerial objects
-    instead instead of Serial.
-
-    """
-
-    def read_am(self, timeout=None):
-        """Read a RawPacket object (or None), convert it to ActiveMessage
-        (or None), and return to the caller"""
-
-        # Get a tos.Rawpacket (or None, if filtered) object
-        p = self.read(timeout)
-        if p is not None:
-            assert isinstance(p, RawPacket)
-            # Convert tos.RawPacket object into an ActiveMessage:
-            p = NoAckDataFrame(p.data)
-            p = ActiveMessage(p.data)
-
-        # Return the ActiveMessage (or None) packet:
-        return p
-
-    def write_am(self, packet, amid, seqno, timeout=2.0):
-        """Convert app packet format to ActiveMessage, and write the
-        ActiveMessage packet to serial"""
-
-        # Convert from app-specific packet to ActiveMessage:
-        p = ActiveMessage(packet, amid=amid)
+    def write(self, packet, amId, timeout=None, blocking=True):
+        r = super(AM, self).write(packet, amId, timeout, blocking)
+        while not r:
+            r = super(AM, self).write(packet, amId, timeout, blocking, inc=0)
+        return True
 
-        # Write to the serial device
-        self.write(p, seqno, timeout)
 
+# class SFClient:
+#     def __init__(self, host, port, qsize=10):
+#         self._in_queue = Queue(qsize)
+#         self._s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+#         self._s.connect((host, port))
+#         data = self._s.recv(2)
+#         if data != 'U ':
+#             print "Wrong handshake"
+#         self._s.send("U ")
+#         print "Connected"
+#         thread.start_new_thread(self.run, ())
+
+#     def run(self):
+#         while True:
+#             length = ord(self._s.recv(1))
+#             data = self._s.recv(length)
+#             data = [ord(c) for c in data][1:]
+#             #print "Recv %d bytes" % (length), ActiveMessage(data)
+#             if self._in_queue.full():
+#                 print "Warning: Buffer overflow"
+#                 self._in_queue.get()
+#             p = RawPacket()
+#             p.data = data
+#             self._in_queue.put(p, block=False)
+
+#     def read(self, timeout=0):
+#         return self._in_queue.get()
+
+#     def write(self, payload):
+#         print "SFClient: write:", payload
+#         if type(payload) != type([]):
+#             # Assume this will be derived from Packet
+#             payload = payload.payload()
+#         payload = [0] + payload
+#         self._s.send(chr(len(payload)))
+#         self._s.send(''.join([chr(c) for c in payload]))
+#         return True
+
+
+################################################################################
 
 class Packet:
     """
@@ -786,6 +489,11 @@ class Packet:
         output.reverse()
         return output
 
+    def _sign(self, val, dim):
+        if val > (1 << (dim * 8 - 1)):
+            return val - (1 << (dim * 8))
+        return val
+
     def __init__(self, desc, packet = None):
         offset = 0
         boffset = 0
@@ -805,6 +513,9 @@ class Packet:
                 if t == 'int':
                     self._values.append(self._decode(packet[offset:offset + s]))
                     offset += s
+                elif t == 'sint':
+                    self._values.append(self._sign(self._decode(packet[offset:offset + s]), s))
+                    offset += s
                 elif t == 'bint':
                     doffset = 8 - (boffset + s)
                     self._values.append((packet[offset] >> doffset) & ((1<<s) - 1))
@@ -842,27 +553,9 @@ class Packet:
         for i in range(len(self._names), len(self._values)):
             r += "%s" % self._values[i]
         return r
-#        return self._values.__str__()
-
-    # Implement the map behavior
-    def __getitem__(self, key):
-        return self.__getattr__(key)
-
-    def __setitem__(self, key, value):
-        self.__setattr__(key, value)
-
-    def __len__(self):
-        return len(self._values)
-
-    def keys(self):
-        return self._names
-
-    def values(self):
-        return self._names
 
     # Implement the struct behavior
     def __getattr__(self, name):
-        #print "DEBUG: __getattr__", name
         if type(name) == type(0):
             return self._names[name]
         else:
@@ -889,7 +582,23 @@ class Packet:
     def __nonzero__(self):
         return True;
 
-    # Custom
+    # Implement the map behavior
+    def __getitem__(self, key):
+        return self.__getattr__(key)
+
+    def __setitem__(self, key, value):
+        self.__setattr__(key, value)
+
+    def __len__(self):
+        return len(self._values)
+
+    def keys(self):
+        return self._names
+
+    def values(self):
+        return self._names
+
+    # Custom functions
     def names(self):
         return self._names
 
@@ -931,6 +640,11 @@ class RawPacket(Packet):
 
 class AckFrame(Packet):
     def __init__(self, payload = None):
+        if isinstance(payload, Packet):
+            if isinstance(payload, RawPacket):
+                payload = payload.data
+            else:
+                payload = payload.payload()
         Packet.__init__(self,
                         [('protocol', 'int', 1),
                          ('seqno',    'int', 1)],
@@ -938,9 +652,11 @@ class AckFrame(Packet):
 
 class DataFrame(Packet):
     def __init__(self, payload = None):
-        if payload != None and type(payload) != type([]):
-            # Assume is a Packet
-            payload = payload.payload()
+        if isinstance(payload, Packet):
+            if isinstance(payload, RawPacket):
+                payload = payload.data
+            else:
+                payload = payload.payload()
         Packet.__init__(self,
                         [('protocol',  'int', 1),
                          ('seqno',     'int', 1),
@@ -950,9 +666,11 @@ class DataFrame(Packet):
 
 class NoAckDataFrame(Packet):
     def __init__(self, payload = None):
-        if payload != None and type(payload) != type([]):
-            # Assume is a Packet
-            payload = payload.payload()
+        if isinstance(payload, Packet):
+            if isinstance(payload, RawPacket):
+                payload = payload.data
+            else:
+                payload = payload.payload()
         Packet.__init__(self,
                         [('protocol',  'int', 1),
                          ('dispatch',  'int', 1),
@@ -960,27 +678,29 @@ class NoAckDataFrame(Packet):
                         payload)
 
 class ActiveMessage(Packet):
-    def __init__(self, gpacket = None, amid = 0x00, dest = 0xFFFF):
-        if type(gpacket) == type([]):
-            payload = gpacket
-        else:
-            # Assume this will be derived from Packet
-            payload = None
+    def __init__(self, packet = None, amId = 0x00, dest = 0xFFFF):
+        payload = None
+        if type(packet) == type([]):
+            payload = packet
+        elif isinstance(packet, NoAckDataFrame):
+            payload = packet.data
+            packet = None
+
         Packet.__init__(self,
                         [('destination', 'int', 2),
-                         ('source',   'int', 2),
-                         ('length',   'int', 1),
-                         ('group',    'int', 1),
-                         ('type',     'int', 1),
-                         ('data',     'blob', None)],
+                         ('source',      'int', 2),
+                         ('length',      'int', 1),
+                         ('group',       'int', 1),
+                         ('type',        'int', 1),
+                         ('data',        'blob', None)],
                         payload)
         if payload == None:
             self.destination = dest
             self.source = 0x0000
             self.group = 0x00
-            self.type = amid
+            self.type = amId
             self.data = []
-            if gpacket:
-                self.data = gpacket.payload()
+            if isinstance(packet, Packet):
+                self.data = packet.payload()
             self.length = len(self.data)
 
index 76498bb1cb5ffba95e638544ba5f76d64d43ac13..0fc584d56312aef7bdd9060ac585f826a5ae53c8 100644 (file)
@@ -31,6 +31,7 @@ bin_SCRIPTS = tos-ident-flags \
              tos-storage-at45db \
              tos-storage-pxa27xp30     \
              tos-build-deluge-image \
-             tos-deluge
+             tos-deluge \
+             tos-dump.py
 
 bin_PROGRAMS = tos-serial-debug
index 1ca3acb5ef1042cb54b8d3ea91e54578dc8fb896..9ec58283e567b4eb881f462fd37870558679048a 100755 (executable)
@@ -39,10 +39,6 @@ PATH_PY_BUILD_IMAGE  = os.path.join(os.path.dirname(sys.argv[0]), 'tos-build-del
 FM_AMID = 0x53
 DM_AMID = 0x54
 SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2
-BAUDRATES = {'micaz': 57600,
-             'telosb': 115200,
-             'iris': 57600,
-            'epic': 115200}
 
 # Commands for FlashManager
 FM_CMD_ERASE     = 0
@@ -371,8 +367,10 @@ def localstop():
     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"
@@ -391,71 +389,55 @@ def checkImgNum():
     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:
 
-    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 = tos.Serial(sys.argv[1], baudrate, flush=True, debug=False)
-        am = tos.AM(s)
-    except:
-        print "ERROR: Unable to initialize serial port connection to", sys.argv[1]
-        sys.exit(-1)
+    am = tos.AM()
 
-    # Check if the mote has the Deluge T2 basestation component:
     try:
         print "Checking if node is a Deluge T2 base station ..."
         ident(timeout=5)
-    except tos.TimeoutError:
+    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:
+    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:
diff --git a/tools/tinyos/misc/tos-dump.py b/tools/tinyos/misc/tos-dump.py
new file mode 100644 (file)
index 0000000..1d669e1
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+import sys
+import tos
+
+if '-h' in sys.argv:
+    print "Usage:", sys.argv[0], "serial@/dev/ttyUSB0:57600"
+    print "      ", sys.argv[0], "network@host:port"
+    sys.exit()
+
+am = tos.AM()
+
+while True:
+    p = am.read()
+    if p:
+       print p
+