From 3c8c3ba304bcd82aa5d36cd1890c6c8b0c517469 Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m@gmail.com>
Date: Fri, 27 Nov 2020 22:55:54 +0100
Subject: [PATCH] improved architecture

---
 config/obsw_com_config.py |  3 ---
 core/tmtc_backend.py      | 41 +++++++++++++++++++++++++++------------
 core/tmtc_client_core.py  | 18 +++++------------
 tmtc_core                 |  2 +-
 4 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/config/obsw_com_config.py b/config/obsw_com_config.py
index 0d45593..07bc864 100644
--- a/config/obsw_com_config.py
+++ b/config/obsw_com_config.py
@@ -49,9 +49,6 @@ def set_communication_interface(tmtc_printer: TmTcPrinter) -> Union[Communicatio
                 g.G_SERIAL_DLE_MAX_QUEUE_LEN, g.G_SERIAL_DLE_MAX_FRAME_SIZE, serial_timeout)
         else:
             communication_interface = DummyComIF(tmtc_printer=tmtc_printer)
-        if not communication_interface.valid:
-            LOGGER.warning("Invalid communication interface!")
-            sys.exit()
         communication_interface.initialize()
         return communication_interface
     except (IOError, OSError):
diff --git a/core/tmtc_backend.py b/core/tmtc_backend.py
index 9580eee..7898f65 100644
--- a/core/tmtc_backend.py
+++ b/core/tmtc_backend.py
@@ -7,7 +7,7 @@ from collections import deque
 from typing import Tuple, Union
 
 from config import obsw_config as g
-from config.obsw_definitions import ModeList
+from config.obsw_definitions import ModeList, ComInterfaces
 from config.obsw_user_code import command_preparation_hook
 
 from tmtc_core.utility.obsw_logger import get_logger
@@ -32,15 +32,17 @@ class TmTcHandler:
     This is the primary class which handles TMTC reception. This can be seen as the backend
     in case a GUI or front-end is implemented.
     """
-    def __init__(self, init_mode: ModeList = ModeList.ListenerMode):
+    def __init__(self, init_com_if: ComInterfaces = ComInterfaces.Dummy,
+                 init_mode: ModeList = ModeList.ListenerMode):
         self.mode = init_mode
-        self.com_if = g.G_COM_IF
+        self.com_if = init_com_if
         # This flag could be used later to command the TMTC Client with a front-end
         self.one_shot_operation = True
 
         self.tmtc_printer: Union[None, TmTcPrinter] = None
         self.communication_interface: Union[None, CommunicationInterface] = None
         self.tm_listener: Union[None, TmListener] = None
+        self.exit_on_com_if_init_failure = True
 
         self.single_command_package: Tuple[bytearray, Union[None, PusTcInfo]] = bytearray(), None
 
@@ -57,16 +59,24 @@ class TmTcHandler:
         """
         self.mode = mode
 
+    def set_com_if(self, com_if: ComInterfaces):
+        self.com_if = com_if
+
     @staticmethod
-    def prepare_tmtc_handler_start(init_mode: ModeList = g.ModeList.ListenerMode):
-        tmtc_handler = TmTcHandler(init_mode)
+    def prepare_tmtc_handler_start(
+            init_com_if: ComInterfaces = ComInterfaces.Dummy,
+            init_mode: ModeList = g.ModeList.ListenerMode):
+        tmtc_handler = TmTcHandler(init_com_if, init_mode)
         tmtc_task = Process(target=TmTcHandler.start_handler, args=(tmtc_handler, ))
         return tmtc_task
 
     @staticmethod
     def start_handler(executed_handler):
+        if not isinstance(executed_handler, TmTcHandler):
+            LOGGER.error("Unexpected argument, should be TmTcHandler!")
+            sys.exit(1)
         executed_handler.initialize()
-        executed_handler.perform_operation()
+        executed_handler.start()
 
     def initialize(self):
         """
@@ -79,12 +89,19 @@ class TmTcHandler:
             com_interface=self.communication_interface, tm_timeout=g.G_TM_TIMEOUT,
             tc_timeout_factor=g.G_TC_SEND_TIMEOUT_FACTOR
         )
-        if self.communication_interface.valid:
+        atexit.register(keyboard_interrupt_handler, com_interface=self.communication_interface)
+
+    def start(self):
+        try:
+            self.communication_interface.open()
             self.tm_listener.start()
-        else:
-            LOGGER.info("No communication interface set for now")
+        except IOError:
+            LOGGER.error("Communication Interface could not be opened!")
             LOGGER.info("TM listener will not be started")
-        atexit.register(keyboard_interrupt_handler, com_interface=self.communication_interface)
+            if self.exit_on_com_if_init_failure:
+                LOGGER.error("Closing TMTC commander..")
+                sys.exit(1)
+        self.perform_operation()
 
     def perform_operation(self):
         """
@@ -117,12 +134,12 @@ class TmTcHandler:
             if self.single_command_package is None:
                 pus_packet_tuple = command_preparation()
             else:
-                LOGGER.info("send package from gui")
+                LOGGER.info("Sending single packet from GUI..")
                 pus_packet_tuple = self.single_command_package
             sender_and_receiver = SingleCommandSenderReceiver(
                 com_interface=self.communication_interface, tmtc_printer=self.tmtc_printer,
                 tm_listener=self.tm_listener)
-            LOGGER.info("Performing single command operation")
+            LOGGER.info("Performing single command operation..")
             sender_and_receiver.send_single_tc_and_receive_tm(pus_packet_tuple=pus_packet_tuple)
             self.mode = g.ModeList.PromptMode
 
diff --git a/core/tmtc_client_core.py b/core/tmtc_client_core.py
index 5bea5f9..39a963c 100755
--- a/core/tmtc_client_core.py
+++ b/core/tmtc_client_core.py
@@ -55,29 +55,21 @@ def run_tmtc_client(use_gui: bool):
         LOGGER.info("Setting global variables")
         set_globals(args)
 
-    LOGGER.info("Starting TMTC Handler")
+    LOGGER.info("Starting TMTC Handler..")
 
-    tmtc_frontend_task = Process
-
-    # Currently does not work, problems with QEMU / Asyncio
     if not use_gui:
-        tmtc_handler = TmTcHandler(g.G_MODE_ID)
+        # The global variables are set by the argument parser.
+        tmtc_handler = TmTcHandler(g.G_COM_IF, g.G_MODE_ID)
         tmtc_handler.set_one_shot_or_loop_handling(g.G_LISTENER_AFTER_OP)
         tmtc_handler.initialize()
-        tmtc_handler.perform_operation()
+        tmtc_handler.start()
     else:
         app = QApplication(["TMTC Commander"])
         tmtc_gui = TmTcFrontend()
         tmtc_gui.start_ui()
 
         sys.exit(app.exec_())
-        # tmtc_handler_task = TmTcHandler.prepare_tmtc_handler_start()
-        # tmtc_frontend = TmTcFrontend()
-        # tmtc_frontend_task = tmtc_frontend.prepare_start(tmtc_frontend)
-        # tmtc_frontend_task.start()
-        # tmtc_handler_task.start()
-        # tmtc_handler_task.join()
-        # tmtc_frontend_task.join()
+
 
 
 
diff --git a/tmtc_core b/tmtc_core
index 1f4f33f..2a12f36 160000
--- a/tmtc_core
+++ b/tmtc_core
@@ -1 +1 @@
-Subproject commit 1f4f33f92ae5b6abe92e89dedf7041ebdee4b63c
+Subproject commit 2a12f3621780fb5df5a9fcd30b936e8d1ad991c7
-- 
GitLab