--- /dev/null
+# "Copyright (c) 2000-2003 The Regents of the University of California.
+# 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 following
+# two paragraphs and the author appear in all copies of this software.
+#
+# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+# OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+#
+# @author Kamin Whitehouse
+#
+
+import sys, string, math, re, os
+from struct import *
+from xml.dom import minidom
+from copy import deepcopy
+
+###########
+# This class can be used to hold a basic nesc type, eg uint8_t It can
+# be set and get through nescType.value, and does type checking
+#
+###########
+
+def findBuildFile(givenString, desiredFilename) :
+ """This function will find a desiredFilename (eg. nescDecls.xml) the build directory
+ from a givenString (e.g 'build/pc'). Legal givenStrings are:
+ 1. Full path, eg: /home/kamin/tinyos-1.x/...
+ 2. relative path, eg: apps/TestRpc/build/pc
+ 3. platform name, eg: pc or telosb
+ """
+
+ #check to see if the given string contains the desiredFilename
+ if givenString.find(desiredFilename) >= 0 :
+ filename = givenString
+
+ #then check to see if it is an absolute or relative path
+ elif givenString.find('/') >= 0 :
+ filename = givenString + desiredFilename
+
+ #then check to see if it is just the platform name
+ elif len(givenString) > 0:
+ filename = 'build/' + givenString + '/' + desiredFilename
+
+ #check if a default platform environment variable is defined
+ elif os.environ.has_key("TINYOS_DEFAULT_PLATFORM") :
+ filename = 'build/' + os.environ["TINYOS_DEFAULT_PLATFORM"] + '/' + desiredFilename
+
+ #otherwise, assume the file is in './'
+ else :
+ filename = desiredFilename
+
+ #check to see if the file was successfully found
+ if not os.path.isfile(filename) :
+ raise IOError("File %s not found" % filename)
+ return filename
+
+
+class nescType( object ) :
+ """A python representation of a nesc type.
+
+ usage:
+ X = nescType.value
+ nescType.value = X
+ bytes = nescType.getBytes()
+ nescType.setBytes(bytes)
+ nescType
+ print nescType
+ """
+
+ def __init__( self , nescType, cType, pythonType, xmlTag,
+ conversionString, size, defaultValue) :
+ """create a new nescType"""
+ self.nescType = nescType
+ self.cType = cType
+ self.pythonType = pythonType
+ self._xmlTag = xmlTag
+ self.size = size
+ self._conversionString = conversionString
+ self.value = defaultValue
+
+ def __repr__(self) :
+ return "%s object at %s:\n\n%20s : %s" % (self.__class__, hex(id(self)), "value", str(self))
+
+ def __str__(self) :
+ if self._conversionString == "c" :
+ return "'" + str(self.value) + "'"
+ else :
+ return str(self.value)
+
+ # this func could be used for type checking
+ def __setattr__(self, name, value) :
+ if self.__dict__.has_key("value") and name == "value":
+ #use the type conversions built into pack
+ pack(self._conversionString, value)
+ self.__dict__[name] = value
+
+ def oneLineStr(self) :
+ return str(self)
+
+ def __deepcopy__(self, memo={}) :
+ result = nescType(self.nescType, self.cType, self.pythonType,
+ self._xmlTag, self._conversionString, self.size,
+ deepcopy(self.value, memo))
+ memo[id(self)] = result
+ return result
+
+ def isType(self, xmlDefinition) :
+ """returns 1 if the xml definition describes this type.
+ Returns 0 otherwise."""
+ if xmlDefinition != None and xmlDefinition.tagName == self._xmlTag and \
+ xmlDefinition.hasAttribute("cname") and \
+ xmlDefinition.getAttribute("cname") == self.cType :
+ return 1
+ elif self.nescType == "void" and xmlDefinition.tagName == self._xmlTag :
+ #void is a special xml case that doesn't have cname defined (grr)
+ return 1
+ else :
+ return 0
+
+ def getBytes(self) :
+ """Hexidecimal representation of a value of this type"""
+ if self.nescType == "void" :
+ return ''
+ try:
+ bytes = pack(self._conversionString, self.value)
+ except Exception, inst:
+ print inst
+ raise Exception("Bytes conversion error: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size) )
+ if len(bytes) != self.size:
+ raise Exception("Wrong number of bytes for conversion: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size))
+ return bytes
+
+ def setBytes(self, bytes):
+ """A value of this type from a hexidecimal representation"""
+ if self.nescType == "void" :
+ return bytes
+ if len(bytes) < self.size:
+ raise Exception("Wrong number of bytes for conversion: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size))
+ try:
+ self.value, = unpack( self._conversionString, bytes[:self.size])
+ except Exception, inst:
+ print inst
+ raise Exception("Bytes conversion error: %s %d bytes to %d" %
+ ( self.nescType, len(bytes), self.size) )
+ return bytes[self.size:]
+
+###########
+# Array of basic nesc types,
+###########
+
+class nescArray( object ) :
+ """A python representation of a nesc array.
+
+ usage:
+ array = nescArray(size, nescType)
+ array = nescArray(myTypes, xmlDecl)
+ X = array[3]
+ X = array[3:6] (returns a list or, if char[] array, a python string)
+ array[3] = X
+ array[3:6] [X,Y,Z] (or, if char[], \"foo\")
+ bytes = array.getBytes()
+ array.setBytes(bytes)
+ array
+ print array
+ """
+
+ def __init__( self , *varargs) :
+ """initialize all elements to 0"""
+ if len(varargs) == 0 :
+ return
+ elif len(varargs) == 2 and type(varargs[0]) == int :
+ (self.len,self.elementType) = varargs[:]
+ bracketStr = "[" + str(self.len) + "]"
+ elif len(varargs) == 2 :
+ (nescTypes, xmlDefinition) = varargs[:]
+ if xmlDefinition.tagName != "type-array" :
+ raise Exception("Not array definition")
+ child = getUniqueChild(xmlDefinition)
+ self.elementType = nescTypes.getTypeFromXML(child)
+ sizeStr = xmlDefinition.getAttribute("elements")[2:]
+ self.len = int(sizeStr)
+ bracketStr = "[" + sizeStr + "]"
+ else :
+ raise Exception("Illegal array params")
+ self.nescType = self.elementType.nescType + bracketStr
+ self.cType = self.elementType.cType + bracketStr
+ self.pythonType = self.elementType.pythonType + bracketStr
+ self.size = self.len * self.elementType.size
+ self.value = []
+ for i in range(self.len):
+ self.value.append(deepcopy(self.elementType))
+
+
+ def __repr__(self) :
+ """A printable representation of the value"""
+ return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self))
+
+ def __str__(self) :
+ """A printable representation of the value"""
+ string = "nescArray of type %s:\n" % self.nescType
+# if self.elementType._conversionString == "c":
+# string += self.oneLineStr()
+# else:
+ for i in range(self.len) :
+ string += "%2d: %s\n" % (i, self.value[i].oneLineStr())
+ return string
+
+ def __getitem__(self, key) :
+ if self.elementType.__class__ == nescType :
+ if key.__class__ == slice:
+ if self.elementType._conversionString == "c":
+ string = ""
+ for item in self.value.__getitem__(key) :
+ string += item.value
+ return string
+ else:
+ return [item.value for item in self.value.__getitem__(key)]
+ else:
+ return self.value.__getitem__(key).value
+ else:
+ return self.value.__getitem__(key)
+
+ def __setitem__(self, key, value) :
+ if self.elementType.__class__ == nescType :
+ if key.__class__ == slice:
+ i=0;
+ for item in self.value.__getitem__(key) :
+ item.value = value[i]
+ i += 1
+ else:
+ self.value.__getitem__(key).value = value
+ else :
+ self.value.__setitem__(key, value)
+
+ def __delitem__(self, key) :
+ return self.value.__delitem__(key)
+
+ def oneLineStr(self) :
+ """A one-line representation of the value"""
+ #maybe the string should just print like a string
+ #but the \x00 chars look like nothing
+# if self.elementType._conversionString == "c":
+# string = '\''
+# for c in self.value :
+# string += c.value
+# string += '\''
+# else:
+ tmpStr = str(self.elementType)
+ if tmpStr.find("\n") >= 0 or len(tmpStr) > 5 :
+ return self.nescType
+ else :
+ i = 0; string = "["
+ while len(string) < 40 and i < self.len :
+ string += str(self.value[i]) + ", "
+ i += 1
+ if i < self.len :
+ string += "...]"
+ else:
+ string += "\b\b]"
+ return string
+
+ def __deepcopy__(self, memo={}) :
+ result = nescArray()
+ memo[id(self)] = result
+ result.elementType = deepcopy(self.elementType, memo)
+ result.nescType = self.nescType
+ result.cType = self.cType
+ result.pythonType = self.pythonType
+ result.len = self.len
+ result.size = self.size
+ result.value = deepcopy(self.value, memo)
+ return result
+
+ def isType(self, xmlDefinition) :
+ """returns 1 if the xml definition describes this type.
+ Returns 0 otherwise."""
+ if ( xmlDefinition != None and xmlDefinition.tagName == "type-array" and
+ int(xmlDefinition.getAttribute("elements")[2:]) == self.len ) :
+ child = getUniqueChild(xmlDefinition)
+ return self.elementType.isType(child)
+ else :
+ return 0
+
+ def getBytes(self) :
+ """Hexidecimal representation of a value of this type"""
+ bytes = ""
+ for i in range(self.len):
+ bytes += self.value[i].getBytes()
+ if len(bytes) != self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ ( self.nescType, len(bytes), self.size))
+ return bytes
+
+
+ def setBytes(self, bytes) :
+ """A value of this type from a hexidecimal representation"""
+ if len(bytes) < self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size) )
+ for i in range(self.len) :
+ bytes = self.value[i].setBytes(bytes)
+ return bytes
+
+###########
+# Pointer to basic nesc types,
+###########
+
+class nescPointer( object ) :
+ """A python representation of a nesc pointer.
+
+ usage:
+ pointer = nescPointer(ptrSize, nescType)
+ pointer = nescPointer(myTypes, xmlDecl)
+ nescType = pointer.value
+ pointer.value = nescType
+ bytes = pointer.getBytes()
+ pointer.setBytes(bytes)
+ pointer
+ print pointer
+ """
+
+ def __init__( self , *varargs) :
+ """initialize all elements to 0"""
+ if len(varargs) == 0:
+ return
+ elif len(varargs) == 2 and varargs[1].__dict__.has_key("tagName"):
+ (nescTypes, xmlDefinition) = varargs[:]
+ if xmlDefinition.tagName != "type-pointer" :
+ raise Exception("Not pointer definition")
+ child = getUniqueChild(xmlDefinition)
+ self.value = nescTypes.getTypeFromXML(child)
+ self.size = int(xmlDefinition.getAttribute("size")[2:])
+ elif len(varargs) == 2 :
+ self.size = varargs[0].types["unsigned int"].size
+ self.value = varargs[1]
+ else :
+ raise Exception("Illegal nescPointer constructor arguments")
+ self.nescType = self.value.nescType + "*"
+ self.cType = self.value.cType + "*"
+ self.pythonType = self.value.pythonType + "*"
+
+ def __repr__(self) :
+ return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self))
+
+ def __str__(self) :
+ """A text representation of the value"""
+ return "ptr-> %s" % str(self.value)
+
+ def oneLineStr(self) :
+ """A one-line representation of the value"""
+ return "ptr-> %s" % self.value.oneLineStr()
+
+ def __deepcopy__(self, memo={}) :
+ result = nescPointer()
+ memo[id(self)] = result
+ result.value = deepcopy(self.value, memo)
+ result.size = self.size
+ result.nescType = self.nescType
+ result.cType = self.cType
+ result.pythonType = self.pythonType
+ return result
+
+ def isType(self, xmlDefinition) :
+ """returns 1 if the xml definition describes this type.
+ Returns 0 otherwise."""
+ if xmlDefinition != None and xmlDefinition.tagName == "type-pointer" :
+ child = getUniqueChild(xmlDefinition)
+ return self.value.isType(child)
+ else :
+ return 0
+
+ def getBytes(self) :
+ bytes = pack (str(self.size)+"s",'\x00')
+ if len(bytes) != self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size) )
+ return bytes
+
+ def setBytes(self, bytes) :
+ if len(bytes) < self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ ( self.nescType, len(bytes), self.size) )
+ return bytes[self.size:]
+
+
+###########
+# Struct of basic nesc types,
+###########
+
+class nescStruct( object ) :
+ """A python representation of a nesc structure.
+
+ usage:
+ struct = nescStruct(myTypes, xmlDecl)
+ struct = nescStruct(structName, (fieldName, type) (fieldName, type), ...)
+ X = struct.field
+ struct.field = X
+ bytes = struct.getBytes()
+ struct.setBytes(bytes)
+ struct
+ print struct
+ """
+
+ def __init__( self, *varargs) :
+ """initialize all fields to 0"""
+ self.__dict__["value"] = {}
+ self.fields = []
+ self.size = 0
+ if len(varargs) == 0 :
+ self.nescType = ""
+ #create the struct from nescType args
+ elif len(varargs) >= 1 and ( type(varargs[0]) == str or
+ type(varargs[0]) == unicode ) :
+ self.nescType = varargs[0]
+ self._parseNescTypeFields(varargs[1:])
+ ## parse the struct def from xml
+ elif len(varargs) == 2 and type(varargs[1]) != tuple :
+ (nescTypes, xmlDefinition) = varargs[:]
+ if xmlDefinition.tagName != "struct" :
+ raise Exception("Not struct definition")
+ if xmlDefinition.hasAttribute("name") == False:
+ raise Exception("Anonymous struct")
+ self.nescType = xmlDefinition.getAttribute("name")
+ if xmlDefinition.getAttribute("size")[2:]:
+ self.size = int(xmlDefinition.getAttribute("size")[2:])
+ else:
+ self.size = 0
+ self._parseXMLFields(nescTypes, xmlDefinition)
+ else :
+ raise Exception("Illegal nescStruct constructor args")
+ self.cType = self.nescType
+ self.pythonType = self.nescType
+ self.__initialized = True
+
+ def __getattr__(self, name) :
+ if self.__dict__.has_key("value") :
+ if self.value.has_key(name) :
+ if self.value[name].__class__ == nescType :
+ return self.value[name].value
+ else :
+ return self.value[name]
+ else :
+ raise AttributeError("No such field \"%s\" in the nescStruct \"%s\"" % (name, self.nescType))
+
+ def __setattr__(self, name, value) :
+ if not self.__dict__.has_key("_nescStruct__initialized") :
+ self.__dict__[name] = value
+ return
+ if self.value.has_key(name) :
+ if self.value[name].__class__ == nescType :
+ self.value[name].value = value;
+ else :
+ self.value[name] = value;
+ elif self.__dict__.has_key(name) :
+ self.__dict__[name] = value
+ else :
+ raise AttributeError("No such field \"%s\" in the nescStruct \"%s\"" % (name, self.nescType))
+
+
+ def __repr__(self) :
+ return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self))
+
+ def __str__(self) :
+ """All fields and values as a readable string"""
+ string = self.nescType + ": \n"
+ for field in self.fields :
+ string += "%30s : %s\n" % (
+ "%s %s" % (self.value[field["name"]].nescType, field["name"]),
+ self.value[field["name"]].oneLineStr() )
+ return string
+
+ def oneLineStr(self) :
+ """A one-line representation of the struct"""
+ return self.nescType
+
+ def __deepcopy__(self, memo={}) :
+ result = self.__class__()
+ memo[id(self)] = result
+ self._copyFields(result, memo)
+ return result
+
+ def _copyFields(self, other, memo=None) :
+ other.size = self.size
+ other.nescType = self.nescType
+ other.cType = self.cType
+ other.pythonType = self.pythonType
+ if memo == None :
+ other.value = deepcopy(self.value)
+ other.fields = deepcopy(self.fields)
+ else :
+ other.value = deepcopy(self.value, memo)
+ other.fields = deepcopy(self.fields, memo)
+ other.__initialized = True
+
+ def _parseXMLFields(self, nescTypes, xmlDefinition) :
+ """Create a list of fields & values given a struct xml declaration."""
+ fields = [node for node in xmlDefinition.getElementsByTagName("field")]
+ fields.sort( lambda A, B : int(A.getAttribute("bit-offset")[2:]) - int(B.getAttribute("bit-offset")[2:]))
+ for fieldDef in fields:
+ field = {}
+ field["name"] = fieldDef.getAttribute("name")
+ field["bitOffset"] = int(fieldDef.getAttribute("bit-offset")[2:])
+ if fieldDef.hasAttribute("bit-size"):
+ field["bitSize"] = int(fieldDef.getAttribute("bit-size")[2:])
+ elif fieldDef.hasAttribute("size"):
+ field["bitSize"] = int(fieldDef.getAttribute("size")[2:])*8
+ self.fields.append(field)
+ self.value[fieldDef.getAttribute("name")] = nescTypes.getTypeFromXML(fieldDef)
+ #here's a weird bug in the nesc.xml generation where the "size" attribute
+ #for packed structs is actually the size of the unpacked struct.
+ if xmlDefinition.hasAttribute("packed") :
+ self.size = self.packedSize()
+ elif xmlDefinition.getAttribute("size")[2:]:
+ self.size = int(xmlDefinition.getAttribute("size")[2:])
+ else:
+ self.size = 0
+ def _parseNescTypeFields(self, fields) :
+ """Create a list of fields & values given a tuple of
+ fieldname,value sequences."""
+ self.size = 0
+ for fieldDef in fields:
+ field = {}
+ (field["name"],fType) = fieldDef
+ field["bitOffset"] = self.size*8
+ field["bitSize"] = fType.size*8
+ self.fields.append(field)
+ self.value[field["name"]] = fType
+ self.size += fType.size
+
+ def isType(self, xmlDefinition) :
+ """returns 1 if the xml definition describes this type.
+ Returns 0 otherwise."""
+ if xmlDefinition == None :
+ return 0
+ child = getUniqueChild(xmlDefinition)
+ if ( ( xmlDefinition.tagName == "struct" and
+ xmlDefinition.getAttribute("name") == self.nescType) or
+ ( xmlDefinition.tagName == "type-tag" and child != None and
+ child.tagName == "struct-ref" and
+ child.getAttribute("name") == self.nescType ) ) :
+ return 1
+ else :
+ return 0
+
+ def getBytes(self) :
+ """Hexidecimal representation of struct"""
+ # We have to be careful in here about:
+ # 1. bit fields (ie. bitSize shorter than nominal type size)
+ # 2. packing (ie. bits that are not part of any particular field)
+ bits = ""
+ for field in self.fields :
+ for i in range(len(bits), field["bitOffset"]) :
+ bits += "0"
+ newBits = hex2bin(self.value[field["name"]].getBytes())
+ bits += newBits[-field["bitSize"]:]
+ #the following loop is just type checking for bit fields. Can we do this on setattr?
+ for i in range(len(newBits)-field["bitSize"]):
+ if newBits[i] == "1":
+ print "Bit-field type error: value of %s.%s being truncated" % (self.nescType,
+ field["name"])
+ for i in range(len(bits), self.size*8) :
+ bits += "0"
+ bytes = bin2hex(bits)
+ if len(bytes) != self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ ( self.nescType, len(bytes), self.size))
+ return bytes
+
+ def setBytes(self, bytes) :
+ """Set all values using hexidecimal representation"""
+ # We have to be careful in here about:
+ # 1. bit fields (ie. bitSize shorter than nominal type size)
+ # 2. packing (ie. bits that are not part of any particular field)
+ if len(bytes) < self.size:
+ raise Exception("Byte conversion error: %s %d bytes to %d" %
+ (self.nescType, len(bytes), self.size) )
+ bits = hex2bin(bytes)
+ for field in self.fields :
+ newBits = ""
+ for i in range(self.value[field["name"]].size*8) :
+ newBits += "0"
+ selectedBits=bits[field["bitOffset"]:field["bitOffset"]+field["bitSize"]]
+ newBits = newBits[:-field["bitSize"]] + selectedBits
+ newBytes = ""
+ for i in range(self.value[field["name"]].size) :
+ newBytes += '\x00'
+ tmpBytes = bin2hex(newBits)
+ newBytes = newBytes[:-len(tmpBytes)] + tmpBytes
+ self.value[field["name"]].setBytes(newBytes);
+ return bytes[self.size:]
+
+ def packedSize(self) :
+ if len(self.fields) == 0 :
+ trueSize = 0
+ else :
+ a,b,lastField = self._findLastNestedField()
+ trueSize = (lastField["bitOffset"] + lastField["bitSize"]) /8
+ return trueSize
+
+ def _findLastNestedField(self) :
+ lastField = self
+ parents = []
+ #find the last (possibly nested) field
+ while issubclass(type(lastField), nescStruct) and len(lastField.fields) > 0 :
+ parent = lastField
+ lastFieldDef = parent.fields[-1]
+ lastField = parent.value[lastFieldDef["name"]]
+ parents.append( parent )
+ return (lastField, parents, lastFieldDef)
+
+
+
+
+
+class TosMsg ( nescStruct ) :
+ """A python representation of a TosMsg.
+ Is a nescStruct object.
+ Can be used with
+ pytos.comm.send, pytos.comm.register, pytos.comm.unregister.
+
+ usage:
+ msg = TosMsg(amType)
+ msg = TosMsg(amType, nescStruct)
+ msg = TosMsg(amType, <nescStruct constructor args>)
+ print msg
+ msg.field = X
+ comm.send(msg)
+ comm.register(msg, f)
+ comm.unregister(msg, f)
+ migMsg = msg.createMigMsg()
+ msg.parseMigMsg(migMsg)
+ """
+
+ def __init__(self, amType, *varargs):
+ self.amType = amType
+ self.parentMsg = None
+ #if this is a nescStruct argument, make myself a clone of it
+ if len(varargs) == 1 and issubclass(type(varargs[0]), nescStruct) :
+ nescStruct._copyFields(varargs[0],self)
+ #otherwise, make myself into a struct with the struct args
+ elif len(varargs) >= 1:
+ nescStruct.__init__(self, *varargs)
+
+ def __deepcopy__(self, memo={}) :
+ result = self.__class__(self.amType)
+ memo[id(self)] = result
+ self._copyFields(result, memo)
+ result.parentMsg = deepcopy(self.parentMsg, memo)
+ return result
+
+ def getParentMsg(self, amOrName) :
+ """This function will get the parent message with the amType or name specified"""
+ if self.parentMsg == None :
+ return None
+ elif self.parentMsg.nescType == amOrName or self.parentMsg.amType == amOrName :
+ return self.parentMsg
+ else :
+ return self.parentMsg.getParentMsg(amOrName)
+
+ def createMigMsg(self) :
+ """Returns a java BaseTOSMsg with same amType and length
+ and with data payload of same bytes"""
+ Message = tinyos.message.Message()
+ msg = Message(self.size)
+ msg.dataSet(unpack( str(self.size) + 'b', self.getBytes() ) )
+ msg.amTypeSet(self.amType)
+# msg.set_type( self.amType )
+# msg.set_length(self.size)
+ return msg
+
+ def parseMigMsg(self, msg) :
+ """Takes a java BaseTOSMsg and creates TosMsg
+ with same amType and length and with data payload of same bytes"""
+ self.amType = msg.amType()
+ data = list(msg.dataGet())
+ self.setBytes(pack(str(len(data)) + 'b', *data))
+
+ def __repr__(self) :
+ return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self))
+
+ def __str__(self) :
+ """All fields and values as a readable string"""
+ return "TosMsg(am=%d) " % self.amType + nescStruct.__str__(self)
+
+ def setBytes(self, bytes) :
+ """Extend this msg to be longer, if necessary to accomodate extra data.
+ This only happens if the last field is a nescArray of length 0.
+ Unlike nescStructs, TosMsg objects are not nested recursively, so it is
+ Ok to do this."""
+ if len(bytes) > self.size : #trueSize() :
+ #print "there are more bytes than fit in this msg... trying to grow msg"
+ lastField, parents,b = self._findLastNestedField()
+ #see if it is an array of size 0
+ if type(lastField) == nescArray and lastField.len == 0 :
+ #make it bigger
+ #print "last field is nescArray[0]... growing"
+ lastFieldSize = lastField.elementType.size
+ numExtraBytes = len(bytes) - self.size #trueSize()
+ if numExtraBytes % lastFieldSize == 0:
+ requiredArraySize = int( numExtraBytes/lastFieldSize )
+ lastField = nescArray(requiredArraySize, lastField.elementType)
+ #print "new size is %d" % numExtraBytes
+ #and set it, changing the size of all parent structs
+ parents.reverse()
+ for parent in parents :
+# trueSize = parent.trueSize()
+ parent.value[parent.fields[-1]["name"]] = lastField
+ parent.fields[-1]["bitSize"] = lastField.size*8
+ parent.size = self.packedSize()# + lastField.size
+ lastField = parent
+ else:
+ #print "last field is not nescArray[0]. Cannot grow. Ignoring extra data."
+ pass
+
+ #make sure everything worked out correctly and call parent's function
+ if len(bytes) != self.size :#trueSize() :
+ raise Exception("Incorrect number of bytes for TosMsg. Byte conversion error: %s %d bytes to %d" % ( self.nescType, len(bytes), self.size) )
+ #print "passing to child to set bytes."
+ nescStruct.setBytes(self,bytes)
+
+
+
+
+
+
+
+def getUniqueChild(xmlDefinition) :
+ child = None
+ for childNode in xmlDefinition.childNodes :
+ if childNode.nodeType == 1 :
+ child = childNode
+ break
+ return child
+
+def bin2hex(bits) :
+ bytes = ""
+ for i in range(0, len(bits), 8 ):
+ bytes += pack('B',int(bits[i:i+8],2))
+ return bytes
+
+def hex2bin(bytes) :
+ bits = ""
+ for i in range(len(bytes)) :
+ val, = unpack('B',bytes[i])
+ for j in range(7,-1,-1):
+ if val>= pow(2,j):
+ bits += "1"
+ val -= pow(2,j)
+ else :
+ bits += "0"
+ return bits
+
+
+def TestAppTypes() :
+ testRpc = appTypes('/home/kamin/tinyos-1.x/contrib/hood/apps/TestRpc/build/telosb/nesc.xml')
+ print testRpc
+
+if __name__ == "__main__": TestAppTypes()