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,
)
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
from tmtcc import CfdpInCcsdsWrapper
from tmtccmd import TcHandlerBase, ProcedureWrapper
from tmtccmd.cfdp.defs import CfdpRequestType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.logging import get_current_time_string
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.tc import (
@ -36,7 +36,7 @@ class TcHandler(TcHandlerBase):
def __init__(
self,
seq_count_provider: FileSeqCountProvider,
cfdp_in_ccsds_wrapper: CfdpInCcsdsWrapper,
cfdp_in_ccsds_handler: CfdpInCcsdsHandler,
pus_verificator: PusVerificator,
high_level_file_logger: logging.Logger,
raw_pus_logger: RawTmtcTimedLogWrapper,
@ -56,11 +56,11 @@ class TcHandler(TcHandlerBase):
pus_verificator=pus_verificator,
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:
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
return True
return False
@ -108,7 +108,7 @@ 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()
not self.cfdp_in_ccsds_handler.put_request_pending()
and not self.cfdp_handler_started
):
put_req_cfg_wrapper = cfdp_procedure.request_wrapper.to_put_request()
@ -118,15 +118,16 @@ class TcHandler(TcHandlerBase):
CFDP_REMOTE_ENTITY_ID,
CFDP_LOCAL_ENTITY_ID,
)
print(put_req)
else:
put_req = cfdp_put_req_params_to_procedure(put_req_cfg_wrapper.cfg)
_LOGGER.info(
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
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 = cast(PduHolder, pdu)
if pdu.is_file_directive:
@ -147,8 +148,8 @@ class TcHandler(TcHandlerBase):
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()
self.cfdp_in_ccsds_handler.confirm_source_packet_sent()
self.cfdp_in_ccsds_handler.source_handler.state_machine()
def queue_finished_cb(self, info: ProcedureWrapper):
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")
q.add_log_cmd(f"GPS: {Info.ENABLE_CORE_HK}")
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:
q.add_pus_tc(cmd)
if op_code in OpCode.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,
set_id=SetId.CORE_HK)))
q.add_pus_tc(
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:
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:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_SKYVIEW_HK}")
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:
q.add_pus_tc(cmd)
if op_code in OpCode.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,
set_id=SetId.SKYVIEW_HK)))
q.add_pus_tc(
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:
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:
q.add_log_cmd(f"GPS: {Info.ON}")
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):
if len(hk_data) < 4*8+4+2+8:
if len(hk_data) < 4 * 8 + 4 + 2 + 8:
pw.dlog(
f"GPS Core dataset with size {len(hk_data)} does not have expected size"
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):
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:
pw.dlog(
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_double = struct.calcsize(fmt_str_double)
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
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
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
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
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
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
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):
pw.dlog("{:<8} {:<8} {:<8} {:<8} {:<8}".format(prn_id[idx], azimuth[idx], elevation[idx], signal_to_noise[idx],
used[idx]))
pw.dlog(
"{:<8} {:<8} {:<8} {:<8} {:<8}".format(
prn_id[idx],
azimuth[idx],
elevation[idx],
signal_to_noise[idx],
used[idx],
)
)
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=6
)

View File

@ -6,14 +6,11 @@ import traceback
from pathlib import Path
from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler
from eive_tmtc.cfdp.tm import CfdpInCcsdsWrapper
from eive_tmtc.cfdp.user import EiveCfdpUser
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
from spacepackets.cfdp import (
ChecksumType,
TransmissionMode,
DirectiveType,
PduFactory,
PduType,
)
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}")
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):
hook_obj = EiveHookObject(default_json_path())
params = SetupParams()
@ -234,7 +209,7 @@ def setup_tmtc_handlers(
high_level_file_logger=printer.file_logger,
raw_pus_logger=raw_logger,
gui=gui,
cfdp_in_ccsds_wrapper=cfdp_in_ccsds_wrapper,
cfdp_in_ccsds_handler=cfdp_in_ccsds_wrapper.handler,
)
return ccsds_handler, tc_handler
@ -285,7 +260,7 @@ def main(): # noqa C901: Complexity okay here.
try:
while True:
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:
sys.exit(0)
elif state.request == BackendRequest.DELAY_IDLE: