improve architecture a bit

This commit is contained in:
Robin Müller 2023-08-29 21:41:29 +02:00
parent 8743f59b56
commit 948f3a1a41
Signed by: muellerr
GPG Key ID: A649FB78196E3849
4 changed files with 104 additions and 57 deletions

31
eive_tmtc/cfdp/tm.py Normal file
View File

@ -0,0 +1,31 @@
import logging
from eive_tmtc.config.definitions import CFDP_APID
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
from spacepackets.cfdp import PduFactory, PduType, DirectiveType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.tm import SpecificApidHandlerBase
_LOGGER = logging.getLogger(__name__)
class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
def __init__(self, cfdp_in_ccsds_handler: CfdpInCcsdsHandler):
super().__init__(CFDP_APID, None)
self.handler = cfdp_in_ccsds_handler
def handle_tm(self, packet: bytes, _user_args: any):
# 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("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)

View File

@ -7,9 +7,9 @@ from eive_tmtc.config.definitions import (
CFDP_LOCAL_ENTITY_ID, CFDP_LOCAL_ENTITY_ID,
) )
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
from tmtcc import CfdpInCcsdsWrapper
from tmtccmd import TcHandlerBase, ProcedureWrapper from tmtccmd import TcHandlerBase, ProcedureWrapper
from tmtccmd.cfdp.defs import CfdpRequestType from tmtccmd.cfdp.defs import CfdpRequestType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.logging import get_current_time_string from tmtccmd.logging import get_current_time_string
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.tc import ( from tmtccmd.tc import (
@ -36,7 +36,7 @@ class TcHandler(TcHandlerBase):
def __init__( def __init__(
self, self,
seq_count_provider: FileSeqCountProvider, seq_count_provider: FileSeqCountProvider,
cfdp_in_ccsds_wrapper: CfdpInCcsdsWrapper, cfdp_in_ccsds_handler: CfdpInCcsdsHandler,
pus_verificator: PusVerificator, pus_verificator: PusVerificator,
high_level_file_logger: logging.Logger, high_level_file_logger: logging.Logger,
raw_pus_logger: RawTmtcTimedLogWrapper, raw_pus_logger: RawTmtcTimedLogWrapper,
@ -56,11 +56,11 @@ class TcHandler(TcHandlerBase):
pus_verificator=pus_verificator, pus_verificator=pus_verificator,
tc_sched_timestamp_len=4, tc_sched_timestamp_len=4,
) )
self.cfdp_in_ccsds_wrapper = cfdp_in_ccsds_wrapper self.cfdp_in_ccsds_handler = cfdp_in_ccsds_handler
def cfdp_done(self) -> bool: def cfdp_done(self) -> bool:
if self.cfdp_handler_started: if self.cfdp_handler_started:
if not self.cfdp_in_ccsds_wrapper.handler.put_request_pending(): if not self.cfdp_in_ccsds_handler.put_request_pending():
self.cfdp_handler_started = False self.cfdp_handler_started = False
return True return True
return False return False
@ -108,7 +108,7 @@ class TcHandler(TcHandlerBase):
cfdp_procedure = info.to_cfdp_procedure() cfdp_procedure = info.to_cfdp_procedure()
if cfdp_procedure.cfdp_request_type == CfdpRequestType.PUT: if cfdp_procedure.cfdp_request_type == CfdpRequestType.PUT:
if ( if (
not self.cfdp_in_ccsds_wrapper.handler.put_request_pending() not self.cfdp_in_ccsds_handler.put_request_pending()
and not self.cfdp_handler_started and not self.cfdp_handler_started
): ):
put_req_cfg_wrapper = cfdp_procedure.request_wrapper.to_put_request() put_req_cfg_wrapper = cfdp_procedure.request_wrapper.to_put_request()
@ -118,15 +118,16 @@ class TcHandler(TcHandlerBase):
CFDP_REMOTE_ENTITY_ID, CFDP_REMOTE_ENTITY_ID,
CFDP_LOCAL_ENTITY_ID, CFDP_LOCAL_ENTITY_ID,
) )
print(put_req)
else: else:
put_req = cfdp_put_req_params_to_procedure(put_req_cfg_wrapper.cfg) put_req = cfdp_put_req_params_to_procedure(put_req_cfg_wrapper.cfg)
_LOGGER.info( _LOGGER.info(
f"CFDP: Starting file put request with parameters:\n{put_req}" f"CFDP: Starting file put request with parameters:\n{put_req}"
) )
self.cfdp_in_ccsds_wrapper.handler.cfdp_handler.put_request(put_req) self.cfdp_in_ccsds_handler.cfdp_handler.put_request(put_req)
self.cfdp_handler_started = True self.cfdp_handler_started = True
for source_pair, dest_pair in self.cfdp_in_ccsds_wrapper.handler: for source_pair, dest_pair in self.cfdp_in_ccsds_handler:
pdu, sp = source_pair pdu, sp = source_pair
pdu = cast(PduHolder, pdu) pdu = cast(PduHolder, pdu)
if pdu.is_file_directive: if pdu.is_file_directive:
@ -147,8 +148,8 @@ class TcHandler(TcHandlerBase):
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}" f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
) )
self.queue_helper.add_ccsds_tc(sp) self.queue_helper.add_ccsds_tc(sp)
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent() self.cfdp_in_ccsds_handler.confirm_source_packet_sent()
self.cfdp_in_ccsds_wrapper.handler.source_handler.state_machine() self.cfdp_in_ccsds_handler.source_handler.state_machine()
def queue_finished_cb(self, info: ProcedureWrapper): def queue_finished_cb(self, info: ProcedureWrapper):
if info is not None: if info is not None:

View File

@ -82,34 +82,52 @@ def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
raise ValueError("invalid interval") raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_CORE_HK}") q.add_log_cmd(f"GPS: {Info.ENABLE_CORE_HK}")
cmds = create_enable_periodic_hk_command_with_interval( cmds = create_enable_periodic_hk_command_with_interval(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK), interval_seconds=interval diag=False,
sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK),
interval_seconds=interval,
) )
for cmd in cmds: for cmd in cmds:
q.add_pus_tc(cmd) q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_CORE_HK: if op_code in OpCode.DISABLE_CORE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}") q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=make_sid(object_id=object_id, q.add_pus_tc(
set_id=SetId.CORE_HK))) create_disable_periodic_hk_command(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in OpCode.REQ_CORE_HK: if op_code in OpCode.REQ_CORE_HK:
q.add_log_cmd(f"GPS: {Info.REQ_CORE_HK}") q.add_log_cmd(f"GPS: {Info.REQ_CORE_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK))) q.add_pus_tc(
create_request_one_hk_command(
sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in OpCode.ENABLE_SKYVIEW_HK: if op_code in OpCode.ENABLE_SKYVIEW_HK:
interval = float(input("Please specify interval in floating point seconds: ")) interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0: if interval <= 0:
raise ValueError("invalid interval") raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_SKYVIEW_HK}") q.add_log_cmd(f"GPS: {Info.ENABLE_SKYVIEW_HK}")
cmds = create_enable_periodic_hk_command_with_interval( cmds = create_enable_periodic_hk_command_with_interval(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK), interval_seconds=interval diag=False,
sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK),
interval_seconds=interval,
) )
for cmd in cmds: for cmd in cmds:
q.add_pus_tc(cmd) q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_SKYVIEW_HK: if op_code in OpCode.DISABLE_SKYVIEW_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_SKYVIEW_HK}") q.add_log_cmd(f"gps: {Info.DISABLE_SKYVIEW_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=make_sid(object_id=object_id, q.add_pus_tc(
set_id=SetId.SKYVIEW_HK))) create_disable_periodic_hk_command(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)
)
)
if op_code in OpCode.REQ_SKYVIEW_HK: if op_code in OpCode.REQ_SKYVIEW_HK:
q.add_log_cmd(f"GPS: {Info.REQ_SKYVIEW_HK}") q.add_log_cmd(f"GPS: {Info.REQ_SKYVIEW_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK))) q.add_pus_tc(
create_request_one_hk_command(
sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)
)
)
if op_code in OpCode.ON: if op_code in OpCode.ON:
q.add_log_cmd(f"GPS: {Info.ON}") q.add_log_cmd(f"GPS: {Info.ON}")
q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0)) q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0))
@ -133,7 +151,7 @@ def handle_gps_data(
def handle_core_data(pw: PrintWrapper, hk_data: bytes): def handle_core_data(pw: PrintWrapper, hk_data: bytes):
if len(hk_data) < 4*8+4+2+8: if len(hk_data) < 4 * 8 + 4 + 2 + 8:
pw.dlog( pw.dlog(
f"GPS Core dataset with size {len(hk_data)} does not have expected size" f"GPS Core dataset with size {len(hk_data)} does not have expected size"
f" of {4*8+4+2+8} bytes" f" of {4*8+4+2+8} bytes"
@ -179,7 +197,7 @@ def handle_core_data(pw: PrintWrapper, hk_data: bytes):
def handle_skyview_data(pw: PrintWrapper, hk_data: bytes): def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
data_length = 8+GpsInfo.MAX_SATELLITES*(8+3*2+1) data_length = 8 + GpsInfo.MAX_SATELLITES * (8 + 3 * 2 + 1)
if len(hk_data) < data_length: if len(hk_data) < data_length:
pw.dlog( pw.dlog(
f"GPS Skyview dataset with size {len(hk_data)} does not have expected size" f"GPS Skyview dataset with size {len(hk_data)} does not have expected size"
@ -195,24 +213,46 @@ def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
inc_len_int16 = struct.calcsize(fmt_str_int16) inc_len_int16 = struct.calcsize(fmt_str_int16)
inc_len_double = struct.calcsize(fmt_str_double) inc_len_double = struct.calcsize(fmt_str_double)
inc_len_uint8 = struct.calcsize(fmt_str_uint8) inc_len_uint8 = struct.calcsize(fmt_str_uint8)
unix = struct.unpack(fmt_str_unix, hk_data[current_idx: current_idx + inc_len_unix])[0] unix = struct.unpack(
fmt_str_unix, hk_data[current_idx : current_idx + inc_len_unix]
)[0]
current_idx += inc_len_unix current_idx += inc_len_unix
prn_id = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16]) prn_id = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16 current_idx += inc_len_int16
azimuth = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16]) azimuth = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16 current_idx += inc_len_int16
elevation = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16]) elevation = struct.unpack(
fmt_str_int16, hk_data[current_idx : current_idx + inc_len_int16]
)
current_idx += inc_len_int16 current_idx += inc_len_int16
signal_to_noise = struct.unpack(fmt_str_double, hk_data[current_idx: current_idx + inc_len_double]) signal_to_noise = struct.unpack(
fmt_str_double, hk_data[current_idx : current_idx + inc_len_double]
)
current_idx += inc_len_double current_idx += inc_len_double
used = struct.unpack(fmt_str_uint8, hk_data[current_idx: current_idx + inc_len_uint8]) used = struct.unpack(
fmt_str_uint8, hk_data[current_idx : current_idx + inc_len_uint8]
)
current_idx += inc_len_uint8 current_idx += inc_len_uint8
pw.dlog(f"Skyview Time: {unix} unix-sec") pw.dlog(f"Skyview Time: {unix} unix-sec")
pw.dlog("{:<8} {:<8} {:<8} {:<8} {:<8}".format('PRN_ID', 'AZ [°]', 'EL [°]', 'S2N [dBW]', 'USED')) pw.dlog(
"{:<8} {:<8} {:<8} {:<8} {:<8}".format(
"PRN_ID", "AZ [°]", "EL [°]", "S2N [dBW]", "USED"
)
)
for idx in range(GpsInfo.MAX_SATELLITES): for idx in range(GpsInfo.MAX_SATELLITES):
pw.dlog("{:<8} {:<8} {:<8} {:<8} {:<8}".format(prn_id[idx], azimuth[idx], elevation[idx], signal_to_noise[idx], pw.dlog(
used[idx])) "{:<8} {:<8} {:<8} {:<8} {:<8}".format(
prn_id[idx],
azimuth[idx],
elevation[idx],
signal_to_noise[idx],
used[idx],
)
)
FsfwTmTcPrinter.get_validity_buffer( FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=6 validity_buffer=hk_data[current_idx:], num_vars=6
) )

View File

@ -6,14 +6,11 @@ import traceback
from pathlib import Path from pathlib import Path
from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler
from eive_tmtc.cfdp.tm import CfdpInCcsdsWrapper
from eive_tmtc.cfdp.user import EiveCfdpUser from eive_tmtc.cfdp.user import EiveCfdpUser
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
from spacepackets.cfdp import ( from spacepackets.cfdp import (
ChecksumType, ChecksumType,
TransmissionMode, TransmissionMode,
DirectiveType,
PduFactory,
PduType,
) )
from eive_tmtc.pus_tc.tc_handler import TcHandler from eive_tmtc.pus_tc.tc_handler import TcHandler
@ -121,28 +118,6 @@ class CustomCcsdsTmHandler(CcsdsTmHandler):
_LOGGER.debug(f"Received packet {packet.hex(sep=',')} with APID {apid}") _LOGGER.debug(f"Received packet {packet.hex(sep=',')} with APID {apid}")
class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
def __init__(self, cfdp_in_ccsds_handler: CfdpInCcsdsHandler):
super().__init__(CFDP_APID, None)
self.handler = cfdp_in_ccsds_handler
def handle_tm(self, packet: bytes, _user_args: any):
# 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("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)
def setup_params() -> (SetupWrapper, int): def setup_params() -> (SetupWrapper, int):
hook_obj = EiveHookObject(default_json_path()) hook_obj = EiveHookObject(default_json_path())
params = SetupParams() params = SetupParams()
@ -234,7 +209,7 @@ def setup_tmtc_handlers(
high_level_file_logger=printer.file_logger, high_level_file_logger=printer.file_logger,
raw_pus_logger=raw_logger, raw_pus_logger=raw_logger,
gui=gui, gui=gui,
cfdp_in_ccsds_wrapper=cfdp_in_ccsds_wrapper, cfdp_in_ccsds_handler=cfdp_in_ccsds_wrapper.handler,
) )
return ccsds_handler, tc_handler return ccsds_handler, tc_handler
@ -285,7 +260,7 @@ def main(): # noqa C901: Complexity okay here.
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() tc_handler.cfdp_in_ccsds_handler.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: