def sendTCackNak(self, ccsdsTCpacketDU, okStatus): """Send a TC ACK or NAK as response to a CCSDSC TC packet to the CCS""" # format the response message according to the ccsdsTCpacketDU if EGSE.IF.s_serverConfiguration.egseAck2 == EGSE.IF.ENABLE_ACK: # normal processing if okStatus: LOG_INFO("CNC.TCserver.sendTCackNak(ACK)") else: LOG_ERROR("CNC.TCserver.sendTCackNak(NAK)") elif EGSE.IF.s_serverConfiguration.egseAck2 == EGSE.IF.ENABLE_NAK: LOG_WARNING("force TC NAK") okStatus = False else: LOG_WARNING("suppress TC ACK/NAK") return apid = ccsdsTCpacketDU.applicationProcessId ssc = ccsdsTCpacketDU.sequenceControlCount tcAckNakDU = EGSE.CNCPDU.TCackNak() # set TM packet header info tcAckNakDU.sequenceControlCount = self.tcAckNakSSC self.tcAckNakSSC = (self.tcAckNakSSC + 1) % 16384 if okStatus: tcAckNakDU.setACK() else: tcAckNakDU.setNAK() setTCackNakAPID(tcAckNakDU, apid) setTCackNakSSC(tcAckNakDU, ssc) # send the ACK/NAK response over the TC link # note: if the ACK/NAK response shall be sent over the TM link, then the # use the following: EGSE.IF.s_ccsLink.pushTMpacket(tcAckNakDU) self.send(tcAckNakDU.getBuffer())
def notifyTCpacketDataUnit(self, tcPktDu): """AD packet / BD segment received""" # send UV ACCEPT confirmation if GRND.IF.s_configuration.grndAck1 == GRND.IF.ENABLE_ACK: LOG_INFO("generate ACK1 (TC_ACK_UV_ACCEPT_CONFIRM)") self.sendResponseDataUnit(tcPktDu, GRND.NCTRSDU.TC_ACK_UV_ACCEPT_CONFIRM) elif GRND.IF.s_configuration.grndAck1 == GRND.IF.ENABLE_NAK: LOG_WARNING("generate NAK1 (TC_ACK_UV_ACCEPT_FAILURE)") self.sendResponseDataUnit(tcPktDu, GRND.NCTRSDU.TC_ACK_UV_ACCEPT_FAILURE) else: LOG_WARNING("suppress ACK1 (TC_ACK_UV_ACCEPT_CONFIRM)") # send UV TRANSMIT confirmation if GRND.IF.s_configuration.grndAck2 == GRND.IF.ENABLE_ACK: LOG_INFO("generate ACK2 (TC_ACK_UV_TRANSMIT_CONFIRM)") self.sendResponseDataUnit(tcPktDu, GRND.NCTRSDU.TC_ACK_UV_TRANSMIT_CONFIRM) elif GRND.IF.s_configuration.grndAck2 == GRND.IF.ENABLE_NAK: LOG_ERROR("generate NAK2 (TC_ACK_UV_TRANSMIT_FAILURE)") self.sendResponseDataUnit(tcPktDu, GRND.NCTRSDU.TC_ACK_UV_TRANSMIT_FAILURE) else: LOG_WARNING("suppress ACK2 (TC_ACK_UV_TRANSMIT_CONFIRM)") # send UV TRANSFER confirmation # this verification stage does not provide ENABLE/DISABLE LOG_INFO("generate ACK3 (TC_ACK_UV_TRANSFER_CONFIRM)") self.sendResponseDataUnit(tcPktDu, GRND.NCTRSDU.TC_ACK_UV_TRANSFER_CONFIRM) # extract the TC packet from the NCTRS TC packet data unit try: packetData = tcPktDu.getTCpacket() except Exception, ex: self.notifyError("TC packet extraction failed", ex) return
def setPacketDataCmd(self, argv, extraData): """Decoded setPacketData command""" self.logMethod("setPacketDataCmd", "SPACE") # consistency check if len(argv) != 2 and len(argv) != 4: LOG_WARNING("invalid parameters passed for setPacketData", "SPACE") return False # extract the arguments pktMnemonic = argv[1] if len(argv) == 2: params = "" values = "" else: params = argv[2] values = argv[3] tmStruct = extraData # check the packet data tmPacketData = SUPP.IF.s_definitions.getTMpacketInjectData(pktMnemonic, params, values, tmStruct) if tmPacketData == None: LOG_WARNING("invalid data passed for setPacketData", "SPACE") return False # initialise the packet data SPACE.IF.s_configuration.tmPacketData = tmPacketData LOG("Packet = " + SPACE.IF.s_configuration.tmPacketData.pktName, "SPACE") LOG("SPID = " + str(SPACE.IF.s_configuration.tmPacketData.pktSPID), "SPACE") LOG("Parameters and values = " + str(SPACE.IF.s_configuration.tmPacketData.parameterValuesList), "SPACE") # notify the GUI self.notifyGUItask("PACKETDATA_SET") return True
def sendCNCackNak(self, cncCommandDU, okStatus): """Send a CnC ACK or NAK as response to a CnC TC packet to the CCS""" # format the response message according to the cncCommandDU # TODO: the recent implementation does not consider specific CnC messages # but simply appends the message to the ACK/NAK token if EGSE.IF.s_serverConfiguration.egseAck2 == EGSE.IF.ENABLE_ACK: # normal processing if okStatus: LOG_INFO("CNC.TCserver.sendCNCackNak(ACK)") else: LOG_ERROR("CNC.TCserver.sendCNCackNak(NAK)") elif EGSE.IF.s_serverConfiguration.egseAck2 == EGSE.IF.ENABLE_NAK: LOG_WARNING("force CnC NAK") okStatus = False else: LOG_WARNING("suppress CNC ACK/NAK") return apid = cncCommandDU.applicationProcessId ssc = cncCommandDU.sequenceControlCount cncMessage = cncCommandDU.getCNCmessage() if okStatus: responseMessage = "ACK " + cncMessage else: responseMessage = "NAK " + cncMessage cncAckNakDU = EGSE.CNCPDU.CNCackNak() cncAckNakDU.applicationProcessId = apid cncAckNakDU.sequenceControlCount = ssc cncAckNakDU.segmentationFlags = CCSDS.PACKET.UNSEGMENTED cncAckNakDU.setCNCmessage(responseMessage) # send the ACK/NAK response over the TC link self.send(cncAckNakDU.getBuffer())
def notifyTCcltuDataUnit(self, tcCltuDu): """CLTU received""" # send UV ACCEPT confirmation if GRND.IF.s_configuration.grndAck1 == GRND.IF.ENABLE_ACK: LOG_INFO("generate ACK1 (TC_ACK_UV_ACCEPT_CONFIRM)") self.sendResponseDataUnit(tcCltuDu, GRND.NCTRSDU.TC_ACK_UV_ACCEPT_CONFIRM) elif GRND.IF.s_configuration.grndAck1 == GRND.IF.ENABLE_NAK: LOG_WARNING("generate NAK1 (TC_ACK_UV_ACCEPT_FAILURE)") self.sendResponseDataUnit(tcCltuDu, GRND.NCTRSDU.TC_ACK_UV_ACCEPT_FAILURE) else: LOG_WARNING("suppress ACK1 (TC_ACK_UV_ACCEPT_CONFIRM)") # send UV TRANSMIT confirmation if GRND.IF.s_configuration.grndAck2 == GRND.IF.ENABLE_ACK: LOG_INFO("generate ACK2 (TC_ACK_UV_TRANSMIT_CONFIRM)") self.sendResponseDataUnit(tcCltuDu, GRND.NCTRSDU.TC_ACK_UV_TRANSMIT_CONFIRM) elif GRND.IF.s_configuration.grndAck2 == GRND.IF.ENABLE_NAK: LOG_ERROR("generate NAK2 (TC_ACK_UV_TRANSMIT_FAILURE)") self.sendResponseDataUnit(tcCltuDu, GRND.NCTRSDU.TC_ACK_UV_TRANSMIT_FAILURE) else: LOG_WARNING("suppress ACK2 (TC_ACK_UV_TRANSMIT_CONFIRM)") # extract the CLTU from the NCTRS CLTU data unit try: cltu = tcCltuDu.getCltu() except Exception as ex: self.notifyError("CLTU extraction failed", ex) return self.notifyCltu(cltu)
def sendPacketCmd(self, argv, extraData): """Decoded sendPacket command""" self.logMethod("sendPacketCmd", "TC") # consistency check if len(argv) != 1 and len(argv) != 3: LOG_WARNING("invalid parameters passed for sendPacket", "TC") return False # extract the arguments if len(argv) == 1: if MC.IF.s_configuration.tcPacketData == None: LOG_WARNING("packet data not initialised", "TC") return False tcPacketData = MC.IF.s_configuration.tcPacketData else: pktMnemonic = argv[1] route = argv[2] tcStruct = extraData # check the packet data tcPacketData = SPACE.IF.s_definitions.getTCpacketInjectData( pktMnemonic, route, tcStruct) if tcPacketData == None: LOG_WARNING("invalid data passed for sendPacket", "TC") return False # send the packet try: MC.IF.s_tcModel.generateTCpacket(tcPacketData) except Exception as ex: LOG_WARNING("cannot send packet: " + str(ex), "TC") return False return True
def setPacketDataCmd(self, argv, extraData): """Decoded setPacketData command""" self.logMethod("setPacketDataCmd", "TC") # consistency check if len(argv) != 3: LOG_WARNING("invalid parameters passed for setPacketData", "TC") return False # extract the arguments pktMnemonic = argv[1] route = argv[2] tcStruct = extraData # check the packet data tcPacketData = SPACE.IF.s_definitions.getTCpacketInjectData( pktMnemonic, route, tcStruct) if tcPacketData == None: LOG_WARNING("invalid data passed for setPacketData", "TC") return False # initialise the packet data MC.IF.s_configuration.tcPacketData = tcPacketData LOG("Packet = " + MC.IF.s_configuration.tcPacketData.pktName, "TC") # notify the GUI self.notifyGUItask("PACKETDATA_SET") return True
def sendTCackNak(self, ccsdsTCpacketDU, okStatus): """Send a TC ACK or NAK as response to a CCSDSC TC packet to the CCS""" # format the response message according to the ccsdsTCpacketDU if EGSE.IF.s_configuration.egseAck2 == EGSE.IF.ENABLE_ACK: # normal processing if okStatus: LOG_INFO("CNC.TCserver.sendTCackNak(ACK)") else: LOG_ERROR("CNC.TCserver.sendTCackNak(NAK)") elif EGSE.IF.s_configuration.egseAck2 == EGSE.IF.ENABLE_NAK: LOG_WARNING("force TC NAK") okStatus = False else: LOG_WARNING("suppress TC ACK/NAK") return apid = ccsdsTCpacketDU.applicationProcessId ssc = ccsdsTCpacketDU.sequenceControlCount tcAckNakDU = EGSE.CNCPDU.TCackNak() if okStatus: tcAckNakDU.setACK() else: tcAckNakDU.setNAK() PUS.SERVICES.service1_setTCackAPID(tcAckNakDU, apid) PUS.SERVICES.service1_setTCackSSC(tcAckNakDU, ssc) self.dataSocket.send(tcAckNakDU.getBufferString())
def processTCpacket(self, tcPacketDu): """ processes a telecommand C&C packet from the CCS implementation of SPACE.IF.ApplicationSoftware.processTCpacket """ apid = tcPacketDu.applicationProcessId LOG_INFO("EUCLIDpowerFEEsim_BS.processTCpacket(" + str(apid) + ")", "SPACE") # packet is a PUS Function Management command if tcPacketDu.serviceType == PUS.SERVICES.TC_FKT_TYPE: if tcPacketDu.serviceSubType == PUS.SERVICES.TC_FKT_PERFORM_FUNCTION: tcFunctionId = tcPacketDu.getUnsigned( self.tcFunctionIdBytePos, self.tcFunctionIdByteSize) LOG("tcFunctionId = " + str(tcFunctionId), "SPACE") if tcFunctionId == BS_Initialize: LOG_INFO("*** BS_Initialize ***", "SPACE") LOG("push HKTM", "SPACE") return self.sendBS_Monitor() elif tcFunctionId == BS_SetLocal: LOG_INFO("*** BS_SetLocal ***", "SPACE") LOG("set the SCOE into the LOCAL commanding mode", "SPACE") self.commandingMode = EPWR_CMD_LOCAL elif tcFunctionId == BS_SetRemote: LOG_INFO("*** BS_SetRemote ***", "SPACE") LOG("set the SCOE into the REMOTE commanding mode", "SPACE") self.commandingMode = EPWR_CMD_REMOTE elif tcFunctionId == BS_LockInstruments: LOG_INFO("*** BS_LockInstruments ***", "SPACE") LOG("not used for simulation", "SPACE") elif tcFunctionId == BS_UnlockInstruments: LOG_INFO("*** BS_UnlockInstruments ***", "SPACE") LOG("not used for simulation", "SPACE") elif tcFunctionId == BS_SetOnline: LOG_INFO("*** BS_SetOnline ***", "SPACE") LOG("set the SCOE into the ONLINE operation mode", "SPACE") self.operationMode = EPWR_OP_ONLINE return self.sendBS_Monitor() elif tcFunctionId == BS_SetOffline: LOG_INFO("*** BS_SetOffline ***", "SPACE") LOG("set the SCOE into the OFFLINE operation mode", "SPACE") self.operationMode = EPWR_OP_OFFLINE return self.sendBS_Monitor() elif tcFunctionId == BS_SelfTest: LOG_INFO("*** BS_SelfTest ***", "SPACE") # the SELFTEST is only allowed in OFFLINE mode if self.operationMode == EPWR_OP_ONLINE: LOG_ERROR("SELFTEST not allowed when system is ONLINE", "SPACE") return False else: # unexpected Function ID LOG_WARNING( "no simulation for Function ID " + str(tcFunctionId) + " implemented", "SPACE") return True LOG_WARNING("TC ignored by simulation", "SPACE") return True
def stopPacketRecorderCmd(self, argv): """Decoded stopPacketRecorder command""" self.logMethod("stopPacketRecorderCmd", "SPACE") # consistency check if not SUPP.IF.s_tmRecorder.isRecording(): LOG_WARNING("Packet recording not started", "SPACE") return False if len(argv) != 1: LOG_WARNING("invalid parameters passed for stopPacketRecorder", "SPACE") return False SUPP.IF.s_tmRecorder.stopRecording(); return True
def createTmVarParamDef(self, paramName, pcfMap): isReadOnly = False try: pcfRecord = pcfMap[paramName] paramPtc = pcfRecord.pcfPtc paramPfc = pcfRecord.pcfPfc try: paramType = getValueType(paramPtc, paramPfc) bitWidth = getBitWidth(paramPtc, paramPfc) defaultValue = pcfRecord.pcfParVal if defaultValue == "" and UTIL.DU.isNumber(paramType): defaultValue = 0 except Exception as ex: # inconsistency LOG_WARNING( "param " + paramName + ": " + str(ex) + " ---> dummy type", "SPACE") paramType = UTIL.DU.UNSIGNED bitWidth = 8 defaultValue = 0 except: LOG_WARNING( "TM param name " + paramName + " not found in pcf.dat ---> dummy param", "SPACE") paramName = "dummy" paramType = UTIL.DU.UNSIGNED bitWidth = 8 defaultValue = 0 # special handling of time parameters if paramType == UTIL.DU.TIME: # TODO: differentiate between absolute and relative time try: timeFormat = getTimeFormat(paramPfc) return PUS.VP.TimeParamDef(paramName, timeFormat, defaultValue, isReadOnly) except Exception as ex: # inconsistency LOG_WARNING( "param " + paramName + ": " + str(ex) + " ---> dummy type", "SPACE") paramType = UTIL.DU.UNSIGNED bitWidth = 8 defaultValue = 0 # special handling of variable size parameters if bitWidth == 0: # TODO: consider also information in the MIB lengthBytes = self.tmParamLengthBytes return PUS.VP.VariableParamDef(paramName, paramType, lengthBytes, defaultValue, isReadOnly) # default handling of normal parameters return PUS.VP.SimpleParamDef(paramName, paramType, bitWidth, defaultValue, isReadOnly)
def recordPacketsCmd(self, argv): """Decoded recordPackets command""" self.logMethod("recordPacketsCmd", "SPACE") # consistency check if SUPP.IF.s_tmRecorder.isRecording(): LOG_WARNING("Packet recording already started", "SPACE") return False if len(argv) != 2: LOG_WARNING("invalid parameters passed for recordPackets", "SPACE") return False # extract the arguments recordFileName = argv[1] SUPP.IF.s_tmRecorder.startRecording(recordFileName); return True
def generateAcksFromTCpacket(self, tcPacketDu, ack1, ack2, ack3, ack4): """ generates a TC acknowledgements according to PUS service 1: implementation of SPACE.IF.OnboardComputer.generateAcksFromTCpacket """ ok = True tcAPID = str(tcPacketDu.applicationProcessId) tcSSC = str(tcPacketDu.sequenceControlCount) if ack1 == SPACE.IF.ENABLE_ACK: LOG_INFO("generate ACK1 (TC_ACK_ACCEPT_SUCC)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_ACCEPT_SUCC) elif ack1 == SPACE.IF.ENABLE_NAK: LOG_ERROR("generate NAK1 (TC_ACK_ACCEPT_FAIL)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_ACCEPT_FAIL) else: LOG_WARNING("suppress ACK1 (TC_ACK_ACCEPT_SUCC)", "SPACE") if ack2 == SPACE.IF.ENABLE_ACK: LOG_INFO("generate ACK2 (TC_ACK_EXESTA_SUCC)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXESTA_SUCC) elif ack2 == SPACE.IF.ENABLE_NAK: LOG_ERROR("generate NAK2 (TC_ACK_EXESTA_FAIL)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXESTA_FAIL) else: LOG_WARNING("suppress ACK2 (TC_ACK_EXESTA_SUCC)", "SPACE") if ack3 == SPACE.IF.ENABLE_ACK: LOG_INFO("generate ACK3 (TC_ACK_EXEPRO_SUCC)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXEPRO_SUCC) elif ack3 == SPACE.IF.ENABLE_NAK: LOG_ERROR("generate NAK3 (TC_ACK_EXEPRO_FAIL)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXEPRO_FAIL) else: LOG_WARNING("suppress ACK3 (TC_ACK_EXEPRO_SUCC)", "SPACE") if ack4 == SPACE.IF.ENABLE_ACK: LOG_INFO("generate ACK4 (TC_ACK_EXECUT_SUCC)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXECUT_SUCC) elif ack4 == SPACE.IF.ENABLE_NAK: LOG_ERROR("generate NAK4 (TC_ACK_EXECUT_FAIL)", "SPACE") ok &= self.generateAck(tcAPID, tcSSC, PUS.SERVICES.TC_ACK_EXECUT_FAIL) else: LOG_WARNING("suppress ACK4 (TC_ACK_EXECUT_SUCC)", "SPACE") return ok
def testCmd(self, argv): """Decoded test command""" self.logMethod("test", "SPACE") # consistency check if len(argv) != 2: LOG_WARNING("invalid parameters passed", "SPACE") return False # extract the arguments testMode = int(argv[1]) if testMode == 0: LOG_INFO("testmode set to nominal", "SPACE") else: LOG_WARNING("testmode set to " + str(testMode), "SPACE") SPACE.IF.s_testMode = testMode return True
def notifyCommand(self, argv, extraData): """Callback for processing the input arguments""" if len(argv) > 0: # decode the command cmd = argv[0].upper() if cmd == "H" or cmd == "HELP": self.helpCmd(argv) elif cmd == "Q" or cmd == "QUIT": self.quitCmd(argv) elif cmd == "P" or cmd == "PACKET1": self.packet1Cmd(argv) elif cmd == "B" or cmd == "PACKET2": self.packet2Cmd(argv) elif cmd == "F" or cmd == "FRAME": self.frameCmd(argv) elif cmd == "C" or cmd == "CLTU1": self.cltu1Cmd(argv) elif cmd == "Z" or cmd == "CLTU2": self.cltu2Cmd(argv) elif cmd == "D" or cmd == "DIRECTIVE": self.directiveCmd(argv) else: LOG_WARNING("Invalid command " + argv[0]) self.helpCmd([]) return 0
def __init__(self, pktSPID, pktMnemonic, params, values, tmStruct, dataField, segmentationFlags): """Initialisation with default data""" self.pktName = pktMnemonic self.pktSPID = pktSPID self.parameterValuesList = [] self.tmStruct = tmStruct self.dataField = dataField self.segmentationFlags = segmentationFlags if params == "" or values == "": return # there are parameter-names and parameter-values paramsLst = params.split(",") valuesLst = values.split(",") # both parts must match if len(paramsLst) != len(valuesLst): LOG_WARNING( "parameter-names or parameter-values have different size") return # create the return list for i in range(len(valuesLst)): param = paramsLst[i].strip().strip("{").strip("}") value = valuesLst[i].strip().strip("{").strip("}") if (len(param) > 0) and (len(value) > 0): self.parameterValuesList.append([param, value])
def createTMparamDef(self, pcfRecord, plfRecords, tmPktDefs): """creates a TM parameter definition""" paramPtc = pcfRecord.pcfPtc paramPfc = pcfRecord.pcfPfc # getBitWidth(...) can raise an exception --> it is catched by the caller bitWidth = getBitWidth(paramPtc, paramPfc) # consistency check OK tmParamDef = SPACE.IF.TMparamDef() tmParamDef.paramName = pcfRecord.pcfName.replace(" ", "_").replace( "&", "_").replace(".", "_").replace("-", "_") tmParamDef.paramDescr = pcfRecord.pcfDescr tmParamDef.paramPtc = paramPtc tmParamDef.paramPfc = paramPfc tmParamDef.bitWidth = bitWidth # related packets # This line has been commented due to problems with pickling and # unpickling (errornous unpickling of the whole definition data). # This backward reference from parameters to packets is not needed # in the existing implementation. #self.pktLinks = {} tmParamDef.minCommutations = 9999 tmParamDef.maxCommutations = 0 for plfRecord in plfRecords: spid = plfRecord.plfSPID if spid in tmPktDefs: # consistency check isBytePos = getIsBytePos(plfRecord) try: valueType = getValueType(paramPtc, paramPfc, isBytePos) except Exception as ex: # inconsistency LOG_WARNING( "param " + pcfRecord.pcfName + ": " + str(ex) + " ---> ignored", "SPACE") continue tmPktDef = tmPktDefs[spid] paramToPacket = SPACE.IF.TMparamToPkt() paramToPacket.paramDef = tmParamDef paramToPacket.valueType = valueType paramToPacket.pktDef = tmPktDef paramToPacket.pktSPID = plfRecord.plfSPID paramToPacket.locOffby = plfRecord.plfOffby paramToPacket.locOffbi = plfRecord.plfOffbi paramToPacket.locNbocc = plfRecord.plfNbocc paramToPacket.locLgocc = plfRecord.plfLgocc tmParamDef.minCommutations = min(paramToPacket.locNbocc, tmParamDef.minCommutations) tmParamDef.maxCommutations = max(paramToPacket.locNbocc, tmParamDef.maxCommutations) tmPktDef.appendParamLink(paramToPacket) # This line has been commented due to problems with pickling and # unpickling (errornous unpickling of the whole definition data). # This backward reference from parameters to packets is not needed # in the existing implementation. #self.pktLinks[spid] = paramToPacket tmParamDef.minCommutations = min(tmParamDef.minCommutations, tmParamDef.maxCommutations) tmParamDef.maxCommutations = max(tmParamDef.minCommutations, tmParamDef.maxCommutations) return tmParamDef
def selfTest(self, bus): LOG_INFO("MILbusRemoteTerminalsImpl.selfTest", "MIL") if SPACE.IF.s_testMode == SELFTEST_RT_ERROR or \ SPACE.IF.s_testMode == SELFTEST_BC_RT_ERROR: LOG_WARNING("inject error", "MIL") return False return True
def tcpDataCallback(self, socket, stateMask): """Callback when a TCP/IP client (e.g. TECO) has send a command""" # read the next set of byte from stdin tcpLineBuffer = self.tcpLineBuffer try: tcpLineBuffer += self.clientSocket.recv(LINEBUFFERLEN).decode( "ascii") LOG("tcpLineBuffer: " + tcpLineBuffer) except: # read failed self.disconnected() return # handle the input: extract the lines from the line buffer lines = tcpLineBuffer.split("\n") # the last line has to be handled in a special way and can not be # processed directly lastLine = lines[-1] lines = lines[:-1] if lastLine == "": # read of the data was complete (incl. "\n") pass else: # last line was cutt off and the rest should come with the next read self.tcpLineBuffer = lastLine for line in lines: # remove a terminating "\r" for clients like telnet if line[-1] == "\r": line = line[:-1] # terminate the client connection if exit has been entered (case insensitive) upperLine = line.upper() if (upperLine == "X") or (upperLine == "EXIT"): LOG("exit requested") # set the OK response back to the TECO retString = "OK 0\n" try: self.clientSocket.send(retString.encode()) except: LOG_ERROR("send of OK response failed!") # terminate the client connection self.disconnected() return # delegate the input pstatus = self.processBuffer(line) if pstatus == 0: # send the OK response back to the TECO retString = "OK 0\n" try: self.clientSocket.send(retString.encode()) except: LOG_ERROR("send of OK response failed!") else: LOG_WARNING("return status = " + str(pstatus)) # set the Error response back to the TECO: retString = "Error: execution failed (see log)!\n" try: self.clientSocket.send(retString.encode()) except: LOG_ERROR("send of Error response failed!")
def getParamExtraction(self, paramName): """returns a parameter extraction of a related parameters""" if paramName not in self.paramLinks: return None paramToPacket = self.paramLinks[paramName] paramDef = paramToPacket.paramDef paramDescr = paramDef.paramDescr bitWidth = paramDef.bitWidth valueType = paramToPacket.valueType pktSPID = paramToPacket.pktSPID locOffby = paramToPacket.locOffby locOffbi = paramToPacket.locOffbi locNbocc = paramToPacket.locNbocc locLgocc = paramToPacket.locLgocc bitStartPos = locOffbi + (locOffby * 8) # check if a parameter commutation is qualified nameElements = paramName.split("#") if len(nameElements) == 1: # normal parameter paramExtraction = TMparamExtraction(bitStartPos, bitWidth, paramName, paramDescr, valueType) else: # supercommutated parameter commutation = int(nameElements[1]) if commutation < 1: LOG_WARNING( "param " + nameElements[0] + " has invalid commutation " + nameElements[1], "SPACE") return None bitPos = bitStartPos + (locLgocc * (commutation - 1)) paramExtraction = TMparamExtraction(bitPos, bitWidth, paramName, paramDescr, valueType) return paramExtraction
def notifyError(self, errorMessage, data): """error notification""" LOG_ERROR(errorMessage) try: LOG(str(data)) except Exception, ex: LOG_WARNING("data passed to notifyError are invalid: " + str(ex))
def sendAckCmd(self, argv): """Decoded sendAck command""" self.logMethod("sendAckCmd", "SPACE") # consistency check if len(argv) != 4: LOG_WARNING("invalid parameters passed for TC acknowledgement", "SPACE") return False # extract the arguments apid = int(argv[1]) ssc = int(argv[2]) subtypeStr = argv[3] if subtypeStr == "1": ackType = PUS.SERVICES.TC_ACK_ACCEPT_SUCC elif subtypeStr == "2": ackType = PUS.SERVICES.TC_ACK_ACCEPT_FAIL elif subtypeStr == "3": ackType = PUS.SERVICES.TC_ACK_EXESTA_SUCC elif subtypeStr == "4": ackType = PUS.SERVICES.TC_ACK_EXESTA_FAIL elif subtypeStr == "5": ackType = PUS.SERVICES.TC_ACK_EXEPRO_SUCC elif subtypeStr == "6": ackType = PUS.SERVICES.TC_ACK_EXEPRO_FAIL elif subtypeStr == "7": ackType = PUS.SERVICES.TC_ACK_EXECUT_SUCC elif subtypeStr == "8": ackType = PUS.SERVICES.TC_ACK_EXECUT_FAIL else: LOG_ERROR("invalid ackType for TC acknowledgement", "SPACE") return False SPACE.IF.s_onboardComputer.generateAck(apid, ssc, ackType); return True
def notifyTCframeCallback(self, frameDU): """notifies when the next TC frame is assembled""" # overloaded from TCencoder LOG("FrameModel.notifyTCframeCallback" + frameDU.getDumpString(), "FRAME") LOG_WARNING("frame cannot be directly sent, there is no NCTRS service", "FRAME")
def listPacketsCmd(self, argv): """Decoded listPackets command""" self.logMethod("listPacketsCmd", "SPACE") # consistency check if len(argv) != 1: LOG_WARNING("invalid parameters passed", "SPACE") return False # dump the packet definitions try: for tmPktDef in SPACE.IF.s_definitions.getTMpktDefs(): LOG( "TM: " + tmPktDef.pktName + " (SPID = " + str(tmPktDef.pktSPID) + ") - " + tmPktDef.pktDescr, "SPACE") for tcPktDef in SPACE.IF.s_definitions.getTCpktDefs(): LOG( "TC: " + tcPktDef.pktName + " (APID = " + str(tcPktDef.pktAPID) + ", TYPE = " + str(tcPktDef.pktType) + ", STPYE = " + str(tcPktDef.pktSType) + ") - " + tcPktDef.pktDescr, "SPACE") except Exception as ex: LOG_ERROR("MIB Error: " + str(ex), "SPACE") return False return True
def sendTc_eScoe(self, tcSpacePDU, telecommandEchoStatus): """Send a (TC_E,SCOE) PDU to the CCS""" if EGSE.IF.s_serverConfiguration.egseAck1 == EGSE.IF.ENABLE_ACK: # normal processing if telecommandEchoStatus == 0: LOG_INFO("EDEN.Server.sendTc_eScoe(OK)") else: LOG_ERROR("EDEN.Server.sendTc_eScoe(ERROR)") elif EGSE.IF.s_serverConfiguration.egseAck1 == EGSE.IF.ENABLE_NAK: LOG_WARNING("force ERROR for (TC_E,SCOE)") telecommandEchoStatus = 1 else: LOG_WARNING("suppress (TC_E,SCOE)") return tc_eScoePDU = EGSE.EDENPDU.TC_Escoe(tcSpacePDU.buffer) tc_eScoePDU.telecommandEchoStatus = telecommandEchoStatus self.sendPDU(tc_eScoePDU)
def tcScoeCmd(self, argv): """Decoded (TC,SCOE) command""" global s_client if len(argv) != 1: LOG_WARNING("Invalid command argument(s)") LOG("usage: tc_scoe") LOG("or: 2") return s_client.sendTcScoe(UnitTest.testData.TC_PACKET_01)
def tcSpaceCmd(self, argv): """Decoded (TC,SPACE) command""" global s_client if len(argv) != 1: LOG_WARNING("Invalid command argument(s)") LOG("usage: tc_space") LOG("or: 1") return s_client.sendTcSpace(testData.TC_PACKET_01)
def stopReplay(self): """stops reading NCTRS frames""" LOG_WARNING("stopReplay", "FRAME") self.running = False if self.nctrsFramesFile != None: self.nctrsFramesFile.close() self.nctrsFramesFile = None self.frameRateMs = None UTIL.TASK.s_processingTask.notifyGUItask("UPDATE_REPLAY")
def pushTMpacket(self, tmPacketDu, ertUTC): """ consumes a telemetry packet: implementation of MC.IF.TMmodel.pushTMpacket """ LOG_INFO("pushTMpacket", "TM") # other packet info LOG("APID = " + str(tmPacketDu.applicationProcessId), "TM") LOG("SSC = " + str(tmPacketDu.sequenceControlCount), "TM") if PUS.PACKET.isPUSpacketDU(tmPacketDu): # PUS packet object.__setattr__(tmPacketDu, "attributeMap2", PUS.PACKET.TM_PACKET_DATAFIELD_HEADER_ATTRIBUTES) LOG("TYPE = " + str(tmPacketDu.serviceType), "TM") LOG("SUBTYPE = " + str(tmPacketDu.serviceSubType), "TM") # the existence of a CRC for PUS packets is mission dependant # for SCOS-2000 compatibility we expect a CRC if not tmPacketDu.checkChecksum(): LOG_ERROR("invalid TM packet CRC", "TM") else: # CCSDS packet LOG("non-PUS packet", "TM") LOG("tmPacketDu = " + str(tmPacketDu), "TM") try: # try to decode the packet tmPacketKey = SUPP.IF.s_definitions.getTMpacketKey(tmPacketDu) LOG("KEY = " + str(tmPacketKey), "TM") tmPktDef = SUPP.IF.s_definitions.getTMpktDefBySPID(tmPacketKey) if tmPktDef == None: LOG_WARNING("packet cannot be identified - don't decode it", "TM") else: tmStructDef = tmPktDef.tmStructDef structBitPos = (CCSDS.PACKET.PRIMARY_HEADER_BYTE_SIZE + tmPktDef.pktDFHsize) << 3 tmStruct = PUS.VP.Struct(tmStructDef) tmStruct.decode(tmPacketDu, structBitPos) LOG("tmStruct =" + str(tmStruct), "TM") except Exception as ex: LOG_WARNING("packet cannot be decoded: " + str(ex), "TM") # processing of PUS telecommands if PUS.PACKET.isPUSpacketDU(tmPacketDu) and tmPacketDu.serviceType == PUS.SERVICES.TC_ACK_TYPE: # packet is a PUS TC Acknowledgement command MC.IF.s_tcModel.notifyTCack(tmPacketDu.serviceSubType) # forward the TM packet also to the TM recorder # where the packet is recorded on demand SUPP.IF.s_tmRecorder.pushTMpacket(tmPacketDu, ertUTC)
def cmdExecCmd(self, argv): """Decoded (CMD,EXEC) command""" global s_client if len(argv) != 2: LOG_WARNING("Invalid command argument(s)") LOG("usage: cmd_exec <message>") LOG("or: 3 <message>") return message = argv[1] s_client.sendCmdExec(message)