예제 #1
0
def readNCTRStmFrameHeader(fd):
    """creates a NCTRS TM data unit according to the NCTRS_TM_DU_VERSION"""
    # the function raises an exception when the read fails
    tmDUtype = getTMdataUnitType()
    if s_tmDUtype == GRND.NCTRSDU.TM_V0_ERT_FORMAT:
        tmDuHeaderByteSize = GRND.NCTRSDU.TM_DU_V0_HEADER_BYTE_SIZE
    elif s_tmDUtype == GRND.NCTRSDU.TM_V1_CDS1_ERT_FORMAT:
        tmDuHeaderByteSize = GRND.NCTRSDU.TM_DU_V1_CDS1_HEADER_BYTE_SIZE
    elif s_tmDUtype == GRND.NCTRSDU.TM_V1_CDS2_ERT_FORMAT:
        tmDuHeaderByteSize = GRND.NCTRSDU.TM_DU_V1_CDS2_HEADER_BYTE_SIZE
    elif s_tmDUtype == GRND.NCTRSDU.TM_V1_CDS3_ERT_FORMAT:
        tmDuHeaderByteSize = GRND.NCTRSDU.TM_DU_V1_CDS3_HEADER_BYTE_SIZE
    else:
        raise Error("Invalid s_tmDUtype " + str(s_tmDUtype))
    # read the TM data unit header
    if type(fd) == SOCKET_TYPE:
        tmDuHeader = fd.recv(tmDuHeaderByteSize)
    else:
        tmDuHeader = fd.read(tmDuHeaderByteSize)
    # consistency check
    tmDuHeaderLen = len(tmDuHeader)
    if tmDuHeaderLen == 0:
        if type(fd) == SOCKET_TYPE:
            raise Error("empty data read")
        else:
            # end of file
            raise Error("")
    if tmDuHeaderLen != tmDuHeaderByteSize:
        raise Error("Read of TM DU header failed: invalid size: " +
                    str(tmDuHeaderLen))
    return tmDuHeader
예제 #2
0
def readNCTRSframe(fd):
    """reads one NCTRS frame from fd, raise execption when there is an error"""
    # read the TM data unit header
    try:
        tmDuHeader = readNCTRStmFrameHeader(fd)
    except Exception as ex:
        raise Error(str(ex))
    tmDu = createTMdataUnit(tmDuHeader)
    # consistency check
    packetSize = tmDu.packetSize
    remainingSizeExpected = packetSize - len(tmDuHeader)
    if remainingSizeExpected <= 0:
        raise Error(
            "Read of TM DU header failed: invalid packet size field: " +
            str(remainingSizeExpected))
    # read the remaining bytes for the TM data unit
    try:
        if type(fd) == SOCKET_TYPE:
            tmRemaining = fd.recv(remainingSizeExpected)
        else:
            tmRemaining = fd.read(remainingSizeExpected)
    except Exception as ex:
        raise Error("Read of remaining TM DU failed: " + str(ex))
    # consistency check
    remainingSizeRead = len(tmRemaining)
    if remainingSizeRead != remainingSizeExpected:
        raise Error(
            "Read of remaining TM DU failed: invalid remaining size: " +
            str(remainingSizeRead))
    # TM frame
    tmDu.append(tmRemaining)
    return tmDu
예제 #3
0
 def decode(self, du, bitPos):
     """
 decodes the contens from a data unit, returns the new position
 overloaded from Entity
 """
     paramType = self.getParamType()
     bitWidth = self.getBitWidth()
     value = self.value
     nextBitPos = bitPos + bitWidth
     # process bit oriented parameter types
     if paramType == UTIL.DU.BITS:
         self.value = du.getBits(bitPos, bitWidth)
         return nextBitPos
     if paramType == UTIL.DU.SBITS:
         self.value = du.getSBits(bitPos, bitWidth)
         return nextBitPos
     # process byte oriented parameter types
     if (bitPos % 8) != 0:
         raise Error("parameter " + self.getParamName() +
                     " position is not byte aligned")
     if (bitWidth % 8) != 0:
         raise Error("parameter " + self.getParamName() +
                     " size is not byte aligned")
     bytePos = bitPos >> 3
     byteWidth = bitWidth >> 3
     defType = type(self.paramDef)
     if defType == VariableParamDef:
         # for variable length parameters: encode the length bytes first
         lengthBytes = self.paramDef.lengthBytes
         byteLength = du.getUnsigned(bytePos, lengthBytes)
         bytePos += lengthBytes
         byteWidth = byteLength
         nextBytePos = bytePos + byteWidth
         nextBitPos = nextBytePos << 3
     if paramType == UTIL.DU.BYTES:
         self.value = du.getBytes(bytePos, byteWidth)
         return nextBitPos
     if paramType == UTIL.DU.UNSIGNED:
         self.value = du.getUnsigned(bytePos, byteWidth)
         return nextBitPos
     if paramType == UTIL.DU.SIGNED:
         self.value = du.getSigned(bytePos, byteWidth)
         return nextBitPos
     if paramType == UTIL.DU.FLOAT:
         self.value = du.getFloat(bytePos, byteWidth)
         return nextBitPos
     if paramType == UTIL.DU.TIME:
         timeFormat = self.paramDef.timeFormat
         self.value = du.getTime(bytePos, timeFormat)
         return nextBitPos
     if paramType == UTIL.DU.STRING:
         self.value = du.getString(bytePos, byteWidth)
         return nextBitPos
     raise Error("unexpected paramType for parameter " +
                 self.getParamName())
예제 #4
0
 def encode(self, du, bitPos):
   """
   encodes the contens into a data unit, returns the new position
   overloaded from Entity
   """
   paramType = self.getParamType()
   bitWidth = self.getBitWidth()
   value = self.value
   nextBitPos = bitPos + bitWidth
   # process bit oriented parameter types
   if paramType == UTIL.DU.BITS:
     du.setBits(bitPos, bitWidth, value)
     return nextBitPos
   if paramType == UTIL.DU.SBITS:
     du.setSBits(bitPos, bitWidth, value)
     return nextBitPos
   # process byte oriented parameter types
   if (bitPos % 8) != 0:
     raise Error("parameter " + self.getParamName() + " position is not byte aligned")
   if (bitWidth % 8) != 0:
     raise Error("parameter " + self.getParamName() + " size is not byte aligned")
   bytePos = bitPos >> 3
   byteWidth = bitWidth >> 3
   defType = type(self.paramDef)
   if defType == VariableParamDef:
     # for variable length parameters: encode the length bytes first
     # for TCs it is also allowed to have no length byte (e.g. CNC protocol)
     lengthBytes = self.paramDef.lengthBytes
     if lengthBytes > 0:
       byteLength = len(value)
       du.setUnsigned(bytePos, lengthBytes, byteLength)
       bytePos += lengthBytes
       byteWidth = byteLength      
   if paramType == UTIL.DU.BYTES:
     du.setBytes(bytePos, byteWidth, value)
     return nextBitPos
   if paramType == UTIL.DU.UNSIGNED:
     du.setUnsigned(bytePos, byteWidth, value)
     return nextBitPos
   if paramType == UTIL.DU.SIGNED:
     du.setSigned(bytePos, byteWidth, value)
     return nextBitPos
   if paramType == UTIL.DU.FLOAT:
     du.setFloat(bytePos, byteWidth, value)
     return nextBitPos
   if paramType == UTIL.DU.TIME:
     timeFormat = self.paramDef.timeFormat
     du.setTime(bytePos, timeFormat, value)
     return nextBitPos
   if paramType == UTIL.DU.STRING:
     du.setString(bytePos, byteWidth, value)
     return nextBitPos
   raise Error("unexpected paramType for parameter " + self.getParamName())
예제 #5
0
 def getTMframe(self, tmDataPacket):
     """
 creates a Transfer TM frame with embedded TM packet
 implementation of LINK.IF.TMframeGenerator.getTMframe
 """
     # create the idle packet
     reservedFrameDataSize = CCSDS.FRAME.TM_FRAME_PRIMARY_HEADER_BYTE_SIZE + \
                             len(tmDataPacket) + \
                             CCSDS.FRAME.CLCW_BYTE_SIZE
     enableSecondaryHeader = (self.frameDefaults.secondaryHeaderFlag == 1)
     if enableSecondaryHeader:
         reservedFrameDataSize += CCSDS.FRAME.TM_FRAME_SECONDARY_HEADER_BYTE_SIZE
     if CCSDS.FRAME.CRC_CHECK:
         reservedFrameDataSize += 2
     remainingFrameDataSize = self.frameDefaults.transferFrameSize - \
                              reservedFrameDataSize
     if remainingFrameDataSize < 0:
         # TM packet does not fit into the frame
         # ---> an exception must be raisedas long as
         #      TM packet segmentation is not implemeted
         raise Error("TM packet with SPID " + str(spid) +
                     " does not fit into transfer frame")
     createIdlePacket = (remainingFrameDataSize != 0)
     if createIdlePacket:
         tmIdlePacket = \
           SPACE.IF.s_tmPacketGenerator.getIdlePacket(remainingFrameDataSize)
     # create the transfer frame
     tmFrame = CCSDS.FRAME.TMframe(
         enableSecondaryHeader=enableSecondaryHeader)
     tmFrame.versionNumber = self.frameDefaults.versionNumber
     tmFrame.spacecraftId = self.frameDefaults.spacecraftId
     tmFrame.virtualChannelId = self.frameDefaults.virtualChannelId
     tmFrame.operationalControlField = self.frameDefaults.operationalControlField
     tmFrame.masterChannelFrameCount = self.masterChannelFrameCount
     self.masterChannelFrameCount += 1
     self.masterChannelFrameCount %= 256
     tmFrame.virtualChannelFCountLow = self.virtualChannelFrameCount
     self.virtualChannelFrameCount += 1
     self.virtualChannelFrameCount %= 256
     tmFrame.secondaryHeaderFlag = self.frameDefaults.secondaryHeaderFlag
     tmFrame.synchronisationFlag = self.frameDefaults.synchronisationFlag
     tmFrame.packetOrderFlag = self.frameDefaults.packetOrderFlag
     tmFrame.segmentLengthId = self.frameDefaults.segmentLengthId
     tmFrame.firstHeaderPointer = self.frameDefaults.firstHeaderPointer
     if enableSecondaryHeader:
         tmFrame.secondaryHeaderVersionNr = self.frameDefaults.secondaryHeaderVersionNr
         tmFrame.secondaryHeaderSize = self.frameDefaults.secondaryHeaderSize
         tmFrame.virtualChannelFCountHigh = self.frameDefaults.virtualChannelFCountHigh
     tmFrame.append(tmDataPacket.getBufferString())
     if createIdlePacket:
         tmFrame.append(tmIdlePacket.getBufferString())
     tmFrame.append(self.clcw.getBufferString())
     if CCSDS.FRAME.CRC_CHECK:
         tmFrame.append("\0" * CCSDS.DU.CRC_BYTE_SIZE)
         tmFrame.setChecksum()
     return tmFrame
예제 #6
0
 def addPacketIDrecord(self, apid, serviceType, serviceSubType, pi1, pi2,
                       packetID):
     """adds a record for packet identification"""
     # note: this table is also relevant for non-pus packets - in this case the
     #       serviceType and serviceSubType fields must be None
     key = (apid, serviceType, serviceSubType, pi1, pi2)
     if key in self.keyFieldIDs:
         raise Error("key " + str(key) +
                     " is already defined in packet ID map")
     value = packetID
     self.packetIDs[key] = value
예제 #7
0
 def fillSlotInTree(self, parentNodeID, slot):
   """fills a Slot into the tree"""
   slotName = slot.getSlotName()
   child = slot.child
   childType = type(child)
   if childType == PUS.VP.Param:
     self.fillParamInTree(parentNodeID, slotName, param=child)
   elif childType == PUS.VP.List:
     self.fillListInTree(parentNodeID, slotName, lst=child)
   else:
     raise Error("child type " + childType + " not supported")
예제 #8
0
 def createFileHandler(self, socket, handler):
     """register a file descriptor handler"""
     # special implementation for faked thread, delegate to parent task
     global s_parentTask
     if self.taskType == FAKETHREAD:
         if s_parentTask:
             s_parentTask.createFileHandler(socket, handler)
         else:
             raise Error("missing parent task for file handler creation")
         return
     # normal implementation
     self.readDictionary[socket] = handler
예제 #9
0
 def __init__(self, slotDef=""):
   self.slotDef = slotDef
   # create the slot child depending on the slot child type in the definition
   childDef = slotDef.childDef
   childType = type(childDef)
   if childType == SimpleParamDef or childType == VariableParamDef or \
      childType == TimeParamDef:
     self.child = Param(paramDef=childDef)
   elif childType == ListDef:
     self.child = List(listDef=childDef)
   else:
     raise Error("child type " + str(childType) + " not supported")
예제 #10
0
 def decode(self, du, bitPos):
   """
   decodes the contens from a data unit, returns the new position
   overloaded from Entity
   """
   # decode the length
   lengthValueBitPos = bitPos
   if (lengthValueBitPos % 8) != 0:
     raise Error("parameter " + self.getLenParamName() + " position is not byte aligned")
   lengthValueBitWidth = self.listDef.lenParamDef.bitWidth
   if (lengthValueBitWidth % 8) != 0:
     raise Error("parameter " + self.getLenParamName() + " size is not byte aligned")
   lengthValueBytePos = lengthValueBitPos >> 3
   lengthValueByteWidth = lengthValueBitWidth >> 3
   lengthValue = du.getUnsigned(lengthValueBytePos, lengthValueByteWidth)
   bitPos += lengthValueBitWidth
   # decode the list entries
   self.setLen(lengthValue)
   for entry in self.entries:
     bitPos = entry.decode(du, bitPos)
   return bitPos
예제 #11
0
 def addKeyFieldRecord(self, apid, serviceType, serviceSubType, pi1bitPos,
                       pi1bitSize, pi2bitPos, pi2bitSize):
     """adds a record for key field identification"""
     # note: apid can be None - in this case all packets with the same
     #       serviceType and serviceSubType are matching such an entry
     # note: this table is also relevant for non-pus packets - in this case the
     #       serviceType and serviceSubType fields must be None
     # note: pi1bitPos, pi1bitSize and/or pi2bitPos, pi2bitSize can be None - in
     #       this case pi1 and/or pi2 are not used for the packet identification
     # note: when pi1bitPos, pi1bitSize and/or pi2bitPos, pi2bitSize are None,
     #       then the related enytry for the packet identification must contain
     #       as well None in the pi1 and/or pi2 field
     key = (apid, serviceType, serviceSubType)
     value = (pi1bitPos, pi1bitSize, pi2bitPos, pi2bitSize)
     if key in self.keyFieldIDs:
         previousValue = self.keyFieldIDs[key]
         if previousValue != value:
             raise Error("key " + str(key) +
                         " is already defined in key field ID map")
     else:
         self.keyFieldIDs[key] = value
예제 #12
0
 def createTimeHandler(self, ms, handler):
     """register a time handler"""
     # special implementation for faked thread, delegate to parent task
     global s_parentTask
     if self.taskType == FAKETHREAD:
         if s_parentTask:
             s_parentTask.createTimeHandler(ms, handler)
         else:
             raise Error("missing parent task for time handler creation")
         return
     # normal implementation: create new timer event and order it into
     # existing ordered timer events
     timeAbsoluteSec = time.time()
     timeoutAbsoluteSec = timeAbsoluteSec + (ms / 1000.0)
     timerEvent = (timeoutAbsoluteSec, handler)
     i = 0
     while i < len(self.timerEvents):
         nextTimeout = self.timerEvents[i][0]
         if nextTimeout > timeoutAbsoluteSec:
             break
         i += 1
     self.timerEvents.insert(i, timerEvent)
예제 #13
0
 def getIdlePacket(self, packetSize):
     """
 creates an idle packet for filling space in a parent container
 (e.g. a CCSDS TM frame):
 implementation of SPACE.IF.TMpacketGenerator.getIdlePacket
 """
     # the idle packet is a TM packet without a secondary header (CCSDS)
     # but with a CRC (if an application expects a CRC)
     if packetSize < (CCSDS.PACKET.PRIMARY_HEADER_BYTE_SIZE +
                      CCSDS.DU.CRC_BYTE_SIZE):
         raise Error("no sufficient space for idle packet")
     applicationProcessId = self.packetDefaults.idlePacketAPID
     idlePacket = self.getTMpacketHelper(packetSize, applicationProcessId)
     # re-calculate the sequence counter (maintained per APID)
     if applicationProcessId in self.sequenceCounters:
         sequenceCounter = (self.sequenceCounters[applicationProcessId] +
                            1) % 16384
     else:
         sequenceCounter = 0
     idlePacket.sequenceControlCount = sequenceCounter
     self.sequenceCounters[applicationProcessId] = sequenceCounter
     # re-calculate the CRC
     idlePacket.setChecksum()
     return idlePacket
예제 #14
0
def getDataFieldHeaderFlag(binaryString, startPos=0):
    """returns the data field header flag field"""
    if (len(binaryString) - startPos) < PRIMARY_HEADER_BYTE_SIZE:
        raise Error("packet header is too small")
    return ((binaryString[startPos + 0] & 0x08) > 0)
예제 #15
0
def getApplicationProcessId(binaryString, startPos=0):
    """returns the application process id field"""
    if (len(binaryString) - startPos) < PRIMARY_HEADER_BYTE_SIZE:
        raise Error("packet header is too small")
    return (((binaryString[startPos + 0] * 256) + binaryString[startPos + 1])
            & 0x07FF)
예제 #16
0
def getPacketLength(binaryString, startPos=0):
    """returns the packet length field"""
    if (len(binaryString) - startPos) < PRIMARY_HEADER_BYTE_SIZE:
        raise Error("packet header is too small")
    return ((binaryString[startPos + 4] * 256) + binaryString[startPos + 5])
예제 #17
0
 def getTCpacket(self, pktName, tcStruct, reuse=True):
     """
 creates a CCSDS TC packet with optional parameter values:
 implementation of MC.IF.TCpacketGenerator.getTCpacket
 """
     # fetch the packet definition
     tcPktDef = SPACE.IF.s_definitions.getTCpktDefByName(pktName)
     if tcPktDef == None:
         raise Error("invalid packet name for packet creation: " + pktName)
     binarySize = tcPktDef.pktSPsize
     applicationProcessId = tcPktDef.pktAPID
     if reuse and pktName in self.packetCache:
         # reuse a packet with the same definition from the cache
         packet = self.packetCache[pktName]
         packet.setLen(binarySize)
         packet.setPacketLength()
     else:
         # create the TC packet
         if tcPktDef.pktHasDFhdr:
             # PUS packet
             serviceType = tcPktDef.pktType
             serviceSubType = tcPktDef.pktSType
             packet = self.getTCpacketHelper(binarySize,
                                             applicationProcessId,
                                             serviceType, serviceSubType)
         else:
             # CCSDS packet
             packet = self.getTCpacketHelper(binarySize,
                                             applicationProcessId)
         self.packetCache[pktName] = packet
     # apply the segmentationFlags
     packet.segmentationFlags = CCSDS.PACKET.UNSEGMENTED
     ### apply the encoded tcStruct ###
     if not tcStruct:
         # create an empty tcStruct with the correct structure
         tcStructDef = tcPktDef.tcStructDef
         if tcStructDef == None:
             raise Error("invalid packet structure for packet creation: " +
                         pktName)
         tcStruct = PUS.VP.Struct(tcStructDef)
     #-- find the correct position for the data
     structBytePos = CCSDS.PACKET.PRIMARY_HEADER_BYTE_SIZE
     if tcPktDef.pktHasDFhdr:
         # PUS packet
         structBytePos += tcPktDef.pktDFHsize
     structBitPos = structBytePos << 3
     structEndBitPos = structBitPos + tcStruct.getBitWidth()
     structEndBytePos = (structEndBitPos + 7) >> 3
     #-- re-size the packet to exactly fit
     tcPacketSize = structEndBytePos
     if tcPktDef.pktCheck:
         tcPacketSize += CCSDS.DU.CRC_BYTE_SIZE
     packet.setLen(tcPacketSize)
     packet.setPacketLength()
     #-- encode the struct
     tcStruct.encode(packet, structBitPos)
     # re-calculate the sequence counter (maintained per APID)
     if applicationProcessId in self.sequenceCounters:
         sequenceCounter = (self.sequenceCounters[applicationProcessId] +
                            1) % 16384
     else:
         sequenceCounter = 0
     packet.sequenceControlCount = sequenceCounter
     self.sequenceCounters[applicationProcessId] = sequenceCounter
     # re-calculate the CRC
     if tcPktDef.pktCheck:
         packet.setChecksum()
     return packet
예제 #18
0
def getVersionNumber(binaryString, startPos=0):
    """returns the version number field"""
    if (len(binaryString) - startPos) < PRIMARY_HEADER_BYTE_SIZE:
        raise Error("packet header is too small")
    return ((binaryString[startPos + 0] & 0xE0) >> 5)
예제 #19
0
 def getTMpacket(self,
                 spid,
                 parameterValues,
                 tmStruct,
                 dataField=None,
                 segmentationFlags=CCSDS.PACKET.UNSEGMENTED,
                 obtUTC=None,
                 reuse=True):
     """
 creates a CCSDS TM packet with optional parameter values:
 implementation of SPACE.IF.TMpacketGenerator.getTMpacket
 """
     # fetch the packet definition
     tmPktDef = SUPP.IF.s_definitions.getTMpktDefBySPID(spid)
     if tmPktDef == None:
         raise Error("invalid SPID for packet creation: " + str(spid))
     binarySize = tmPktDef.pktSPsize
     applicationProcessId = tmPktDef.pktAPID
     if reuse and spid in self.packetCache:
         # reuse a packet with the same definition from the cache
         packet = self.packetCache[spid]
         packet.setLen(binarySize)
         packet.setPacketLength()
     else:
         # create the TM packet
         if tmPktDef.pktHasDFhdr:
             # PUS packet
             serviceType = tmPktDef.pktType
             serviceSubType = tmPktDef.pktSType
             packet = self.getTMpacketHelper(binarySize,
                                             applicationProcessId,
                                             serviceType, serviceSubType)
             # initialise PI1 and PI2 if configured
             if tmPktDef.pktPI1val != None:
                 pi1BitPos = tmPktDef.pktPI1off * 8
                 pi1BitWidth = tmPktDef.pktPI1wid
                 pi1Value = tmPktDef.pktPI1val
                 packet.setBits(pi1BitPos, pi1BitWidth, pi1Value)
             if tmPktDef.pktPI2val != None:
                 pi2BitPos = tmPktDef.pktPI2off * 8
                 pi2BitWidth = tmPktDef.pktPI2wid
                 pi2Value = tmPktDef.pktPI2val
                 packet.setBits(pi2BitPos, pi2BitWidth, pi2Value)
         else:
             # CCSDS packet
             packet = self.getTMpacketHelper(binarySize,
                                             applicationProcessId)
         self.packetCache[spid] = packet
     # apply the segmentationFlags
     packet.segmentationFlags = segmentationFlags
     # apply the datafield
     if dataField:
         dataFieldOffset, dataFieldData = dataField
         minExpectedPacketSize = dataFieldOffset + len(dataFieldData)
         if tmPktDef.pktCheck:
             minExpectedPacketSize += CCSDS.DU.CRC_BYTE_SIZE
         # re-size the packet if needed
         if len(packet) < minExpectedPacketSize:
             binarySize = minExpectedPacketSize
             packet.setLen(binarySize)
             packet.setPacketLength()
         packet.setBytes(dataFieldOffset, len(dataFieldData), dataFieldData)
     ### apply the encoded tmStruct ###
     if tmStruct != None:
         #-- find the correct position for the data
         structBytePos = CCSDS.PACKET.PRIMARY_HEADER_BYTE_SIZE
         if tmPktDef.pktHasDFhdr:
             # PUS packet
             structBytePos += tmPktDef.pktDFHsize
         structBitPos = structBytePos << 3
         structEndBitPos = structBitPos + tmStruct.getBitWidth()
         structEndBytePos = (structEndBitPos + 7) >> 3
         #-- re-size the packet to exactly fit
         tmPacketSize = structEndBytePos
         if tmPktDef.pktCheck:
             tmPacketSize += CCSDS.DU.CRC_BYTE_SIZE
         binarySize = max(binarySize, tmPacketSize)
         packet.setLen(binarySize)
         packet.setPacketLength()
         #-- encode the struct
         tmStruct.encode(packet, structBitPos)
     # apply the parameters
     for paramNameValue in parameterValues:
         paramName, paramValue = paramNameValue
         # special handling for PUS service 1 parameters for TC acknowledgement
         if paramName == "PUS_TYPE1_APID":
             PUS.SERVICES.service1_setTCackAPID(packet, int(paramValue))
             continue
         if paramName == "PUS_TYPE1_SSC":
             PUS.SERVICES.service1_setTCackSSC(packet, int(paramValue))
             continue
         # search the definition of the parameter (TMparamExtraction)
         paramExtraction = tmPktDef.getParamExtraction(paramName)
         if paramExtraction == None:
             LOG_WARNING(
                 "packet with SPID " + str(spid) +
                 " does not have a parameter " + paramName, "SPACE")
         else:
             # apply the parameter value
             bitPos = paramExtraction.bitPos
             bitLength = paramExtraction.bitWidth
             valueType = paramExtraction.valueType
             if valueType == UTIL.DU.BITS:
                 packet.setBits(bitPos, bitLength, paramValue)
             elif valueType == UTIL.DU.SBITS:
                 packet.setSBits(bitPos, bitLength, paramValue)
             else:
                 bytePos = bitPos // 8
                 byteLength = bitLength // 8
                 if valueType == UTIL.DU.UNSIGNED:
                     packet.setUnsigned(bytePos, byteLength, paramValue)
                 elif valueType == UTIL.DU.SIGNED:
                     bytePos = bitPos // 8
                     byteLength = bitLength // 8
                     packet.setSigned(bytePos, byteLength, paramValue)
                 elif valueType == UTIL.DU.FLOAT:
                     bytePos = bitPos // 8
                     byteLength = bitLength // 8
                     packet.setFloat(bytePos, byteLength, paramValue)
                 else:
                     # TIME and other types are passed as string
                     # TODO: use specific encodings
                     bytePos = bitPos // 8
                     byteLength = bitLength // 8
                     packet.setString(bytePos, byteLength, paramValue)
     # re-calculate the time stamp
     if tmPktDef.pktHasDFhdr and self.packetDefaults.hasTmTT:
         if obtUTC == None:
             obtUTC = UTIL.TIME.getActualTime()
         obtTime = UTIL.TCO.correlateToOBTmissionEpoch(obtUTC)
         packet.setTimeTag(obtTime)
     # re-calculate the sequence counter (maintained per APID)
     if applicationProcessId in self.sequenceCounters:
         sequenceCounter = (self.sequenceCounters[applicationProcessId] +
                            1) % 16384
     else:
         sequenceCounter = 0
     packet.sequenceControlCount = sequenceCounter
     self.sequenceCounters[applicationProcessId] = sequenceCounter
     # re-calculate the CRC
     if tmPktDef.pktCheck:
         packet.setChecksum()
     return packet
예제 #20
0
 def getTMpacket(self,
                 spid,
                 parameterValues=[],
                 dataField=None,
                 segmentationFlags=CCSDS.PACKET.UNSEGMENTED,
                 obtUTC=None,
                 reuse=True):
     """
 creates a CCSDS TM packet with optional parameter values:
 implementation of SPACE.IF.TMpacketGenerator.getTMpacket
 """
     # fetch the packet definition
     tmPktDef = SPACE.IF.s_definitions.getTMpktDefBySPID(spid)
     if tmPktDef == None:
         raise Error("invalid SPID for packet creation: " + str(spid))
     binarySize = tmPktDef.pktSPsize
     applicationProcessId = tmPktDef.pktAPID
     if reuse and spid in self.packetCache:
         # reuse a packet with the same definition from the cache
         packet = self.packetCache[spid]
         packet.setLen(binarySize)
         packet.setPacketLength()
     else:
         # create the TM packet
         if tmPktDef.pktHasDFhdr:
             # PUS packet
             serviceType = tmPktDef.pktType
             serviceSubType = tmPktDef.pktSType
             packet = self.getTMpacketHelper(binarySize,
                                             applicationProcessId,
                                             serviceType, serviceSubType)
             # initialise PI1 and PI2 if configured
             if tmPktDef.pktPI1val != None:
                 pi1BitPos = tmPktDef.pktPI1off * 8
                 pi1BitWidth = tmPktDef.pktPI1wid
                 pi1Value = tmPktDef.pktPI1val
                 packet.setBits(pi1BitPos, pi1BitWidth, pi1Value)
             if tmPktDef.pktPI2val != None:
                 pi2BitPos = tmPktDef.pktPI2off * 8
                 pi2BitWidth = tmPktDef.pktPI2wid
                 pi2Value = tmPktDef.pktPI2val
                 packet.setBits(pi2BitPos, pi2BitWidth, pi2Value)
         else:
             # CCSDS packet
             packet = self.getTMpacketHelper(binarySize,
                                             applicationProcessId)
         self.packetCache[spid] = packet
     # apply the segmentationFlags
     packet.segmentationFlags = segmentationFlags
     # apply the datafield
     if dataField:
         dataFieldOffset, dataFieldData = dataField
         minExpectedPacketSize = dataFieldOffset + len(dataFieldData)
         if tmPktDef.pktCheck:
             minExpectedPacketSize += 2
         # re-size the packet if needed
         if len(packet) < minExpectedPacketSize:
             packet.setLen(minExpectedPacketSize)
             packet.setPacketLength()
         packet.setBytes(dataFieldOffset, len(dataFieldData), dataFieldData)
     # apply the parameters
     for paramNameValue in parameterValues:
         paramName, paramValue = paramNameValue
         # special handling for PUS service 1 parameters for TC acknowledgement
         if paramName == "PUS_TYPE1_APID":
             PUS.SERVICES.service1_setTCackAPID(packet, int(paramValue))
             continue
         if paramName == "PUS_TYPE1_SSC":
             PUS.SERVICES.service1_setTCackSSC(packet, int(paramValue))
             continue
         # search the definition of the parameter (TMparamExtraction)
         paramExtraction = tmPktDef.getParamExtraction(paramName)
         if paramExtraction == None:
             LOG_WARNING(
                 "packet with SPID " + str(spid) +
                 " does not have a parameter " + paramName, "SPACE")
         else:
             # apply the parameter value
             bitPos = paramExtraction.bitPos
             bitLength = paramExtraction.bitWidth
             isInteger = paramExtraction.isInteger
             if isInteger:
                 packet.setBits(bitPos, bitLength, paramValue)
             else:
                 bytePos = bitPos / 8
                 byteLength = bitLength / 8
                 packet.setString(bytePos, byteLength, paramValue)
     # re-calculate the time stamp
     if tmPktDef.pktHasDFhdr and self.hasTmTT:
         if obtUTC == None:
             obtUTC = UTIL.TIME.getActualTime()
         obtTime = UTIL.TCO.correlateToOBTmissionEpoch(obtUTC)
         packet.setTimeTag(obtTime)
     # re-calculate the sequence counter (maintained per APID)
     if applicationProcessId in self.sequenceCounters:
         sequenceCounter = (self.sequenceCounters[applicationProcessId] +
                            1) % 16384
     else:
         sequenceCounter = 0
     packet.sequenceControlCount = sequenceCounter
     self.sequenceCounters[applicationProcessId] = sequenceCounter
     # re-calculate the CRC
     if tmPktDef.pktCheck:
         packet.setChecksum()
     return packet