create CFDP components

This commit is contained in:
Robin Müller 2022-09-09 16:55:04 +02:00
parent aca667248c
commit 0d9b6b7086
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814

127
common.py
View File

@ -11,17 +11,27 @@ from spacepackets.cfdp import (
GenericPduPacket,
PduHolder,
PduFactory,
ChecksumTypes,
ConditionCode,
)
from tmtccmd.cfdp import (
RemoteEntityCfgTable,
RemoteEntityCfg,
LocalEntityCfg,
CfdpUserBase,
IndicationCfg,
TransactionId,
)
from spacepackets.util import UnsignedByteField
from tmtccmd.cfdp.defs import CfdpRequestType, CfdpStates
from tmtccmd.cfdp.handler import SourceHandler, DestHandler
from tmtccmd.cfdp.mib import DefaultFaultHandlerBase
from tmtccmd.cfdp.request import PutRequest, PutRequestCfg
from tmtccmd.cfdp.user import (
FileSegmentRecvdParams,
MetadataRecvParams,
TransactionFinishedParams,
)
from tmtccmd.logging import get_current_time_string
from tmtccmd.pus.pus_11_tc_sched import Subservices as Pus11Subservices
from tmtccmd.tc.queue import DefaultPusQueueHelper
@ -51,7 +61,12 @@ from common_tmtc.pus_tc.service_20_parameters import pack_service20_commands_int
from common_tmtc.pus_tc.service_2_raw_cmd import pack_service_2_commands_into
from common_tmtc.pus_tc.service_3_housekeeping import pack_service_3_commands_into
from common_tmtc.pus_tc.service_8_func_cmd import pack_service_8_commands_into
from examples.tmtcc import EXAMPLE_PUS_APID, EXAMPLE_CFDP_APID
from examples.tmtcc import (
EXAMPLE_PUS_APID,
EXAMPLE_CFDP_APID,
CFDP_LOCAL_ENTITY_ID,
CFDP_REMOTE_ENTITY_ID,
)
from tmtccmd import TcHandlerBase, get_console_logger, TmTcCfgHookBase, BackendBase
from tmtccmd.pus import VerificationWrapper
from tmtccmd.tc import (
@ -71,15 +86,56 @@ from common_tmtc.pus_tm.factory_hook import pus_factory_hook
LOGGER = get_console_logger()
class ExampleCfdpUser(CfdpUserBase):
def transaction_indication(self, transaction_id: TransactionId):
pass
def eof_sent_indication(self, transaction_id: TransactionId):
pass
def transaction_finished_indication(self, params: TransactionFinishedParams):
pass
def metadata_recv_indication(self, params: MetadataRecvParams):
pass
def file_segment_recv_indication(self, params: FileSegmentRecvdParams):
pass
def report_indication(self, transaction_id: TransactionId, status_report: any):
pass
def suspended_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode
):
pass
def resumed_indication(self, transaction_id: TransactionId, progress: int):
pass
def fault_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def abandoned_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def eof_recv_indication(self, transaction_id: TransactionId):
pass
class CfdpCcsdsWrapper(SpecificApidHandlerBase):
def __init__(
self,
cfg: LocalEntityCfg,
user: CfdpUserBase,
cfdp_seq_cnt_provider: ProvidesSeqCount,
remote_cfg: Sequence[RemoteEntityCfg],
ccsds_seq_cnt_provider: ProvidesSeqCount,
remote_cfgs: Sequence[RemoteEntityCfg],
ccsds_apid: int,
cfdp_seq_cnt_provider: ProvidesSeqCount,
ccsds_seq_cnt_provider: ProvidesSeqCount,
):
"""Wrapper helper type used to wrap PDU packets into CCSDS packets and to extract PDU
packets from CCSDS packets.
@ -89,7 +145,6 @@ class CfdpCcsdsWrapper(SpecificApidHandlerBase):
virtual filestore implementation.
:param cfdp_seq_cnt_provider: Every CFDP file transfer has a transaction sequence number.
This provider is used to retrieve that sequence number.
:param remote_cfg:
:param ccsds_seq_cnt_provider: Each CFDP PDU is wrapped into a CCSDS space packet, and each
space packet has a dedicated sequence count. This provider is used to retrieve the
sequence count.
@ -98,7 +153,7 @@ class CfdpCcsdsWrapper(SpecificApidHandlerBase):
CFDP packets.
"""
super().__init__(EXAMPLE_CFDP_APID, None)
self.handler = CfdpHandler(cfg, user, cfdp_seq_cnt_provider, remote_cfg)
self.handler = CfdpHandler(cfg, user, cfdp_seq_cnt_provider, remote_cfgs)
self.ccsds_seq_cnt_provider = ccsds_seq_cnt_provider
self.ccsds_apid = ccsds_apid
@ -138,18 +193,15 @@ class CfdpHandler:
cfg: LocalEntityCfg,
user: CfdpUserBase,
seq_cnt_provider: ProvidesSeqCount,
remote_cfg: Sequence[RemoteEntityCfg],
remote_cfgs: Sequence[RemoteEntityCfg],
):
self.dest_id = UnsignedByteField(EXAMPLE_PUS_APID, 2)
self.remote_cfg_table = RemoteEntityCfgTable()
self.remote_cfg_table.add_configs(remote_cfg)
self.remote_cfg_table.add_configs(remote_cfgs)
self.dest_handler = DestHandler(cfg, user, self.remote_cfg_table)
self.source_handler = SourceHandler(cfg, seq_cnt_provider, user)
def put_request(
self,
request: PutRequest
):
def put_request(self, request: PutRequest):
if self.remote_cfg_table.get_cfg(request.cfg.destination_id):
raise ValueError(
f"No remote CFDP config found for entity ID {request.cfg.destination_id}"
@ -284,7 +336,18 @@ class TcHandler(TcHandlerBase):
cfdp_procedure = info.to_cfdp_procedure()
if cfdp_procedure.cfdp_request_type == CfdpRequestType.PUT:
if not self.cfdp_in_ccsds_wrapper.handler.put_request_pending():
put_req = cfdp_procedure.request_wrapper.to_put_request()
# put_req = cfdp_procedure.request_wrapper.to_put_request()
with open("/tmp/hello.txt") as of:
of.write("Hello first CFDP file")
# TODO: Replace hardcoded put request if the request works
put_request_cfg = PutRequestCfg(
destination_id=self.cfdp_in_ccsds_wrapper.handler.dest_id,
source_file=Path("/tmp/hello.txt"),
dest_file="/tmp/hello-created-by-dest.txt",
closure_requested=False,
trans_mode=TransmissionModes.UNACKNOWLEDGED,
)
put_req = PutRequest(put_request_cfg)
LOGGER.info(f"Starting put request {put_req}")
# TODO: Only start put request if there isn't one pending yet. The source handler
# state can probably be used for this.
@ -345,10 +408,40 @@ def setup_params(hook_obj: TmTcCfgHookBase) -> SetupWrapper:
def setup_tmtc_handlers(
verif_wrapper: VerificationWrapper,
printer: FsfwTmTcPrinter,
cfdp_handler: CfdpCcsdsWrapper,
raw_logger: RawTmtcTimedLogWrapper,
) -> (CcsdsTmHandler, TcHandler):
fh_base = DefaultFaultHandlerBase()
cfdp_cfg = LocalEntityCfg(
local_entity_id=CFDP_LOCAL_ENTITY_ID,
indication_cfg=IndicationCfg(),
default_fault_handlers=fh_base,
)
remote_cfg = RemoteEntityCfg(
closure_requested=False,
entity_id=CFDP_REMOTE_ENTITY_ID,
max_file_segment_len=1024,
check_limit=None,
crc_on_transmission=False,
crc_type=ChecksumTypes.CRC_32,
default_transmission_mode=TransmissionModes.UNACKNOWLEDGED,
)
cfdp_seq_count_provider = FileSeqCountProvider(
max_bit_width=16, file_name=Path("cfdp_transaction_cnt.txt")
)
cfdp_ccsds_seq_count_provider = PusFileSeqCountProvider(
file_name=Path("cfdp_ccsds_seqcnt.txt")
)
cfdp_user = ExampleCfdpUser()
cfdp_in_ccsds_handler = CfdpCcsdsWrapper(
cfg=cfdp_cfg,
remote_cfgs=[remote_cfg],
ccsds_apid=EXAMPLE_CFDP_APID,
ccsds_seq_cnt_provider=cfdp_ccsds_seq_count_provider,
cfdp_seq_cnt_provider=cfdp_seq_count_provider,
user=cfdp_user,
)
pus_handler = PusHandler(
printer=printer, raw_logger=raw_logger, wrapper=verif_wrapper
)
@ -358,8 +451,10 @@ def setup_tmtc_handlers(
file_logger=printer.file_logger,
raw_logger=raw_logger,
pus_verificator=verif_wrapper.pus_verificator,
seq_count_provider=PusFileSeqCountProvider(),
cfdp_in_ccsds_wrapper=cfdp_handler,
seq_count_provider=PusFileSeqCountProvider(
file_name=Path("pus_ccsds_seqcnt.txt")
),
cfdp_in_ccsds_wrapper=cfdp_in_ccsds_handler,
)
return ccsds_handler, tc_handler