add support for closure handling #119
@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="CFDP Test File Small" type="PythonConfigurationType" factoryName="Python" folderName="CFDP">
|
<configuration default="false" name="CFDP Test File Small No Closure" type="PythonConfigurationType" factoryName="Python" folderName="CFDP">
|
||||||
<module name="tmtc" />
|
<module name="tmtc" />
|
||||||
<option name="INTERPRETER_OPTIONS" value="" />
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
<option name="PARENT_ENVS" value="true" />
|
<option name="PARENT_ENVS" value="true" />
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtcc.py" />
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tmtcc.py" />
|
||||||
<option name="PARAMETERS" value="cfdp filetest/cfdp_test.txt /tmp/cfdp_test.txt -d 0.2" />
|
<option name="PARAMETERS" value="cfdp filetest/cfdp_test.txt /tmp/cfdp_test.txt --no-closure -d 0.2" />
|
||||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
<option name="EMULATE_TERMINAL" value="false" />
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
<option name="MODULE_MODE" value="false" />
|
<option name="MODULE_MODE" value="false" />
|
@ -6,11 +6,18 @@
|
|||||||
|
|
||||||
import enum
|
import enum
|
||||||
|
|
||||||
|
from spacepackets import PacketType
|
||||||
|
from spacepackets.ccsds import PacketId
|
||||||
from spacepackets.util import UnsignedByteField
|
from spacepackets.util import UnsignedByteField
|
||||||
|
|
||||||
PUS_APID = 0x65
|
PUS_APID = 0x65
|
||||||
SPACE_PACKET_IDS = (0x08 << 8 | PUS_APID,)
|
|
||||||
CFDP_APID = 0x66
|
CFDP_APID = 0x66
|
||||||
|
PUS_PACKET_ID = PacketId(PacketType.TM, True, PUS_APID)
|
||||||
|
CFDP_PACKET_ID = PacketId(PacketType.TM, False, CFDP_APID)
|
||||||
|
SPACE_PACKET_IDS = (
|
||||||
|
PUS_PACKET_ID.raw(),
|
||||||
|
CFDP_PACKET_ID.raw(),
|
||||||
|
)
|
||||||
|
|
||||||
CFDP_LOCAL_ENTITY_ID = UnsignedByteField(byte_len=2, val=1)
|
CFDP_LOCAL_ENTITY_ID = UnsignedByteField(byte_len=2, val=1)
|
||||||
CFDP_REMOTE_ENTITY_ID = UnsignedByteField(byte_len=2, val=CFDP_APID)
|
CFDP_REMOTE_ENTITY_ID = UnsignedByteField(byte_len=2, val=CFDP_APID)
|
||||||
|
2
deps/tmtccmd
vendored
2
deps/tmtccmd
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 229a2b5032b0c1becd93fe37f34ddc93a6b425c4
|
Subproject commit f3c9501891b582f5b4c61aec5eb939d05a2e24d2
|
@ -20,8 +20,13 @@ from pus_tm.devs.gps import handle_gps_data
|
|||||||
from pus_tm.devs.gyros import handle_gyros_hk_data
|
from pus_tm.devs.gyros import handle_gyros_hk_data
|
||||||
from tmtc.power.tm import handle_pdu_data, handle_p60_hk_data, handle_acu_hk_data
|
from tmtc.power.tm import handle_pdu_data, handle_p60_hk_data, handle_acu_hk_data
|
||||||
from pus_tm.devs.syrlinks import handle_syrlinks_hk_data
|
from pus_tm.devs.syrlinks import handle_syrlinks_hk_data
|
||||||
from tmtc.acs.imtq import ImtqSetIds, handle_self_test_data, handle_eng_set, \
|
from tmtc.acs.imtq import (
|
||||||
handle_calibrated_mtm_measurement, handle_raw_mtm_measurement
|
ImtqSetIds,
|
||||||
|
handle_self_test_data,
|
||||||
|
handle_eng_set,
|
||||||
|
handle_calibrated_mtm_measurement,
|
||||||
|
handle_raw_mtm_measurement,
|
||||||
|
)
|
||||||
from pus_tm.defs import FsfwTmTcPrinter
|
from pus_tm.defs import FsfwTmTcPrinter
|
||||||
from pus_tm.system.core import handle_core_hk_data
|
from pus_tm.system.core import handle_core_hk_data
|
||||||
from pus_tm.devs.mgms import handle_mgm_hk_data
|
from pus_tm.devs.mgms import handle_mgm_hk_data
|
||||||
|
31
tmtcc.py
31
tmtcc.py
@ -7,12 +7,15 @@ from pathlib import Path
|
|||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from spacepackets import SpacePacketHeader, SpacePacket
|
from spacepackets import SpacePacketHeader, SpacePacket
|
||||||
|
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
|
||||||
from spacepackets.cfdp import (
|
from spacepackets.cfdp import (
|
||||||
ConditionCode,
|
ConditionCode,
|
||||||
ChecksumType,
|
ChecksumType,
|
||||||
TransmissionMode,
|
TransmissionMode,
|
||||||
PduHolder,
|
PduHolder,
|
||||||
DirectiveType,
|
DirectiveType,
|
||||||
|
PduFactory,
|
||||||
|
PduType,
|
||||||
)
|
)
|
||||||
from tmtccmd.cfdp import CfdpUserBase, TransactionId
|
from tmtccmd.cfdp import CfdpUserBase, TransactionId
|
||||||
from tmtccmd.cfdp.defs import CfdpRequestType
|
from tmtccmd.cfdp.defs import CfdpRequestType
|
||||||
@ -182,11 +185,20 @@ class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
|
|||||||
self.handler = cfdp_in_ccsds_handler
|
self.handler = cfdp_in_ccsds_handler
|
||||||
|
|
||||||
def handle_tm(self, packet: bytes, _user_args: any):
|
def handle_tm(self, packet: bytes, _user_args: any):
|
||||||
ccsds_header_raw = packet[0:6]
|
# Ignore the space packet header. Its only purpose is to use the same protocol and
|
||||||
sp_header = SpacePacketHeader.unpack(ccsds_header_raw)
|
# have a seaprate APID for space packets. If this function is called, the APID is correct.
|
||||||
pdu = packet[6:]
|
pdu = packet[SPACE_PACKET_HEADER_SIZE:]
|
||||||
sp = SpacePacket(sp_header, sec_header=None, user_data=pdu)
|
pdu_base = PduFactory.from_raw(pdu)
|
||||||
self.handler.pass_packet(sp)
|
if pdu_base.pdu_type == PduType.FILE_DATA:
|
||||||
|
LOGGER.info("Received File Data PDU TM")
|
||||||
|
else:
|
||||||
|
if pdu_base.directive_type == DirectiveType.FINISHED_PDU:
|
||||||
|
LOGGER.info(f"Received Finished PDU TM")
|
||||||
|
else:
|
||||||
|
LOGGER.info(
|
||||||
|
f"Received File Directive PDU with type {pdu_base.directive_type!r} TM"
|
||||||
|
)
|
||||||
|
self.handler.pass_pdu_packet(pdu_base)
|
||||||
|
|
||||||
|
|
||||||
class TcHandler(TcHandlerBase):
|
class TcHandler(TcHandlerBase):
|
||||||
@ -207,7 +219,6 @@ class TcHandler(TcHandlerBase):
|
|||||||
self.file_logger = file_logger
|
self.file_logger = file_logger
|
||||||
self.raw_logger = raw_logger
|
self.raw_logger = raw_logger
|
||||||
self.gui = gui
|
self.gui = gui
|
||||||
self.cfdp_done = False
|
|
||||||
self.queue_helper = DefaultPusQueueHelper(
|
self.queue_helper = DefaultPusQueueHelper(
|
||||||
queue_wrapper=None,
|
queue_wrapper=None,
|
||||||
pus_apid=PUS_APID,
|
pus_apid=PUS_APID,
|
||||||
@ -216,6 +227,9 @@ class TcHandler(TcHandlerBase):
|
|||||||
)
|
)
|
||||||
self.cfdp_in_ccsds_wrapper = cfdp_in_ccsds_wrapper
|
self.cfdp_in_ccsds_wrapper = cfdp_in_ccsds_wrapper
|
||||||
|
|
||||||
|
def cfdp_done(self) -> bool:
|
||||||
|
return not self.cfdp_in_ccsds_wrapper.handler.put_request_pending()
|
||||||
|
|
||||||
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
|
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
|
||||||
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
|
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
|
||||||
if info.proc_type == TcProcedureType.DEFAULT:
|
if info.proc_type == TcProcedureType.DEFAULT:
|
||||||
@ -298,7 +312,6 @@ class TcHandler(TcHandlerBase):
|
|||||||
)
|
)
|
||||||
elif info.proc_type == TcProcedureType.CFDP:
|
elif info.proc_type == TcProcedureType.CFDP:
|
||||||
LOGGER.info(f"Finished CFDP queue")
|
LOGGER.info(f"Finished CFDP queue")
|
||||||
self.cfdp_done = True
|
|
||||||
|
|
||||||
|
|
||||||
def setup_params() -> SetupWrapper:
|
def setup_params() -> SetupWrapper:
|
||||||
@ -423,12 +436,16 @@ def main():
|
|||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
state = tmtc_backend.periodic_op(None)
|
state = tmtc_backend.periodic_op(None)
|
||||||
|
tc_handler.cfdp_in_ccsds_wrapper.handler.fsm()
|
||||||
if state.request == BackendRequest.TERMINATION_NO_ERROR:
|
if state.request == BackendRequest.TERMINATION_NO_ERROR:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
elif state.request == BackendRequest.DELAY_IDLE:
|
elif state.request == BackendRequest.DELAY_IDLE:
|
||||||
LOGGER.info("TMTC Client in IDLE mode")
|
LOGGER.info("TMTC Client in IDLE mode")
|
||||||
time.sleep(3.0)
|
time.sleep(3.0)
|
||||||
elif state.request == BackendRequest.DELAY_LISTENER:
|
elif state.request == BackendRequest.DELAY_LISTENER:
|
||||||
|
if tc_handler.cfdp_done():
|
||||||
|
LOGGER.info("CFDP transaction done, closing client")
|
||||||
|
sys.exit(0)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
elif state.request == BackendRequest.DELAY_CUSTOM:
|
elif state.request == BackendRequest.DELAY_CUSTOM:
|
||||||
if state.next_delay.total_seconds() < 0.5:
|
if state.next_delay.total_seconds() < 0.5:
|
||||||
|
Loading…
Reference in New Issue
Block a user