|
|
|
@@ -4,10 +4,15 @@ from pathlib import Path
|
|
|
|
|
from typing import cast
|
|
|
|
|
|
|
|
|
|
from spacepackets import SpacePacket, SpacePacketHeader
|
|
|
|
|
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
|
|
|
|
|
from spacepackets.cfdp import (
|
|
|
|
|
TransmissionModes,
|
|
|
|
|
ChecksumTypes,
|
|
|
|
|
TransmissionMode,
|
|
|
|
|
ChecksumType,
|
|
|
|
|
ConditionCode,
|
|
|
|
|
PduHolder,
|
|
|
|
|
DirectiveType,
|
|
|
|
|
PduFactory,
|
|
|
|
|
PduType,
|
|
|
|
|
)
|
|
|
|
|
from spacepackets.cfdp.pdu import MetadataPdu, FileDataPdu
|
|
|
|
|
from tmtccmd.cfdp import (
|
|
|
|
@@ -152,11 +157,20 @@ class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
|
|
|
|
|
self.handler = cfdp_in_ccsds_handler
|
|
|
|
|
|
|
|
|
|
def handle_tm(self, packet: bytes, _user_args: any):
|
|
|
|
|
ccsds_header_raw = packet[0:6]
|
|
|
|
|
sp_header = SpacePacketHeader.unpack(ccsds_header_raw)
|
|
|
|
|
pdu = packet[6:]
|
|
|
|
|
sp = SpacePacket(sp_header, sec_header=None, user_data=pdu)
|
|
|
|
|
self.handler.pass_packet(sp)
|
|
|
|
|
# Ignore the space packet header. Its only purpose is to use the same protocol and
|
|
|
|
|
# have a seaprate APID for space packets. If this function is called, the APID is correct.
|
|
|
|
|
pdu = packet[SPACE_PACKET_HEADER_SIZE:]
|
|
|
|
|
pdu_base = PduFactory.from_raw(pdu)
|
|
|
|
|
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 PusHandler(SpecificApidHandlerBase):
|
|
|
|
@@ -202,9 +216,11 @@ class TcHandler(TcHandlerBase):
|
|
|
|
|
seq_cnt_provider=seq_count_provider,
|
|
|
|
|
pus_verificator=pus_verificator,
|
|
|
|
|
)
|
|
|
|
|
self.cfdp_done = False
|
|
|
|
|
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):
|
|
|
|
|
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
|
|
|
|
|
if info.proc_type == TcProcedureType.DEFAULT:
|
|
|
|
@@ -248,35 +264,29 @@ class TcHandler(TcHandlerBase):
|
|
|
|
|
)
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.cfdp_handler.put_request(put_req)
|
|
|
|
|
self.cfdp_handler_started = True
|
|
|
|
|
(
|
|
|
|
|
pdu_holder,
|
|
|
|
|
packet,
|
|
|
|
|
) = self.cfdp_in_ccsds_wrapper.handler.pull_next_source_packet()
|
|
|
|
|
self.queue_helper.add_ccsds_tc(packet)
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
|
|
|
|
|
metadata = cast(MetadataPdu, pdu_holder.to_metadata_pdu())
|
|
|
|
|
self.queue_helper.add_log_cmd(
|
|
|
|
|
f"CFDP Source: Sending Metadata PDU for file with size {metadata.file_size}"
|
|
|
|
|
)
|
|
|
|
|
(
|
|
|
|
|
pdu_holder,
|
|
|
|
|
packet,
|
|
|
|
|
) = self.cfdp_in_ccsds_wrapper.handler.pull_next_source_packet()
|
|
|
|
|
fd_pdu = cast(FileDataPdu, pdu_holder.to_file_data_pdu())
|
|
|
|
|
self.queue_helper.add_ccsds_tc(packet)
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
|
|
|
|
|
self.queue_helper.add_log_cmd(
|
|
|
|
|
f"CFDP Source: Sending File Data PDU for segment at offset {fd_pdu.offset} "
|
|
|
|
|
f"with length {len(fd_pdu.file_data)}"
|
|
|
|
|
)
|
|
|
|
|
(
|
|
|
|
|
pdu_holder,
|
|
|
|
|
packet,
|
|
|
|
|
) = self.cfdp_in_ccsds_wrapper.handler.pull_next_source_packet()
|
|
|
|
|
self.queue_helper.add_log_cmd(f"CFDP Source: Sending EOF PDU")
|
|
|
|
|
self.queue_helper.add_ccsds_tc(packet)
|
|
|
|
|
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
|
|
|
|
|
for source_pair, dest_pair in self.cfdp_in_ccsds_wrapper.handler:
|
|
|
|
|
pdu, sp = source_pair
|
|
|
|
|
pdu = cast(PduHolder, pdu)
|
|
|
|
|
if pdu.is_file_directive:
|
|
|
|
|
if pdu.pdu_directive_type == DirectiveType.METADATA_PDU:
|
|
|
|
|
metadata = pdu.to_metadata_pdu()
|
|
|
|
|
self.queue_helper.add_log_cmd(
|
|
|
|
|
f"CFDP Source: Sending Metadata PDU for file with size "
|
|
|
|
|
f"{metadata.file_size}"
|
|
|
|
|
)
|
|
|
|
|
elif pdu.pdu_directive_type == DirectiveType.EOF_PDU:
|
|
|
|
|
self.queue_helper.add_log_cmd(
|
|
|
|
|
f"CFDP Source: Sending EOF PDU"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
fd_pdu = pdu.to_file_data_pdu()
|
|
|
|
|
self.queue_helper.add_log_cmd(
|
|
|
|
|
f"CFDP Source: Sending File Data PDU for segment at offset "
|
|
|
|
|
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
|
|
|
|
|
)
|
|
|
|
|
self.queue_helper.add_ccsds_tc(sp)
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
|
|
|
|
|
self.cfdp_in_ccsds_wrapper.handler.source_handler.state_machine()
|
|
|
|
|
|
|
|
|
|
def send_cb(self, params: SendCbParams):
|
|
|
|
@@ -317,7 +327,7 @@ class TcHandler(TcHandlerBase):
|
|
|
|
|
)
|
|
|
|
|
elif info.proc_type == TcProcedureType.CFDP:
|
|
|
|
|
LOGGER.info(f"Finished CFDP queue")
|
|
|
|
|
self.cfdp_done = True
|
|
|
|
|
self.cfdp_sending_done = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setup_params(hook_obj: TmTcCfgHookBase) -> SetupWrapper:
|
|
|
|
@@ -343,12 +353,7 @@ def setup_params(hook_obj: TmTcCfgHookBase) -> SetupWrapper:
|
|
|
|
|
return setup_wrapper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setup_tmtc_handlers(
|
|
|
|
|
verif_wrapper: VerificationWrapper,
|
|
|
|
|
printer: FsfwTmTcPrinter,
|
|
|
|
|
raw_logger: RawTmtcTimedLogWrapper,
|
|
|
|
|
) -> (CcsdsTmHandler, TcHandler):
|
|
|
|
|
|
|
|
|
|
def setup_cfdp_handler() -> CfdpInCcsdsWrapper:
|
|
|
|
|
fh_base = ExampleCfdpFaultHandler()
|
|
|
|
|
cfdp_cfg = LocalEntityCfg(
|
|
|
|
|
local_entity_id=CFDP_LOCAL_ENTITY_ID,
|
|
|
|
@@ -361,8 +366,8 @@ def setup_tmtc_handlers(
|
|
|
|
|
max_file_segment_len=1024,
|
|
|
|
|
check_limit=None,
|
|
|
|
|
crc_on_transmission=False,
|
|
|
|
|
crc_type=ChecksumTypes.CRC_32,
|
|
|
|
|
default_transmission_mode=TransmissionModes.UNACKNOWLEDGED,
|
|
|
|
|
crc_type=ChecksumType.CRC_32,
|
|
|
|
|
default_transmission_mode=TransmissionMode.UNACKNOWLEDGED,
|
|
|
|
|
)
|
|
|
|
|
cfdp_seq_count_provider = FileSeqCountProvider(
|
|
|
|
|
max_bit_width=16, file_name=Path("seqcnt_cfdp_transaction.txt")
|
|
|
|
@@ -379,13 +384,21 @@ def setup_tmtc_handlers(
|
|
|
|
|
cfdp_seq_cnt_provider=cfdp_seq_count_provider,
|
|
|
|
|
user=cfdp_user,
|
|
|
|
|
)
|
|
|
|
|
cfdp_in_ccsds_wrapper = CfdpInCcsdsWrapper(cfdp_in_ccsds_handler)
|
|
|
|
|
return CfdpInCcsdsWrapper(cfdp_in_ccsds_handler)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setup_tmtc_handlers(
|
|
|
|
|
verif_wrapper: VerificationWrapper,
|
|
|
|
|
printer: FsfwTmTcPrinter,
|
|
|
|
|
raw_logger: RawTmtcTimedLogWrapper,
|
|
|
|
|
) -> (CcsdsTmHandler, TcHandler):
|
|
|
|
|
cfdp_in_ccsds_wrapper = setup_cfdp_handler()
|
|
|
|
|
pus_handler = PusHandler(
|
|
|
|
|
printer=printer, raw_logger=raw_logger, wrapper=verif_wrapper
|
|
|
|
|
)
|
|
|
|
|
ccsds_handler = CcsdsTmHandler(None)
|
|
|
|
|
ccsds_handler.add_apid_handler(pus_handler)
|
|
|
|
|
ccsds_handler.add_apid_handler(cfdp_in_ccsds_wrapper)
|
|
|
|
|
tc_handler = TcHandler(
|
|
|
|
|
file_logger=printer.file_logger,
|
|
|
|
|
raw_logger=raw_logger,
|
|
|
|
|