From 20108699775c56a05bf17d7cdfa68614d017261c Mon Sep 17 00:00:00 2001
From: "Robin.Mueller" <robin.mueller.m@gmail.com>
Date: Sun, 15 Dec 2019 02:19:43 +0100
Subject: [PATCH] comIF continued

---
 OBSW_Config.py                                |  5 +-
 OBSW_UdpClient.py                             | 22 ++++--
 comIF/OBSW_ComInterface.py                    | 25 ++++++-
 comIF/OBSW_Ethernet_ComIF.py                  | 71 ++++++++++++++++++-
 comIF/OBSW_Serial_ComIF.py                    | 12 ++++
 gui/OBSW_TmtcGUI.py                           |  1 -
 sendreceive/OBSW_CommandSenderReceiver.py     | 60 +++-------------
 .../OBSW_MultipleCommandsSenderReceiver.py    |  1 -
 sendreceive/OBSW_SequentialSenderReceiver.py  | 10 +--
 .../OBSW_SingleCommandSenderReceiver.py       | 10 +--
 test/OBSW_UnitTest.py                         | 11 ++-
 utility/OBSW_TmTcPrinter.py                   |  4 +-
 12 files changed, 152 insertions(+), 80 deletions(-)

diff --git a/OBSW_Config.py b/OBSW_Config.py
index e555f56..c9712dc 100644
--- a/OBSW_Config.py
+++ b/OBSW_Config.py
@@ -17,16 +17,17 @@ modeId = 0
 service = 17
 displayMode = "long"
 
+comIF = 0
 # Time related
 tmTimeout = 10
 tcSendTimeoutFactor = 2.0
 
 # Ethernet connection settings
 recAddress = 0
-sendAddress = 0
+sendAddress = (0, 0)
 sockSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 sockReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-sockSend.setblocking(0)
+
 # Print Settings
 printToFile = False
 printRawTmData = False
diff --git a/OBSW_UdpClient.py b/OBSW_UdpClient.py
index 63fa2a2..0e39ad7 100644
--- a/OBSW_UdpClient.py
+++ b/OBSW_UdpClient.py
@@ -57,7 +57,6 @@ import atexit
 import signal
 import queue
 import socket
-import time
 import unittest
 import argparse
 
@@ -67,6 +66,8 @@ from tc.OBSW_TcPacker import PUSTelecommand, createTotalTcQueue, serviceTestSele
 from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver, connectToBoard
 from sendreceive.OBSW_SingleCommandSenderReceiver import SingleCommandSenderReceiver
 from sendreceive.OBSW_SequentialSenderReceiver import SequentialCommandSenderReceiver
+from utility.OBSW_TmTcPrinter import TmtcPrinter
+from comIF.OBSW_Ethernet_ComIF import EthernetComIF
 
 # Mode options, set by args parser
 modeList = {
@@ -79,6 +80,7 @@ modeList = {
 }
 
 
+# noinspection PyTypeChecker
 def main():
     args = parseInputArguments()
     setGlobals(args)
@@ -89,28 +91,31 @@ def main():
     setUpSocket()
     atexit.register(g.keyboardInterruptHandler)
     print("Attempting to connect")
+    tmtcPrinter = TmtcPrinter(g.displayMode, g.printToFile)
+    communicationInterface = EthernetComIF(tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor)
     connectToBoard()
 
     if g.modeId == "ListenerMode":
-        Receiver = CommandSenderReceiver(g.displayMode, g.tmTimeout, g.tcSendTimeoutFactor, g.printToFile)
+        Receiver = CommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout, g.tcSendTimeoutFactor,
+                                         True, g.printToFile)
         Receiver.performListenerMode()
 
     elif g.modeId == "SingleCommandMode":
         pusPacketTuple = commandPreparation()
-        SenderAndReceiver = SingleCommandSenderReceiver(g.displayMode, pusPacketTuple, g.tmTimeout,
-                                                        g.tcSendTimeoutFactor, True, g.printToFile)
+        SenderAndReceiver = SingleCommandSenderReceiver(communicationInterface, tmtcPrinter, pusPacketTuple,
+                                                        g.tmTimeout, g.tcSendTimeoutFactor, True, g.printToFile)
         SenderAndReceiver.sendSingleTcAndReceiveTm()
 
     elif g.modeId == "ServiceTestMode":
         serviceQueue = queue.Queue()
-        SenderAndReceiver = SequentialCommandSenderReceiver(g.displayMode, g.tmTimeout,
+        SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout,
                                                             serviceTestSelect(g.service, serviceQueue),
                                                             g.tcSendTimeoutFactor, True, g.printToFile)
         SenderAndReceiver.sendQueueTcAndReceiveTmSequentially()
 
     elif g.modeId == "SoftwareTestMode":
         allTcQueue = createTotalTcQueue()
-        SenderAndReceiver = SequentialCommandSenderReceiver(g.displayMode, g.tmTimeout,
+        SenderAndReceiver = SequentialCommandSenderReceiver(communicationInterface, tmtcPrinter, g.tmTimeout,
                                                             allTcQueue, g.tcSendTimeoutFactor, True, g.printToFile)
         SenderAndReceiver.sendQueueTcAndReceiveTmSequentially()
 
@@ -140,7 +145,9 @@ def parseInputArguments():
                            '0: GUI Mode, 1:Listener Mode, '
                            '2: Single Command Mode, 3: Service Test Mode, '
                            '4: Software Test Mode, 5: Unit Test Mode ', default=0)
-    argParser.add_argument('-c', '--clientIP', help='Client(Computer) IP. Default:\'\'', default='')
+    argParser.add_argument('-c', '--comIF', type=int, help='Communication Interface. 0 for Ethernet, 1 for Serial',
+                           default=1)
+    argParser.add_argument('--clientIP', help='Client(Computer) IP. Default:\'\'', default='')
     argParser.add_argument('-b', '--boardIP', help='Board IP. Default: 169.254.1.38', default='169.254.1.38')
     argParser.add_argument('-s', '--service',  help='Service to test. Default: 17', default=17)
     argParser.add_argument('-t', '--tmTimeout', type=float, help='TM Timeout. Default: 10)', default=10.0)
@@ -182,6 +189,7 @@ def setGlobals(args):
         service = args.service
     g.recAddress = recAddress
     g.sendAddress = sendAddress
+    g.comIF = args.comIF
     g.sockReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     g.sockSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     g.modeId = modeId
diff --git a/comIF/OBSW_ComInterface.py b/comIF/OBSW_ComInterface.py
index 5b3ca25..8bfc0eb 100644
--- a/comIF/OBSW_ComInterface.py
+++ b/comIF/OBSW_ComInterface.py
@@ -1,10 +1,31 @@
-class CommunicationInterface():
+# -*- coding: utf-8 -*-
+"""
+Program: OBSW_UnitTest.py
+Date: 01.11.2019
+Description: Generic Communication Interface. Defines the syntax of the communication functions
+
+@author: R. Mueller
+"""
+
+
+class CommunicationInterface:
     def __init__(self):
         pass
 
     def sendTelecommand(self, tcPacket):
         pass
 
-    def receiveTelemetry(self, tmPacket):
+    def performListenerMode(self):
+        pass
+
+    def receiveTelemetry(self):
         pass
 
+    def receiveTelemetryDeserializeAndStore(self, tmQueue):
+        pass
+
+    def receiveTelemetryAndStoreTuple(self, tmTupleQueue):
+        pass
+
+    def pollInterface(self, parameter):
+        pass
diff --git a/comIF/OBSW_Ethernet_ComIF.py b/comIF/OBSW_Ethernet_ComIF.py
index f15ec6e..7edae71 100644
--- a/comIF/OBSW_Ethernet_ComIF.py
+++ b/comIF/OBSW_Ethernet_ComIF.py
@@ -1,6 +1,73 @@
+# -*- coding: utf-8 -*-
+"""
+Program: OBSW_UnitTest.py
+Date: 01.11.2019
+Description: Ethernet Communication Interface
+
+@author: R. Mueller
+"""
+
+
 from comIF.OBSW_ComInterface import CommunicationInterface
+import OBSW_Config as g
+from tm.OBSW_TmPacket import PUSTelemetryFactory
+import select
 
 
 class EthernetComIF(CommunicationInterface):
-    def __init__(self):
-        pass
+    def __init__(self, tmtcPrinter, tmTimeout, tcTimeoutFactor):
+        super().__init__()
+        self.tmtcPrinter = tmtcPrinter
+        self.tmTimeout = tmTimeout
+        self.tcTimeoutFactor = tcTimeoutFactor
+
+    def sendTelecommand(self, tcPacket):
+        g.sockSend.sendto(tcPacket, g.sendAddress)
+
+    def performListenerMode(self):
+        pollTimeout = 10
+        while True:
+            print("Listening for packages ...")
+            ready = self.pollInterface(pollTimeout)
+            if ready is None:
+                pass
+            elif ready[0]:
+                packet = self.receiveTelemetry()
+                self.tmtcPrinter.printTelemetry(packet)
+
+    # check for one sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...)
+    # returns true on success
+    def checkForOneTelemetrySequence(self):
+        tmReady = self.pollInterface(self.tmTimeout * self.tcTimeoutFactor)
+        if tmReady[0]:
+            while tmReady[0]:
+                packet = self.receiveTelemetry()
+                self.tmtcPrinter.printTelemetry(packet)
+                tmReady = self.pollInterface(self.tmTimeout / 1.5)
+                if tmReady is None:
+                    return True
+
+    def receiveTelemetry(self):
+        data = g.sockReceive.recvfrom(1024)[0]
+        packet = PUSTelemetryFactory(data)
+        return packet
+
+    def receiveTelemetryDeserializeAndStore(self, tmQueue):
+        data = g.sockReceive.recvfrom(1024)[0]
+        packet = PUSTelemetryFactory(data)
+        tmQueue.put(packet)
+        return tmQueue
+
+    def receiveTelemetryAndStoreTuple(self, tmTupleQueue):
+        data = g.sockReceive.recvfrom(1024)[0]
+        tmInfo = PUSTelemetryFactory(data).packTmInformation()
+        tmTuple = (data, tmInfo)
+        tmTupleQueue.put(tmTuple)
+        return tmTuple
+
+    def pollInterface(self, timeout):
+        ready = select.select([g.sockReceive], [], [], timeout)
+        if ready is None:
+            pass
+        elif ready[0]:
+            return ready
diff --git a/comIF/OBSW_Serial_ComIF.py b/comIF/OBSW_Serial_ComIF.py
index 2aaa369..55f2738 100644
--- a/comIF/OBSW_Serial_ComIF.py
+++ b/comIF/OBSW_Serial_ComIF.py
@@ -3,5 +3,17 @@ from comIF.OBSW_ComInterface import CommunicationInterface
 
 class SerialComIF(CommunicationInterface):
     def __init__(self):
+        super().__init__()
+
+    def sendTelecommand(self, tcPacket):
+        pass
+
+    def receiveTelemetry(self):
+        pass
+
+    def receiveTelemetryDeserializeAndStore(self, tmQueue):
+        pass
+
+    def receiveTelemetryAndStoreTuple(self, tmTupleQueue):
         pass
 
diff --git a/gui/OBSW_TmtcGUI.py b/gui/OBSW_TmtcGUI.py
index 09599a9..a64eca3 100644
--- a/gui/OBSW_TmtcGUI.py
+++ b/gui/OBSW_TmtcGUI.py
@@ -14,7 +14,6 @@
     R. Mueller
 """
 from tkinter import *
-import OBSW_Config as g
 
 # A first simple version has drop down menus to chose all necessary options
 # which are normally handled by the args parser.
diff --git a/sendreceive/OBSW_CommandSenderReceiver.py b/sendreceive/OBSW_CommandSenderReceiver.py
index e9c6844..bc18169 100644
--- a/sendreceive/OBSW_CommandSenderReceiver.py
+++ b/sendreceive/OBSW_CommandSenderReceiver.py
@@ -15,24 +15,23 @@ This is still experimental.
 import OBSW_Config as g
 import select
 import time
-import atexit
-from utility.OBSW_TmTcPrinter import TmtcPrinter
-from tm.OBSW_TmPacket import PUSTelemetryFactory
 
 
 # Generic TMTC SendReceive class which is implemented
 # by specific implementations (e.g. SingleCommandSenderReceiver)
 class CommandSenderReceiver:
-    def __init__(self, comInterface, displayMode, tmTimeout, tcSendTimeoutFactor, printTc, doPrintToFile):
-        self.displayMode = displayMode
+    def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcSendTimeoutFactor, printTc, doPrintToFile):
         self.tmTimeout = tmTimeout
         self.printTc = printTc
 
+        self.comInterface = comInterface
+        self.tmtcPrinter = tmtcPrinter
+
         self.replyReceived = False
         self.tmReady = False
         self.pusPacketInfo = []
         self.pusPacket = []
-        self.tmtcPrinter = TmtcPrinter(self.displayMode, doPrintToFile)
+
         self.start_time = 0
         self.elapsed_time = 0
         self.timeoutCounter = 0
@@ -42,22 +41,14 @@ class CommandSenderReceiver:
 
     # checks for replies. if no reply is received, send telecommand again
     def checkForFirstReply(self):
-        self.tmReady = select.select([g.sockReceive], [], [], self.tmTimeout * self.tcSendTimeoutFactor)
-        if self.tmReady[0]:
-            self.checkForOneTelemetrySequence()
+        tmSequenceCheckSuccess = self.comInterface.checkForOneTelemetrySequence()
+        if tmSequenceCheckSuccess:
             self.replyReceived = True
         else:
             if len(self.pusPacket) == 0:
                 print("No command has been sent yet")
             else:
-                self.sendTelecommand()
-
-    # check for one sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...)
-    def checkForOneTelemetrySequence(self):
-        while self.tmReady[0]:
-            packet = self.receiveTelemetry()
-            self.tmtcPrinter.printTelemetry(packet)
-            self.tmReady = select.select([g.sockReceive], [], [], self.tmTimeout / 1.5)
+                self.comInterface.sendTelecommand(self.pusPacket)
 
     # Check for special queue entries.
     def checkQueueEntry(self, tcQueueEntry):
@@ -76,20 +67,6 @@ class CommandSenderReceiver:
         else:
             self.queueEntryIsTelecommand = True
 
-    def sendTelecommand(self):
-        if self.printTc:
-            self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode)
-        g.sockSend.sendto(self.pusPacket, g.sendAddress)
-
-    def performListenerMode(self):
-        timeoutInSeconds = 10
-        while True:
-            print("Listening for packages ...")
-            ready = select.select([g.sockReceive], [], [], timeoutInSeconds)
-            if ready[0]:
-                packet = self.receiveTelemetry()
-                self.tmtcPrinter.printTelemetry(packet)
-
     def checkForTimeout(self):
         if self.timeoutCounter == 5:
             print("No response from command !")
@@ -103,27 +80,6 @@ class CommandSenderReceiver:
             self.start_time = time.time()
         time.sleep(3)
 
-    @staticmethod
-    def receiveTelemetry():
-        data = g.sockReceive.recvfrom(1024)[0]
-        packet = PUSTelemetryFactory(data)
-        return packet
-
-    @staticmethod
-    def receiveTelemetryDeserializeAndStore(tmQueue):
-        data = g.sockReceive.recvfrom(1024)[0]
-        packet = PUSTelemetryFactory(data)
-        tmQueue.put(packet)
-        return tmQueue
-
-    @staticmethod
-    def receiveTelemetryAndStoreTuple(tmTupleQueue):
-        data = g.sockReceive.recvfrom(1024)[0]
-        tmInfo = PUSTelemetryFactory(data).packTmInformation()
-        tmTuple = (data, tmInfo)
-        tmTupleQueue.put(tmTuple)
-        return tmTuple
-
 
 def connectToBoard():
     # Maybe there is a cleaner way to start comm with udp server
diff --git a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py
index 47f28f5..baea7fe 100644
--- a/sendreceive/OBSW_MultipleCommandsSenderReceiver.py
+++ b/sendreceive/OBSW_MultipleCommandsSenderReceiver.py
@@ -39,7 +39,6 @@ class MultipleCommandSenderReceiver(SequentialCommandSenderReceiver):
                 time.sleep(1)
             # self.handleTcResending() Turned off for now, not needed
             if self.doPrintToFile:
-                print("HELLOOOO !")
                 self.tmtcPrinter.printToFile()
         except (KeyboardInterrupt, SystemExit):
             super().handleInterrupt(receiverThread)
diff --git a/sendreceive/OBSW_SequentialSenderReceiver.py b/sendreceive/OBSW_SequentialSenderReceiver.py
index 91135a4..ead1f3a 100644
--- a/sendreceive/OBSW_SequentialSenderReceiver.py
+++ b/sendreceive/OBSW_SequentialSenderReceiver.py
@@ -8,7 +8,7 @@
 @brief
     Used to send multiple TCs in sequence and listen for replies after each sent tc
 """
-from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver, connectToBoard
+from sendreceive.OBSW_CommandSenderReceiver import CommandSenderReceiver
 import threading
 import OBSW_Config as g
 import time
@@ -69,7 +69,9 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver):
     def sendAndReceiveFirstPacket(self):
         self.checkQueueEntry(self.tcQueue.get())
         if self.queueEntryIsTelecommand:
-            self.sendTelecommand()
+            if self.printTc:
+                self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode)
+            self.sendTelecommand(self.pusPacket)
         else:
             self.sendAndReceiveFirstPacket()
 
@@ -95,7 +97,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver):
 
     def handleReplyListening(self):
         if self.firstReplyReceived:
-            self.tmReady = select.select([g.sockReceive], [], [], 2.0)
+            self.comInterface.pollInterface(2.0)
             if self.tmReady[0]:
                 self.handleTelemetrySequence()
         else:
@@ -103,7 +105,7 @@ class SequentialCommandSenderReceiver(CommandSenderReceiver):
 
     def handleTelemetrySequence(self):
         if self.run_event.is_set():
-            self.checkForOneTelemetrySequence()
+            self.comInterface.checkForOneTelemetrySequence()
             # set this flag so the other thread can send the next telecommand
             self.replyReceived = True
             if self.tcQueue.empty():
diff --git a/sendreceive/OBSW_SingleCommandSenderReceiver.py b/sendreceive/OBSW_SingleCommandSenderReceiver.py
index 4964cb3..20a46f7 100644
--- a/sendreceive/OBSW_SingleCommandSenderReceiver.py
+++ b/sendreceive/OBSW_SingleCommandSenderReceiver.py
@@ -16,21 +16,21 @@ import time
 
 # Specific implementation of CommandSenderReceiver to send a single telecommand
 class SingleCommandSenderReceiver(CommandSenderReceiver):
-    def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, doPrintToFile):
-        super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, doPrintToFile)
+    def __init__(self, comInterface, displayMode, pusPacketTuple, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile):
+        super().__init__(comInterface, displayMode, tmTimeout, tcTimeoutFactor, printTc, doPrintToFile)
         self.pusPacketTuple = pusPacketTuple
         (self.pusPacketInfo, self.pusPacket) = self.pusPacketTuple
 
     def sendSingleTcAndReceiveTm(self):
-        self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket, self.displayMode)
+        self.tmtcPrinter.displaySentCommand(self.pusPacketInfo, self.pusPacket)
         print("Starting listener thread")
         threading.Thread(target=self.receiveReply).start()
-        g.sockSend.sendto(self.pusPacket, g.sendAddress)
+        self.comInterface.sendTelecommand(self.pusPacket)
         while not self.replyReceived:
             # wait until reply is received
             time.sleep(3)
         if self.replyReceived:
-            self.performListenerMode()
+            self.comInterface.performListenerMode()
 
     # runs in separate thread. sends TC again if no TM is received after timeout
     def receiveReply(self):
diff --git a/test/OBSW_UnitTest.py b/test/OBSW_UnitTest.py
index 531a2aa..669eebd 100644
--- a/test/OBSW_UnitTest.py
+++ b/test/OBSW_UnitTest.py
@@ -27,12 +27,17 @@ import queue
 from tc.OBSW_TcPacker import packService17TestInto, packService5TestInto, packDummyDeviceTestInto
 from sendreceive.OBSW_MultipleCommandsSenderReceiver import MultipleCommandSenderReceiver
 from OBSW_UdpClient import connectToBoard
+from utility.OBSW_TmTcPrinter import TmtcPrinter
+from comIF.OBSW_Ethernet_ComIF import EthernetComIF
 
 
 class TestService(unittest.TestCase):
+    testQueue = queue.Queue()
+
     @classmethod
     def setUpClass(cls):
         cls.displayMode = "long"
+
         # default timeout for receiving TM, set in subclass manually
         cls.tmTimeout = 3
         # wait intervals between tc send bursts.
@@ -45,11 +50,13 @@ class TestService(unittest.TestCase):
         cls.testQueue = queue.Queue()
         cls.tcTimeoutFactor = 3.0
         cls.printFile = True
+        cls.tmtcPrinter = TmtcPrinter(cls.displayMode, cls.printFile)
+        cls.communicationInterface = EthernetComIF(cls.tmtcPrinter)
         connectToBoard()
 
     def performTestingAndGenerateAssertionDict(self):
-        UnitTester = MultipleCommandSenderReceiver(self.displayMode, self.testQueue, self.tmTimeout,
-                                                   self.waitIntervals, self.waitTime, self.printTm,
+        UnitTester = MultipleCommandSenderReceiver(self.communicationInterface, self.tmtcPrinter, self.testQueue,
+                                                   self.tmTimeout, self.waitIntervals, self.waitTime, self.printTm,
                                                    self.printTc, self.tcTimeoutFactor, self.printFile)
         (tcInfoQueue, tmInfoQueue) = UnitTester.sendTcQueueAndReturnTcInfo()
         assertionDict = self.analyseTmTcInfo(tmInfoQueue, tcInfoQueue)
diff --git a/utility/OBSW_TmTcPrinter.py b/utility/OBSW_TmTcPrinter.py
index 4c7af73..ac318be 100644
--- a/utility/OBSW_TmTcPrinter.py
+++ b/utility/OBSW_TmTcPrinter.py
@@ -74,11 +74,11 @@ class TmtcPrinter:
             print(self.printBuffer)
 
     # This function handles the printing of Telecommands
-    def displaySentCommand(self, pusPacketInfo, pusPacket, displayMode):
+    def displaySentCommand(self, pusPacketInfo, pusPacket):
         if len(pusPacket) == 0:
             print("Empty packet was sent, configuration error")
             exit()
-        if displayMode == "short":
+        if self.displayMode == "short":
             self.handleShortTcPrint(pusPacketInfo)
         else:
             self.handleLongTcPrint(pusPacketInfo)
-- 
GitLab