[Tinyos-2-commits] CVS: tinyos-2.x/tools/tinyos/misc tinyos.py, 1.3, 1.4 tos-build-deluge-image, 1.2, 1.3 tos-deluge, 1.8, 1.9

Razvan Musaloiu-E. razvanm at users.sourceforge.net
Sun Jan 13 20:22:03 PST 2008


Update of /cvsroot/tinyos/tinyos-2.x/tools/tinyos/misc
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv20053/tools/tinyos/misc

Modified Files:
	tinyos.py tos-build-deluge-image tos-deluge 
Log Message:
Super Duper update to Deluge T2. The manual and the testing scripts are temporary out-of-date.

Some of the improvements are:
- simplified images (ident and metadata were merged)
- network-order representation of fields
- new version of tinyos.py
- improved sharing of volumes.


Index: tinyos.py
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tools/tinyos/misc/tinyos.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** tinyos.py	16 Jul 2007 22:11:03 -0000	1.3
--- tinyos.py	14 Jan 2008 04:22:01 -0000	1.4
***************
*** 1,32 ****
! import struct, time, serial, socket
  
! # Copyright (c) 2007 Johns Hopkins University.
! # All rights reserved.
! #
! # Permission to use, copy, modify, and distribute this software and its
! # documentation for any purpose, without fee, and without written
! # agreement is hereby granted, provided that the above copyright
! # notice, the (updated) modification history and the author appear in
! # all copies of this source code.
! #
! # 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 HOLDERS OR CONTRIBUTORS
! # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
! # OR PROFITS) 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.
  
! # @author Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
! # @author Razvan Musaloiu-E. <razvanm at cs.jhu.edu>
  
! ###############################################################################
! # TinyOS 2 Python Serial Module
! ###############################################################################
  
  class Serial:
      HDLC_FLAG_BYTE = 0x7e
      HDLC_CTLESC_BYTE = 0x7d
--- 1,30 ----
! """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
! from Queue import Queue
! 
! __version__ = "$Id$"
! 
! __all__ = ['Serial', 'GenericPacket', 'RawPacket',
!            'AckFrame', 'DataFrame', 'NoAckDataFrame',
!            'ActiveMessage']
! 
! _seqno = 1
! 
! def list2hex(v):
!     return " ".join(["%02x" % p for p in v])
  
  class Serial:
+     """
+     A Serial object offers a way to send and data using a HDLC-like
+     formating.
+     """
+     
      HDLC_FLAG_BYTE = 0x7e
      HDLC_CTLESC_BYTE = 0x7d
***************
*** 41,71 ****
      SERIAL_PROTO_PACKET_NOACK = 69
      SERIAL_PROTO_PACKET_UNKNOWN = 255
      
!     __s = None        # An instance of serial.Serial object
!     __debug = False   # Debug mode
!     
!     __baud_rate = {}
!     
!     def __init__(self, port, baudrate):
!         __baud_rate = {'telos': 115200, 'telosb': 115200, 
!                        'tmote': 115200, 'micaz': 57600, 
!                        'mica2': 57600, 'mica2dot': 19200, 
!                        'eyes': 115200, 'intelmote2': 115200}
!         
!         # Converts baud rate from platform name to value, if necessary
!         try:
!             baudrate = int(baudrate)
!         except:
!             baudrate = __baud_rate.get(baudrate)
!         
!         if not baudrate == None:
!             self.__s = serial.Serial(port, baudrate, rtscts=0, timeout=0.5)
          else:
!             raise ValueError, 'Invalid baud rate'
!     
!     def __format_packet(self, packet):
!         return " ".join(["%02x" % p for p in packet]) + " | " + \
!                " ".join(["%d" % p for p in packet])
!     
      def crc16(self, base_crc, frame_data):
          crc = base_crc
--- 39,73 ----
      SERIAL_PROTO_PACKET_NOACK = 69
      SERIAL_PROTO_PACKET_UNKNOWN = 255
+   
+     _debug = False   # Debug mode
      
!     def __init__(self, port, baudrate, flush=True):
!        self._s = serial.Serial(port, baudrate, rtscts=0, timeout=0.5)
!        self._queue = Queue()
!        self._ts = None
!        self._seqno = 0
! 
!        self._s.flushInput()
!        start = time.time();
!        if flush:
!            print "Flushing the serial port",
!            while time.time() - start < 1:
!                p = self.sniff()
!                sys.stdout.write(".")
!            if not self._debug:
!                sys.stdout.write("\n")
! 
!     def _format_packet(self, payload):
!         f = NoAckDataFrame(payload)
!         if f.protocol == self.SERIAL_PROTO_ACK:
!             rpacket = AckFrame(payload)
!             return "Ack seqno: %d" % (rpacket.seqno)
          else:
!             rpacket = ActiveMessage(f.data)
!             return "D: %04x S: %04x L: %02x G: %02x T: %02x | %s" % \
!                    (rpacket.destination, rpacket.source,
!                     rpacket.length, rpacket.group, rpacket.type,
!                     list2hex(rpacket.data))
! 
      def crc16(self, base_crc, frame_data):
          crc = base_crc
***************
*** 80,84 ****
          return crc
      
!     def __encode(self, val, dim):
          output = []
          for i in range(dim):
--- 82,86 ----
          return crc
      
!     def _encode(self, val, dim):
          output = []
          for i in range(dim):
***************
*** 87,91 ****
          return output
      
!     def __decode(self, v):
          r = long(0)
          for i in v[::-1]:
--- 89,93 ----
          return output
      
!     def _decode(self, v):
          r = long(0)
          for i in v[::-1]:
***************
*** 93,99 ****
          return r
      
!     def __get_byte(self):
          try:
!             r = struct.unpack("B", self.__s.read())[0]
              return r
          except struct.error:
--- 95,101 ----
          return r
      
!     def _get_byte(self):
          try:
!             r = struct.unpack("B", self._s.read())[0]
              return r
          except struct.error:
***************
*** 101,109 ****
              raise socket.timeout
      
!     def __put_bytes(self, data):
          for b in data:
!             self.__s.write(struct.pack('B', b))
      
!     def __unescape(self, packet):
          r = []
          esc = False
--- 103,112 ----
              raise socket.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
***************
*** 118,122 ****
          return r
      
!     def __escape(self, packet):
          r = []
          for b in packet:
--- 121,125 ----
          return r
      
!     def _escape(self, packet):
          r = []
          for b in packet:
***************
*** 129,221 ****
      
      # Returns the next incoming serial packet
!     def sniff_packet(self):
          try:
!             d = self.__get_byte()
              ts = time.time()
              while d != self.HDLC_FLAG_BYTE:
!                 d = self.__get_byte()
                  ts = time.time()
              packet = [d]
!             d = self.__get_byte()
              if d == self.HDLC_FLAG_BYTE:
!                 d = self.__get_byte()
                  ts = time.time()
              else:
                  packet.append(d)
              while d != self.HDLC_FLAG_BYTE:
!                 d = self.__get_byte()
                  packet.append(d)
!             un_packet = self.__unescape(packet)
              
!             crc = self.crc16(0, un_packet[1:-3])
!             packet_crc = self.__decode(un_packet[-3:-1])
              
!             if self.__debug == True:
                  if crc != packet_crc:
!                     print "Warning: wrong CRC!"
!                 print "Recv:", self.__format_packet(un_packet)
!             return (ts, un_packet)
          except socket.timeout:
              return None
!     
!     # Filters and returns the next incoming serial packet with 
!     # specified AM group ID and AM ID
!     def read_packet(self, am_group, am_id):
!         packet = None
          
!         while True:
!             packet = self.sniff_packet()
!             if not packet == None and len(packet[1]) >= 10:
!                 if (packet[1])[8] == am_group and (packet[1])[9] == am_id:
!                     break
!             
!         return packet
      
      # Sends data with the specified AM group ID and AM ID. To have a "reliable"
      # transfer, num_tries defines how many times to retry before giving up
!     def write_packet(self, am_group, am_id, data, num_tries=10):
          for i in range(num_tries):
!             # The first byte after SERIAL_PROTO_PACKET_ACK is a sequence
!             # number that will be send back by the mote to ack the receive of
!             # the data.
!             packet = [self.SERIAL_PROTO_PACKET_ACK, 0, self.TOS_SERIAL_ACTIVE_MESSAGE_ID,
!                       0xff, 0xff,
!                       0, 0,
!                       len(data), am_group, am_id] + data
!             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]
!             
!             self.__put_bytes(packet)
!             if self.__debug == True:
!                 print "Send:", self.__format_packet(packet)
              
              # Waits for ACK
              for j in range(3):
!                 while True:
!                     packet = self.sniff_packet()
!                     if packet == None:
!                         break
!                     elif (packet[1])[1] == self.SERIAL_PROTO_ACK:
                          return True
                          
-             # Debug messages
-             if self.__debug == True:
-                 if i == (num_tries - 1):
-                     print "Failed to send the packet!" 
-                 else:
-                     print "Timeout waiting for ACK... Retry"
-                     
          return False
      
!     # Sets whether debugging message will in this module will be printed
!     def set_debug(self, debug):
!         self.__debug = debug
  
  class GenericPacket:
      """ GenericPacket """
  
!     def __decode(self, v):
          r = long(0)
          for i in v:
--- 132,249 ----
      
      # Returns the next incoming serial packet
!     def sniff(self, skip_queue = False):
!         """Wait for a packet and return it as a RawPacket."""
!         
!         if (not skip_queue and not self._queue.empty()):
!             print "DEBUG: sniff_packet: return a packet from the queue(%d)." % self._queue.qsize()
!             return self._queue.get()
          try:
!             d = self._get_byte()
              ts = time.time()
              while d != self.HDLC_FLAG_BYTE:
!                 d = self._get_byte()
                  ts = time.time()
              packet = [d]
!             d = self._get_byte()
              if d == self.HDLC_FLAG_BYTE:
!                 d = self._get_byte()
                  ts = time.time()
              else:
                  packet.append(d)
              while d != self.HDLC_FLAG_BYTE:
!                 d = self._get_byte()
                  packet.append(d)
!             if self._debug == True:
!                 print "sniff: unescaped", packet
!             packet = self._unescape(packet)
              
!             crc = self.crc16(0, packet[1:-3])
!             packet_crc = self._decode(packet[-3:-1])
              
!             if self._debug:
                  if crc != packet_crc:
!                     print "Warning: wrong CRC! %s" % packet
!                 if self._ts == None:
!                     self._ts = ts
!                 else:
!                     print "%.4f (%.4f) Recv:" % (ts, ts - self._ts), self._format_packet(packet[1:-3])
!                 self._ts = ts
!             return RawPacket(ts, packet[1:-3], crc == packet_crc)
          except socket.timeout:
              return None
! 
!     def sniff_am(self, skip_queue = False, timeout=0):
!         """Wait for a packet and return it as a ActiveMessage."""
          
!         start = time.time();
!         p = None
!         done = False
!         while not done:
!             while p == None:
!                 if timeout == 0 or time.time() - start < timeout:
!                     p = self.sniff(skip_queue)
!                 else:
!                     return None
!             if p.crc:
!                 done = True
!         return ActiveMessage(NoAckDataFrame(p.data).data)
! 
      
      # Sends data with the specified AM group ID and AM ID. To have a "reliable"
      # transfer, num_tries defines how many times to retry before giving up
!     def write(self, payload, num_tries=3):
!         """
!         Write a packet. If the payload argument is a list, it is
!         assumed to be exactly the payload. Otherwise the payload is
!         assume to be a GenericPacket and the real payload is obtain
!         by calling the .payload().
!         """
!         
!         global _seqno
!         if type(payload) != type([]):
!             # Assume this will be derived from GenericPacket
!             payload = payload.payload()
!         _seqno = (_seqno + 1) % 100
!         packet = DataFrame();
!         packet.protocol = self.SERIAL_PROTO_PACKET_ACK
!         packet.seqno = _seqno
!         packet.dispatch = 0
!         packet.data = payload
!         packet = packet.payload()
!         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]
! 
          for i in range(num_tries):
!             self._put_bytes(packet)
!             if self._debug == True:
!                 print "Send:", packet
              
              # Waits for ACK
              for j in range(3):
!                 p = self.sniff(skip_queue = True)
!                 if p != None:
!                     ack = AckFrame(p.data)
!                     if ack.protocol == self.SERIAL_PROTO_ACK:
!                         if ack.seqno != _seqno:
!                             print ">" * 40, "Wrong ACK!", ack.seqno, _seqno, "<" * 40
                          return True
+                     else:
+                         if self._debug == True:
+                             print "write_packet: put a packet in the queue(%d)." % (self._queue.qsize())
+                         self._queue.put(p)
                          
          return False
      
!     def debug(self, debug):
!         self._debug = debug
! 
! 
  
  class GenericPacket:
      """ GenericPacket """
  
!     def _decode(self, v):
          r = long(0)
          for i in v:
***************
*** 223,227 ****
          return r
      
!     def __encode(self, val, dim):
          output = []
          for i in range(dim):
--- 251,255 ----
          return r
      
!     def _encode(self, val, dim):
          output = []
          for i in range(dim):
***************
*** 232,250 ****
      
      def __init__(self, desc, packet = None):
          self.__dict__['_schema'] = [(t, s) for (n, t, s) in desc]
          self.__dict__['_names'] = [n for (n, t, s) in desc]
          self.__dict__['_values'] = []
-         offset = 10
          if type(packet) == type([]):
              for (t, s) in self._schema:
                  if t == 'int':
!                     self._values.append(self.__decode(packet[offset:offset + s]))
                      offset += s
                  elif t == 'blob':
                      if s:
!                         self._values.append(packet[offset:offset + s])
!                         offset += s
                      else:
!                         self._values.append(packet[offset:-3])
          elif type(packet) == type(()):
              for i in packet:
--- 260,301 ----
      
      def __init__(self, desc, packet = None):
+         offset = 0
+         boffset = 0
+         sum = 0
+         for i in range(len(desc)-1, -1, -1):
+             (n, t, s) = desc[i]
+             if s == None:
+                 if sum > 0:
+                     desc[i] = (n, t, -sum)
+                 break
+             sum += s
          self.__dict__['_schema'] = [(t, s) for (n, t, s) in desc]
          self.__dict__['_names'] = [n for (n, t, s) in desc]
          self.__dict__['_values'] = []
          if type(packet) == type([]):
              for (t, s) in self._schema:
                  if t == 'int':
!                     self._values.append(self._decode(packet[offset:offset + s]))
!                     offset += s
!                 elif t == 'bint':
!                     doffset = 8 - (boffset + s)
!                     self._values.append((packet[offset] >> doffset) & ((1<<s) - 1))
!                     boffset += s
!                     if boffset == 8:
!                         offset += 1
!                         boffset = 0
!                 elif t == 'string':
!                     self._values.append(''.join([chr(i) for i in packet[offset:offset + s]]))
                      offset += s
                  elif t == 'blob':
                      if s:
!                         if s > 0:
!                             self._values.append(packet[offset:offset + s])
!                             offset += s
!                         else:
!                             self._values.append(packet[offset:s])
!                             offset = len(packet) + s
                      else:
!                         self._values.append(packet[offset:])
          elif type(packet) == type(()):
              for i in packet:
***************
*** 258,262 ****
  
      def __str__(self):
!         return self._values.__str__()
  
      # Implement the map behavior
--- 309,319 ----
  
      def __str__(self):
!         r = ""
!         for i in range(len(self._names)):
!             r += "%s: %s " % (self._names[i], self._values[i])
!         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
***************
*** 278,281 ****
--- 335,339 ----
      # Implement the struct behavior
      def __getattr__(self, name):
+         #print "DEBUG: __getattr__", name
          if type(name) == type(0):
              return self._names[name]
***************
*** 289,292 ****
--- 347,365 ----
              self._values[self._names.index(name)] = value
  
+     def __ne__(self, other):
+         if other.__class__ == self.__class__:
+             return self._values != other._values
+         else:
+             return True
+ 
+     def __eq__(self, other):
+         if other.__class__ == self.__class__:
+             return self._values == other._values
+         else:
+             return False
+ 
+     def __nonzero__(self):
+         return True;
+ 
      # Custom
      def names(self):
***************
*** 298,306 ****
      def payload(self):
          r = []
          for i in range(len(self._schema)):
              (t, s) = self._schema[i]
              if t == 'int':
!                 r += self.__encode(self._values[i], s)
!             else:
                  r += self._values[i]
          return r
--- 371,459 ----
      def payload(self):
          r = []
+         boffset = 0
          for i in range(len(self._schema)):
              (t, s) = self._schema[i]
              if t == 'int':
!                 r += self._encode(self._values[i], s)
!                 boffset = 0
!             elif t == 'bint':
!                 doffset = 8 - (boffset + s)
!                 if boffset == 0:
!                     r += [self._values[i] << doffset]
!                 else:
!                     r[-1] |= self._values[i] << doffset
!                 boffset += s
!                 if boffset == 8:
!                     boffset = 0
!             elif self._values[i] != []:
                  r += self._values[i]
+         for i in self._values[len(self._schema):]:
+             r += i
          return r
+ 
+ 
+ class RawPacket(GenericPacket):
+     def __init__(self, ts = None, data = None, crc = None):
+         GenericPacket.__init__(self,
+                                [('ts' , 'int', 4),
+                                 ('crc', 'int', 1),
+                                 ('data', 'blob', None)],
+                                None)
+         self.ts = ts;
+         self.data = data
+         self.crc = crc
+         
+ 
+ class AckFrame(GenericPacket):
+     def __init__(self, payload = None):
+         GenericPacket.__init__(self,
+                                [('protocol',  'int', 1),
+                                 ('seqno',  'int', 1)],
+                                payload)
+ 
+ class DataFrame(GenericPacket):
+     def __init__(self, payload = None):
+         if payload != None and type(payload) != type([]):
+             # Assume is a GenericPacket
+             payload = payload.payload()
+         GenericPacket.__init__(self,
+                                [('protocol',  'int', 1),
+                                 ('seqno',  'int', 1),
+                                 ('dispatch',  'int', 1),
+                                 ('data', 'blob', None)],
+                                payload)
+ 
+ class NoAckDataFrame(GenericPacket):
+     def __init__(self, payload = None):
+         if payload != None and type(payload) != type([]):
+             # Assume is a GenericPacket
+             payload = payload.payload()
+         GenericPacket.__init__(self,
+                                [('protocol',  'int', 1),
+                                 ('dispatch',  'int', 1),
+                                 ('data', 'blob', None)],
+                                payload)
+ 
+ class ActiveMessage(GenericPacket):
+     def __init__(self, gpacket = None, am_id = 0x00, dest = 0xFFFF):
+         if type(gpacket) == type([]):
+             payload = gpacket
+         else:
+             # Assume this will be derived from GenericPacket
+             payload = None
+         GenericPacket.__init__(self,
+                                [('destination', 'int', 2),
+                                 ('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 = am_id
+             self.data = gpacket.payload()
+             self.length = len(self.data)
+ 

Index: tos-build-deluge-image
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tools/tinyos/misc/tos-build-deluge-image,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** tos-build-deluge-image	16 Jul 2007 22:11:04 -0000	1.2
--- tos-build-deluge-image	14 Jan 2008 04:22:01 -0000	1.3
***************
*** 32,36 ****
  DELUGE_MAX_PAGES = 128
  
- DELUGE_METADATA_SIZE = 16
  DELUGE_IDENT_SIZE = 128
  
--- 32,35 ----
***************
*** 41,44 ****
--- 40,44 ----
    return s + [0] * (dim - len(s))
  
+ # Encode to big endian
  def encode(val, dim):
    output = []
***************
*** 46,57 ****
        output.append(val & 0xFF)
        val = val >> 8
    return output
  
- def decode(v):
-   r = long(0)
-   for i in v[::-1]:
-       r = (r << 8) + i
-   return r
- 
  def int2byte(v):
      return "".join([struct.pack("B", i) for i in v])
--- 46,52 ----
        output.append(val & 0xFF)
        val = val >> 8
+   output.reverse()
    return output
  
  def int2byte(v):
      return "".join([struct.pack("B", i) for i in v])
***************
*** 70,75 ****
  
  def pages(data):
!     return (len(data) / DELUGE_BYTES_PER_PAGE) + \
!                (len(data) % DELUGE_BYTES_PER_PAGE != 0)
  
  def align(data):
--- 65,73 ----
  
  def pages(data):
!   l = len(data) - 2*DELUGE_MAX_PAGES
!   if l % DELUGE_BYTES_PER_PAGE != 0:
!     sys.stderr.write("ERROR: Bug in padding!")
!     sys.exit()
!   return l / DELUGE_BYTES_PER_PAGE
  
  def align(data):
***************
*** 79,126 ****
    return data + [0] * (DELUGE_BYTES_PER_PAGE - mod)
  
! def deluge_metadata(data, img_num):
!   uid = ident['uid_hash']
!   num_pages = pages(data)
!   image_number = img_num
!   crc = crc16([image_number] + [num_pages])
!   completed_pages = num_pages
!   return encode(uid, 4) + \
!          encode(version, 2) + \
!          [image_number] + \
!          [num_pages] + \
!          encode(crc, 2) + \
!          [completed_pages] + \
!          [0] + \
!          encode(len(data) + 16, 2) + \
!          ([0] * 2)
! 
! def deluge_ident():
!   tmp = sencode(ident['program_name'], 16) + \
!         sencode(ident['user_id'], 16) + \
!         sencode(ident['hostname'], 16) + \
!         sencode(ident['platform'], 16) + \
          encode(ident['size'], 4) + \
!         encode(ident['unix_time'], 4) + \
!         encode(ident['user_hash'], 4) + \
!         encode(ident['uid_hash'], 4)
    return tmp + [0] * (DELUGE_IDENT_SIZE - len(tmp))
  
  def deluge_crc(data):
    crc = [0] * DELUGE_MAX_PAGES
!   crc[0] = crc16(data[2*DELUGE_MAX_PAGES:DELUGE_BYTES_PER_PAGE])
!   #sys.stderr.write("crc[0] = 0x%x\n" % (crc[0]))
!   j = 1
!   for i in range(DELUGE_BYTES_PER_PAGE, len(data)-1, DELUGE_BYTES_PER_PAGE):
      crc[j] = crc16(data[i:i+DELUGE_BYTES_PER_PAGE])
!     #sys.stderr.write("crc[%d] = 0x%x\n" % (j, crc[j]))
      j += 1
!   return reduce(operator.add, [encode(i, 2) for i in crc]) + data[2*DELUGE_MAX_PAGES:]
! 
! version = 0
  
  for i in range(len(sys.argv)):
!   if sys.argv[i] == '-v':
!     version = int(sys.argv[i+1])
!   elif sys.argv[i] == '-i':
      img_num = int(sys.argv[i+1])
      
--- 77,109 ----
    return data + [0] * (DELUGE_BYTES_PER_PAGE - mod)
  
! def deluge_ident(data):
!   tmp = encode(ident['uidhash'], 4) + \
          encode(ident['size'], 4) + \
!         [pages(data), 0]
!   crc = crc16(tmp)
!   tmp += encode(crc, 2) + \
!          sencode(ident['appname'], 16) + \
!          sencode(ident['username'], 16) + \
!          sencode(ident['hostname'], 16) + \
!          sencode(ident['platform'], 16) + \
!          encode(ident['timestamp'], 4) + \
!          encode(ident['userhash'], 4)
    return tmp + [0] * (DELUGE_IDENT_SIZE - len(tmp))
  
  def deluge_crc(data):
    crc = [0] * DELUGE_MAX_PAGES
!   j = 0
!   sys.stderr.write("CRCs:\n  ")
!   for i in range(0, len(data)-1, DELUGE_BYTES_PER_PAGE):
      crc[j] = crc16(data[i:i+DELUGE_BYTES_PER_PAGE])
!     sys.stderr.write("0x%04X " % (crc[j]))
!     if (j + 1) % 7 == 0:
!       sys.stderr.write("\n  ")
      j += 1
!   sys.stderr.write("\n")
!   return reduce(operator.add, [encode(i, 2) for i in crc]) + data
  
  for i in range(len(sys.argv)):
!   if sys.argv[i] == '-i':
      img_num = int(sys.argv[i+1])
      
***************
*** 131,135 ****
  for (k, v) in ident_list:
    ident[k] = v
! for p in ['unix_time', 'user_hash', 'uid_hash']:
    ident[p] = int(ident[p][:-1], 16)
  
--- 114,118 ----
  for (k, v) in ident_list:
    ident[k] = v
! for p in ['timestamp', 'userhash', 'uidhash']:
    ident[p] = int(ident[p][:-1], 16)
  
***************
*** 179,184 ****
  
  sys.stderr.write('Ihex read complete:\n')
! sys.stderr.write('  Total bytes = %d\n' % reduce(operator.add, [len(l) for (_, l) in all]))
! sys.stderr.write('  Sections = %d\n' % len(all))
  
  # Usually, there are two sections: one for the code and one for the
--- 162,168 ----
  
  sys.stderr.write('Ihex read complete:\n')
! sys.stderr.write('  ' + '\n  '.join(["%5d bytes starting at 0x%X" % (len(l), a) for (a, l) in all]))
! sys.stderr.write('\n')
! sys.stderr.write('  %d bytes in %d sections\n' % (reduce(operator.add, [len(l) for (_, l) in all]), len(all)))
  
  # Usually, there are two sections: one for the code and one for the
***************
*** 190,198 ****
                encode(len(data), 4) + \
                data
! ident['size'] = len(all_data)
! all_data = deluge_ident() + all_data
! all_data = align([0] * 2 * DELUGE_MAX_PAGES + all_data)
  all_data = deluge_crc(all_data)
! sys.stdout.write(int2byte(deluge_metadata(all_data, img_num)) + \
!       int2byte(all_data))
  
--- 174,182 ----
                encode(len(data), 4) + \
                data
! padding = [0] * (DELUGE_BYTES_PER_PAGE - len(all_data) % DELUGE_BYTES_PER_PAGE)
! if len(padding) < DELUGE_BYTES_PER_PAGE:
!   all_data += padding
  all_data = deluge_crc(all_data)
! ident['size'] = DELUGE_IDENT_SIZE + len(all_data)
! sys.stdout.write(int2byte(deluge_ident(all_data)) + int2byte(all_data))
  

Index: tos-deluge
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tools/tinyos/misc/tos-deluge,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** tos-deluge	20 Dec 2007 21:23:51 -0000	1.8
--- tos-deluge	14 Jan 2008 04:22:01 -0000	1.9
***************
*** 1,80 ****
  #!/usr/bin/env python
  
! # Copyright (c) 2007 Johns Hopkins University.
! # All rights reserved.
! #
! # Permission to use, copy, modify, and distribute this software and its
! # documentation for any purpose, without fee, and without written
! # agreement is hereby granted, provided that the above copyright
! # notice, the (updated) modification history and the author appear in
! # all copies of this source code.
! #
! # 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 HOLDERS OR CONTRIBUTORS
! # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
! # OR PROFITS) 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.
! 
! # @author Chieh-Jan Mike Liang <cliang4 at cs.jhu.edu>
! # @author Razvan Musaloiu-E. <razvanm at cs.jhu.edu>
! 
! ###############################################################################
! # Deluge Python Toolchain
! #
! # A command line utility to interact with nodes via a direct serial connection.
! # For the usage menu, please run this tool without any arguments. For example, 
! # "./tos-deluge"
! ###############################################################################
! 
! import sys, os, stat, struct, subprocess, time
  import tinyos
  from datetime import datetime
  import os.path 
  
- # Script-specific parameters
- HEX_OUTPUT_LINE_SIZE = 16
  # 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
! SERIAL_AMGROUP     = 0
! SERIAL_AMID        = 0xAB
  SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2
  
! # Serial message types
! MSG_ERASE     = 0
! MSG_WRITE     = 1
! MSG_READ      = 2
! MSG_REPROG    = 5
! MSG_DISS      = 6
! MSG_REPROG_BS = 7
! MSG_SYNC      = 8
! MSG_IDENT     = 9
  
  ERROR_SUCCESS = 0   # T2-compatible
  ERROR_FAIL    = 1   # T2-compatible
  
! # Deluge-specific parameters
! DELUGE_PLATFORMS       = ["telosb", "micaz"]   # Currently supported platforms
! DELUGE_MAX_PAGES       = 128
! DELUGE_METADATA_OFFSET = 0   # Location offset in the image
! DELUGE_METADATA_SIZE   = 16
! DELUGE_IDENT_OFFSET    = 16 + (2 * DELUGE_MAX_PAGES)
! DELUGE_IDENT_SIZE      = 16 + 16 + 16 + 16 + 4 + 4 + 4 + 4   # Metadata size in binary 
!                                                              # image
  
! class SerialReqPacket(tinyos.GenericPacket):
      def __init__(self, packet = None):
          tinyos.GenericPacket.__init__(self,
!                                       [('msg_type', 'int',  1),
!                                        ('img_num',  'int',  1),
!                                        ('offset',   'int',  2),
!                                        ('len',      'int',  2),
!                                        ('data',     'blob', None)],
                                        packet)
  
--- 1,59 ----
  #!/usr/bin/env python
  
! import sys, stat, struct, subprocess, time
  import tinyos
  from datetime import datetime
  import os.path 
  
  # Path to the python script that builds Deluge image from XML
! PATH_PY_BUILD_IMAGE  = './tos-build-deluge-image'
  
  # TinyOS serial communication parameters
! FM_AMID = 0xAB
! DM_AMID = 0xAC
  SERIAL_DATA_LENGTH = 28 - 1 - 1 - 2 - 2
+ BAUDRATES = {'micaz': 57600,
+              'telosb': 115200}
  
! # Commands for FlashManager
! FM_CMD_ERASE     = 0
! FM_CMD_WRITE     = 1
! FM_CMD_READ      = 2
! FM_CMD_CRC       = 3
! FM_CMD_ADDR      = 4
! FM_CMD_SYNC      = 5
! FM_CMD_IDENT     = 6
! 
! # Commands for DelugeManager
! DM_CMD_STOP             = 1
! DM_CMD_LOCAL_STOP       = 2
! DM_CMD_ONLY_DISSEMINATE = 3
! DM_CMD_DISSEMINATE_AND_REPROGRAM = 4
! DM_CMD_REPROGRAM        = 5
! DM_CMD_BOOT             = 6
  
  ERROR_SUCCESS = 0   # T2-compatible
  ERROR_FAIL    = 1   # T2-compatible
  
! # Deluge parameters
! DELUGE_MAX_PAGES    = 128
! DELUGE_IDENT_OFFSET = 0
! DELUGE_IDENT_SIZE   = 128
  
! class FMReqPacket(tinyos.GenericPacket):
      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):
!     def __init__(self, packet = None):
!         tinyos.GenericPacket.__init__(self,
!                                       [('cmd',    'int',  1),
!                                        ('imgNum', 'int',  1)],
                                        packet)
  
***************
*** 86,101 ****
                                       packet)
  
! # Displays an integer representation of byte stream to hex representation
! def print_hex(start_addr, byte_stream):
!     num_iterations = int( (len(byte_stream) - 1) / HEX_OUTPUT_LINE_SIZE ) + 1
!   
!     for i in range(num_iterations):
!         line = "%07x" % start_addr + " "   # Prints memory address
!         for j in range(HEX_OUTPUT_LINE_SIZE):
!             if (i * HEX_OUTPUT_LINE_SIZE + j) < len(byte_stream):
!                 line += "%02x" % byte_stream[i * HEX_OUTPUT_LINE_SIZE + j] + " "
!     print line
!     
!     start_addr += HEX_OUTPUT_LINE_SIZE
  
  # Computes 16-bit CRC
--- 65,93 ----
                                       packet)
  
! class Ident(tinyos.GenericPacket):
!     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):
!     def __init__(self, packet = None):
!         tinyos.GenericPacket.__init__(self,
!                                       [('appname',  'string', 16),
!                                        ('timestamp','int', 4),
!                                        ('uidhash',  'int', 4),
!                                        ('nodeid',   'int', 2)],
!                                       packet)
! 
  
  # Computes 16-bit CRC
***************
*** 113,178 ****
      return crc
  
! # Converts a byte-stream array to int representation
! def toInt(byte_stream):
!     r = long(0)
!     for i in byte_stream[::-1]:
!         r = (r << 8) + i
!     
!     return r
! 
! # Converts a byte-stream array to string representation
! def toString(byte_stream):
!     r = ""
!     for i in range(len(byte_stream)):
!         if byte_stream[i] == 0:
!             r += " "
          else:
!             r += struct.pack("B", byte_stream[i])
!     
!     return r
  
! # Converts a byte-stream array to image status string representation
! def toStatusStr(num_space, binary_stream):
!     r = "%sProg Name:   %s\n" % (" " * num_space, 
!                                  toString(binary_stream[16:32]))
!     r += "%sCompiled On: %s\n" % (" " * num_space, 
!                                   datetime.fromtimestamp(toInt(binary_stream[84:88])).strftime('%a %h %d %T %Y'))
!     r += "%sPlatform:    %s\n" % (" " * num_space, 
!                                   toString(binary_stream[64:80]))
!     r += "%sUser ID:     %s\n" % (" " * num_space, 
!                                   toString(binary_stream[32:48]))
!     r += "%sHost Name:   %s\n" % (" " * num_space, 
!                                   toString(binary_stream[48:64]))
!     r += "%sUser Hash:   %s\n" % (" " * num_space, 
!                                   hex(toInt(binary_stream[88:92])))
!     r += "%sNum Pages:   %d/%d" % (" " * num_space, 
!                                    toInt(binary_stream[7:8]), 
!                                    toInt(binary_stream[10:11]))
!     
!     r += "\n\n"
!     r += "%sSize:        %d\n" % (" " * num_space, 
!                                    toInt(binary_stream[12:14]))
!     r += "%sUID:         %d\n" % (" " * num_space, 
!                                    toInt(binary_stream[0:4]))
!     r += "%sVersion:     %d" % (" " * num_space, 
!                                    toInt(binary_stream[4:6]))
!     
!     return r
  
! # Reads a portion from the image in the external flash
! def op_read(s, img_num, offset, length):
      r = []
      
!     # Gets the metadata (first 16 bytes of the image)
!     sreqpkt = SerialReqPacket((MSG_READ, img_num, offset, length, []))
      while True:
!         if sreqpkt['len'] > SERIAL_DATA_LENGTH:
!             sreqpkt['len'] = SERIAL_DATA_LENGTH
          
!         if s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()):
!             packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!             sreplypkt = SerialReplyPacket(packet[1])
!             if sreplypkt.error == ERROR_SUCCESS:
!                 r.extend(sreplypkt.data)
              else:
                  r = None
--- 105,147 ----
      return crc
  
! def handleResponse(success, msg):
!     if success == True:
!         packet = s.sniff_am()
!         while packet and packet.type == 100:
!             print "".join([chr(i) for i in p.data])
!             packet = s.sniff_am()
!         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():
!     sreqpkt = FMReqPacket((FM_CMD_IDENT, 0, 0, 0, []))
!     if s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID)):
!         packet = s.sniff_am()
!         reply = SerialReplyPacket(packet.data)
!         if reply.error == ERROR_SUCCESS:
!             return ShortIdent(reply.data)
!     return 0
  
! 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()
!             reply = SerialReplyPacket(packet.data)
!             if reply.error == ERROR_SUCCESS:
!                 r.extend(reply.data)
              else:
                  r = None
***************
*** 182,283 ****
              break
          
!         sreqpkt['offset'] = sreqpkt['offset'] + sreqpkt['len']
!         if sreqpkt['offset'] >= (offset + length):
              break
!         sreqpkt['len'] = (offset + length) - sreqpkt['offset']
!         
!     return r
! 
! def op_ident(s):
!     sreqpkt = SerialReqPacket((MSG_IDENT, 0, 0, 0, []))
!     if s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()):
!         packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!         sreplypkt = SerialReplyPacket(packet[1])
!         if sreplypkt.error == ERROR_SUCCESS:
!             return toInt(sreplypkt.data)
!     return 0
!     
! # Checks for valid CRC and image timestamp
! def verifyMetaData(r):
!     if r != None:
!         if crc16(r[6:8]) == toInt(r[8:10]) and r[84:88] != [0xFF, 0xFF, 0xFF, 0xFF]:
!             return True
!         else:
!             print "WARNING: Invalid image format detected"
!     
!     return False
! 
! # Returns the metadata (first 16 bytes of the image) plus the "ident" 
! # (DELUGE_IDENT_SIZE bytes after CRC)
! def getMetaData(s, img_num):
!     # Gets the metadata (first 16 bytes of the image)
!     r = op_read(s, img_num, DELUGE_METADATA_OFFSET, DELUGE_METADATA_SIZE)
! 
!     # Gets the "ident" portion of the image
!     if r != None:
!         temp = op_read(s, img_num, DELUGE_IDENT_OFFSET, DELUGE_IDENT_SIZE)
!         if temp != None:
!             r.extend(temp)
!             return r
!     
!     print "ERROR: Unable to retrieve image information over serial"
!     return None
  
! # Prints status of the image in the external flash
! def op_ping(s, img_num):
!     uid = op_ident(s)
!     metadata = getMetaData(s, img_num)
!     if not metadata == None:
!         if verifyMetaData(metadata) == True:
!             print "Connected to Deluge node."
!             # Prints out image status
!             print "--------------------------------------------------"
!             print "Currently Executing:"
!             print "  UID:         %d" % (uid)
!             print "Stored image %d" % img_num
!             print toStatusStr(2, metadata)
!             print "--------------------------------------------------"
!             return True
!         
!     return False
  
! # Erases an image volume
! def op_erase(s, img_num):
!     sreqpkt = SerialReqPacket((MSG_ERASE, img_num, 0, 0, []))
!     success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload())
!     if success == True:
!         packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!         sreplypkt = SerialReplyPacket(packet[1])
!         if sreplypkt.error == ERROR_SUCCESS:
!             return True
!         else:
!             print "ERROR: Unable to erase the flash volume"
!             return False
!         
!     print "ERROR: Unable to send the command"
!     return False
  
! def op_sync(s, img_num):
!     sreqpkt = SerialReqPacket((MSG_SYNC, img_num, 0, 0, []))
!     success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload())
!     if success == True:
!         packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!         sreplypkt = SerialReplyPacket(packet[1])
!         if sreplypkt.error == ERROR_SUCCESS:
!             return True
!         else:
!             print "ERROR: Unable to sync the flash volume"
!             return False
!         
!     print "ERROR: Unable to send the command"
!     return False
  
! # Writes to an image volume
! def op_write(s, img_num, binary_stream):
!     sreqpkt = SerialReqPacket((MSG_WRITE, img_num, 0, 0, []))
!     local_crc = 0   # Running CRC
!     length = len(binary_stream)
      total_length = length   # For progress bar
!     next_tick = 100   # For progress bar
      start_time = time.time()
      
--- 151,176 ----
              break
          
!         sreqpkt.offset += sreqpkt.length
!         if sreqpkt.offset >= (offset + length):
              break
!         sreqpkt.length = (offset + length) - sreqpkt.offset
  
!     return r
  
! def erase(imgNum):
!     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")
  
! def sync(imgNum):
!     sreqpkt = FMReqPacket((FM_CMD_SYNC, imgNum, 0, 0, []))
!     success = s.write(tinyos.ActiveMessage(sreqpkt, am_id=FM_AMID))
!     return handleResponse(success, "ERROR: Unable to sync the flash volume")
  
! def write(imgNum, data):
!     sreqpkt = FMReqPacket((FM_CMD_WRITE, imgNum, 0, 0, []))
!     length = len(data)
      total_length = length   # For progress bar
!     next_tick = 100         # For progress bar
      start_time = time.time()
      
***************
*** 293,307 ****
          # Calculates the payload size for the current packet
          if length >= SERIAL_DATA_LENGTH:
!             sreqpkt.len = SERIAL_DATA_LENGTH
          else:
!             sreqpkt.len = length
!         sreqpkt.data = []
!         
!         # Reads in the file we want to transmit
!         for i in range(sreqpkt.len):
!             sreqpkt.data.append(struct.unpack("B", binary_stream[sreqpkt.offset + i])[0])
          
          # Sends over serial to the mote
!         if s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()) == False:
              print
              print "ERROR: Unable to send the last serial packet (file offset: %d)" % sreqpkt.offset
--- 186,196 ----
          # 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)):
              print
              print "ERROR: Unable to send the last serial packet (file offset: %d)" % sreqpkt.offset
***************
*** 309,322 ****
          
          # Waiting for confirmation
!         packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!         sreplypkt = SerialReplyPacket(packet[1])
!         if sreplypkt.error != ERROR_SUCCESS:
              print
              print "ERROR: Unable to write to the flash volume (file offset: %d)" % sreqpkt.offset
              return False
              
!         local_crc = s.crc16(local_crc, sreqpkt.data)   # Computes running CRC
!         length -= sreqpkt.len
!         sreqpkt.offset += sreqpkt.len
  
      print '\r' + ' ' * 52,
--- 198,210 ----
          
          # Waiting for confirmation
!         packet = s.sniff_am()
!         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
  
      print '\r' + ' ' * 52,
***************
*** 324,330 ****
      print "\r%s bytes in %.2f seconds (%.4f bytes/s)" % (total_length, elasped_time, int(total_length) / (elasped_time))
      return True
  
  # Injects an image (specified by tos_image_xml) to an image volume
! def op_inject(s, img_num, tos_image_xml):
      # Checks for valid file path
      try:
--- 212,253 ----
      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:
+         if crc16(i.payload()[0:10]) == i.crc and i.timestamp != 0xFFFFFFFF:
+             return True
+         else:
+             print "No valid image was detected."
+     return False
+ 
+ def getIdent(imgNum):
+     r = read(imgNum, DELUGE_IDENT_OFFSET, DELUGE_IDENT_SIZE)
+     if r:
+         return Ident(r)
+     print "ERROR: Unable to retrieve the ident."
+     return None
+ 
+ def formatIdent(i):
+     r  = "  Prog Name:   %s\n" % (i.appname)
+     r += "  UID:         0x%08X\n" % (i.uidhash)
+     r += "  Compiled On: %s\n" % (datetime.fromtimestamp(i.timestamp).strftime('%a %h %d %T %Y'))
+     r += "  Platform:    %s\n" % (i.platform)
+     r += "  User ID:     %s\n" % (i.username)
+     r += "  Host Name:   %s\n" % (i.hostname)
+     r += "  User Hash:   0x%08X\n" % (i.userhash)
+     r += "  Size:        %d\n" % (i.size)
+     r += "  Num Pages:   %d" % (i.pages)
+     return r
+ 
+ def formatShortIdent(i):
+     r  = "  Prog Name:   %s\n" % (i.appname)
+     r += "  UID:         0x%08X\n" % (i.uidhash)
+     r += "  Compiled On: %s\n" % (datetime.fromtimestamp(i.timestamp).strftime('%a %h %d %T %Y'))
+     r += "  Node ID:     %d\n" % (i.nodeid)
+     return r
  
  # Injects an image (specified by tos_image_xml) to an image volume
! def inject(imgNum, tos_image_xml):
      # Checks for valid file path
      try:
***************
*** 340,506 ****
    
      # Gets status information of stored image
!     version = 0
!     metadata = getMetaData(s, img_num)
!     if not metadata == None:
          print "Connected to Deluge nodes."
!         if verifyMetaData(metadata) == True:
              print "--------------------------------------------------"
!             print "Stored image %d" % img_num
!             print toStatusStr(2, metadata)
!             version = toInt(metadata[4:6]) + 1   # Increments the version
      else:
          return False
!     
      # Creates binary image from the TOS image XML
      print "--------------------------------------------------"
!     p = subprocess.Popen([PATH_PY_BUILD_IMAGE, "-v", str(version), "-i", str(img_num), tos_image_xml], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      print p.stderr.read(),
      print "--------------------------------------------------"
      
      # Writes the new binary image
!     image = p.stdout.read()
!     if len(image) > 0 and op_erase(s, img_num):
!         if op_write(s, img_num, image):
!             if op_sync(s, img_num):
                  print "--------------------------------------------------"
-                 metadata = getMetaData(s, img_num)
-                 if not metadata == None:
-                     if verifyMetaData(metadata) == True:
-                         print "Replace image with:"
-                         print toStatusStr(2, metadata)
-                         print "--------------------------------------------------"
-                         return True
      
      return False
  
! # Requests the base station to reprogram itself
! def op_reprog_bs(s, img_num):
!     metadata = getMetaData(s, img_num)
!     if not metadata == None:
!         if verifyMetaData(metadata) == True:
!             sreqpkt = SerialReqPacket((MSG_REPROG_BS, img_num, 0, 0, []))
!             success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload())
!             if success == True:
!                 packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!                 sreplypkt = SerialReplyPacket(packet[1])
!                 if sreplypkt.error == ERROR_SUCCESS:
!                     return True
!                 else:
!                     print "ERROR: Unable to reprogram the base station"
!                 
!             print "ERROR: Unable to send the command"
!     
      return False
  
! # Requests the network to reprogram with the specified image number
! def op_reprog(s, img_num):
!     sreqpkt = SerialReqPacket((MSG_REPROG, img_num, 0, 0, []))
!     success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload())
!     if success == True:
!         packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!         sreplypkt = SerialReplyPacket(packet[1])
!         if sreplypkt.error == ERROR_SUCCESS:
!             return True
!         else:
!             print "ERROR: Unable to reprogram the network"
!             return False
!         
!     print "ERROR: Unable to send the command"
  
! # Requests the mote to disseminate an image
! def op_diss(s, img_num):
!     metadata = getMetaData(s, img_num)
!     if not metadata == None:
!         if verifyMetaData(metadata) == True:
!             sreqpkt = SerialReqPacket((MSG_DISS, img_num, 0, 0, []))
!             success = s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload())
!             if success == True:
!                 packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!                 sreplypkt = SerialReplyPacket(packet[1])
!                 if sreplypkt.error == ERROR_SUCCESS:
!                     return True
!                 else:
!                     print "ERROR: Unable to start the command dissemination"
!                 
!             print "ERROR: Unable to send the command"
!             
!     return False
  
! # Resets image versioning information
! def op_reset(s, img_num):
!     sreqpkt = SerialReqPacket((MSG_WRITE, img_num, 4, 2, [0, 0]))
!     if s.write_packet(SERIAL_AMGROUP, SERIAL_AMID, sreqpkt.payload()) == False:
!         print "ERROR: Unable to send the command"
!         return False
!         
!     # Waiting for confirmation
!     packet = s.read_packet(SERIAL_AMGROUP, SERIAL_AMID)
!     sreplypkt = SerialReplyPacket(packet[1])
!     if sreplypkt.error != ERROR_SUCCESS:
!         print "ERROR: Unable to write new versioning information"
!         return False
!     else:
!         if op_sync(s, img_num) == False:
!             return False
!             
!     return True
  
  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>\n     Either the platform name or the baud rate value"
!     print "      -------------------"
!     print "      | micaz  |  57600 |"
!     print "      ---------+---------"
!     print "      | telosb | 115200 |"
!     print "      -------------------"
!     print ""
!     print "  -p --ping\n     Provide status of the image in the external flash"
!     print "  -i --inject\n     Inject a compiled TinyOS application"
!     print "      [options]: tos_image.xml file path"
!     print "  -r --reprogram\n     Reprogram the network"
!     print "  -b --reprogram_bs\n     Reprogram only the directly-connected mote"
!     print "  -d --dissemination\n     Disseminate the image in the external flash to the network"
!     print "  -e --erase\n     Erase an image in the external flash"
!     print "  -s --reset\n     Reset the versioning information for a given image"
  
! # ======== MAIN ======== #
! num_req_arg = 5   # Minimum number of required arguments for this script
! if len(sys.argv) >= num_req_arg:
      # Checks for valid image number format
      try:
!         sys.argv[4] = int(sys.argv[4])
      except:
          print "ERROR: Image number is not valid"
!         os._exit(-1)
!     
      # Initializes serial port communication
      try:
!         s = tinyos.Serial(sys.argv[1], sys.argv[2])
!         s.set_debug(False)
      except:
          print "ERROR: Unable to initialize serial port connection to", sys.argv[1]
!         os._exit(-1)
!     
      if sys.argv[3] in ["-p", "--ping"]:
          print "Pinging node ..."
!         op_ping(s, sys.argv[4]) 
!     elif sys.argv[3] in ["-i", "--inject"] and len(sys.argv) == (num_req_arg + 1):
          print "Pinging node ..."
!         op_inject(s, sys.argv[4], sys.argv[5])
      elif sys.argv[3] in ["-r", "--reprogram"]:
!         if op_reprog(s, sys.argv[4]):
              print "Command sent"
!     elif sys.argv[3] in ["-b", "--reprogram_bs"]:
!         if op_reprog_bs(s, sys.argv[4]):
              print "Command sent"
!     elif sys.argv[3] in ["-d", "--dissemination"]:
!         if op_diss(s, sys.argv[4]):
              print "Command sent"
!     elif sys.argv[3] in ["-e", "--erase"]:
!         if op_erase(s, sys.argv[4]):
!             print "Image number %d erased" % sys.argv[4]
!     elif sys.argv[3] in ["-s", "--reset"]:
!         if op_reset(s, sys.argv[4]):
!             print "Successfully reset image versioning information"
      else:
          print_usage()
--- 263,429 ----
    
      # Gets status information of stored image
!     i = getIdent(imgNum)
!     if ident:
          print "Connected to Deluge nodes."
!         if verifyIdent(i):
              print "--------------------------------------------------"
!             print "Stored image %d" % imgNum
!             print formatIdent(i)
      else:
          return False
! 
      # Creates binary image from the TOS image XML
      print "--------------------------------------------------"
!     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(),
      print "--------------------------------------------------"
      
      # Writes the new binary image
!     image = [struct.unpack("B", c)[0] for c in p.stdout.read()]
!     if len(image) > 0 and erase(imgNum):
!         if write(imgNum, image):
!             if sync(imgNum):
!                 print "--------------------------------------------------"
!                 print "Replace image with:"
!                 print formatIdent(getIdent(imgNum))
                  print "--------------------------------------------------"
      
      return False
  
! def ping(imgNum):
!     uid = ident()
!     # Prints out image status
!     print "--------------------------------------------------"
!     print "Currently Executing:"
!     print formatShortIdent(ident())
!     i = getIdent(imgNum)
!     if verifyIdent(i):
!         print "Stored image %d" % 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))
!     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))
!     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))
!     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))
!     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))
!     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))
!     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 "  -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"
!     print "  -e --erase       Erase an image in the external flash"
!     print "  -b --boot        Force a reboot of the mote"
!     print "  -r --reprogram   Reprogram the mote"
!     print "  -d --disseminate Disseminate the image in the external flash to the network"
!     print "  -dr --disseminate-and-reprogram"
!     print "  -s --stop        Stop the dissemination "
!     print "  -ls --local-stop Stop the dissemination only on the local mote"
  
! #     print "  -b --reprogram_bs\n     Reprogram only the directly-connected mote"
! #     print "  -s --reset\n     Reset the versioning information for a given image"
! 
! def checkImgNum():
!     global imgNum
      # Checks for valid image number format
      try:
!         imgNum = int(sys.argv[4])
      except:
          print "ERROR: Image number is not valid"
!         sys.exit(-1)
!     return imgNum
! 
! # ======== MAIN ======== #
! if len(sys.argv) >= 4:
! 
!     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]
!         sys.exit(-1)
! 
      if sys.argv[3] in ["-p", "--ping"]:
+         checkImgNum()
          print "Pinging node ..."
!         ping(imgNum) 
!     elif sys.argv[3] in ["-i", "--inject"] and len(sys.argv) == 6:
!         checkImgNum()
          print "Pinging node ..."
!         inject(imgNum, sys.argv[5])
!     elif sys.argv[3] in ["-e", "--erase"]:
!         checkImgNum()
!         if erase(imgNum):
!             print "Image number %d erased" % imgNum
!     elif sys.argv[3] in ["-b", "--boot"]:
!         if boot():
!             print "Command sent"
      elif sys.argv[3] in ["-r", "--reprogram"]:
!         checkImgNum()
!         if reprogram(imgNum):
              print "Command sent"
!     elif sys.argv[3] in ["-d", "--disseminate"]:
!         checkImgNum()
!         if disseminate(imgNum):
              print "Command sent"
!     elif sys.argv[3] in ["-dr", "--disseminate-and-reboot"]:
!         checkImgNum()
!         if disseminateAndReboot(imgNum):
              print "Command sent"
!     elif sys.argv[3] in ["-s", "--stop"]:
!         if stop():
!             print "Command sent"
!     elif sys.argv[3] in ["-ls", "--local-stop"]:
!         if localstop():
!             print "Command sent"
! 
! 
! #     elif sys.argv[3] in ["-b", "--reprogram_bs"]:
! #         if op_reprog_bs(imgNum):
! #             print "Command sent"
! #     elif sys.argv[3] in ["-s", "--reset"]:
! #         if op_reset(imgNum):
! #             print "Successfully reset image versioning information"
      else:
          print_usage()
***************
*** 508,509 ****
--- 431,464 ----
  else:
      print_usage()
+ 
+ sys.exit()
+ 
+ # Testing ------------------------------------------------------------
+ 
+ s = tinyos.Serial('/dev/ttyUSB0', 115200, flush=False)
+ # print "ident: 0x%x" % ident()
+ # r = read(0, 0, 10)
+ # print "read:", len(r), r
+ 
+ # erase(0)
+ # write(0, [i % 256 for i in range(20*1024)])
+ # r = read(0, 0, 10)
+ # print "read:", len(r), r
+ 
+ # inject(0, 'build/telosb/tos_image.xml')
+ ping(0)
+ 
+ # print formatDescription(getMetadata(0), getIdent(0))
+ # print getMetadata(0)
+ # print getIdent(0)
+ 
+ # print verifyDescription(getMetadata(0), getIdent(0))
+ 
+ # print formatShortIdent(ident())
+ 
+ # def encode(val, dim):
+ #   output = []
+ #   for i in range(dim):
+ #       output.append(val & 0xFF)
+ #       val = val >> 8
+ #   return output



More information about the Tinyos-2-commits mailing list